You are on page 1of 7

Michael Joseph C.

Canino BSCS – 3
#7 Minimax of Modified Tic Tac Toe

Code:
//Tic-tac-toe playing AI. Exhaustive tree-search. WTFPL
//Matthew Steel 2009, www.www.repsilat.com

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

char gridChar(int i) {
switch(i) {
case -1:
return 'X';
case 0:
return ' ';
case 1:
return '0';
}
}

void draw(int b[9]) {


printf(" %c | %c |
%c\n",gridChar(b[0]),gridChar(b[1]),gridChar(b[2]));
printf("---+---+---\n");
printf(" %c | %c |
%c\n",gridChar(b[3]),gridChar(b[4]),gridChar(b[5]));
printf("---+---+---\n");
printf(" %c | %c |
%c\n",gridChar(b[6]),gridChar(b[7]),gridChar(b[8]));
}

int win(const int board[9]) {


//determines if a player has won, returns 0 otherwise.
unsigned wins[8][3] =
{{0,1,2},{3,4,5},{6,7,8},{0,3,6},{1,4,7},{2,5,8},{0,4,8},{2,4,6}};
int i;
for(i = 0; i < 8; ++i) {
if(board[wins[i][0]] != 0 &&
board[wins[i][0]] == board[wins[i][1]] &&
board[wins[i][0]] == board[wins[i][2]])
return board[wins[i][2]];
}
return 0;
}

int minimax(int board[9], int player) {


//How is the position like for player (their turn) on board?
int winner = win(board);
if(winner != 0) return winner*player;

int move = -1;


int score = -2;//Losing moves are preferred to no move
int i;
for(i = 0; i < 9; ++i) {//For all moves,
if(board[i] == 0) {//If legal,
board[i] = player;//Try the move
int thisScore = -minimax(board, player*-1);
if(thisScore > score) {
score = thisScore;
move = i;
}//Pick the one that's worst for the opponent
board[i] = 0;//Reset board after try
}
}
if(move == -1) return 0;
return score;
}

void computerMove(int board[9]) {


int move = -1;
int score = -2;
int i;
for(i = 0; i < 9; ++i) {
if(board[i] == 0) {
board[i] = 1;
int tempScore = -minimax(board, -1);
board[i] = 0;
if(tempScore > score) {
score = tempScore;
move = i;
}
}
}
//returns a score based on minimax tree at a given node.
board[move] = 1;
}

void playerMove(int board[9]) {


int move = 0;
do {
printf("Input move ([0..8]): ");
scanf("%d", &move);
printf("\n");
} while (move >= 9 || move < 0 && board[move] == 0);
board[move] = -1;
}

int * flipCoin()
{
int lower = 1, upper = 2, count = 9;
static int r[9];

srand((unsigned) time(NULL));

for (int i = 0; i < count; i++) {


r[i] = (rand() % (upper - lower + 1)) + lower;
}

return r;
}

int main() {
int board[9] = {0,0,0,0,0,0,0,0,0};
int coin;
int player = 0;
unsigned turn;
int *p;

printf("A coin will be flipped.\n\nChoose:\n\n1 - Heads\n2 -


Tails\n\n? ");
scanf("%d", &player);

p = flipCoin();

for(turn = 0; turn < 9 && win(board) == 0; ++turn) {


printf("The coin has been flipped.\n");

coin = *(p + turn);

printf("Result: %d\n", coin);

if(coin != player) {
printf("Computer's turn:\n");

computerMove(board);
draw(board);

else {
printf("Your turn:\n");
draw(board);
playerMove(board);
}
}

switch(win(board)) {
case 0:
printf("A draw. How droll.\n");
break;
case 1:
printf("You lose.\n");
break;
case -1:
draw(board);
printf("You win. Inconceivable!\n");
break;
}
}

Explanation:
The modified tic-tac-toe I created is based on one of the Tic-tac-toe variants, which is the
Random turn tic-tac-toe.

Link: Tic-tac-toe variants - Wikipedia

*N: I forgot to change 10 to 9 in the code

In the C code I added a flipCoin() function that returns an int pointer. This function creates an
array (line 96) that can hold up to *9 values of random 1 or 2. The srand() function is used
together with the time() function (line 98) that uses the current time as a seed for random
generator. 1 represents heads and 2 represents tails that are generated in Line 101. It will
determine if it’s the computer or the player’s turn. Line 104 returns the address of the array in
the location in which the function is called.

Line 115 will ask the player if he will play Heads or Tails. Line 118 will call the flipCoin() function
(example if the coin is tossed in real life) and assign to the int pointer p to access the pre-
defined values in the array to determine the turn sequence. Line 123 will access the value
(either 1 or 2) present in the address pointed by the pointer. Based on the value, for example, if
the player chooses to play as head (1), if the result is 1 (Head), the player will first to play. If the
result is 2 (Tails), it’s the computer’s turn. The game will continue (the turns are now based on
the pre-define values in the array) until there’s a winner or draw.
Online Compiler: https://onlinegdb.com/gFAMa4uzj

You might also like