This is my first program using a class that I personally designed. Please pay special attention to the design of the class and I would love pointers and advice on how to better improve logical design of classes (what should be grouped with them, better ways of creating classes to interact with each other, etc).
I am also aware that there are constructors and deconstructors, but i'm unsure when I should use those or how they should be implemented. Advice for those would be helpful as well! I recently decided to stop using using namespace std; as i've read there are many dangers with this practice and frankly...writing std:: isn't all that difficult. If someone has a counterargument to this I would love to hear it as I am a beginner and could be very wrong.
Main
//implementation of TicTacToe
//Using classes this time
#include <iostream>
#include "TicTacToeClass.h"
int main()
{
//Assumes no play unless user decides they want to play and initializes game variable to TicTacToe class
bool play = false;
TicTacToe game;
play = game.getUserWantToPlay();
//allows for multiple games to be played
while(play == true)
{
char playerWinner = 'n';
char squareArray[9] = {'1', '2', '3', '4', '5', '6', '7', '8', '9'};
char player = 'X';
//single game iteration
while(playerWinner == 'n')
{
game.drawBoard(squareArray);
game.getPlayerMove(squareArray, player);
playerWinner = game.checkForWin(squareArray, player);
if(playerWinner == 'n')
{
player = game.togglePlayer(player);
}
}
game.drawBoard(squareArray);
play = game.getUserWantToPlay();
}
return(0);
}
Class Implementation
//TicTacToe class implementation
//Leeroy Jenkins
#include "TicTacToeClass.h"
#include <iostream>
bool TicTacToe::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(char boardArray[])
{
//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 << " " << boardArray[0] << " | " << boardArray[1] << " | " << boardArray[2] << std::endl;
std::cout << "____|_____|____" << std::endl;
std::cout << " | | " << std::endl;
std::cout << " " << boardArray[3] << " | " << boardArray[4] << " | " << boardArray[5] << std::endl;
std::cout << "____|_____|____" << std::endl;
std::cout << " | | " << std::endl;
std::cout << " " << boardArray[6] << " | " << boardArray[7] << " | " << boardArray[8] << std::endl;
}
void TicTacToe::getPlayerMove(char boardArray[], 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 x = 0; x < 9; x++)
{
//If finds the array number makes the change to the iteration...prevents x or o movement
if(playerMove == boardArray[x] && playerMove != 'X' && playerMove != 'O' && playerMove != 'x' && playerMove != 'o')
{
boardArray[x] = player;
playerMoveFound = true;
}
}
if(playerMoveFound == false)
{
std::cout << "Invalid player move..." << std::endl;
}
}
}
char TicTacToe::checkForWin(char boardArray[], char player)
{
char playerWin = 'n';
int testForTie = 0;
//Tests winning combinations
if(boardArray[0] == boardArray[1] && boardArray[1] == boardArray[2])
{
playerWin = player;
}
else if(boardArray[0] == boardArray[3] && boardArray[3] == boardArray[6])
{
playerWin = player;
}
else if(boardArray[0] == boardArray[4] && boardArray[4] == boardArray[8])
{
playerWin = player;
}
else if(boardArray[1] == boardArray[4] && boardArray[4] == boardArray[7])
{
playerWin = player;
}
else if(boardArray[2] == boardArray[4] && boardArray[4] == boardArray[6])
{
playerWin = player;
}
else if(boardArray[2] == boardArray[5] && boardArray[5] == boardArray[8])
{
playerWin = player;
}
else if(boardArray[3] == boardArray[4] && boardArray[4] == boardArray[5])
{
playerWin = player;
}
else if(boardArray[6] == boardArray[7] && boardArray[7] == boardArray[8])
{
playerWin = player;
}
else
{
//Tests for a tie game
for(int x = 0; x < 9; x++)
{
if(boardArray[x] == 'x' || boardArray[x] == 'o' || boardArray[x] == 'X' || boardArray[x] == 'O')
{
testForTie++;
}
}
if(testForTie == 9)
{
playerWin = 't';
}
}
if(playerWin == player)
{
if(player == 'X')
{
std::cout << std::endl << "Congratulations player 1! You Win!" << std::endl;
}
else
{
std::cout << std::endl << "Congratulations player 2! 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);
}
Class Header
/*
* TicTacToeClass.h
*
* Created on: Jun 15, 2016
*/
#ifndef TICTACTOECLASS_H_
#define TICTACTOECLASS_H_
class TicTacToe
{
public:
bool getUserWantToPlay();
void drawBoard(char boardArray[]);
void getPlayerMove(char boardArray[], char player);
char togglePlayer(char player);
char checkForWin(char boardArray[], char player);
};
#endif /* TICTACTOECLASS_H_ */
using namespace std;!" would have been the first low-hanging fruit piece of feedback you would have received. Any counter-argument advocating its use is inherently flawed, good job killing bad habits early! \$\endgroup\$