Last active
December 22, 2015 06:29
-
-
Save AnnaOpss/6431552 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <string.h> | |
/* This function looks for winning moves of a player */ | |
void findThreat (int, int [][2], int [][3]); | |
int main (int argc, char* argv[]) | |
{ | |
int grid[3][3], nextgrid[3][3], i, j, col, row, positionO, Threats[2][2]; | |
int Forks[2][2], forknum, win, shouldgoon; | |
puts("========================="); | |
puts("| OOO | OOO | X X | HELLO, AND WELCOME STRANGER"); | |
puts("| O O | O O | X |"); | |
puts("| OOO | OOO | X X | GET READY NOT TO WIN AT"); | |
puts("|=======|=======|=======|"); | |
puts("| | X X | | TIC-TAC-TOE!!"); | |
puts("| | X | |"); | |
puts("| | X X | |"); | |
puts("|=======|=======|=======| For input, think of a grid like:"); | |
puts("| X X | | |"); | |
puts("| X | | | 1 2 3"); | |
puts("| X X | | | 4 5 6"); | |
puts("|=======|=======|=======| 7 8 9"); | |
puts(""); | |
puts(""); | |
win = 0; | |
for (i=0; i<3; i++) | |
for (j=0; j<3; j++) { | |
grid[i][j] = 0; | |
nextgrid[i][j] = 0; | |
} | |
do { | |
puts("Place your O:"); | |
scanf("%d", &positionO); | |
puts(""); | |
if (positionO > 9 || positionO < 1) | |
continue; | |
positionO = positionO - 1; | |
col = positionO % 3; | |
row = positionO / 3; | |
if (grid[row][col] != 0) | |
continue; | |
grid[row][col] = 1; | |
// WINNING STRATEGY COURTESY OF | |
// https://en.wikipedia.org/wiki/Tic-tac-toe#Strategy | |
// 1. Win | |
findThreat (2, Threats, grid); | |
if (Threats[0][0] != -1) { | |
grid[Threats[0][0]][Threats[0][1]] = 2; | |
win = 1; | |
goto print; // I know, http://xkcd.com/292/ | |
} | |
// 2. Block | |
findThreat (1, Threats, grid); | |
if (Threats[0][0] != -1) { | |
grid[Threats[0][0]][Threats[0][1]] = 2; | |
goto print; | |
} | |
// 3. Fork | |
for (i=0; i<3; i++) | |
for (j=0; j<3; j++) { | |
memcpy(nextgrid, grid, 3*3*sizeof (int)); | |
if (grid[i][j] != 0) | |
continue; | |
nextgrid[i][j] = 2; | |
findThreat (2, Threats, nextgrid); | |
if (Threats[0][0] != -1 && Threats[1][0] != -1) { | |
grid[i][j] = 2; | |
goto print; | |
} | |
} | |
// 4. Block an opponent's fork | |
for (i=0; i<2; i++) | |
for (j=0; j<2; j++) | |
Forks[i][j]=-1; | |
forknum = 0; | |
for (i=0; i<3; i++) | |
for (j=0; j<3; j++) { | |
memcpy(nextgrid, grid, 3*3*sizeof (int)); | |
if (grid[i][j] != 0) | |
continue; | |
nextgrid[i][j] = 1; | |
findThreat (1, Threats, nextgrid); | |
if (Threats[0][0] != -1 && Threats[1][0] != -1) { | |
Forks[forknum][0] = i; | |
Forks[forknum][1] = j; | |
forknum++; | |
} | |
} | |
// Option 2 (means there's only one fork possible, block it) | |
if (forknum == 1) { | |
grid[Forks[0][0]][Forks[0][1]] = 2; | |
goto print; | |
} | |
// Option 1 (more than one fork possible, force into defending) | |
if (forknum == 2) { | |
for (i=0; i<3; i++) | |
for (j=0; j<3; j++) { | |
memcpy(nextgrid, grid, 3*3*sizeof (int)); | |
if (grid[i][j] != 0) | |
continue; | |
nextgrid[i][j] = 2; | |
findThreat (2, Threats, nextgrid); | |
if ((Threats[0][0] == Forks[0][0] && Threats[0][1] == Forks[0][1]) || | |
(Threats[0][0] == Forks[1][0] && Threats[0][1] == Forks[1][1])) | |
continue; | |
if (Threats[0][0] != -1) { | |
grid[i][j] = 2; | |
goto print; | |
} | |
} | |
} | |
// 5. Center | |
if (grid[1][1] == 0) { | |
grid[1][1] = 2; | |
goto print; | |
} | |
// 6. Opposite corner | |
if (grid[0][0] == 1){ grid[2][2] = 2; goto print;} | |
if (grid[0][2] == 1){ grid[2][0] = 2; goto print;} | |
if (grid[2][0] == 1){ grid[0][2] = 2; goto print;} | |
if (grid[2][2] == 1){ grid[0][0] = 2; goto print;} | |
// 7. Empty corner | |
if (grid[0][0] == 0){ grid[0][0] = 2; goto print;} | |
if (grid[0][2] == 0){ grid[0][2] = 2; goto print;} | |
if (grid[2][0] == 0){ grid[2][0] = 2; goto print;} | |
if (grid[2][2] == 0){ grid[2][2] = 2; goto print;} | |
// 8. Empty side | |
if (grid[0][1] == 0){ grid[0][1] = 2; goto print;} | |
if (grid[1][0] == 0){ grid[1][0] = 2; goto print;} | |
if (grid[2][1] == 0){ grid[2][1] = 2; goto print;} | |
if (grid[1][2] == 0){ grid[1][2] = 2; goto print;} | |
print: | |
for (i=0; i<3; i++) { | |
for (j=0; j<3; j++) | |
switch (grid[i][j]) { | |
case 0: | |
printf ("_ "); | |
break; | |
case 1: | |
printf ("O "); | |
break; | |
case 2: | |
printf ("X "); | |
break; | |
} | |
printf("\n"); | |
} | |
printf("\n"); | |
if (win) break; | |
shouldgoon = 0; | |
for (i=0; i<3; i++) | |
for (j=0; j<3; j++) | |
if (grid[i][j] == 0) | |
shouldgoon = 1; | |
} while (shouldgoon); | |
return 0; | |
} | |
void findThreat (int player, int Threats [][2], int grid[][3]) { | |
int k, threatnum, i, j, a; | |
for (i=0; i<2; i++) | |
for (j=0; j<2; j++) | |
Threats[i][j] = -1; | |
threatnum = 0; | |
// Threats on a row | |
for (i=0; i<3; i++) { | |
k = 0; | |
a = -1; | |
for (j=0; j<3; j++) { | |
if (grid[i][j] == player) | |
k++; | |
if (grid[i][j] == 0) | |
a = j; | |
} | |
if (k == 2 && a != -1) { | |
Threats[threatnum][0] = i; | |
Threats[threatnum][1] = a; | |
threatnum++; | |
} | |
} | |
// Threats on a column | |
for (j=0; j<3; j++) { | |
k = 0; | |
a = -1; | |
for (i=0; i<3; i++) { | |
if (grid[i][j] == player) | |
k++; | |
if (grid[i][j] == 0) | |
a = i; | |
} | |
if (k == 2 && a != -1) { | |
Threats[threatnum][0] = a; | |
Threats[threatnum][1] = j; | |
threatnum++; | |
} | |
} | |
// Threats on top-to-bottom diagonal | |
k = 0; | |
a = -1; | |
for (i=0; i<3; i++) { | |
if (grid[i][i] == player) | |
k++; | |
if (grid[i][i] == 0) | |
a=i; | |
} | |
if (k == 2 && a != -1) { | |
Threats[threatnum][0] = a; | |
Threats[threatnum][1] = a; | |
threatnum++; | |
} | |
// Threats on the other diagonal | |
k = 0; | |
a = -1; | |
for (i=0; i<3; i++) { | |
if (grid[i][2-i] == player) | |
k++; | |
if (grid[i][2-i] == 0) | |
a = i; | |
} | |
if (k == 2 && a != -1) { | |
Threats[threatnum][0] = a; | |
Threats[threatnum][1] = 2 - a; | |
threatnum++; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment