llyando
llyando

Reputation: 35

While loop is going one too far

So the problem I'm having is this: When a win condition is met the program should stop the while loop and just display the win/lose/draw message, but instead it allows the X and O of the game to take one more turn and I'm rather at a loss as to why. Any help would be greatly appreciated.

#include <iostream>
#include <cmath>
#include <string>
#include <cstdlib>
#include <ctime>
const int yCoordMax = 6;
const int xCoordMax = 2;

int xCoord;
int yCoord;
int square = 0;
const char PLAYER1 = 'X';
const char COMPUTER = 'O';
const int MAXTURN = 9;
char playerChar ; //the current turn's player's symbol
const std::string WIN = "You won! How nice.\n";
const std::string LOSE = "You lost.\n";
const std::string DRAW = "It's a draw.\n";
const std::string PLAY = "You will be the X's against the computer O's\n\n";
const std::string INSTRUCTIONS = "Enter the number of the square you wish to mark\nwith 1 being top left and 9 being bottom right.\n\n";
const std::string INVALIDSQUARE = "Please enter a correct square number between 1 and 9.\n";
const std::string SQUAREISFULL = "That square is already marked. Choose another.\n";
bool gameOver = false;
bool isGameDraw = false;

char boardChoices[3][3] = {{'1', '2', '3'},{'4', '5', '6'},{'7', '8', '9'}};

void drawBoard(void);
void playGame(void);
bool checkForWinner(void);
void isMoveValid(void);

int main()
{
    std::srand(time(0)); //sets the seed for computer only once
    std::cout << PLAY;
    std::cout << INSTRUCTIONS;
    playerChar = PLAYER1;
        while(!gameOver)
            {
            drawBoard();
            playGame();
            isMoveValid();
            gameOver = checkForWinner();
            }
    if (playerChar == 'O' && !isGameDraw)
        {
            drawBoard();
            std::cout << std::endl << std::endl << "Player 1 [X] Wins! Game Over!\n";
        }
        else if (playerChar == 'X' && !isGameDraw)
        {
            drawBoard();
            std::cout << std::endl << std::endl << "Player 2 [O] Wins! Game Over!\n";
        }
        else
        {
            drawBoard();
            std::cout << std::endl << std::endl << "It's a draw! Game Over!\n";
        }
return 0;
}

void drawBoard()
{
std::cout << std::endl << std::endl << "gameover says " << gameOver << std::endl;
std::cout << "+----" << "+----+" << "----+" << std::endl; // 0
std::cout << "|  " << boardChoices[0][0] << " " << "|  " << boardChoices[0][1] << " |" << "  " << boardChoices[0][2] << " |" << std::endl; // 1 input here only [1][0], [1][1], [1][2]
std::cout << "+----" << "+----+" << "----+" << std::endl; // 2
std::cout << "|  " << boardChoices[1][0] << " " << "|  " << boardChoices[1][1] << " |" << "  " << boardChoices[1][2] << " |" << std::endl; // 3 input here only [3][0], [3][1], [3][2]
std::cout << "+----" << "+----+" << "----+" << std::endl; // 4
std::cout << "|  " << boardChoices[2][0] << " " << "|  " << boardChoices[2][1] << " |" << "  " << boardChoices[2][2] << " |" << std::endl; // 5 input here only [5][0], [5][1], [5][2]
std::cout << "+----" << "+----+" << "----+" << std::endl;
}

