-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtick Tack toe.cpp
181 lines (170 loc) · 6.07 KB
/
tick Tack toe.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <vector>
using namespace std;
class arena{
public :
char board[3][3]; //The board
int turns; //number of turns played.
int compX; //stores computers predicted move
int compY;
arena(){ //Constructor creates an empty board and set no. of terns as zero.
for(int i=0;i<3;i++)
for(int j=0;j<3;j++)
this->board[i][j] = '_';
this->turns = 0;
}
char isWon(){
if(turns>4){ //not possible to win in 4 turns.
if(board[0][0]==board[1][1] && board[1][1]==board[2][2] && board[0][0]!='_') // '\'Diagonal win
return board[0][0];
if(board[0][2]==board[1][1] && board[1][1]==board[2][0] && board[0][2]!='_') // '/'Diagonal win
return board[0][2];
for(int i=0;i<3;i++){
if(board[0][i]==board[1][i] && board[1][i]==board[2][i] && board[0][i]!='_') // column win
return board[0][i];
if(board[i][0]==board[i][1] && board[i][1]==board[i][2] && board[i][0]!='_') // row win
return board[i][0];
}
}
return '.'; //not yet won
}
void printBoard(){ //print current state of the board
cout<<endl;
for(int i=0;i<3;i++){
for(int j=0;j<2;j++)
cout<<this->board[i][j]<<"|";
cout<<this->board[i][2]<<endl;
}
return;
}
int makeMove(int i,int j,char c){ //execute the move.
if(this->board[i][j] != '_' || i<0 || i>2 || j<0 || j>2){
cout<<"invalid move, try again!"; //check for invalid moves.
return 0;
}
this->board[i][j] = c;
return 1;
}
vector<pair<int,int>> left(){ //returns vector of co-ordinates which are empty.
vector<pair<int,int>> myemp;
for(int i=0;i<3;i++)
for(int j=0;j<3;j++)
if(this->board[i][j]=='_')
myemp.push_back(make_pair(i,j));
return myemp;
}
int minimax(int depth, char turn){ //recursive min-max algorithm for predicting computer's move.
int minscore = 2,maxscore = -2;
int score;
vector<pair<int,int>> emp;
emp = this->left();
if(this->isWon()=='X')
return 1;
if(this->isWon()=='O')
return -1;
if(this->turns >= 9) //DRAW
return 0;
for(int i=0;i<emp.size();i++){
if(turn == 'X'){
if(this->board[emp[i].first][emp[i].second] == '_'){
this->makeMove(emp[i].first,emp[i].second,'X');
this->turns++;
score = this->minimax(depth+1,'O');
maxscore = max(score,maxscore);
}
else //this state probably never occurs.
cout<<"something wrong here"<<depth<<"\n";
this->board[emp[i].first][emp[i].second] = '_';
this->turns--;
if(score > 0 && depth==0){
this->compX = emp[i].first;
this->compY = emp[i].second;
return 1;
}
else if(score > 0)
return 1;
else if(score == 0 && depth==0){
this->compX = emp[i].first;
this->compY = emp[i].second;
}
else if(depth == 0 && i == emp.size()-1 && maxscore < 0){
this->compX = emp[i].first;
this->compY = emp[i].second;
return -1;
}
}
else if(turn == 'O'){
if(this->board[emp[i].first][emp[i].second] == '_'){
this->makeMove(emp[i].first,emp[i].second,'O');
this->turns++;
score = this->minimax(depth+1,'X');
minscore = min(score,minscore);
}
else //this state probably never occurs.
cout<<"something wrong here"<<depth<<"\n";
this->board[emp[i].first][emp[i].second] = '_';
this->turns--;
if(score < 0)
return -1;
}
}
return turn=='X'?maxscore:minscore;
}
};
int main(){
char start;
cout<<"Welcome to the GAME!!!\n\n";
playing:
youfool:
cout<<"Who starts? (X for Comp and O for Player):\n";
cin>>start;
if(start != 'X' && start != 'O')
goto youfool;
arena *game = new arena();
int won=0;
if(start == 'X'){ //Computer starts with a random position.
int x,y;
x = rand();
y = rand();
cout<<"\nComputer's turn:\n";
game->makeMove(x%3,y%3,'X');
game->turns ++;
game->printBoard();
}
while(game->isWon()=='.' && game->turns<9){ //Play game until 9 moves or an early win.
int x,y,chance=-1;
repeat:
cout<<"\nP1 enter your move (co-ordinates [0-2][0-2]) :\n"; //Player enters his move
cin>>x>>y;
if(!game->makeMove(x,y,'O')) //Player's move is executed
goto repeat;
game->turns ++;
game->printBoard();
if(game->turns >= 9 || game->isWon()!='.')
break;
cout<<"Computer's turn:\n";
chance = game->minimax(0,'X'); //Computer enters it's move
game->makeMove(game->compX,game->compY,'X'); //Computer's move is executed
game->turns ++;
game->printBoard();
}
//Print the result of the match.
if(game->isWon() == 'X'){
cout<<"\n1Computer Wins\n";
won = 1;
}
if(game->isWon() == 'O'){
cout<<"\n2Player Wins\n";
won = 1;
}
if(game->turns>=9 && won==0)
cout<<"\nDRAW!!";
char again;
cout<<"\n\nWanna play again? (Y/N):";
cin>>again;
if(again == 'Y' || again == 'y')
goto playing;
return 0;
}