private double tryMove( int[,] board, Move move) { double []input = new double[9]; int index = 0; for (int x = 0; x < 3; x++) { for (int y = 0; y < 3; y++) { if (board[x,y] == TicTacToe.NOUGHTS) { input[index] = -1; } else if (board[x,y] == TicTacToe.CROSSES) { input[index] = 1; } else if (board[x,y] == TicTacToe.EMPTY) { input[index] = 0; } if ((x == move.x) && (y == move.y)) { input[index] = -1; } index++; } } double []output = this.network.ComputeOutputs(input); return output[0]; }
private Move centerOpen( int[,] board, int color) { Move center = new Move((int) 1, (int) 1, color); if (Board.isEmpty(board, center)) { return center; } else { return null; } }
/** * Gets this player's next move. It is always the next available square. * * @param board * <code>Board</code> representation of the current game state. * @param prev * <code>Move</code> representing the previous move in the the * game. * @param player * <code>int</code> representing the pieces this * <code>Player</code> is playing with. One of * <code>TicTacToe.NOUGHTS</code> or * <code>TicTacToe.CROSSES</code> * @return <code>Move</code> Next move for this player. */ public Move getMove( int[,] board, Move prev, int player) { for (byte x = 0; x < 3; x++) { for (byte y = 0; y < 3; y++) { Move m = new Move(x, y, player); if (Board.isEmpty(board, m)) { return m; } } } throw new Exception("I'm just looking for the first " + "empty square and I can't move!"); }
/** * Gets the next move of this player. * * @param board * <code>Board</code> representation of the current game state. * @param prev * <code>Move</code> representing the previous move in the the * game. * @param color * <code>int</code> representing the pieces this * <code>Player</code> is playing with. One of * <code>TicTacToe.NOUGHTS</code> or * <code>TicTacToe.CROSSES</code> * @return <code>Move</code> Next move of this player. */ public Move getMove( int[,] board, Move prev, int color) { Board.printBoard(board); // ask for move Console.WriteLine("You are playing: " + TicTacToe.resolvePiece(color) + ", select your move."); Console.Write("X position? "); int x = getCoord(); Console.Write("Y position? "); int y = getCoord(); return new Move(x, y, color); }
/** * Gets this player's next move. It is always the next available square. * * @param board * <code>Board</code> representation of the current game state. * @param prev * <code>Move</code> representing the previous move in the the * game. * @param player * <code>int</code> representing the pieces this * <code>Player</code> is playing with. One of * <code>TicTacToe.NOUGHTS</code> or * <code>TicTacToe.CROSSES</code> * @return <code>Move</code> Next move for this player. */ public Move getMove( int[,] board, Move prev, int player) { Random rand = new Random(); for (;;) { int x = (int) (rand.NextDouble() * 3.0); int y = (int)(rand.NextDouble() * 3.0); Move m = new Move(x, y, player); if (Board.isEmpty(board, m)) { return m; } } }
private Move findWin( int[,] board, Move move1, Move move2, Move move3, int color) { if ((board[move1.x,move1.y] == color) && (board[move2.x,move2.y] == color) && (board[move3.x,move3.y] == TicTacToe.EMPTY)) { return move3; } else if ((board[move2.x,move2.y] == color) && (board[move3.x,move3.y] == color) && (board[move1.x,move1.y] == TicTacToe.EMPTY)) { return move1; } else if ((board[move1.x,move1.y] == color) && (board[move3.x,move3.y] == color) && (board[move2.x,move2.y] == TicTacToe.EMPTY)) { return move2; } else { return null; } }
private Move cornerOpen( int[,] board, int color) { Move corner1 = new Move((int) 0, (int) 0, color); Move corner2 = new Move((int) 2, (int) 2, color); Move corner3 = new Move((int) 2, (int) 0, color); Move corner4 = new Move((int) 0, (int) 2, color); if (Board.isEmpty(board, corner1)) { return corner1; } else if (Board.isEmpty(board, corner2)) { return corner2; } else if (Board.isEmpty(board, corner3)) { return corner3; } else if (Board.isEmpty(board, corner4)) { return corner4; } else { return null; } }
public Move getMove( int[,] board, Move prev, int color) { Move bestMove = null; double bestScore = double.MinValue; for (int x = 0; x <3; x++) { for (int y = 0; y < 3; y++) { Move move = new Move((int) x, (int) y, color); if (Board.isEmpty(board, move)) { double d = tryMove(board, move); if ((d > bestScore) || (bestMove == null)) { bestScore = d; bestMove = move; } } } } return bestMove; }
public static Move[] GetEmptyPositions(int[,] board, int visual) { int length = board.Length, actualSize = 0; Move[] emptyPositions = new Move[] { }; Array.Resize(ref emptyPositions, length); for (int x = 0; x < 3; x++) { for (int y = 0; y < 3; y++) { if (board[x, y] == TicTacToe.EMPTY) { emptyPositions[actualSize] = new Move(x, y, visual); actualSize++; } } } Array.Resize(ref emptyPositions, actualSize); return emptyPositions; }
private Move canWin( int [,]board, int color) { Move move1, move2, move3, move; for (int i = 0; i < 3; i++) { move1 = new Move((int) 0, (int) i, color); move2 = new Move((int) 1, (int) i, color); move3 = new Move((int) 2, (int) i, color); move = findWin(board, move1, move2, move3, color); if (move != null) { return move; } } for (int i = 0; i < 3; i++) { move1 = new Move((int) i, (int) 0, color); move2 = new Move((int) i, (int) 1, color); move3 = new Move((int) i, (int) 2, color); move = findWin(board, move1, move2, move3, color); if (move != null) { return move; } } move1 = new Move((int) 0, (int) 0, color); move2 = new Move((int) 1, (int) 1, color); move3 = new Move((int) 2, (int) 2, color); move = findWin(board, move1, move2, move3, color); if (move != null) { return move; } move1 = new Move((int) 2, (int) 0, color); move2 = new Move((int) 0, (int) 0, color); move3 = new Move((int) 0, (int) 2, color); move = findWin(board, move1, move2, move3, color); if (move != null) { return move; } return null; }
// main guts of the game private Player play(Move prev) { for (;;) { // new board here else players can alter the game board as they // wish! int[,] b = Board.copy(this._board); Move move = this._players[this._player].getMove(b, prev, this._player); if (move == null) { throw new Exception("Player supplied null move"); } // check square is empty if (!Board.isEmpty(this._board, move)) { Console.WriteLine("That square is not empty"); play(prev); } // place piece if (!Board.placePiece(this._board, move)) { Console.WriteLine("Illegal Move - try again"); play(prev); } if (Board.isWinner(this._board, this._player)) { return this._players[this._player]; } // change player this._player = TicTacToe.reverse(this._player); if (Board.isFull(this._board)) { return null; } prev = move; } }
/** * Gets the next move of this player. * * @param board * <code>Board</code> representation of the current game state. * @param prev * <code>Move</code> representing the previous move in the the * game. * @param color * <code>int</code> representing the pieces this * <code>Player</code> is playing with. One of * <code>TicTacToe.NOUGHTS</code> or * <code>TicTacToe.CROSSES</code> * @return <code>Move</code> Next move of this player. */ public Move getMove( int[,] board, Move prev, int color) { this._player = color; Node root = new Node(board, prev); int max = int.MinValue; Node child; Node bestNode = null; while ((child = root.getChild()) != null) { int val = minimaxAB(child, true, int.MinValue, int.MaxValue); if (val >= max) { max = val; bestNode = child; } } return bestNode.move(); }
public Move getMove( int[,] board, Move prev, int color) { if (Board.isFull(board)) { return null; } Move result = null; int other = TicTacToe.reverse(color); if (result == null) { result = canWin(board, color); } if (result == null) { result = canWin(board, other); } // Step 1: Is the center open if (result == null) { result = centerOpen(board, color); } // Step 2: Is the corner open if (result == null) { result = cornerOpen(board, color); } // Step 3: Move somewhere if (result == null) { result = moveSomewhere(board, color); } if (result.color() != color) { result = new Move(result.x, result.y, color); } return result; }
/** * Determines if the square the specified <code>Move</code> takes place in * is empty or not. * * @param move * <code>Move</code> to check position of. * @return <code>bool</code>, true if the square is empty. */ public static bool isEmpty( int[,] board, Move move) { return (board[move.x,move.y] == TicTacToe.EMPTY); }
/** * Does the move specified in <code>m</code> on <code>board</code>. * * @param board * <code>int[,]</code> of board to perform move on. * @param m * <code>Move</code> to perform. * @return <code>bool</code> of whether the move succeeded or not. * @throws IllegalStateException * If the move is not legal. */ public static bool placePiece( int[,] board, Move m) { if (board[m.x,m.y] != TicTacToe.EMPTY) { throw new Exception("Tried to play a piece on " + "top of another at (" + m.x + ", " + m.y + ")"); } else { board[m.x,m.y] = m.color(); return true; } }
/** * Creates a node with the specified board position, reached by the * specified move. * * @param board * <code>Board</code> of the board position of this node. * @param move * <code>Move</code> last move that was taken to reach this * board position. */ public Node( int[,] board, Move move) { this._board = board; this._move = move; }
/** * Gets the "next" child for this node, or <code>null</code> if all * children of this node have already been found. * * @return <code>Node</code> Representation of child (one move on) in the * game tree. */ public Node getChild() { bool firstColumn = true; for (int x = this._x; x < 3; x++) { int starter = 0; if (firstColumn) { starter = this._y; } for (int y = starter; y < 3; y++) { Move m = new Move(x, y, this.player()); if (Board.isEmpty(this._board, m)) { int[,] newPos = Board.copy(this._board); Board.placePiece(newPos, m); Node child = new Node(newPos, m); this._children[this.childNum++] = child; if (y >= (3 - 1)) { this._x = (int) (x + 1); this._y = 0; } else { this._x = x; this._y = (int) (y + 1); } this._leaf = false; this._leafdef = true; return child; } } firstColumn = false; } this._leaf = true; this._leafdef = true; return null; }