void playGame()
{
    std::cout << std::endl;

    if(playerChar == PLAYER1)
        {
      std::cout << "X's turn :: ";
      std::cin >> square;
        }
    else if(playerChar == COMPUTER)
        {
        square = rand() % 9 + 1;
        std::cout << "O's turn:: " << square << std::endl << std::endl;
        }
      if (square == 1)
         {yCoord = 0;
         xCoord = 0;}
      if (square == 2)
         {yCoord = 0;
         xCoord = 1;}
      if (square == 3)
         {yCoord = 0;
         xCoord = 2;}
      if (square == 4)
         {yCoord = 1;
         xCoord = 0;}
      if (square == 5)
         {yCoord = 1;
         xCoord = 1;}
      if (square == 6)
         {yCoord = 1;
         xCoord = 2;}
      if (square == 7)
         {yCoord = 2;
         xCoord = 0;}
      if (square == 8)
         {yCoord = 2;
         xCoord = 1;}
      if (square == 9)
         {yCoord = 2;
         xCoord = 2;}
}

void isMoveValid()
{
    if(playerChar == PLAYER1 && boardChoices[yCoord][xCoord] != PLAYER1 && boardChoices[yCoord][xCoord] != COMPUTER)
    {
        boardChoices[yCoord][xCoord] = playerChar;
        playerChar = COMPUTER;
    }
    else if(playerChar == COMPUTER && boardChoices[yCoord][xCoord] != PLAYER1 && boardChoices[yCoord][xCoord] != COMPUTER)
    {
        boardChoices[yCoord][xCoord] = COMPUTER;
        playerChar = PLAYER1;
    }
    else
    {
        if(playerChar == PLAYER1)
        std::cout << SQUAREISFULL;
    }

}

bool checkForWinner()
{
    std::string victoryOrDefeat;
    if(playerChar == COMPUTER)
    {
        victoryOrDefeat = LOSE;
    }
    else if(playerChar == PLAYER1)
    {
        victoryOrDefeat = WIN;
    }
   if(boardChoices[0][0] == playerChar && boardChoices[0][1] == playerChar && boardChoices[0][2] == playerChar) // Horizontal
      {std::cout << victoryOrDefeat;
      return true;}
   if(boardChoices[1][0] == playerChar && boardChoices[1][1] == playerChar && boardChoices[1][2] == playerChar) // Horizontal
      {std::cout << victoryOrDefeat;
      return true;}
   if(boardChoices[2][0] == playerChar && boardChoices[2][1] ==  playerChar && boardChoices[2][2] == playerChar) // Horizontal
      {std::cout << victoryOrDefeat;
      return true;}

   if(boardChoices[0][0] == playerChar && boardChoices[1][0] == playerChar && boardChoices[2][0] == playerChar) // Vertical
      {std::cout << victoryOrDefeat;
      return true;}
   if(boardChoices[0][1] == playerChar && boardChoices[1][1] == playerChar && boardChoices[2][1] == playerChar) // Vertical
      {std::cout << victoryOrDefeat;
      return true;}
   if(boardChoices[0][2] == playerChar && boardChoices[1][2] ==  playerChar && boardChoices[2][2] == playerChar) // Vertical
      {std::cout << victoryOrDefeat;
      return true;}

   if(boardChoices[0][0] == playerChar && boardChoices[1][1] == playerChar && boardChoices[2][2] == playerChar) // Diagonal
      {std::cout << victoryOrDefeat;
      return true;}
   if(boardChoices[0][2] == playerChar && boardChoices[1][1] ==  playerChar && boardChoices[2][0] == playerChar) // Diagonal
      {std::cout << victoryOrDefeat;
      return  true;}

  for (int i = 0; i < 3; i++)//Check for draw
    {
        for (int j = 0; j < 3; j++)
        {
            if (boardChoices[i][j] != 'X' && boardChoices[i][j] != 'O')
            {
                return false;
            }
        }
    }
    isGameDraw = true;
    return true;
}

Upvotes: 2

Views: 253

Answers (1)

user2736738
user2736738

Reputation: 30906

I have got it..You are changing playerChar after each isMoveValid() check as a result when you should be checking with X you are checking with O..simple do this change after checking the winner..that will give correct result.

Initially when player1 gives X position you are checking the win move for giving O and in later cases too this happens.. That's why it's getting the error.

Upvotes: 3

Related Questions