#include <iostream>
using namespace std;
int minEval(int board[9]);
int maxEval(int board[9]);
//This function displays the board.
void displayBoard(int board[9]) {
for (int i = 0; i<9; i++) {
if (board[i] == 0) {
cout << i << "\t";
}
else if (board[i] == 1) {
cout << "X\t";
}
else if (board[i] == -1) {
cout << "O\t";
}
if (i == 2 || i == 5 || i == 8) {
cout << "\n" << endl;
}
}
}
//This functions checks if the game is won
bool checkWin(int board[9]) {
if ((board[0] == board[1] && board[1] == board[2] && board[0] != 0) ||
(board[3] == board[4] && board[4] == board[5] && board[4] != 0) ||
(board[6] == board[7] && board[7] == board[8] && board[6] != 0)) {
return true;
}
else if ((board[0] == board[3] && board[3] == board[6] && board[0] != 0) ||
(board[1] == board[4] && board[4] == board[7] && board[4] != 0) ||
(board[2] == board[5] && board[5] == board[8] && board[2] != 0)) {
return true;
}
else if ((board[0] == board[4] && board[4] == board[8] && board[4] != 0) ||
(board[2] == board[4] && board[4] == board[6] && board[4] != 0)) {
return true;
}
else {
return false;
}
}
//This function checks for a draw.
bool checkDraw(int board[9]) {
int counter = 0;
for (int i = 0; i<9; i++) {
if (board[i] != 0) {
counter++;
}
}
if (counter == 9) {
return true;
}
else {
return false;
}
}
int minEval(int board[9]) {
//Checks if the board state is a win and returns 1000, which means max wins.
if (checkWin(board)) {
return 1000;
}
//If the game is drawn, it returns 0.
else if (checkDraw(board)) {
return 0;
}
//Defines the finalScore, which is the score such that max wins.
int finalScore = 1000;
//int position;
//Loops through the board and if that spot is empty, it places O at the slot and runs maxEval and reverts the board after getting the score.
for (int i = 0; i < 9; i++) {
if (board[i] == 0) {
board[i] = -1;
int score = maxEval(board);
if (score < finalScore) {
finalScore = score;
//position = i;
}
board[i] = 0;
}
}
//cout << position << endl;
return finalScore;
}
//Does exactly what minEval does with a couple of minor differences.
int maxEval(int board[9]) {
if (checkWin(board)) {
return -1000;
}
else if (checkDraw(board)) {
return 0;
}
int finalScore = -1000;
//int position;
for (int i = 0; i < 9; i++) {
if (board[i] == 0) {
board[i] = 1;
int score = minEval(board);
if (score > finalScore) {
finalScore = score;
//position = i;
}
board[i] = 0;
}
}
//cout << position << endl;
return finalScore;
}
//This function is supposed to determine which position corresponds to the best score and place either X or 0 on that position.
void playMove(int board[9], int player) {
//finalScore is either 1000 or -1000.
int finalScore = player * -1000;
int position;
//Like min and max, it loops through the board and places either an X or an O depending on the input, player, and calls either min or max.
for (int i = 0; i < 9; i++) {
if (board[i] == 0) {
board[i] = player;
int score;
if (player == 1) {
score = maxEval(board);
}
else {
score = minEval(board);
}
//The added position should correspond to the one with the best score, but on execution, something completely different happens.
//The AI makes terrible moves and doesn't play to win.
if (player == 1 && score >= finalScore) {
finalScore = score;
//cout << finalScore << endl;
position = i;
}
else if (player == -1 && score <= finalScore) {
finalScore = score;
//cout << finalScore << endl;
position = i;
}
board[i] = 0;
}
}
board[position] = player;
}
int main() {
//The starting board with all 0s, indicating the board is empty. 1 is for X and -1 is for O.
int matrix[9] = { 0, 0, 0, 0, 0, 0, 0, 0, 0 };
//int matrix[9] = { 1, -1, 1, 0, -1, 0, -1, 0, 0 };
//int test = maxEval(matrix);
//cout << test << endl;
//Loops through and plays by itself.
for (int i = 0; i < 9; i++) {
int player;
if (i % 2 == 0) {
player = -1;
}
else {
player = 1;
}
playMove(matrix, player);
displayBoard(matrix);
cout << "\n\n";
}
cin.get();
return 0;
}