I've made a Tic-Tac-Toe program (non-AI) for 2 human players. I will implement AI for a computer player later on. I am a beginner programmer and am also new to classes, which I've implemented in this program. I want to know how this could be optimized.
//the main class is all the way at the end
#include "stdafx.h"
#include <iostream>
#include <string>
#include <Windows.h>
//To Implement Color Mechanics
HANDLE hCon;
enum Color { DARKBLUE = 1, DARKGREEN, DARKTEAL, DARKRED, DARKPINK, DARKYELLOW, GRAY, DARKGRAY, BLUE, GREEN, TEAL, RED, PINK, YELLOW, WHITE };
void SetColor(Color c){
if(hCon == NULL)
hCon = GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleTextAttribute(hCon, c);
}
//As of now the program asks for player names but this functionality was added later on, but that disrupted some methods in the game class
//so i declared these global variables to keep the changes to a minimum
std::string player1, player2;
//its the game class, all the methods and the constructor are written right after the class
class game{
public:
game();
int insert(int,char);
int win();
void win_display();
private:
char board[9];
void color_conv(char);
void Winner(int);
};
//constructor for the class game
game::game(){
SetColor(DARKGREEN);
std::cout<<"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~Tic-Tac-Taoe~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"<<std::endl;
std::cout<<"*By Default Player 1 is 'O' and Player 2 is 'X'\n";
std::cout<<"*The choice of cells is mapped out in the following legend\n\n\n";
std::cout<<" 1 | 2 | 3 \n____|____|____\n 4 | 5 | 6 \n____|____|____\n 7 | 8 | 9 \n | | \n\n";
std::cout<<"********************************************************************************\n\n\n";
SetColor(WHITE);
//This fills up the board array with '-' a filler character, also it looks good :)
for(int k=0;k<9;k++){
board[k]='-';
}
}
//this function in game class is used to insert the right mark, i.e 'O' or 'X' , in the player's choice of position
//the return values are used in the main program to determine a valid choice
//if there is an invalid choice the current player is given another choice until he makes a valid choice
int game::insert(int choice, char mark){
SetColor(WHITE);
if(choice<=9 && board[choice-1]=='-'){
board[choice-1]=mark;
std::cout<<" "<<board[0]<<" | "<<board[1]<<" | "<<board[2]<<" \n____|____|____\n "<<board[3]<<" | "<<board[4]<<" | "<<board[5]<<" \n____|____|____\n "<<board[6]<<" | "<<board[7]<<" | "<<board[8]<<" \n | | \n\n";
return 1;
}
else if(choice>9){
SetColor(RED);
std::cout<<"Valid choices are only 1 through 9....\n\n";
SetColor(WHITE);
return 0;
}
else if(board[choice-1]!='-'){
SetColor(RED);
std::cout<<"This choice was already taken....\n\n";
SetColor(WHITE);
return 0;
}
}
//this funtion determines if there is a win
//return values are 1 for win, 0 for loss, 2 for draw
int game::win(){
//the conditions listed are for row1,row2,row3,col1,col2,col3,diagonal1 and diagonal2 respectively
if( (board[0]==board[1] && board[1]==board[2] && board[0]!='-')
||(board[3]==board[4] && board[4]==board[5] && board[3]!='-')
||(board[6]==board[7] && board[7]==board[8] && board[6]!='-')
||(board[0]==board[3] && board[3]==board[6] && board[0]!='-')
||(board[1]==board[4] && board[4]==board[7] && board[1]!='-')
||(board[2]==board[5] && board[5]==board[8] && board[2]!='-')
||(board[0]==board[4] && board[4]==board[8] && board[0]!='-')
||(board[2]==board[4] && board[4]==board[6] && board[2]!='-')){
return 1;
}
//condition for draw----> if its not a win and the board is full i.e. no '-' chars
while(true){
for(int k=0;k<9;k++){
//if there are any '-' chars then the game is not complete thus we return 0
if(board[k]=='-'){
return 0;
}
}
return 2;
}
return 0;
}
//changes the color of the input character
//this is implemented by the "win_display()"
void game::color_conv(char c){
SetColor(TEAL);
std::cout<<c;
SetColor(WHITE);
}
//display mechanism for a win/draw situation
//this is implemented to selectively color the winning condition like row1, col1, etc
void game::win_display(){
if((board[0]==board[1] && board[1]==board[2])){
std::cout<<" ";
color_conv(board[0]);
std::cout<<" | ";
color_conv(board[1]);
std::cout<<" | ";
color_conv(board[2]);
std::cout<<" \n____|____|____\n "<<board[3]<<" | "<<board[4]<<" | "<<board[5]<<" \n____|____|____\n "<<board[6]<<" | "<<board[7]<<" | "<<board[8]<<" \n | | \n\n";
Winner(0);
}
else if((board[3]==board[4] && board[4]==board[5])){
std::cout<<" "<<board[0]<<" | "<<board[1]<<" | "<<board[2]<<" \n____|____|____\n ";
color_conv(board[3]);
std::cout<<" | ";
color_conv(board[4]);
std::cout<<" | ";
color_conv(board[5]);
std::cout<<" \n____|____|____\n "<<board[6]<<" | "<<board[7]<<" | "<<board[8]<<" \n | | \n\n";
Winner(3);
}
else if((board[6]==board[7] && board[7]==board[8])){
std::cout<<" "<<board[0]<<" | "<<board[1]<<" | "<<board[2]<<" \n____|____|____\n "<<board[3]<<" | "<<board[4]<<" | "<<board[5]<<" \n____|____|____\n ";
color_conv(board[6]);
std::cout<<" | ";
color_conv(board[7]);
std::cout<<" | ";
color_conv(board[8]);
std::cout<<" \n | | \n\n";
Winner(6);
}
else if((board[0]==board[3] && board[3]==board[6])){
std::cout<<" ";
color_conv(board[0]);
std::cout<<" | "<<board[1]<<" | "<<board[2]<<" \n____|____|____\n ";
color_conv(board[3]);
std::cout<<" | "<<board[4]<<" | "<<board[5]<<" \n____|____|____\n ";
color_conv(board[6]);
std::cout<<" | "<<board[7]<<" | "<<board[8]<<" \n | | \n\n";
Winner(0);
}
else if((board[1]==board[4] && board[4]==board[7])){
std::cout<<" "<<board[0]<<" | ";
color_conv(board[1]);
std::cout<<" | "<<board[2]<<" \n____|____|____\n "<<board[3]<<" | ";
color_conv(board[4]);
std::cout<<" | "<<board[5]<<" \n____|____|____\n "<<board[6]<<" | ";
color_conv(board[7]);
std::cout<<" | "<<board[8]<<" \n | | \n\n";
Winner(1);
}
else if((board[2]==board[5] && board[5]==board[8])){
std::cout<<" "<<board[0]<<" | "<<board[1]<<" | ";
color_conv(board[2]);
std::cout<<" \n____|____|____\n "<<board[3]<<" | "<<board[4]<<" | ";
color_conv(board[5]);
std::cout<<" \n____|____|____\n "<<board[6]<<" | "<<board[7]<<" | ";
color_conv(board[8]);
std::cout<<" \n | | \n\n";
Winner(2);
}
else if((board[0]==board[4] && board[4]==board[8])){
std::cout<<" ";
color_conv(board[0]);
std::cout<<" | "<<board[1]<<" | "<<board[2]<<" \n____|____|____\n "<<board[3]<<" | ";
color_conv(board[4]);
std::cout<<" | "<<board[5]<<" \n____|____|____\n "<<board[6]<<" | "<<board[7]<<" | ";
color_conv(board[8]);
std::cout<<" \n | | \n\n";
Winner(0);
}
else if((board[2]==board[4] && board[4]==board[6])){
std::cout<<" "<<board[0]<<" | "<<board[1]<<" | ";
color_conv(board[2]);
std::cout<<" \n____|____|____\n "<<board[3]<<" | ";
color_conv(board[4]);
std::cout<<" | "<<board[5]<<" \n____|____|____\n ";
color_conv(board[6]);
std::cout<<" | "<<board[7]<<" | "<<board[8]<<" \n | | \n\n";
Winner(2);
}
}
//again this function is implemented by "win_display()" to display which player won
void game::Winner(int k){
if(board[k]=='O'){
SetColor(YELLOW);
std::cout<<player1<<" Won....\n";
SetColor(WHITE);
}
else if(board[k]=='X'){
SetColor(YELLOW);
std::cout<<player2<<" Won....\n";
SetColor(WHITE);
}
}
// main function
int main(){
int choice,i=1,turn_check;
int check=0;
game current_game;
SetColor(DARKPINK);
std::cout<<"Enter the 1st Player's Name....\n\n";
std::getline(std::cin,player1);
std::cout<<"Enter the 2nd Player's Name....\n\n";
std::getline(std::cin,player2);
SetColor(WHITE);
//to play turn wise I implemented an odd\even check
//as such when a valid choice is not made by the player, which we will know from the return value of game::insert()
//the counter i is set decremented by 1 to give the current player another chance
while(check==0){
//player 1's turn
if(i%2!=0){
std::cout<<player1<<": Enter Your Choice...."<<std::endl;
std::cin>>choice;
turn_check=current_game.insert(choice,'O');
}
//check if the game is won
check=current_game.win();
//player 2's turn
if(i%2==0){
std::cout<<player2<<": Enter Your Choice...."<<std::endl;
std::cin>>choice;
turn_check=current_game.insert(choice,'X');
}
//check if the game is won
check=current_game.win();
//increment i for the next player's turn
i++;
//if player has not made a valid chance give the player another chance
if(turn_check==0){
i--;
}
}
//at this point check=1 or 2 i.e. game is won or draw the following conditional statement check for this and displays appropriate message
if(check==1){
current_game.win_display();
}
else {
SetColor(PINK);
std::cout<<"The Game is a Draw!!!\n";
SetColor(WHITE);
}
return 0;
}
//The End