I made some changes to my class structure and the way I determine a win. I was attempting to decide if it made sense to keep the player completely isolated to TicTacToe
game class or if it made sense to make a player class to add additional functionality.
So that you can see the progress of the code my initial implementation without classes can be found here and my first implementation with classes can be found here.
I decided to separate out the bool getUserWantToPlay()
function from the game class simply because the user could cin
a negative answer and avoid creating an instance of the TicTacToe
class all together. Is that proper thinking?
Ideally from this review, I would like to receive further advice on class implementation as well as recommendations on how classes should interact with each other. Improving my code with built in functions and clear concise syntax would also be great.
Main
//implementation of TicTacToe
//Using classes this time
#include <iostream>
#include "TicTacToeClass.h"
bool getUserWantToPlay();
int main()
{
//Assumes no play unless user decides they want to play and initializes game variable to TicTacToe class
bool play = false;
play = getUserWantToPlay();
//allows for multiple games to be played
while(play == true)
{
TicTacToe game;
char playerWinner = 'n';
char player = 'X';
//single game iteration
while(playerWinner == 'n')
{
game.drawBoard();
game.getPlayerMove(player);
playerWinner = game.checkForWin(player);
if(playerWinner == 'n')
{
player = game.togglePlayer(player);
}
}
game.drawBoard();
game = TicTacToe();
play = getUserWantToPlay();
}
return(0);
}
Class Header
/*
* TicTacToeClass.h
*
* Created on: Jun 15, 2016
*
*/
#ifndef TICTACTOECLASS_H_
#define TICTACTOECLASS_H_
class TicTacToe
{
public:
TicTacToe();
void drawBoard();
void getPlayerMove(char player);
char togglePlayer(char player);
char checkForWin(char player);
private:
char squareArray[9];
int moveCounter;
};
#endif /* TICTACTOECLASS_H_ */
Class Implementation
//TicTacToe class implementation
//Leeroy Jenkins
#include "TicTacToeClass.h"
#include <iostream>
TicTacToe::TicTacToe()
: squareArray{'1','2','3','4','5','6','7','8','9'},
moveCounter(0)
{
}
bool getUserWantToPlay()
{
char response;
bool invalidResponse = true;
bool play = false;
while(invalidResponse == true)
{
std::cout << "Would you like to play a new game of TicTacToe? (y/n) " << std::endl;
std::cin >> response;
if(response == 'y')
{
invalidResponse = false;
play = true;
}
else if(response == 'n')
{
std::cout << "No Problem!";
invalidResponse = false;
}
else
{
std::cout << "Please input a proper response (y/n)" << std::endl;
}
}
return play;
}
void TicTacToe::drawBoard()
{
//draws the game board with updated characters for each player
std::cout << "Player 1 (X) - Player 2 (O)" << std::endl << std::endl << std::endl;
std::cout << " | |" << std::endl;
std::cout << " " << squareArray[0] << " | " << squareArray[1] << " | " << squareArray[2] << std::endl;
std::cout << "____|_____|____" << std::endl;
std::cout << " | | " << std::endl;
std::cout << " " << squareArray[3] << " | " << squareArray[4] << " | " << squareArray[5] << std::endl;
std::cout << "____|_____|____" << std::endl;
std::cout << " | | " << std::endl;
std::cout << " " << squareArray[6] << " | " << squareArray[7] << " | " << squareArray[8] << std::endl;
}
void TicTacToe::getPlayerMove(char player)
{
//Gets player move and stores in board array for display through next iteration
bool playerMoveFound = false;
char playerTurn = '0';
char playerMove = '0';
if(player == 'X')
{
playerTurn = '1';
}
else
{
playerTurn = '2';
}
while(playerMoveFound == false)
{
std::cout << "Player " << playerTurn << " please make a move" << std::endl;
std::cin >> playerMove;
for(int counter = 0; counter < 9; counter++)
{
//If finds the array number makes the change to the iteration...prevents x or o movement
if(playerMove == squareArray[counter] && playerMove != 'X' && playerMove != 'O' && playerMove != 'x' && playerMove != 'o')
{
squareArray[counter] = player;
playerMoveFound = true;
//Move counter implemented to streamline check for win/check for tie
moveCounter++;
}
}
if(playerMoveFound == false)
{
std::cout << "Invalid player move..." << std::endl;
}
}
}
char TicTacToe::checkForWin(char player)
{
char playerWin = 'n';
//Ignores iteration if move counter is less than 5 since win/tie impossible until that point
if(moveCounter >= 5)
{
//Test rows for win
for(int rowCounter = 0; rowCounter < 8; rowCounter+=2)
{
if(squareArray[rowCounter] == squareArray[rowCounter + 1] && squareArray[rowCounter + 1] == squareArray[rowCounter + 2])
{
playerWin = player;
}
}
//Tests columns for win
for(int columnCounter = 0; columnCounter < 3; columnCounter++)
{
if(squareArray[columnCounter] == squareArray[columnCounter + 3] && squareArray[columnCounter + 3] == squareArray[columnCounter + 6])
{
playerWin = player;
}
}
//Tests both diagnols
if(squareArray[0] == squareArray[4] && squareArray[4] == squareArray[8])
{
playerWin = player;
}
else if(squareArray[2] == squareArray[4] && squareArray[4] == squareArray[6])
{
playerWin = player;
}
//Checks for Tie
if(moveCounter == 9 && playerWin != player)
{
playerWin = 't';
}
if(playerWin == player)
{
std::cout << std::endl << "Congratulations player " << player << "! You Win!" << std::endl;
}
else if(playerWin == 't')
{
std::cout << "Tie! You should play again to settle the duel!" << std::endl;
}
}
return(playerWin);
}
char TicTacToe::togglePlayer(char player)
{
player = player == 'X' ? 'O':'X';
return(player);
}