Hi im new to c++ programming and am having trouble with my game. When a player chooses an already taken space or invalid move it skips their go. I would like for the player to be able to go again.
If there is any other problems you can see or any tips you can give me to tidy it up that would be great, or just any feedback.
Thank You
#include <iostream>
#include <conio.h>
#include <stdio.h>
#include <stdlib.h>
using namespace std;
char matrix[3][3] = { '1', '2', '3', '4', '5', '6', '7', '8', '9' };
int rear;
char player = 'X';
void mainMenu();
void play();
//strings for the player names to be chosen//
string charName = "Player1";
string charName2 = "Player 2";
//Noughts and Crosses//
int main()
{
system("Color 2E"); //Background and text colour//
mainMenu();
return 0;
}
void mainMenu()
{
system("CLS");
char userChoice = 'o';
do
{
//Main Menu//
cout << "\n Welcome to Noughts and Crosses" << endl
<< "\n\n 1. Play Game " << endl
<< " 2. How to Play" << endl
<< " 3. Who to refer to if the program malfunctions" << endl
<< " 4. Credits" << endl
<< " 5. Exit" << endl;
cout << "\n Please make a choice: ";
cin >> userChoice;
system("CLS");
if (userChoice == '1')
play();
else if (userChoice == '2')
cout <<
"\n\n\n Instructions:\n\n Enter the player names then press enter to proceed
with the game.\n To select the square you would like to place your marker enter the
square name followed by the ENTER key.\n Repeat this until a player has three of their
markers in a row. This can be in any direction.\n\n BE CAREFUL NOT TO CHOOSE AN ALREADY
TAKEN SPACE. OTHERWISE YOU WILL MISS A GO!!!\n\n Enjoy.\n\n\n"
<< endl;
else if (userChoice == '3')
cout << "\n\n\n Made in Visual Studios using C++\n Version 2.0\n\n" <<
endl;
else if (userChoice == '4')
cout << "\n\n\n Created by Jamie Clifford.\n Made in Visual Studios using
C++\n Version 2.0\n\n\n " << endl;
else if (userChoice == '5')
{
cout << " Good bye" << endl;
}
else
cout << " Error - Please choose again" << endl;
} while (userChoice != '5');
}
void Draw()
{
system("CLS");
//Board//
cout << "\n\n Noughts and Crosses \n\n";
for (int i = 0; i < 3; i++)
{
cout << " ";
for (int j = 0; j < 3; j++)
{
cout << matrix[i][j] << " ";
}
cout << endl;
}
}
void Input()
{
int a;
++rear;
player;
do
{
//Beginning of game, where player input their chosen space//
{ if (player == 'X')
cout << "\n It's " << charName << "'s turn. Enter a number: ";
else if (player == 'O')
cout << "\n It's " << charName2 << "'s turn. Enter a number: ";
}
cin >> a;
if (a == 1 && matrix[0][0] == '1')
matrix[0][0] = player;
else if (a == 2 && matrix[0][1] == '2')
matrix[0][1] = player;
else if (a == 3 && matrix[0][2] == '3')
matrix[0][2] = player;
else if (a == 4 && matrix[1][0] == '4')
matrix[1][0] = player;
else if (a == 5 && matrix[1][1] == '5')
matrix[1][1] = player;
else if (a == 6 && matrix[1][2] == '6')
matrix[1][2] = player;
else if (a == 7 && matrix[2][0] == '7')
matrix[2][0] = player;
else if (a == 8 && matrix[2][1] == '8')
matrix[2][1] = player;
else if (a == 9 && matrix[2][2] == '9')
matrix[2][2] = player;
else {
cout << "\n Invalid number, please try again.\n\n ";
system("pause");
rear--;
cin.ignore();
cin.get();
}
} while (a == -1);
}
void togglePlayer()
{
if (player == 'X')
player = 'O';
else player = 'X';
}
char Win()
{
//first player//
if (matrix[0][0] == 'X' && matrix[0][1] == 'X' && matrix[0][2] == 'X')
return 'X';
if (matrix[1][0] == 'X' && matrix[1][1] == 'X' && matrix[1][2] == 'X')
return 'X';
if (matrix[2][0] == 'X' && matrix[2][1] == 'X' && matrix[2][2] == 'X')
return 'X';
if (matrix[0][0] == 'X' && matrix[1][0] == 'X' && matrix[2][0] == 'X')
return 'X';
if (matrix[0][1] == 'X' && matrix[1][1] == 'X' && matrix[2][1] == 'X')
return 'X';
if (matrix[0][2] == 'X' && matrix[1][2] == 'X' && matrix[2][2] == 'X')
return 'X';
if (matrix[0][0] == 'X' && matrix[1][1] == 'X' && matrix[2][2] == 'X')
return 'X';
if (matrix[2][0] == 'X' && matrix[1][1] == 'X' && matrix[0][2] == 'X')
return 'X';
//second player//
if (matrix[0][0] == 'O' && matrix[0][1] == 'O' && matrix[0][2] == 'O')
return 'O';
if (matrix[1][0] == 'O' && matrix[1][1] == 'O' && matrix[1][2] == 'O')
return 'O';
if (matrix[2][0] == 'O' && matrix[2][1] == 'O' && matrix[2][2] == 'O')
return 'O';
if (matrix[0][0] == 'O' && matrix[1][0] == 'O' && matrix[2][0] == 'O')
return 'O';
if (matrix[0][1] == 'O' && matrix[1][1] == 'O' && matrix[2][1] == 'O')
return 'O';
if (matrix[0][2] == 'O' && matrix[1][2] == 'O' && matrix[2][2] == 'O')
return 'O';
if (matrix[0][0] == 'O' && matrix[1][1] == 'O' && matrix[2][2] == 'O')
return 'O';
if (matrix[2][0] == 'O' && matrix[1][1] == 'O' && matrix[0][2] == 'O')
return 'O';
return '/';
}
void play()
{//Players enter their names//
cout << "\n\n Player 1 enter your name: ";
cin >> charName;
cout << "\n\n Player 2 enter your name: ";
cin >> charName2;
char choice;
Draw();
Start:
while (1)
{
Input();
Draw();
if (Win() == 'X')
{
cout << "\n " << charName << " Wins The Game ";
break;
}
else if (Win() == 'O')
{
cout << "\n " << charName2 << " Wins The Game " << endl;
break;
}
else if (rear == 9)
{
cout << " Draw" << endl;
break;
}
togglePlayer();
}
//Choice to play the game again or return to the main menu//
cout << "\n\n ";
cout << " Do you want to go play again? ";
cout << "\n\n 1. Yes\n";
cout << " 2. No\n\n";
cout << " ";
cin >> choice;
if (choice == '1')
cout <<"\n Enjoy\n";
else if (choice == '2')
mainMenu();
while (choice != '1');
{
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
matrix[i][j] = i * 3 + (j + 1) + 48;
}
}
rear = 0;
player = 'X';
goto Start;
}
}
1. Indentation: You must indent what's inside the scopes ({}) so that it's possible to understand where loops/conditions start/end.
2. Global variables: You seem to be using a global variable rear. First of all global variables should be tagged like calling it g_rear so that whoever is reading the code knows it's a global variable. Second, it's not clear what this variable does from its name.
3. Possible infinite loop in line 242: while (choice != '1');
4. Use of goto: In general you should not use goto unless it's for error handling. The easiest way to debug/maintain code is if you know exactly the entry point into a piece of code and the exit point from that piece of code. A goto means you get to some point in the program in several different ways with the state of the program possibly being very different in each time.
5. Use loops instead of repeating yourself:
if (matrix[0][0] == 'X' && matrix[0][1] == 'X' && matrix[0][2] == 'X')
return 'X';
if (matrix[1][0] == 'X' && matrix[1][1] == 'X' && matrix[1][2] == 'X')
return 'X';
if (matrix[2][0] == 'X' && matrix[2][1] == 'X' && matrix[2][2] == 'X')
return 'X';
if (matrix[0][0] == 'X' && matrix[1][0] == 'X' && matrix[2][0] == 'X')
return 'X';
if (matrix[0][1] == 'X' && matrix[1][1] == 'X' && matrix[2][1] == 'X')
return 'X';
if (matrix[0][2] == 'X' && matrix[1][2] == 'X' && matrix[2][2] == 'X')
return 'X';
if (matrix[0][0] == 'X' && matrix[1][1] == 'X' && matrix[2][2] == 'X')
return 'X';
if (matrix[2][0] == 'X' && matrix[1][1] == 'X' && matrix[0][2] == 'X')
return 'X';
//second player//
if (matrix[0][0] == 'O' && matrix[0][1] == 'O' && matrix[0][2] == 'O')
return 'O';
if (matrix[1][0] == 'O' && matrix[1][1] == 'O' && matrix[1][2] == 'O')
return 'O';
if (matrix[2][0] == 'O' && matrix[2][1] == 'O' && matrix[2][2] == 'O')
return 'O';
if (matrix[0][0] == 'O' && matrix[1][0] == 'O' && matrix[2][0] == 'O')
return 'O';
if (matrix[0][1] == 'O' && matrix[1][1] == 'O' && matrix[2][1] == 'O')
return 'O';
if (matrix[0][2] == 'O' && matrix[1][2] == 'O' && matrix[2][2] == 'O')
return 'O';
if (matrix[0][0] == 'O' && matrix[1][1] == 'O' && matrix[2][2] == 'O')
return 'O';
if (matrix[2][0] == 'O' && matrix[1][1] == 'O' && matrix[0][2] == 'O')
return 'O';
Is a huge messy code, it's very difficult to see if there's a bug in it. Do the same with loops.
Same is true here:
if (a == 1 && matrix[0][0] == '1')
matrix[0][0] = player;
else if (a == 2 && matrix[0][1] == '2')
matrix[0][1] = player;
else if (a == 3 && matrix[0][2] == '3')
matrix[0][2] = player;
else if (a == 4 && matrix[1][0] == '4')
matrix[1][0] = player;
else if (a == 5 && matrix[1][1] == '5')
matrix[1][1] = player;
else if (a == 6 && matrix[1][2] == '6')
matrix[1][2] = player;
else if (a == 7 && matrix[2][0] == '7')
matrix[2][0] = player;
else if (a == 8 && matrix[2][1] == '8')
matrix[2][1] = player;
else if (a == 9 && matrix[2][2] == '9')
matrix[2][2] = player;
6. As for your actual question: Here:
else {
cout << "\n Invalid number, please try again.\n\n ";
system("pause");
rear--;
cin.ignore();
cin.get();
}
Change it to:
else {
cout << "\n Invalid number, please try again.\n\n ";
system("pause");
rear--;
cin.ignore();
cin.get();
a=-1;
}
To trigger the do ... while loop to make another cycle.
Just add in the else condition in Input()
a = -1;
Related
I am working on creating a recursion function that tells me when there are no more numbers in a string that I pass into it. For some reason, the recursion works fine and stops when there are no more numbers. However, when I try to return the numbers and use them in my code, I either get random characters or it will fail the program if I set the function to a variable string. Here is my code:
if (checkX(equalsLocation, math)) {
cout << "Start on the left side, x is on the right" << endl;
xSide = 1;
cout << partOneFinder(0, equalsLocation, math, "") << endl;
}
And then my function is here:
string partOneFinder(int current, int max, string math, string total) {
cout << "This is the current iteration: " << current << "and the string: " << total <<endl;
if (((math[current] == '0') || (math[current] == '1') || (math[current] == '2') || (math[current] == '3') || (math[current] == '4') || (math[current] == '5') ||
(math[current] == '6') || (math[current] == '7') || (math[current] == '8') || (math[current] == '9')) && current <= max)
{
total += math[current];
partOneFinder(current + 1, max, math, total);
} else if (math[current] == 'x'){
cout << "FOUND X!" << endl;
}
else {
string testTotal = total;
return testTotal;
}
}
What am I doing wrong?
You have to execute return statement in all execution paths of non-void function, or undefined behavior is invoked.
string partOneFinder(int current, int max, string math, string total) {
cout << "This is the current iteration: " << current << "and the string: " << total <<endl;
if (((math[current] == '0') || (math[current] == '1') || (math[current] == '2') || (math[current] == '3') || (math[current] == '4') || (math[current] == '5') ||
(math[current] == '6') || (math[current] == '7') || (math[current] == '8') || (math[current] == '9')) && current <= max)
{
total += math[current];
// return something (I guessed to return the result of recursive call)
return partOneFinder(current + 1, max, math, total);
} else if (math[current] == 'x'){
cout << "FOUND X!" << endl;
// return something (I couldn't guess)
return "";
}
else {
string testTotal = total;
return testTotal;
}
}
I'm in the beginning stages of creating a tic-tac-toe game in C++, and in order to place the "pieces" on the board, I use a switch statement. Inside the switch, there are if-else statements to check if the requested space is occupied. However, whenever I input a spot, It executes the if-statement (places the piece), and then also executes the else-statement (says "Try again" and makes the player repeat their turn).
I've tried moving the 'break' statement before the else and within the if, but it seems to create more errors than it fixes. I also tried explicitly coding 'else-if' statements instead of just 'else', but it didn't work either.
Switch-statement:
bool place_pieces(int input, bool turn)
{
bool occupied{ false };
switch (input) {
case 7:
if (board[0][0] != 'x' && board[0][0] != 'o') {
if (turn == true)
board[0][0] = 'x';
else
board[0][0] = 'o';
}
else if (board[0][0] == 'x' || board[0][0] == 'o') {
occupied = true;
cout << "Try again" << endl;
}
break;
case 8:
if (board[0][1] != 'x' && board [0][1] != 'o') {
if (turn == true)
board[0][1] = 'x';
else
board[0][1] = 'o';
}
else if (board[0][1] == 'x' || board[0][1] == 'o') {
occupied = true;
cout << "Try again" << endl;
}
break;
case 9:
if (board[0][2] != 'x' && board[0][2] != 'o') {
if (turn == true)
board[0][2] = 'x';
else
board[0][2] = 'o';
}
else if (board[0][2] == 'x' || board[0][2] == 'o') {
occupied = true;
cout << "Try again" << endl;
}
break;
case 4:
if (board[1][0] != 'x' && board[1][0] != 'o') {
if (turn == true)
board[1][0] = 'x';
else
board[1][0] = 'o';
}
else if (board[1][0] == 'x' || board[1][0] == 'o') {
occupied = true;
cout << "Try again" << endl;
}
break;
case 5:
if (board[1][1] != 'x' && board[1][1] != 'o') {
if (turn == true)
board[1][1] = 'x';
else
board[1][1] = 'o';
}
else if (board[1][1] == 'x' || board[1][1] == 'o') {
occupied = true;
cout << "Try again" << endl;
}
break;
case 6:
if (board[1][2] != 'x' && board[1][2] != 'o') {
if (turn == true)
board[1][2] = 'x';
else
board[1][2] = 'o';
}
else if (board[1][2] == 'x' || board[1][2] == 'o') {
occupied = true;
cout << "Try again" << endl;
}
break;
case 1:
if (board[2][0] != 'x' && board[2][0] != 'o') {
if (turn == true)
board[2][0] = 'x';
else
board[2][0] = 'o';
}
else if (board[2][0] == 'x' || board[2][0] == 'o') {
occupied = true;
cout << "Try again" << endl;
}
break;
case 2:
if (board[2][1] != 'x' && board[2][1] != 'o') {
if (turn == true)
board[2][1] = 'x';
else
board[2][1] = 'o';
}
else if (board[2][1] == 'x' || board[2][1] == 'o') {
occupied = true;
cout << "Try again" << endl;
}
break;
case 3:
if (board[2][2] != 'x' && board[2][2] != 'o') {
if (turn == true)
board[2][2] = 'x';
else
board[2][2] = 'o';
}
else if (board[2][2] == 'x' || board[2][2] == 'o') {
occupied = true;
cout << "Try again" << endl;
}
break;
}
return occupied;
}
Game loop:
while (!game_over) {
x_turn = true;
cout << "Player 1: ";
cin >> player_input;
place_pieces(player_input, x_turn);
if (place_pieces(player_input, x_turn) == true) {
draw_board();
cout << endl;
continue;
}
else {
draw_board();
cout << endl;
}
x_turn = false;
cout << "Player 2: ";
cin >> player_input;
place_pieces(player_input, x_turn);
if (place_pieces(player_input, x_turn) == true) {
draw_board();
cout << endl;
continue;
}
else {
draw_board();
cout << endl;
}
}
I want it to just display the new board with the piece added, and not say "Try again" or have the player repeat their turn.
You can even find out the problem without debugging. A review shows that you are doing
place_pieces(player_input, x_turn);
if (place_pieces(player_input, x_turn) == true) {
So you first place the piece, and then, in the if statement, you call the function again. And only in the if statement your are checking the return value.
If you call your function for 2 times with the same parameter, then at the 2nd time, the place will always be occupied.
Your misunderstanding is that you think that in the if statement just the return value will be checked. But that is not true. The function will be called again.
That is a so called side effect. You should not call functions in if statements or other boolean expressions.
The solution is easy. Declare a bool variable, get the result and then check the bool in the if:
bool result = place_pieces(player_input, x_turn);
if (result) {
Hope this helps . . .
Homework problem from class: I have to generate a tic tac toe game which uses a coin toss to determine who goes first. I've generated most of my code, but there are still several things/bugs I can't figure out.
I know how to do the coin flip. But, how do I get the program to choose who goes first.
Winning square or Game-ending square doesn't get X or O on it.
There is no message for a Tie game.
There is no message when you just press enter without entering any value.
#include "pch.h"
#include <iostream>
#include <string>
#include <cstdlib>
#include <time.h>
using namespace std;
void Flip_Coin();
void Do_Exercise();
void Display_Board();
void Ask_Turn();
char Check_Winner();
void Computer_Player_Turn();
char Board[3][3] = { '1', '2', '3', '4', '5', '6', '7', '8', '9' };
int n = 0;
int main()
{
srand(time(0));
Do_Exercise();
cin.get();
return 0;
}
void Do_Exercise()
{
Flip_Coin();
while (true)
{
n++;
Display_Board();
Ask_Turn();
if (Check_Winner() == 'X')
{
cout << "Human Wins!" << endl;
break;
}
else if (Check_Winner() == 'O')
{
cout << "Computer Wins!" << endl;
break;
}
else if (Check_Winner() == 'T' && n == 9)
{
cout << "It's a draw." << endl;
break;
}
Computer_Player_Turn();
if (Check_Winner() == 'X')
{
cout << "Human Wins!" << endl;
break;
}
else if (Check_Winner() == 'O')
{
cout << "Computer Wins!" << endl;
break;
}
else if (Check_Winner() == 'T' && n == 9)
{
cout << "It's a draw." << endl;
break;
}
}
}
void Flip_Coin()
{
int Flip;
cout << "Welcome to Tic - Tac - toe.\n\n"
<< "Wait I am flipping a coin to see who goes first . . .\n\n";
Flip = rand() % 2;
if (Flip == 0)
{
cout << "Computer wins coin toss.\n\n";
}
else
{
cout << "Human wins coin toss.\n\n";
}
cout << "The board is laid out like this:\n\n";
}
void Display_Board()
{
for (int Row = 0; Row < 3; Row++)
{
for (int Column = 0; Column < 3; Column++)
{
cout << Board[Row][Column] << "\t";
}
cout << "\n\n";
}
}
void Ask_Turn()
{
string input;
while (true)
{
cout << "Enter the position to place your X: ";
cin >> input;
cout << endl;
if (input != "")
{
char entered = input.c_str()[0]; // sets char character to act in place of string
if (entered >= '1' && entered <= '9')
{
cout << "The human places a X-token at position: " << entered << "\n\n";
cout << "Current board:\n\n";
int entered_number = entered - '0'; // changes char to int form
int index = entered_number - 1;
int row = index / 3;
int col = index % 3;
char grid_position = Board[row][col];
if (grid_position == 'X' || grid_position == 'O')
{
cout << "That position is already taken. ";
}
else {
Board[row][col] = 'X';
break;
}
}
else {
cout << "You must entered in the the range of 1-9.\n";
}
}
else {
cout << "You must enter something!"; // doesnt work
}
}
}
char Check_Winner()
{
//first player
if (Board[0][0] == 'X' && Board[0][1] == 'X' && Board[0][2] == 'X')
return 'X';
if (Board[1][0] == 'X' && Board[1][1] == 'X' && Board[1][2] == 'X')
return 'X';
if (Board[2][0] == 'X' && Board[2][1] == 'X' && Board[2][2] == 'X')
return 'X';
if (Board[0][0] == 'X' && Board[1][0] == 'X' && Board[2][0] == 'X')
return 'X';
if (Board[0][1] == 'X' && Board[1][1] == 'X' && Board[2][1] == 'X')
return 'X';
if (Board[0][2] == 'X' && Board[1][2] == 'X' && Board[2][2] == 'X')
return 'X';
if (Board[0][0] == 'X' && Board[1][1] == 'X' && Board[2][2] == 'X')
return 'X';
if (Board[2][0] == 'X' && Board[1][1] == 'X' && Board[0][2] == 'X')
return 'X';
//second player
if (Board[0][0] == 'O' && Board[0][1] == 'O' && Board[0][2] == 'O')
return 'O';
if (Board[1][0] == 'O' && Board[1][1] == 'O' && Board[1][2] == 'O')
return 'O';
if (Board[2][0] == 'O' && Board[2][1] == 'O' && Board[2][2] == 'O')
return 'O';
if (Board[0][0] == 'O' && Board[1][0] == 'O' && Board[2][0] == 'O')
return 'O';
if (Board[0][1] == 'O' && Board[1][1] == 'O' && Board[2][1] == 'O')
return 'O';
if (Board[0][2] == 'O' && Board[1][2] == 'O' && Board[2][2] == 'O')
return 'O';
if (Board[0][0] == 'O' && Board[1][1] == 'O' && Board[2][2] == 'O')
return 'O';
if (Board[2][0] == 'O' && Board[1][1] == 'O' && Board[0][2] == 'O')
return 'O';
return 'T';
}
void Computer_Player_Turn()
{
while (true)
{
int computer_choice = (rand() % 9) + 1;
int row = (computer_choice - 1) / 3;
int col = (computer_choice - 1) % 3;
char grid_position = Board[row][col];
if (grid_position == 'X' || grid_position == 'O')
{
continue;
}
else {
cout << "The Computer places a O-token at position: " << computer_choice << "\n\n";
Board[row][col] = 'O';
break;
}
}
}
Here is the solution.
1) Right now you have hard-coded to call Ask_Turn first and then call Computer_Player_Turn. Instead of calling them in this way, call them first from coin flip and then let the two functions call each other when they finish.
2) Call Display_Board() before checking for winner.
3) Fixed here. You were only adding n by 1 for every 2 turns.
4) Ask for the input in a while loop, and as long as the input is empty be in the loop
So making all those changes, the code should look something similar to below.
I have tested the code here, https://onlinegdb.com/S1Qdcr63X
#include <iostream>
#include <string>
#include <cstdlib>
#include <time.h>
using namespace std;
void Flip_Coin();
void Do_Exercise();
void Display_Board();
void Ask_Turn();
char Check_Winner();
void Computer_Player_Turn();
char Board[3][3] = { '1', '2', '3', '4', '5', '6', '7', '8', '9' };
int n = 0;
void Computer_Player_Turn();
void Ask_Turn();
int main()
{
srand(time(0));
Do_Exercise();
cin.get();
return 0;
}
void Do_Exercise()
{
Flip_Coin();
}
void Flip_Coin()
{
int Flip;
cout << "Welcome to Tic - Tac - toe.\n\n"
<< "Wait I am flipping a coin to see who goes first . . .\n\n";
Flip = rand() % 2;
if (Flip == 0)
{
cout << "Computer wins coin toss.\n\n";
Computer_Player_Turn();
}
else
{
cout << "Human wins coin toss.\n\n";
Ask_Turn();
}
}
void Display_Board()
{
for (int Row = 0; Row < 3; Row++)
{
for (int Column = 0; Column < 3; Column++)
{
cout << Board[Row][Column] << "\t";
}
cout << "\n\n";
}
}
char Check_Winner()
{
//first player
if (Board[0][0] == 'X' && Board[0][1] == 'X' && Board[0][2] == 'X')
return 'X';
if (Board[1][0] == 'X' && Board[1][1] == 'X' && Board[1][2] == 'X')
return 'X';
if (Board[2][0] == 'X' && Board[2][1] == 'X' && Board[2][2] == 'X')
return 'X';
if (Board[0][0] == 'X' && Board[1][0] == 'X' && Board[2][0] == 'X')
return 'X';
if (Board[0][1] == 'X' && Board[1][1] == 'X' && Board[2][1] == 'X')
return 'X';
if (Board[0][2] == 'X' && Board[1][2] == 'X' && Board[2][2] == 'X')
return 'X';
if (Board[0][0] == 'X' && Board[1][1] == 'X' && Board[2][2] == 'X')
return 'X';
if (Board[2][0] == 'X' && Board[1][1] == 'X' && Board[0][2] == 'X')
return 'X';
//second player
if (Board[0][0] == 'O' && Board[0][1] == 'O' && Board[0][2] == 'O')
return 'O';
if (Board[1][0] == 'O' && Board[1][1] == 'O' && Board[1][2] == 'O')
return 'O';
if (Board[2][0] == 'O' && Board[2][1] == 'O' && Board[2][2] == 'O')
return 'O';
if (Board[0][0] == 'O' && Board[1][0] == 'O' && Board[2][0] == 'O')
return 'O';
if (Board[0][1] == 'O' && Board[1][1] == 'O' && Board[2][1] == 'O')
return 'O';
if (Board[0][2] == 'O' && Board[1][2] == 'O' && Board[2][2] == 'O')
return 'O';
if (Board[0][0] == 'O' && Board[1][1] == 'O' && Board[2][2] == 'O')
return 'O';
if (Board[2][0] == 'O' && Board[1][1] == 'O' && Board[0][2] == 'O')
return 'O';
return 'T';
}
bool winner()
{
if (Check_Winner() == 'X')
{
cout << "Human Wins!" << endl;
return true;
}
else if (Check_Winner() == 'O')
{
cout << "Computer Wins!" << endl;
return true;
}
else if (Check_Winner() == 'T' && n == 9)
{
cout << "It's a draw." << endl;
return true;
}
return false;
}
void Ask_Turn()
{
n++;
string input = "";
while (true)
{
do
{
cout << "Enter the position to place your X: ";
cin >> input;
cout << endl;
}
while(input == "" || (input.c_str()[0] < '1' || input.c_str()[0] > '9'));
char entered = input.c_str()[0]; // sets char character to act in place of string
cout << "The human places a X-token at position: " << entered << "\n\n";
cout << "Current board:\n\n";
int entered_number = entered - '0'; // changes char to int form
int index = entered_number - 1;
int row = index / 3;
int col = index % 3;
char grid_position = Board[row][col];
if (grid_position == 'X' || grid_position == 'O')
{
cout << "That position is already taken. ";
n--;
Ask_Turn();
}
else {
Board[row][col] = 'X';
break;
}
}
Display_Board();
if(winner())
return;
else
Computer_Player_Turn();
}
void Computer_Player_Turn()
{
n++;
while (true)
{
int computer_choice = (rand() % 9) + 1;
int row = (computer_choice - 1) / 3;
int col = (computer_choice - 1) % 3;
char grid_position = Board[row][col];
if (grid_position == 'X' || grid_position == 'O')
{
continue;
}
else {
cout << "The Computer places a O-token at position: " << computer_choice << "\n\n";
Board[row][col] = 'O';
break;
}
}
Display_Board();
if(winner())
return;
else
Ask_Turn();
}
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question appears to be off-topic because it lacks sufficient information to diagnose the problem. Describe your problem in more detail or include a minimal example in the question itself.
Closed 8 years ago.
Improve this question
I am creating a tic-tac-toe program and cannot get the game to accurately check if there is a tie. The tie should be declared when all numbers on the board are filled with 'X' or 'O' & there is no winner.
With the code I have now, every time I run the program it declares there is a tie. Am I placing the function wrong? I think something is wrong INSIDE of the tieGame() boolean.
using namespace std;
char board[9] { //array of characters with number placeholders for chars X and O
'1', '2', '3', '4', '5', '6', '7', '8', '9'
};
bool checkWinner(void) {
bool winner = false;
if // Check for possible winning solutions for X
((board[0] == 'X' && board[1] == 'X' && board[2] == 'X')
||
(board[3] == 'X' && board[4] == 'X' && board[5] == 'X')
||
(board[6] == 'X' && board[7] == 'X' && board[8] == 'X')
||
(board[0] == 'X' && board[4] == 'X' && board[8] == 'X')
||
(board[2] == 'X' && board[4] == 'X' && board[6] == 'X')
||
(board[0] == 'X' && board[3] == 'X' && board[6] == 'X')
||
(board[1] == 'X' && board[4] == 'X' && board[7] == 'X')
||
(board[2] == 'X' && board[5] == 'X' && board[8] == 'X'))
{
winner = 1; // Winner is true if conditions are met
cout << "Player 1 Wins!" << endl;
}
else if // Check for possible winning solutions for O
((board[0] == 'O' && board[1] == 'O' && board[2] == 'O')
||
(board[3] == 'O' && board[4] == 'O' && board[5] == 'O')
||
(board[6] == 'O' && board[7] == 'O' && board[8] == 'O')
||
(board[0] == 'O' && board[4] == 'O' && board[8] == 'O')
||
(board[2] == 'O' && board[4] == 'O' && board[6] == 'O')
||
(board[0] == 'O' && board[3] == 'O' && board[6] == 'O')
||
(board[1] == 'O' && board[4] == 'O' && board[7] == 'O')
||
(board[2] == 'O' && board[5] == 'O' && board[8] == 'O'))
{
winner = 1; // winner is True if conditions are met
cout << "Player 2 Wins!" << endl;
}
return winner; // Is there a winner?
}
bool tieGame() {
bool tiegame = false;
if // check for tie
((board[0] == 'X' || 'O') && (board[1] == 'X' || 'O') && (board[2] == 'X' || 'O')
&&
(board[3] == 'X' || 'O') && (board[4] == 'X' || 'O') && (board[5] == 'X' || 'O')
&&
(board[6] == 'X' || 'O') && (board[7] == 'X' || 'O') && (board[8] == 'X' || 'O'))
{
tiegame = 1;
cout << "The game is a tie! Play again!" << endl;
}
else {
tiegame = 0;
}
return tiegame; // Is the game a tie?
}
void displayBoard(void) { //Displays the game board
int index; // used to access the array
index = 0;
cout << endl;
cout << board[index] << "|" << board[index+1] << "|" << board[index+2] << endl;
cout << "-----" << endl;
cout << board[index+3] << "|" << board[index+4] << "|" << board[index+5] << endl;
cout << "-----" << endl;
cout << board[index+6] << "|" << board[index+7] << "|" << board[index+8] << endl;
}
void tictactoe(void) { //Main function; displays board and inputs player moves
int movePosition; // used to track user input and replace array indexes with the user input
cout << "Player 1 is X, player 2 is O" << endl;
for (int i=0; i < 5; i++) {
if (tieGame() ) {
cout << "Tie game!" << endl;
return;
}
displayBoard(); // Display game board with updated characters
if (checkWinner() ) //if winner is TRUE, return "Winner" and exit game.
{
cout << "Good Game!" << endl;
return;
}
cout << "Player 1, Enter the space number where you would like to place X" << endl;
cin >> movePosition; // Retrieve user input & call it 'movePosition'
while ((board[movePosition - 1] == 'X' || board[movePosition - 1] == 'O')) { //Check to make sure a user has not
cout << "This space is already taken. Please choose an open space." << endl; // attempted to enter a
cin >> movePosition; // value that has already been entered
}
board[movePosition - 1] = 'X';
displayBoard(); // Display game board with updated characters
if (checkWinner() ) //if winner is TRUE, return "Winner" and exit game.
{
cout << "Good Game!" << endl;
return;
}
cout << "Player 2, Enter the space number where you would like to place O" << endl;
cin >> movePosition;
while ((board[movePosition - 1] == 'X' || board[movePosition - 1] == 'O')) {
cout << "This space is already taken. Please choose an open space." << endl;
cin >> movePosition;
}
board[movePosition - 1] = 'O';
}
}
int main (int argc, char *argv[]) {
tictactoe();
}
The conditions like the following are wrong:
(board[0] == 'X' || 'O')
Because of C++ operator precedence and evaluation rules, the compiler understands it as:
(board[0] == 'X') || ('O' != 0)
The second part is, of course, always true, so it always succeeds for every field and therefore for the whole board.
You would need to write it explicitly in two comparisons like this:
(board[0] == 'X' || board[0] == 'O')
For the future, a better solution than a bunch of conditions would be a loop, for example:
bool tieGame()
{
for (int i = 0; i < 9; i++) {
if (board[i] != 'X' && board[i] != 'O') {
// Some field is empty, not a tie
return false;
}
}
// All fields are either 'X' or 'O'
cout << "The game is a tie! Play again!" << endl;
return true;
}
And even more better, as Nenad wrote in his answer, just count the number of free spaces left (or the used fields) -- that's just one variable comparison instead of going through the whole board each time.
You can check if it's a tie by having a counter
int freeSpaces = 9;
Which you will decrement each time players fills an empty slot on board.
Then check
if (freeSpaces == 0 && !winner) tieGame = true;
else tieGame = false;
The expressions of the form (board[0] == 'X' || 'O') always evaluate to true since 'O' is a non-zero value (79 to be exact). As a result, all your checks for tieGame are true. What you want is (board[0] == 'X' || board[0] == 'O').
Is there a way to store the x and y entered by the user into a location for the array.
I have this:
if (x == 1 && y == 1)
{
board[0][0] = playerMarker;
}
I want to make it so the x and y are stored into a variable that matches the name of a spot in an array.
But I want to try and make it more like this:
if (currentMove == '1' && squareOne == '1')
squareOne = playerMarker;
This is a code I have seen above. The code bellow is my own.
void playerMove(char* CurrentPlayer, char (&board)[3][3], char &playerMarker)
{
bool bValidMove;
int x,y;
// Prompt the player for a move
cout << "Player " << CurrentPlayer << "'s move:" << endl;
// Loop until we get a valid move
do
{
cout << "Please enter the row number for the place you wish to mark: " << endl;
cin >> x;
cout << "Please enter the column number for the place you wish to mark" << endl;
cin >> y;
bValidMove = true;
// Check for a valid move
if (x == 1 && y == 1)
{
board[0][0] = playerMarker;
}
else if (x == 1 && y == 2)
{
board[0][1] = playerMarker;
}
else if (x == 1 && y == 3)
{
board[0][2] = playerMarker;
}
else if (x == 2 && y == 1)
{
board[1][0] = playerMarker;
}
else if (x == 2 && y == 2)
{
board[1][1] = playerMarker;
}
else if (x == 2 && y == 3)
{
board[1][2] = playerMarker;
}
else if (x == 3 && y == 1)
{
board[2][0] = playerMarker;
}
else if (x == 3 && y == 2)
{
board[2][1] = playerMarker;
}
else if (x == 3 && y == 3)
{
board[2][2] = playerMarker;
}
else
{
cout << "Invalid Move. Try again." << endl;
bValidMove = false;
}
}
while (!bValidMove);
}
This is the code I am trying to make my own into.
// Ask current player for a move
cout << currentPlayer << "'s move: ";
bool validMove;
// Loop until a valid move is chosen
do
{
char currentMove;
cin >> currentMove;
validMove = true;
// Check for a valid move
if (currentMove == '1' && squareOne == '1')
squareOne = playerMarker;
else if (currentMove == '2' && squareTwo == '2')
squareTwo = playerMarker;
else if (currentMove == '3' && squareThree == '3')
squareThree = playerMarker;
else if (currentMove == '4' && squareFour == '4')
squareFour = playerMarker;
else if (currentMove == '5' && squareFive == '5')
squareFive = playerMarker;
else if (currentMove == '6' && squareSix == '6')
squareSix = playerMarker;
else if (currentMove == '7' && squareSeven == '7')
squareSeven = playerMarker;
else if (currentMove == '8' && squareEight == '8')
squareEight = playerMarker;
else if (currentMove == '9' && squareNine == '9')
squareNine = playerMarker;
else
{
cout << "Invalid Move. Try again: ";
validMove = false;
}
} while ( !validMove );
ok this is just a guess at what you want, but here it goes:
do
{
cout << "Please enter the row number for the place you wish to mark: " << endl;
cin >> x;
cout << "Please enter the column number for the place you wish to mark" << endl;
cin >> y;
bValidMove = true;
int xx = x-'1';
int yy = y-'1';
if ( xx < 0 || xx > 2 || yy < 0 || yy > 2 )
{
cout << "Invalid Move (outside board). Try again: ";
validMove = false;
} else if ( board[xx][yy] == 0 ) {
board[xx][yy] = playerMarker;
} else {
cout << "Invalid Move (position already taken). Try again: ";
validMove = false;
}
etc etc
This assumes the board is a 3x3 array, containing 0 when the position is not taken by a player, and takes row 1/2/3 and col 1/2/3 as input.
Hope this helps...
You could do
char& squareOne = board[0][0];
char& squareTwo = board[0][1];
char& squareThree = board[0][2];
char& squareFour = board[1][0];
...
The ampersand(&) means that squareFour is a reference to board[1][0] (they share the same underlying memory, so changing one is changing both).
Note that instead of 9 'if's, you can compute the row/column and set
board[row][column] = playerMarker (row & column may be reversed for you)