Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using System.Runtime.CompilerServices;
- using System.Security.Cryptography.X509Certificates;
- using System.Text.RegularExpressions;
- namespace TicTacToeAI
- {
- internal class TicTacToe
- {
- struct Move
- {
- public int score;
- public int x;
- public int y;
- }
- int[,] TicTacToeBoard = {
- {0, 0, 0},
- {0, 0, 0},
- {0, 0, 0}
- };
- string[,] TicTacToePrint =
- {
- {" ", " ", " "},
- {" ", " ", " "},
- {" ", " ", " "},
- };
- int playerTurn = 0;
- int playerWon = 0;
- int playerWantToPlay = 1;
- int a1 = 0;
- int a2 = 0;
- int a3 = 0;
- int b1 = 0;
- int b2 = 0;
- int b3 = 0;
- int c1 = 0;
- int c2 = 0;
- int c3 = 0;
- static void Main(string[] args)
- {
- TicTacToe t = new TicTacToe();
- while (t.playerWantToPlay == 1)
- {
- Regex regex = new Regex(@"^[ABC][123]$");
- Console.WriteLine("X or O?");
- string choice = Console.ReadLine();
- if (choice.ToLower() == "x")
- {
- t.playerTurn = 0;
- }
- else if (choice.ToLower() == "o")
- {
- t.playerTurn = 1;
- }
- else
- {
- t.playerTurn = 1;
- }
- int turn = 0;
- while (t.playerWon == 0)
- {
- t.BoardStateToPrintState();
- t.PrintPlayableBoard();
- bool match = false;
- string loc = "";
- int valid = 0;
- while (match == false)
- {
- if (t.playerTurn == turn)
- {
- if (turn == 0)
- {
- Console.Write("Location to add X: ");
- }
- else
- {
- Console.Write("Location to add O: ");
- }
- loc = Console.ReadLine();
- match = regex.IsMatch(loc);
- }
- else
- {
- t.AdvancedTurn(turn, t.TicTacToeBoard);
- match = true;
- }
- valid = t.ValidateBoardState(loc);
- if (valid == 0) t.ModBoard(loc, turn);
- if (t.CheckForTicTacToe(true) != 0)
- {
- t.playerWon = t.CheckForTicTacToe();
- }
- }
- Console.WriteLine("Evaluation of position: " + t.Evaluate(t.TicTacToeBoard, turn));
- if (turn == 0 && valid == 0)
- {
- turn = 1;
- }
- else if (turn == 1 && valid == 0)
- {
- turn = 0;
- }
- else
- {
- turn = turn;
- }
- }
- Console.WriteLine("Another round?");
- if (Console.ReadLine().ToLower() == "y")
- {
- Console.Clear();
- for (int x = 0; x < 3; x++)
- {
- for (int y = 0; y < 3; y++)
- {
- t.TicTacToeBoard[x, y] = 0;
- t.TicTacToePrint[x, y] = " ";
- }
- }
- t.playerWon = 0;
- }
- else
- {
- t.playerWantToPlay = 0;
- }
- }
- }
- void PlaceVoid(int x, int y)
- {
- TicTacToeBoard[x - 1, y - 1] = 0;
- }
- void PlaceX(int x, int y)
- {
- TicTacToeBoard[x - 1, y - 1] = 1;
- }
- void PlaceO(int x, int y)
- {
- TicTacToeBoard[x - 1, y - 1] = 2;
- }
- void ModBoard(string loc, int turn)
- {
- switch (loc)
- {
- case "A1":
- if (turn == 0)
- {
- PlaceX(1, 1);
- }
- else
- {
- PlaceO(1, 1);
- }
- break;
- case "A2":
- if (turn == 0)
- {
- PlaceX(1, 2);
- }
- else
- {
- PlaceO(1, 2);
- }
- break;
- case "A3":
- if (turn == 0)
- {
- PlaceX(1, 3);
- }
- else
- {
- PlaceO(1, 3);
- }
- break;
- case "B1":
- if (turn == 0)
- {
- PlaceX(2, 1);
- }
- else
- {
- PlaceO(2, 1);
- }
- break;
- case "B2":
- if (turn == 0)
- {
- PlaceX(2, 2);
- }
- else
- {
- PlaceO(2, 2);
- }
- break;
- case "B3":
- if (turn == 0)
- {
- PlaceX(2, 3);
- }
- else
- {
- PlaceO(2, 3);
- }
- break;
- case "C1":
- if (turn == 0)
- {
- PlaceX(3, 1);
- }
- else
- {
- PlaceO(3, 1);
- }
- break;
- case "C2":
- if (turn == 0)
- {
- PlaceX(3, 2);
- }
- else
- {
- PlaceO(3, 2);
- }
- break;
- case "C3":
- if (turn == 0)
- {
- PlaceX(3, 3);
- }
- else
- {
- PlaceO(3, 3);
- }
- break;
- }
- }
- int[,] CopyBoard(int[,] board)
- {
- int[,] newBoard = new int[3, 3];
- for (int x = 0; x < 3; x++)
- {
- for (int y = 0; y < 3; y++)
- {
- newBoard[x, y] = board[x, y];
- }
- }
- return newBoard;
- }
- int CountPlayerSpaces(int[,] board, int id)
- {
- int c = 0;
- for (int x = 0; x < 2; x++)
- {
- for (int y = 0; y < 2; y++)
- {
- c += board[x, y] == id ? 1 : 0;
- }
- }
- return c;
- }
- // Returns 0 for None,
- // 1 for X,
- // 2 for O
- int CheckForTicTacToe(bool ChatDisabled = false)
- {
- /*
- * There are eight possible win-states:
- * X B B
- * X B B
- * X B B
- *
- * B X B
- * B X B
- * B X B
- *
- * B B X
- * B B X
- * B B X
- *
- * X X X
- * B B B
- * B B B
- *
- * B B B
- * X X X
- * B B B
- *
- * B B B
- * B B B
- * X X X
- *
- * X B B
- * B X B
- * B B X
- *
- * B B X
- * B X B
- * X B B
- */
- // Really, there are sixteen, but I don't want to get into it.
- int w = 0;
- // Horizontals:
- for (int x = 0; x < 3; x++)
- {
- if (TicTacToeBoard[x, 0] == TicTacToeBoard[x, 1] && TicTacToeBoard[x, 1] == TicTacToeBoard[x, 2] && TicTacToeBoard[x, 0] != 0)
- {
- switch (TicTacToeBoard[x, 0])
- {
- case 1:
- w = 1;
- if (!ChatDisabled == true)
- {
- Console.WriteLine("X Won At Row " + (x + 1) + ".");
- }
- break;
- case 2:
- w = 2;
- if (!ChatDisabled == true)
- {
- Console.WriteLine("O Won At Row " + (x + 1) + ".");
- }
- break;
- }
- }
- }
- // Verticals:
- for (int y = 0; y < 3; y++)
- {
- if (TicTacToeBoard[0, y] == TicTacToeBoard[1, y] && TicTacToeBoard[1, y] == TicTacToeBoard[2, y] && TicTacToeBoard[0, y] != 0)
- {
- switch (TicTacToeBoard[0, y])
- {
- case 1:
- w = 1;
- Console.WriteLine("X Won At Column " + (y + 1) + ".");
- break;
- case 2:
- w = 2;
- Console.WriteLine("O Won At Column " + (y + 1) + ".");
- break;
- }
- }
- }
- // Diagonals:
- if (TicTacToeBoard[0, 0] == TicTacToeBoard[1, 1] && TicTacToeBoard[1, 1] == TicTacToeBoard[2, 2] && TicTacToeBoard[1, 1] != 0)
- {
- switch (TicTacToeBoard[1, 1])
- {
- case 1:
- w = 1;
- if (!ChatDisabled == true)
- {
- Console.WriteLine("X Won At LR Diagonal");
- }
- break;
- case 2:
- w = 2;
- if (!ChatDisabled == true)
- {
- Console.WriteLine("O Won At LR Diagonal");
- }
- break;
- }
- }
- if (TicTacToeBoard[0, 2] == TicTacToeBoard[1, 1] && TicTacToeBoard[1, 1] == TicTacToeBoard[2, 0] && TicTacToeBoard[1, 1] != 0)
- {
- switch (TicTacToeBoard[1, 1])
- {
- case 1:
- w = 1;
- if (!ChatDisabled == true)
- {
- Console.WriteLine("X Won At RL Diagonal");
- }
- break;
- case 2:
- w = 2;
- if (!ChatDisabled == true)
- {
- Console.WriteLine("O Won At RL Diagonal");
- }
- break;
- }
- }
- return w;
- }
- // void PrintBoardState()
- void BoardStateToPrintState()
- {
- for (int x = 0; x < 3; x++)
- {
- for (int y = 0; y < 3; y++)
- {
- switch (TicTacToeBoard[x, y])
- {
- case 0:
- TicTacToePrint[x, y] = " ";
- break;
- case 1:
- TicTacToePrint[x, y] = "X";
- break;
- case 2:
- TicTacToePrint[x, y] = "O";
- break;
- }
- }
- }
- }
- void PrintPlayableBoard()
- {
- Console.WriteLine(" " + TicTacToePrint[0, 0] + " | " + TicTacToePrint[0, 1] + " | " + TicTacToePrint[0, 2]);
- Console.WriteLine("---+---+---");
- Console.WriteLine(" " + TicTacToePrint[1, 0] + " | " + TicTacToePrint[1, 1] + " | " + TicTacToePrint[1, 2]);
- Console.WriteLine("---+---+---");
- Console.WriteLine(" " + TicTacToePrint[2, 0] + " | " + TicTacToePrint[2, 1] + " | " + TicTacToePrint[2, 2]);
- }
- int ValidateBoardState(string loc)
- {
- if (loc == "A1")
- {
- if (TicTacToeBoard[0, 0] != 0) return 1;
- }
- else if (loc == "A2")
- {
- if (TicTacToeBoard[0, 1] != 0) return 1;
- }
- else if (loc == "A3")
- {
- if (TicTacToeBoard[0, 2] != 0) return 1;
- }
- else if (loc == "B1")
- {
- if (TicTacToeBoard[1, 0] != 0) return 1;
- }
- else if (loc == "B2")
- {
- if (TicTacToeBoard[1, 1] != 0) return 1;
- }
- else if (loc == "B3")
- {
- if (TicTacToeBoard[1, 2] != 0) return 1;
- }
- else if (loc == "C1")
- {
- if (TicTacToeBoard[2, 0] != 0) return 1;
- }
- else if (loc == "C2")
- {
- if (TicTacToeBoard[2, 1] != 0) return 1;
- }
- else if (loc == "C3")
- {
- if (TicTacToeBoard[2, 2] != 0) return 1;
- }
- return 0;
- }
- void RandomTurn(int turn, int[,] board)
- {
- Random r = new Random();
- int isValid = 1;
- string move = "";
- int loopCap = 0;
- while (loopCap < 1000)
- {
- loopCap++;
- move = (char)(r.Next(1, 4) + 64) + r.Next(1, 4).ToString();
- isValid = ValidateBoardState(move);
- // Console.Write(move);
- // Console.Write(isValid);
- // Console.Write(loopCap);
- // Console.Write(" ");
- if (isValid == 0) break;
- }
- // Console.WriteLine("");
- ModBoard(move, turn);
- }
- void AdvancedTurn(int turn, int[,] board)
- {
- Move eval = new Move();
- int isValid = 1;
- string move = "";
- int loopCap = 0;
- while (loopCap < 1)
- {
- int _a = 0;
- _a = CountPlayerSpaces(board, 0);
- eval = Minimax(board, 9, turn);
- loopCap++;
- move = (char)(eval.x + 65) + (eval.y + 1).ToString();
- isValid = ValidateBoardState(move);
- if (isValid == 0) break;
- }
- Console.WriteLine("Attempts: " + loopCap);
- Console.WriteLine("Minimax Algorithm Data:");
- Console.WriteLine("\t Score: " + eval.score);
- Console.WriteLine("\t X Value: " + eval.x);
- Console.WriteLine("\t Y Value: " + eval.y);
- Console.WriteLine("Move chosen: " + move);
- ModBoard(move, turn);
- }
- int BoardBinary(int[,] board)
- {
- int boardBin = 0;
- for (int x = 0; x < 3; x++)
- {
- for (int y = 0; y < 3; y++)
- {
- boardBin |= board[x, y];
- boardBin <<= 2;
- }
- }
- return boardBin;
- }
- /*
- List<int[,]> RecursiveMoves(int[,] board, int currentPlayer)
- {
- List<int[,]> moves = new List<int[,]>();
- if (CheckForTicTacToe(true) != 0) return moves;
- for (int x = 0; x < 3; x++)
- {
- for (int y = 0; y < 3; y++)
- {
- if (board[x, y] == 0)
- {
- int[,] newBoard = CopyBoard(board);
- newBoard[x, y] = currentPlayer + 1;
- moves.Add(newBoard);
- List<int[,]> childMoves = RecursiveMoves(newBoard, 3 - currentPlayer);
- moves.AddRange(childMoves);
- }
- }
- }
- return moves;
- }
- */
- int Evaluate(int[,] board, int currentPlayer)
- {
- currentPlayer++;
- int opponent = 3 - currentPlayer;
- int WinLoss = 1000;
- int center = 10;
- int cornerFirst = 50;
- int corner = 10;
- int fork = 200;
- int tiar = 100;
- int eval = 0;
- // If we've won, the position is obviously good. If we've lost, the position is obviously bad.
- // If it's a draw, it doesn't matter who was winning, the game is over.
- if (CheckForTicTacToe(true) == currentPlayer) return WinLoss;
- if (CheckForTicTacToe(true) == opponent) return -WinLoss;
- if (CheckForTicTacToe(true) == 0 && CountPlayerSpaces(board, 0) == 0) return 0;
- // Control of the center is good. Having the enemy control the center, not so much.
- if (board[1, 1] == currentPlayer) eval += center;
- if (board[1, 1] == opponent) eval -= center;
- // According to the guide for the perfect Tic-Tac-Toe game, controlling the upper-left corner as X is best if it's our first move.
- // We can determine this due to a neat little quirk where the first move means there's only one occupied space.
- if (board[0, 0] == currentPlayer && CountPlayerSpaces(board, 0) == 8 && board[0, 0] == 1) eval += cornerFirst;
- // Corner control is important. We put emphasis on corner control.
- eval += board[0, 0] == currentPlayer ? corner : 0;
- eval += board[0, 2] == currentPlayer ? corner : 0;
- eval += board[2, 0] == currentPlayer ? corner : 0;
- eval += board[2, 2] == currentPlayer ? corner : 0;
- eval -= board[0, 0] == opponent ? corner : 0;
- eval -= board[0, 2] == opponent ? corner : 0;
- eval -= board[2, 0] == opponent ? corner : 0;
- eval -= board[2, 2] == opponent ? corner : 0;
- // We don't care too much about edges.
- eval += board[0, 1] == currentPlayer ? 5 : 0;
- eval += board[1, 0] == currentPlayer ? 5 : 0;
- eval += board[1, 2] == currentPlayer ? 5 : 0;
- eval += board[2, 1] == currentPlayer ? 5 : 0;
- eval -= board[0, 1] == opponent ? 5 : 0;
- eval -= board[1, 0] == opponent ? 5 : 0;
- eval -= board[1, 2] == opponent ? 5 : 0;
- eval -= board[2, 1] == opponent ? 5 : 0;
- // We should avoid having the opponent have two-in-a-rows (TIARs) while incentivising having us have TIARs
- for (int x = 0; x < 8; x++)
- {
- eval += IdentifyTIARs(board, currentPlayer - 1, x) != null ? tiar : 0;
- }
- for (int x = 0; x < 8; x++)
- {
- eval -= IdentifyTIARs(board, opponent - 1, x) != null ? tiar : 0;
- }
- // If we have a fork, the enemy could block it. However, while hard, it's possible to block a fork (I think.) Therefore, we only put
- // 200 points on our forks.
- for (int x = 0; x < 9; x++)
- {
- eval += IdentifyForks(board, currentPlayer - 1, x) != null ? fork : 0;
- }
- // If the enemy has a fork, and we ignored it, the game might as well be considered lost. Avoid letting the enemy fork us at any cost.
- for (int x = 0; x < 9; x++)
- {
- eval -= IdentifyForks(board, opponent - 1, x) != null ? WinLoss : 0;
- }
- return eval;
- }
- /*
- * GOALS:
- * Identify if a row/column/diagonal has a two-in-a-row (TIAR) in favor of that player
- * CRD VALUES:
- * 0: Row 1
- * 1: Row 2
- * 2: Row 3
- * 3: Column 1
- * 4: Column 2
- * 5: Column 3
- * 6: Left-Right Diagonal
- * 7: Right-Left Diagonal
- * After that, if a TIAR is found, it outputes:
- * 1: Hole found in first position (Leftmost for rows, Highest for columns and diagonals)
- * 2: Hole found in middle position
- * 3: Hole found in last position
- * If no TIAR was found, the function returns Null.
- */
- int? IdentifyTIARs(int[,] board, int currentPlayer, int crd)
- {
- int? holePos = null;
- currentPlayer += 1;
- // Console.WriteLine("CurrentPlayer debug: " + currentPlayer);
- switch (crd)
- {
- case 0:
- if (board[0, 0] == 0 && board[0, 1] == currentPlayer && board[0, 2] == currentPlayer) holePos = 1;
- if (board[0, 0] == currentPlayer && board[0, 1] == 0 && board[0, 2] == currentPlayer) holePos = 2;
- if (board[0, 0] == currentPlayer && board[0, 1] == currentPlayer && board[0, 2] == 0) holePos = 3;
- break;
- case 1:
- if (board[1, 0] == 0 && board[1, 1] == currentPlayer && board[1, 2] == currentPlayer) holePos = 1;
- if (board[1, 0] == currentPlayer && board[1, 1] == 0 && board[1, 2] == currentPlayer) holePos = 2;
- if (board[1, 0] == currentPlayer && board[1, 1] == currentPlayer && board[1, 2] == 0) holePos = 3;
- break;
- case 2:
- if (board[2, 0] == 0 && board[2, 1] == currentPlayer && board[2, 2] == currentPlayer) holePos = 1;
- if (board[2, 0] == currentPlayer && board[2, 1] == 0 && board[2, 2] == currentPlayer) holePos = 2;
- if (board[2, 0] == currentPlayer && board[2, 1] == currentPlayer && board[2, 2] == 0) holePos = 3;
- break;
- case 3:
- if (board[0, 0] == 0 && board[1, 0] == currentPlayer && board[2, 0] == currentPlayer) holePos = 1;
- if (board[0, 0] == currentPlayer && board[1, 0] == 0 && board[2, 0] == currentPlayer) holePos = 2;
- if (board[0, 0] == currentPlayer && board[1, 0] == currentPlayer && board[2, 0] == 0) holePos = 3;
- break;
- case 4:
- if (board[0, 1] == 0 && board[1, 1] == currentPlayer && board[2, 1] == currentPlayer) holePos = 1;
- if (board[0, 1] == currentPlayer && board[1, 1] == 0 && board[2, 1] == currentPlayer) holePos = 2;
- if (board[0, 1] == currentPlayer && board[1, 1] == currentPlayer && board[2, 1] == 0) holePos = 3;
- break;
- case 5:
- if (board[0, 2] == 0 && board[1, 2] == currentPlayer && board[2, 2] == currentPlayer) holePos = 1;
- if (board[0, 2] == currentPlayer && board[1, 2] == 0 && board[2, 2] == currentPlayer) holePos = 2;
- if (board[0, 2] == currentPlayer && board[1, 2] == currentPlayer && board[2, 2] == 0) holePos = 3;
- break;
- case 6:
- if (board[0, 0] == 0 && board[1, 1] == currentPlayer && board[2, 2] == currentPlayer) holePos = 1;
- if (board[0, 0] == currentPlayer && board[1, 1] == 0 && board[2, 2] == currentPlayer) holePos = 2;
- if (board[0, 0] == currentPlayer && board[1, 1] == currentPlayer && board[2, 2] == 0) holePos = 3;
- break;
- case 7:
- if (board[0, 2] == 0 && board[1, 1] == currentPlayer && board[2, 0] == currentPlayer) holePos = 1;
- if (board[0, 2] == currentPlayer && board[1, 1] == 0 && board[2, 0] == currentPlayer) holePos = 2;
- if (board[0, 2] == currentPlayer && board[1, 1] == currentPlayer && board[2, 0] == 0) holePos = 3;
- break;
- }
- return holePos;
- }
- int? IdentifyForks(int[,] board, int currentPlayer, int holePos)
- {
- int? forkID = null;
- int locQuan = 0;
- switch (holePos)
- {
- case 0:
- if (IdentifyTIARs(board, currentPlayer, 0) == 2 || IdentifyTIARs(board, currentPlayer, 0) == 3) locQuan++;
- if (IdentifyTIARs(board, currentPlayer, 3) == 2 || IdentifyTIARs(board, currentPlayer, 3) == 3) locQuan++;
- if (IdentifyTIARs(board, currentPlayer, 6) == 2 || IdentifyTIARs(board, currentPlayer, 6) == 3) locQuan++;
- if (locQuan > 1) forkID = 0;
- break;
- case 1:
- if (IdentifyTIARs(board, currentPlayer, 0) == 1 || IdentifyTIARs(board, currentPlayer, 0) == 3) locQuan++;
- if (IdentifyTIARs(board, currentPlayer, 4) == 2 || IdentifyTIARs(board, currentPlayer, 4) == 3) locQuan++;
- if (locQuan > 1) forkID = 1;
- break;
- case 2:
- if (IdentifyTIARs(board, currentPlayer, 0) == 1 || IdentifyTIARs(board, currentPlayer, 0) == 2) locQuan++;
- if (IdentifyTIARs(board, currentPlayer, 5) == 2 || IdentifyTIARs(board, currentPlayer, 5) == 3) locQuan++;
- if (IdentifyTIARs(board, currentPlayer, 7) == 2 || IdentifyTIARs(board, currentPlayer, 7) == 3) locQuan++;
- if (locQuan > 1) forkID = 2;
- break;
- case 3:
- if (IdentifyTIARs(board, currentPlayer, 1) == 2 || IdentifyTIARs(board, currentPlayer, 1) == 3) locQuan++;
- if (IdentifyTIARs(board, currentPlayer, 3) == 1 || IdentifyTIARs(board, currentPlayer, 3) == 3) locQuan++;
- if (locQuan > 1) forkID = 3;
- break;
- case 4:
- if (IdentifyTIARs(board, currentPlayer, 1) == 1 || IdentifyTIARs(board, currentPlayer, 1) == 3) locQuan++;
- if (IdentifyTIARs(board, currentPlayer, 4) == 1 || IdentifyTIARs(board, currentPlayer, 4) == 3) locQuan++;
- if (IdentifyTIARs(board, currentPlayer, 6) == 1 || IdentifyTIARs(board, currentPlayer, 6) == 3) locQuan++;
- if (IdentifyTIARs(board, currentPlayer, 7) == 1 || IdentifyTIARs(board, currentPlayer, 7) == 3) locQuan++;
- if (locQuan > 1) forkID = 4;
- break;
- case 5:
- if (IdentifyTIARs(board, currentPlayer, 1) == 1 || IdentifyTIARs(board, currentPlayer, 3) == 2) locQuan++;
- if (IdentifyTIARs(board, currentPlayer, 5) == 1 || IdentifyTIARs(board, currentPlayer, 5) == 3) locQuan++;
- if (locQuan > 1) forkID = 5;
- break;
- case 6:
- if (IdentifyTIARs(board, currentPlayer, 2) == 2 || IdentifyTIARs(board, currentPlayer, 2) == 3) locQuan++;
- if (IdentifyTIARs(board, currentPlayer, 3) == 1 || IdentifyTIARs(board, currentPlayer, 3) == 2) locQuan++;
- if (IdentifyTIARs(board, currentPlayer, 7) == 1 || IdentifyTIARs(board, currentPlayer, 7) == 2) locQuan++;
- if (locQuan > 1) forkID = 6;
- break;
- case 7:
- if (IdentifyTIARs(board, currentPlayer, 2) == 1 || IdentifyTIARs(board, currentPlayer, 2) == 3) locQuan++;
- if (IdentifyTIARs(board, currentPlayer, 4) == 1 || IdentifyTIARs(board, currentPlayer, 4) == 2) locQuan++;
- if (locQuan > 1) forkID = 7;
- break;
- case 8:
- if (IdentifyTIARs(board, currentPlayer, 2) == 1 || IdentifyTIARs(board, currentPlayer, 2) == 2) locQuan++;
- if (IdentifyTIARs(board, currentPlayer, 5) == 1 || IdentifyTIARs(board, currentPlayer, 5) == 2) locQuan++;
- if (IdentifyTIARs(board, currentPlayer, 6) == 1 || IdentifyTIARs(board, currentPlayer, 6) == 2) locQuan++;
- if (locQuan > 1) forkID = 8;
- break;
- }
- return forkID;
- }
- Move Minimax(int[,] board, int depth, int currentPlayer, bool max = true)
- {
- if (depth == 0 || CountPlayerSpaces(board, 0) == 0)
- {
- return new Move { score = Evaluate(board, currentPlayer) };
- }
- int bestScore = 1;
- Move m = new Move();
- if (max)
- {
- bestScore = int.MinValue;
- for (int x = 0; x < 3; x++)
- {
- for (int y = 0; y < 3; y++)
- {
- if (board[x, y] == 0)
- {
- int[,] newBoard = CopyBoard(board);
- newBoard[x, y] = currentPlayer + 1;
- m = Minimax(newBoard, depth - 1, 1 - currentPlayer, false);
- int score = m.score;
- m.x = score > bestScore ? x : m.x;
- m.y = score > bestScore ? y : m.y;
- bestScore = score > bestScore ? score : bestScore;
- }
- }
- }
- }
- else
- {
- bestScore = int.MaxValue;
- for (int x = 0; x < 3; x++)
- {
- for (int y = 0; y < 3; y++)
- {
- if (board[x, y] == 0)
- {
- int[,] newBoard = CopyBoard(board);
- newBoard[x, y] = currentPlayer + 1;
- m = Minimax(newBoard, depth - 1, 1 - currentPlayer, true);
- int score = m.score;
- m.x = score < bestScore ? x : m.x;
- m.y = score < bestScore ? y : m.y;
- bestScore = score < bestScore ? score : bestScore;
- }
- }
- }
- }
- m.score = bestScore;
- return m;
- }
- void FuckassCounter(int[,] board)
- {
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement