Last active
October 11, 2019 17:48
-
-
Save peterthorsteinson/0799f7400178e0bddc130946059dbc24 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
using System; | |
namespace TicTacToeHumanVsMachineBruteForce | |
{ | |
class Program | |
{ | |
static char[] cells; | |
static Random rand = new Random(); | |
static void Main() | |
{ | |
int numberXWins = 0; | |
int numberOWins = 0; | |
int numberDraws = 0; | |
int numberGames = 0; | |
for (int i = 0; i < 1000; i++) // loop for playing 1000 games | |
{ | |
numberGames++; | |
Console.WriteLine("Human is X, Maxchine is O. X goes first.\n"); | |
cells = new char[] { ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', }; | |
Display(); | |
int moveCount = 0; | |
while (true) // loop for playing a single game | |
{ | |
// comment one and only one of the following two lines of code | |
//PlayHumanMove(); // real human player | |
PlayHumanMove(true); // simulate human player with random | |
moveCount++; | |
if (DidHumanWin()) | |
{ | |
numberXWins++; | |
Console.WriteLine("\n**********\nHuman wins!\n**********\n"); | |
break; | |
} | |
PlayMachineMove(); | |
moveCount++; | |
if (DidMachineWin()) | |
{ | |
numberOWins++; | |
Console.WriteLine("\n**********\nMachine wins!\n**********\n"); | |
break; | |
} | |
if (moveCount >= 9) // last move for machine O was already played | |
{ | |
numberDraws++; | |
Console.WriteLine("\n**********\nDraw!\n**********\n"); | |
break; | |
} | |
} | |
} | |
Console.WriteLine("Games played: " + numberGames); | |
Console.WriteLine("X - Random simulated human wins: " + numberXWins + " -> " + (numberXWins * 100.0) / numberGames + " %"); | |
Console.WriteLine("O - Machine wins: " + numberOWins + " -> " + (numberOWins * 100.0) / numberGames + " %"); | |
Console.WriteLine("Draws: " + numberDraws + " -> " + (numberDraws * 100.0) / numberGames + " %"); | |
} | |
static void Display() | |
{ | |
Console.WriteLine(); | |
Console.WriteLine(" " + cells[0] + " | " + cells[1] + " | " + cells[2]); | |
Console.WriteLine("---+---+---"); | |
Console.WriteLine(" " + cells[3] + " | " + cells[4] + " | " + cells[5]); | |
Console.WriteLine("---+---+---"); | |
Console.WriteLine(" " + cells[6] + " | " + cells[7] + " | " + cells[8]); | |
} | |
static void PlayHumanMove(bool simulateHumanWithRandom = false) | |
{ | |
if (simulateHumanWithRandom) | |
{ | |
int randpos; | |
while (true) | |
{ | |
randpos = rand.Next(1, 10); // random move in (1, 10] | |
if (cells[randpos - 1] == ' ') break; | |
} | |
cells[randpos - 1] = 'X'; | |
Display(); | |
return; | |
} | |
Console.WriteLine("\nPlay X: 1 to 9, 0 to quit."); | |
int pos; | |
while (true) | |
{ | |
if (!(int.TryParse(Console.ReadKey(true).KeyChar.ToString(), out pos))) | |
{ | |
// human hit a key that is not a digit in 0 -> 9 so try again | |
Console.Beep(); | |
continue; | |
} | |
if (pos == 0) | |
{ | |
// human hit 0 key so terminate game | |
Console.WriteLine("\nBye"); | |
Environment.Exit(0); | |
} | |
if (cells[pos - 1] != ' ') | |
{ | |
// human tried to move in cell that is not blank | |
Console.Beep(); | |
continue; | |
} | |
cells[pos - 1] = 'X'; | |
Display(); | |
return; | |
} | |
} | |
static void PlayMachineMove() | |
{ | |
// center is best initial move so machine should move there right of the bat if possible | |
if (cells[4] == ' ') | |
{ | |
cells[4] = 'O'; | |
Display(); | |
return; | |
} | |
// capitalize O on 1st row win | |
if (cells[0] == 'O' && cells[1] == 'O' && cells[2] == ' ') | |
{ | |
cells[2] = 'O'; | |
Display(); | |
return; | |
} | |
if (cells[0] == 'O' && cells[2] == 'O' && cells[1] == ' ') | |
{ | |
cells[1] = 'O'; | |
Display(); | |
return; | |
} | |
if (cells[1] == 'O' && cells[2] == 'O' && cells[0] == ' ') | |
{ | |
cells[0] = 'O'; | |
Display(); | |
return; | |
} | |
// capitalize O on 2nd row win | |
if (cells[3] == 'O' && cells[4] == 'O' && cells[5] == ' ') | |
{ | |
cells[5] = 'O'; | |
Display(); | |
return; | |
} | |
if (cells[3] == 'O' && cells[5] == 'O' && cells[4] == ' ') | |
{ | |
cells[4] = 'O'; | |
Display(); | |
return; | |
} | |
if (cells[4] == 'O' && cells[5] == 'O' && cells[3] == ' ') | |
{ | |
cells[3] = 'O'; | |
Display(); | |
return; | |
} | |
// capitalize O on 3rd row win | |
if (cells[6] == 'O' && cells[7] == 'O' && cells[8] == ' ') | |
{ | |
cells[8] = 'O'; | |
Display(); | |
return; | |
} | |
if (cells[6] == 'O' && cells[8] == 'O' && cells[7] == ' ') | |
{ | |
cells[7] = 'O'; | |
Display(); | |
return; | |
} | |
if (cells[7] == 'O' && cells[8] == 'O' && cells[6] == ' ') | |
{ | |
cells[6] = 'O'; | |
Display(); | |
return; | |
} | |
// capitalize O on 1st col win | |
if (cells[0] == 'O' && cells[3] == 'O' && cells[6] == ' ') | |
{ | |
cells[6] = 'O'; | |
Display(); | |
return; | |
} | |
if (cells[0] == 'O' && cells[6] == 'O' && cells[3] == ' ') | |
{ | |
cells[3] = 'O'; | |
Display(); | |
return; | |
} | |
if (cells[3] == 'O' && cells[6] == 'O' && cells[0] == ' ') | |
{ | |
cells[0] = 'O'; | |
Display(); | |
return; | |
} | |
// capitalize O on 2nd col win | |
if (cells[1] == 'O' && cells[4] == 'O' && cells[7] == ' ') | |
{ | |
cells[7] = 'O'; | |
Display(); | |
return; | |
} | |
if (cells[1] == 'O' && cells[7] == 'O' && cells[4] == ' ') | |
{ | |
cells[4] = 'O'; | |
Display(); | |
return; | |
} | |
if (cells[4] == 'O' && cells[7] == 'O' && cells[1] == ' ') | |
{ | |
cells[1] = 'O'; | |
Display(); | |
return; | |
} | |
// capitalize O on 3rd col win | |
if (cells[2] == 'O' && cells[5] == 'O' && cells[8] == ' ') | |
{ | |
cells[8] = 'O'; | |
Display(); | |
return; | |
} | |
if (cells[2] == 'O' && cells[8] == 'O' && cells[5] == ' ') | |
{ | |
cells[5] = 'O'; | |
Display(); | |
return; | |
} | |
if (cells[5] == 'O' && cells[8] == 'O' && cells[2] == ' ') | |
{ | |
cells[2] = 'O'; | |
Display(); | |
return; | |
} | |
// capitalize O on diag \ win | |
if (cells[0] == 'O' && cells[4] == 'O' && cells[8] == ' ') | |
{ | |
cells[8] = 'O'; | |
Display(); | |
return; | |
} | |
if (cells[0] == 'O' && cells[8] == 'O' && cells[4] == ' ') | |
{ | |
cells[4] = 'O'; | |
Display(); | |
return; | |
} | |
if (cells[4] == 'O' && cells[8] == 'O' && cells[0] == ' ') | |
{ | |
cells[0] = 'O'; | |
Display(); | |
return; | |
} | |
// capitalize O on diag / win | |
if (cells[2] == 'O' && cells[4] == 'O' && cells[6] == ' ') | |
{ | |
cells[6] = 'O'; | |
Display(); | |
return; | |
} | |
if (cells[2] == 'O' && cells[6] == 'O' && cells[4] == ' ') | |
{ | |
cells[4] = 'O'; | |
Display(); | |
return; | |
} | |
if (cells[4] == 'O' && cells[6] == 'O' && cells[2] == ' ') | |
{ | |
cells[2] = 'O'; | |
Display(); | |
return; | |
} | |
// prevent X from 1st row win | |
if (cells[0] == 'X' && cells[1] == 'X' && cells[2] == ' ') | |
{ | |
cells[2] = 'O'; | |
Display(); | |
return; | |
} | |
if (cells[0] == 'X' && cells[2] == 'X' && cells[1] == ' ') | |
{ | |
cells[1] = 'O'; | |
Display(); | |
return; | |
} | |
if (cells[1] == 'X' && cells[2] == 'X' && cells[0] == ' ') | |
{ | |
cells[0] = 'O'; | |
Display(); | |
return; | |
} | |
// prevent X from 2nd row win | |
if (cells[3] == 'X' && cells[4] == 'X' && cells[5] == ' ') | |
{ | |
cells[5] = 'O'; | |
Display(); | |
return; | |
} | |
if (cells[3] == 'X' && cells[5] == 'X' && cells[4] == ' ') | |
{ | |
cells[4] = 'O'; | |
Display(); | |
return; | |
} | |
if (cells[4] == 'X' && cells[5] == 'X' && cells[3] == ' ') | |
{ | |
cells[3] = 'O'; | |
Display(); | |
return; | |
} | |
// prevent X from 3rd row win | |
if (cells[6] == 'X' && cells[7] == 'X' && cells[8] == ' ') | |
{ | |
cells[8] = 'O'; | |
Display(); | |
return; | |
} | |
if (cells[6] == 'X' && cells[8] == 'X' && cells[7] == ' ') | |
{ | |
cells[7] = 'O'; | |
Display(); | |
return; | |
} | |
if (cells[7] == 'X' && cells[8] == 'X' && cells[6] == ' ') | |
{ | |
cells[6] = 'O'; | |
Display(); | |
return; | |
} | |
// prevent X from 1st col win | |
if (cells[0] == 'X' && cells[3] == 'X' && cells[6] == ' ') | |
{ | |
cells[6] = 'O'; | |
Display(); | |
return; | |
} | |
if (cells[0] == 'X' && cells[6] == 'X' && cells[3] == ' ') | |
{ | |
cells[3] = 'O'; | |
Display(); | |
return; | |
} | |
if (cells[3] == 'X' && cells[6] == 'X' && cells[0] == ' ') | |
{ | |
cells[0] = 'O'; | |
Display(); | |
return; | |
} | |
// prevent X from 2nd col win | |
if (cells[1] == 'X' && cells[4] == 'X' && cells[7] == ' ') | |
{ | |
cells[7] = 'O'; | |
Display(); | |
return; | |
} | |
if (cells[1] == 'X' && cells[7] == 'X' && cells[4] == ' ') | |
{ | |
cells[4] = 'O'; | |
Display(); | |
return; | |
} | |
if (cells[4] == 'X' && cells[7] == 'X' && cells[1] == ' ') | |
{ | |
cells[1] = 'O'; | |
Display(); | |
return; | |
} | |
// prevent X from 3rd col win | |
if (cells[2] == 'X' && cells[5] == 'X' && cells[8] == ' ') | |
{ | |
cells[8] = 'O'; | |
Display(); | |
return; | |
} | |
if (cells[2] == 'X' && cells[8] == 'X' && cells[5] == ' ') | |
{ | |
cells[5] = 'O'; | |
Display(); | |
return; | |
} | |
if (cells[5] == 'X' && cells[8] == 'X' && cells[2] == ' ') | |
{ | |
cells[2] = 'O'; | |
Display(); | |
return; | |
} | |
// prevent X from diag \ win | |
if (cells[0] == 'X' && cells[4] == 'X' && cells[8] == ' ') | |
{ | |
cells[8] = 'O'; | |
Display(); | |
return; | |
} | |
if (cells[0] == 'X' && cells[8] == 'X' && cells[4] == ' ') | |
{ | |
cells[4] = 'O'; | |
Display(); | |
return; | |
} | |
if (cells[4] == 'X' && cells[8] == 'X' && cells[0] == ' ') | |
{ | |
cells[0] = 'O'; | |
Display(); | |
return; | |
} | |
// prevent X from diag / win | |
if (cells[2] == 'X' && cells[4] == 'X' && cells[6] == ' ') | |
{ | |
cells[6] = 'O'; | |
Display(); | |
return; | |
} | |
if (cells[2] == 'X' && cells[6] == 'X' && cells[4] == ' ') | |
{ | |
cells[4] = 'O'; | |
Display(); | |
return; | |
} | |
if (cells[4] == 'X' && cells[6] == 'X' && cells[2] == ' ') | |
{ | |
cells[2] = 'O'; | |
Display(); | |
return; | |
} | |
// win is not imminent for either player at this point | |
if (cells[4] == 'X') // if center cell is human X then take any available corner cell | |
{ | |
if (cells[0] == ' ') | |
{ | |
cells[0] = 'O'; | |
Display(); | |
return; | |
} | |
if (cells[2] == ' ') | |
{ | |
cells[2] = 'O'; | |
Display(); | |
return; | |
} | |
if (cells[6] == ' ') | |
{ | |
cells[6] = 'O'; | |
Display(); | |
return; | |
} | |
if (cells[8] == ' ') | |
{ | |
cells[8] = 'O'; | |
Display(); | |
return; | |
} | |
} | |
else // center cell must be machine O so take any available edge cell | |
{ | |
if (cells[1] == ' ') | |
{ | |
cells[1] = 'O'; | |
Display(); | |
return; | |
} | |
if (cells[3] == ' ') | |
{ | |
cells[3] = 'O'; | |
Display(); | |
return; | |
} | |
if (cells[5] == ' ') | |
{ | |
cells[5] = 'O'; | |
Display(); | |
return; | |
} | |
if (cells[7] == ' ') | |
{ | |
cells[7] = 'O'; | |
Display(); | |
return; | |
} | |
} | |
// move to any available square | |
if (cells[0] == ' ') | |
{ | |
cells[0] = 'O'; | |
Display(); | |
return; | |
} | |
if (cells[1] == ' ') | |
{ | |
cells[1] = 'O'; | |
Display(); | |
return; | |
} | |
if (cells[2] == ' ') | |
{ | |
cells[2] = 'O'; | |
Display(); | |
return; | |
} | |
if (cells[3] == ' ') | |
{ | |
cells[3] = 'O'; | |
Display(); | |
return; | |
} | |
if (cells[4] == ' ') | |
{ | |
cells[4] = 'O'; | |
Display(); | |
return; | |
} | |
if (cells[5] == ' ') | |
{ | |
cells[5] = 'O'; | |
Display(); | |
return; | |
} | |
if (cells[6] == ' ') | |
{ | |
cells[6] = 'O'; | |
Display(); | |
return; | |
} | |
if (cells[7] == ' ') | |
{ | |
cells[7] = 'O'; | |
Display(); | |
return; | |
} | |
if (cells[8] == ' ') | |
{ | |
cells[8] = 'O'; | |
Display(); | |
return; | |
} | |
} | |
static bool DidHumanWin() | |
{ | |
if ((cells[0] == 'X' && cells[1] == 'X' && cells[2] == 'X') || // row 1 | |
(cells[3] == 'X' && cells[4] == 'X' && cells[5] == 'X') || // row 2 | |
(cells[6] == 'X' && cells[7] == 'X' && cells[8] == 'X') || // row 3 | |
(cells[0] == 'X' && cells[3] == 'X' && cells[6] == 'X') || // col 1 | |
(cells[1] == 'X' && cells[4] == 'X' && cells[7] == 'X') || // col 2 | |
(cells[2] == 'X' && cells[5] == 'X' && cells[8] == 'X') || // col 3 | |
(cells[0] == 'X' && cells[4] == 'X' && cells[8] == 'X') || // diag \ | |
(cells[6] == 'X' && cells[4] == 'X' && cells[2] == 'X')) // diag / | |
return true; | |
return false; | |
} | |
static bool DidMachineWin() | |
{ | |
if ((cells[0] == 'O' && cells[1] == 'O' && cells[2] == 'O') || // row 1 | |
(cells[3] == 'O' && cells[4] == 'O' && cells[5] == 'O') || // row 2 | |
(cells[6] == 'O' && cells[7] == 'O' && cells[8] == 'O') || // row 3 | |
(cells[1] == 'O' && cells[4] == 'O' && cells[7] == 'O') || // col 2 | |
(cells[2] == 'O' && cells[5] == 'O' && cells[8] == 'O') || // col 3 | |
(cells[0] == 'O' && cells[4] == 'O' && cells[8] == 'O') || // diag \ | |
(cells[6] == 'O' && cells[4] == 'O' && cells[2] == 'O')) // diag / | |
return true; | |
return false; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment