public Move GetMove(SquareTypes[,] board) { List <double> inputs = new List <double> { getInputForSquareType(board[0, 0]), getInputForSquareType(board[0, 1]), getInputForSquareType(board[0, 2]), getInputForSquareType(board[1, 0]), getInputForSquareType(board[1, 1]), getInputForSquareType(board[1, 2]), getInputForSquareType(board[2, 0]), getInputForSquareType(board[2, 1]), getInputForSquareType(board[2, 2]), }; Brain.ProcessInput(inputs); int i = 0; Neuron firedNeuron; var neurons = Brain.OutputLayer.Neurons.OrderByDescending(n => n.PulseValue).ToList(); do { firedNeuron = neurons[i++]; }while (board[firedNeuron.Id.Item2 % 3, firedNeuron.Id.Item2 / 3] != SquareTypes.N); return(new Move(firedNeuron.Id.Item2 % 3, firedNeuron.Id.Item2 / 3)); }
/// <summary> /// Enumerates all possible moves that could be made for the given board. /// </summary> private List <SquareTypes[, ]> getAllPossibleNextBoards(SquareTypes[,] board, SquareTypes squareType) { List <SquareTypes[, ]> possibleBoards = new List <SquareTypes[, ]>(); for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { // Skip squares that are taken. if (board[i, j] != SquareTypes.N) { continue; } // Create the new board. SquareTypes[,] possibleBoard = new SquareTypes[3, 3]; Array.Copy(board, possibleBoard, 9); // Set the possible move. possibleBoard[i, j] = squareType; // Add the possible board to the list of boards. possibleBoards.Add(possibleBoard); } } return(possibleBoards); }
// Loads the board into the input signal array. // This just flattens the 2d board into a 1d array. private void setInputSignalArray(ISignalArray inputArr, SquareTypes[,] board) { inputArr[0] = squareToInt(board[0, 0]); inputArr[1] = squareToInt(board[1, 0]); inputArr[2] = squareToInt(board[2, 0]); inputArr[3] = squareToInt(board[0, 1]); inputArr[4] = squareToInt(board[1, 1]); inputArr[5] = squareToInt(board[2, 1]); inputArr[6] = squareToInt(board[0, 2]); inputArr[7] = squareToInt(board[1, 2]); inputArr[8] = squareToInt(board[2, 2]); }
private void AssertEqualBoards(SquareTypes[,] expected, SquareTypes[,] actual) { Assert.AreEqual(expected[0, 0], actual[0, 0]); Assert.AreEqual(expected[1, 0], actual[1, 0]); Assert.AreEqual(expected[2, 0], actual[2, 0]); Assert.AreEqual(expected[0, 1], actual[0, 1]); Assert.AreEqual(expected[1, 1], actual[1, 1]); Assert.AreEqual(expected[2, 1], actual[2, 1]); Assert.AreEqual(expected[0, 2], actual[0, 2]); Assert.AreEqual(expected[1, 2], actual[1, 2]); Assert.AreEqual(expected[2, 2], actual[2, 2]); }
internal static SquareTypes GetWinner(SquareTypes[,] Board) { if (Board[0, 0] != SquareTypes.N) { var type = Board[0, 0]; if (type == Board[0, 1] && type == Board[0, 2]) return type; if (type == Board[1, 0] && type == Board[2, 0]) return type; if (type == Board[1, 1] && type == Board[2, 2]) return type; } if (Board[0, 2] != SquareTypes.N) { var type = Board[0, 2]; if (type == Board[1, 1] && type == Board[2, 0]) return type; if (type == Board[1, 2] && type == Board[2, 2]) return type; } if (Board[0, 1] != SquareTypes.N) { var type = Board[0, 1]; if (type == Board[1, 1] && type == Board[2, 1]) return type; } if (Board[1, 0] != SquareTypes.N) { var type = Board[1, 0]; if (type == Board[1, 1] && type == Board[1, 2]) return type; } if (Board[2, 0] != SquareTypes.N) { var type = Board[2, 0]; if (type == Board[2, 1] && type == Board[2, 2]) return type; } return SquareTypes.N; }
public Move GetMove(SquareTypes[,] board) { int x = random.Next(3); int y = random.Next(3); while (board[x, y] != SquareTypes.N) { x = random.Next(3); y = random.Next(3); } return(new Move(x, y)); }
/// <summary> /// Gets the next move as dictated by the neural network. /// </summary> public Move GetMove(SquareTypes[,] board) { // Clear the network Brain.ResetState(); // Convert the game board into an input array for the network setInputSignalArray(Brain.InputSignalArray, board); // Activate the network Brain.Activate(); // Find the highest-scoring available move Move move = null; double max = double.MinValue; for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { // If the square is taken, skip it. if (board[i, j] != SquareTypes.N) { continue; } // Set the score for this square. double score = Brain.OutputSignalArray[i * 3 + j]; // If this is the first available move we've found, // set it to the current best. if (move == null) { move = new Move(i, j); max = score; } // If this square has a higher score than any we've // found, set it to the current best. else if (max < score) { move.X = i; move.Y = j; max = score; } } } return(move); }
public static void DisplayBoard(SquareTypes[,] board) { string a = board[0, 0] == SquareTypes.N ? " " : board[0, 0].ToString(); string b = board[0, 1] == SquareTypes.N ? " " : board[0, 1].ToString(); string c = board[0, 2] == SquareTypes.N ? " " : board[0, 2].ToString(); string d = board[1, 0] == SquareTypes.N ? " " : board[1, 0].ToString(); string e = board[1, 1] == SquareTypes.N ? " " : board[1, 1].ToString(); string f = board[1, 2] == SquareTypes.N ? " " : board[1, 2].ToString(); string g = board[2, 0] == SquareTypes.N ? " " : board[2, 0].ToString(); string h = board[2, 1] == SquareTypes.N ? " " : board[2, 1].ToString(); string i = board[2, 2] == SquareTypes.N ? " " : board[2, 2].ToString(); Console.WriteLine("+---+---+---+"); Console.WriteLine($"| {a} | {b} | {c} |"); Console.WriteLine("+---+---+---+"); Console.WriteLine($"| {d} | {e} | {f} |"); Console.WriteLine("+---+---+---+"); Console.WriteLine($"| {g} | {h} | {i} |"); Console.WriteLine("+---+---+---+"); }
public Move GetMove(SquareTypes[,] board) { int moveNum = 0; for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { if (board[i, j] != SquareTypes.N) { moveNum++; } } } //first move is always a corner if (moveNum == 0) { return(new Move(0, 0)); } //second move should be the center if free, else a corner if (moveNum == 1) { if (board[1, 1] == SquareTypes.N) { return(new Move(1, 1)); } return(new Move(0, 0)); } //make a winning move if possible for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { if (board[i, j] != SquareTypes.N) { continue; } board[i, j] = SquareType; var winner = TicTacToeGame.GetWinner(board); board[i, j] = SquareTypes.N; if (winner == SquareType) { return(new Move(i, j)); } } } //if we can't win, check if there are any moves that we have to make //to prevent ourselves from losing for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { if (board[i, j] != SquareTypes.N) { continue; } //set the move to the opponent's type board[i, j] = SquareType == SquareTypes.X ? SquareTypes.O : SquareTypes.X; var winner = TicTacToeGame.GetWinner(board); board[i, j] = SquareTypes.N; //if the opponent will win by moving here, move here to block them if (winner != SquareTypes.N) { return(new Move(i, j)); } } } //if we're here, that means we have made at least 1 move already and can't win //nor lose in 1 move, so just make the optimal play which would be to a free //corner that isn't blocked Move move = null; int max = -1; for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { if (board[i, j] != SquareTypes.N) { continue; } board[i, j] = SquareType; int count = 0; for (int m = 0; m < 3; m++) { for (int n = 0; n < 3; n++) { if (board[m, n] != SquareTypes.N) { continue; } board[m, n] = SquareType; var winner = TicTacToeGame.GetWinner(board); board[m, n] = SquareTypes.N; if (winner == SquareType) { count++; } } } board[i, j] = SquareTypes.N; if (count > max) { move = new Move(i, j); max = count; } } } return(move); }
public TicTacToeGame() { Board = new SquareTypes[3, 3]; }
public void GetWinnerTest() { SquareTypes[,] board = TicTacToeGame.GetBoardFromString(@" | | | | | | "); SquareTypes expected = SquareTypes.N; SquareTypes actual; actual = TicTacToeGame.GetWinner(board); Assert.AreEqual(expected, actual); //Diagnol left to right board = TicTacToeGame.GetBoardFromString(@"X|O|O O|X|O O|O|X"); expected = SquareTypes.X; actual = TicTacToeGame.GetWinner(board); Assert.AreEqual(expected, actual); //Diagnol right to left board = TicTacToeGame.GetBoardFromString(@"O|O|X O|X| X|O|X"); expected = SquareTypes.X; actual = TicTacToeGame.GetWinner(board); Assert.AreEqual(expected, actual); //Horizontal bottom board = TicTacToeGame.GetBoardFromString(@"X| |X X|X|O O|O|O"); expected = SquareTypes.O; actual = TicTacToeGame.GetWinner(board); Assert.AreEqual(expected, actual); //Horizontal middle board = TicTacToeGame.GetBoardFromString(@"X|O|O X|X|X O|O| "); expected = SquareTypes.X; actual = TicTacToeGame.GetWinner(board); Assert.AreEqual(expected, actual); //Horizontal top board = TicTacToeGame.GetBoardFromString(@"O|O|O X|X|O |O|X"); expected = SquareTypes.O; actual = TicTacToeGame.GetWinner(board); Assert.AreEqual(expected, actual); //Vertical right board = TicTacToeGame.GetBoardFromString(@"X|O|O O|X|O X|O|O"); expected = SquareTypes.O; actual = TicTacToeGame.GetWinner(board); Assert.AreEqual(expected, actual); //Vertical middle board = TicTacToeGame.GetBoardFromString(@"X|O| |O|X X|O| "); expected = SquareTypes.O; actual = TicTacToeGame.GetWinner(board); Assert.AreEqual(expected, actual); //Vertical left board = TicTacToeGame.GetBoardFromString(@"X|O| X| |O X|O| "); expected = SquareTypes.X; actual = TicTacToeGame.GetWinner(board); Assert.AreEqual(expected, actual); //No winner board = TicTacToeGame.GetBoardFromString(@"X|O| | |O X|O| "); expected = SquareTypes.N; actual = TicTacToeGame.GetWinner(board); Assert.AreEqual(expected, actual); //No winner board = TicTacToeGame.GetBoardFromString(@"X|O|O |X|O X|O| "); expected = SquareTypes.N; actual = TicTacToeGame.GetWinner(board); Assert.AreEqual(expected, actual); //No winner board = TicTacToeGame.GetBoardFromString(@"X|X| O|X|O X|O|O "); expected = SquareTypes.N; actual = TicTacToeGame.GetWinner(board); Assert.AreEqual(expected, actual); //No winner board = TicTacToeGame.GetBoardFromString(@"X|X|O O|X|X X|O|O"); expected = SquareTypes.N; actual = TicTacToeGame.GetWinner(board); Assert.AreEqual(expected, actual); }
/// <summary> /// Gets the winner based on the specified board. /// </summary> /// <param name="Board"></param> /// <returns> /// The SquareType of the winner, or SquareTypes.N /// if no one has won yet or there's a draw. /// </returns> public static SquareTypes GetWinner(SquareTypes[,] Board) { if (Board[0, 0] != SquareTypes.N) { var type = Board[0, 0]; //top left to bottom left if (type == Board[0, 1] && type == Board[0, 2]) { return(type); } //top left to top right if (type == Board[1, 0] && type == Board[2, 0]) { return(type); } //top left to bottom right if (type == Board[1, 1] && type == Board[2, 2]) { return(type); } } if (Board[0, 2] != SquareTypes.N) { var type = Board[0, 2]; //bottom left to top right if (type == Board[1, 1] && type == Board[2, 0]) { return(type); } //bottom left to bottom right if (type == Board[1, 2] && type == Board[2, 2]) { return(type); } } if (Board[0, 1] != SquareTypes.N) { var type = Board[0, 1]; //middle left to middle right if (type == Board[1, 1] && type == Board[2, 1]) { return(type); } } if (Board[1, 0] != SquareTypes.N) { var type = Board[1, 0]; //middle top to middle bottom if (type == Board[1, 1] && type == Board[1, 2]) { return(type); } } if (Board[2, 0] != SquareTypes.N) { var type = Board[2, 0]; //top right to bottom right if (type == Board[2, 1] && type == Board[2, 2]) { return(type); } } return(SquareTypes.N); }