예제 #1
0
        /// <summary>
        /// Returns the best move score
        /// </summary>
        /// <param name="col_to_move_in">The best move index for this level of move</param>
        /// <param name="remaining_depth"></param>
        /// <param name="white_min"></param>
        /// <param name="black_max"></param>
        /// <param name="board"></param>
        /// <returns></returns>
        int findBestBlackMove(AbstractBoard.CommonMove col_to_move_in, int remaining_depth, int white_min, int black_max, C4Board board)
        {
            int best_score  = BIG_SCORE;
            var best_move   = new AbstractBoard.CommonMove();
            var move_status = new AbstractBoard.MoveResult();

            List <AbstractBoard.CommonMove> valid_moves = board.validMoves();

            for (int black_move_idx = 0; black_move_idx < valid_moves.Count; ++black_move_idx)
            {
                // Make each move in turn and see if it would be a winning move
                var curr_move = valid_moves[black_move_idx];
                var new_board = new C4Board(board);
                move_status = new_board.makeMove(curr_move);

                if (move_status.was_winning_move)
                {
                    col_to_move_in.move_idx = curr_move.move_idx;
                    return(BLACK_WIN);
                }

                int score = 0;

                if (remaining_depth == 0)
                {
                    score = new_board.rateBoard();
                }
                else
                {
                    score = findBestWhiteMove(col_to_move_in: curr_move,
                                              remaining_depth: remaining_depth - 1,
                                              white_min: white_min,
                                              black_max: black_max,
                                              board: new_board);
                }


                if (score < best_score)
                {
                    // Best move yet
                    best_score         = score;
                    best_move.move_idx = curr_move.move_idx;

                    if (black_max > best_score)
                    {
                        black_max = best_score;
                    }
                }

                if (black_max <= white_min)
                {
                    // Pruning - short-circuit rest of processing
                    col_to_move_in.move_idx = best_move.move_idx;
                    return(best_score);
                }
            }

            col_to_move_in.move_idx = best_move.move_idx;
            return(best_score);
        }
예제 #2
0
        public C4Board(AbstractBoard board)
        {
            if (board is C4Board)
            {
                C4Board c4_board = board as C4Board;

                // Call C4Board ctor
                setupBoard(c4_board);
            }
        }
예제 #3
0
        private void setupBoard(C4Board board)
        {
            // Copy squares
            for (int row_idx = 0; row_idx < NUM_ROWS; ++row_idx)
            {
                for (int col_idx = 0; col_idx < NUM_COLS; ++col_idx)
                {
                    squares[row_idx, col_idx] = board.squares[row_idx, col_idx];
                }
            }

            blackToMove = board.blackToMove;

            // Copy numPieceInCol
            for (int col_idx = 0; col_idx < NUM_COLS; ++col_idx)
            {
                numPiecesInCol[col_idx] = board.numPiecesInCol[col_idx];
            }
        }
예제 #4
0
        /*
         * Work out how much credit to give the given colour in the
         * current position
         */
        public int rateBoard(PieceType colour)
        {
            const int THREE_IN_LINE_WITH_GAP_SCORE = 100;
            int       result = 0;

            // Try moving in each of the empty squares and see if this
            // gives a win:
            // TO DO: Look for a move that gives us 3+ a gap in a block of 4.

            // Copy squares
            for (int row_idx = 0; row_idx < NUM_ROWS; ++row_idx)
            {
                for (int col_idx = 0; col_idx < NUM_COLS; ++col_idx)
                {
                    if (squares[row_idx, col_idx] == PieceType.EMPTY)
                    {
                        //System.Console.WriteLine($"Considering row {row_idx} col {col_idx}");
                        var new_board = new C4Board(this);

                        if (colour == PieceType.WHITE)
                        {
                            new_board.blackToMove = true;
                        }
                        else
                        {
                            new_board.blackToMove = false;
                        }

                        MoveResult res = new_board.placePiece(row_idx, col_idx);

                        if (res.was_winning_move)
                        {
                            // Give more credit to a lower winning move than a higher up one
                            result += THREE_IN_LINE_WITH_GAP_SCORE;
                            result += NUM_COLS - col_idx;
                            //System.Console.WriteLine("3 in line with gap found");
                        }
                    }
                } // end for col
            }     // end for row
            return(result);
        }
예제 #5
0
 // TO DO: Use abstract board throughout
 public BestMoveFinder(C4Board board)
 {
     this.board = board;
 }
예제 #6
0
 public C4Board(C4Board board)
 {
     setupBoard(board);
 }