Пример #1
0
        public static void DrawBoard(Position inputBoard)
        {
            for (int i = 0; i < 6; i++) {
                if (i == 0) {
                    Console.WriteLine("┌───┬───┬───┬───┬───┬───┬───┐");
                } else if (i >= 1) {
                    Console.WriteLine("├───┼───┼───┼───┼───┼───┼───┤");
                }

                for (int j = 0; j < 7; j++) {
                    int shiftNumber = 5 - i + (7*j);
                    String piece;
                    if ((0x1UL << shiftNumber & inputBoard.arrayOfBitboard[0]) != 0) {
                        piece = "O";
                    } else if ((0x1UL << shiftNumber & inputBoard.arrayOfBitboard[1]) != 0) {
                        piece = "X";
                    } else {
                        piece = " ";
                    }

                    Console.Write("│ " + piece + " ");
                }
                Console.WriteLine("│");
            }
            Console.WriteLine("└───┴───┴───┴───┴───┴───┴───┘");
            Console.WriteLine("  1   2   3   4   5   6   7");
            Console.WriteLine("");
            Console.WriteLine("Key: " + inputBoard.key);
            Console.WriteLine("");
        }
Пример #2
0
        public static UInt64 perft(int depth, Position inputBoard)
        {
            UInt64 nodes = 0;
            if (inputBoard.HasWon(inputBoard.arrayOfBitboard[(inputBoard.nPlies-1) & 1]) || inputBoard.nPlies == 42) {
                return 1;
            } else if (depth == 1) {
                for (int i = 0; i < 7; i++) {
                    if (inputBoard.height[i] - 7 * i <= 5) {
                        nodes++;
                    }
                }
                return nodes;
            }

            for (int i = 0; i < 7; i++) {
                if (inputBoard.height[i] - 7 * i <= 5) {
                    inputBoard.MakeMove(inputBoard.height[i]);
                    nodes += perft(depth - 1, inputBoard);
                    inputBoard.UnmakeMove();
                }
            }

            return nodes;
        }
Пример #3
0
        public static int solve(int nodeType, Position inputBoard, int ply, int alpha, int beta, int depth)
        {
            // return score for terminal state
            if (inputBoard.HasWon(inputBoard.arrayOfBitboard[(inputBoard.nPlies - 1) & 1])) {
                return -Constants.WIN + ply;
            } else if (inputBoard.nPlies == 42) {
                Debug.Assert(depth == 0);
                return Constants.DRAW;
            }

            // "Mate" distance pruning
            //if (nodeType != Constants.ROOT) {
                alpha = Math.Max(ply-Constants.WIN, alpha);
                beta = Math.Min(Constants.WIN - (ply + 1), beta);
                if (alpha >= beta) {
                    return alpha;
                }
            //}

            // probe transposition table
            TTEntry entry = Solve.TranspositionTable.probeTTable(inputBoard.key);

            // If entry has a flag type, then key will match (probe function performs check), only empty entries will have a key that doesn't match
            if (entry.flag == Constants.EXACT
                || entry.flag == Constants.L_BOUND && entry.evaluationScore >= beta
                || entry.flag == Constants.U_BOUND && entry.evaluationScore <= alpha) {
                Debug.Assert(entry.key == inputBoard.key && entry.depth == depth);

                // Only exact and lower bound entries can satisfy this condition and they all have valid moves stored, so don't have to check if move == -1 (only the case with upper bound entries)
                if (entry.evaluationScore >= beta) {
                    Debug.Assert(entry.move != Constants.NO_MOVE);
                    updateKillers(entry.move, ply);
                }
                return entry.evaluationScore;
            }

            // hash move, if entry is exact then code will not be reached and if entry is an upper bound then it will have no move
            int hashMove = (entry.flag == Constants.L_BOUND && entry.evaluationScore < beta) ? entry.move : Constants.NO_MOVE;
            int bestScore = -Constants.INF;
            int movesMade = 0;
            bool raisedAlpha = false;
            movePicker mPicker = new movePicker(inputBoard, ply, hashMove);
            int bestMove = Constants.NO_MOVE;

            // loop through all moves
            while (true) {
                int move = mPicker.getNextMove();

                if (move == Constants.NO_MOVE) {
                    break;
                }

                inputBoard.MakeMove(move);
                int score = -solve(Constants.NON_ROOT, inputBoard, ply + 1, -beta, -alpha, depth - 1);
                inputBoard.UnmakeMove();
                nodesVisited++;
                movesMade++;

                if (score >= beta) {
                    TTEntry newEntry = new TTEntry(inputBoard.key, Constants.L_BOUND, depth, score, move);
                    Solve.TranspositionTable.storeTTable(inputBoard.key, newEntry);
                    updateKillers(move, ply);
                    updateHistory(depth, ply, move);

                    if (movesMade == 1) {
                        fh1++;
                    } else {
                        fh++;
                    }
                    return score;
                } else if (score > bestScore) {
                    bestScore = score;
                    bestMove = move;
                    if (score > alpha) {
                        alpha = score;
                        raisedAlpha = true;
                    }
                }
            }
            // Store in transposition table
            if (raisedAlpha) {
                TTEntry newEntry = new TTEntry(inputBoard.key, Constants.EXACT, depth, alpha, bestMove);
                Solve.TranspositionTable.storeTTable(inputBoard.key, newEntry);
            } else {
                TTEntry newEntry = new TTEntry(inputBoard.key, Constants.U_BOUND, depth, bestScore, Constants.NO_MOVE); // no best move
                Solve.TranspositionTable.storeTTable(inputBoard.key, newEntry);
            }
            return bestScore;
        }
Пример #4
0
 public static void PerftTest()
 {
     for (int i = 1; i < 14; i++) {
         Position test = new Position("");
         Stopwatch stopwatch = new Stopwatch();
         stopwatch.Start();
         UInt64 nodeCount = Constants.perft(i, test);
         stopwatch.Stop();
         Console.WriteLine("Depth: " + i + "\t\tNodes: " + nodeCount.ToString("#,##0") + "\t\tTime: " + stopwatch.ElapsedMilliseconds.ToString("#,##0") + "\t\tNPS: " + (nodeCount/((UInt64)stopwatch.ElapsedMilliseconds+1)*1000).ToString("#,##0"));
     }
 }
Пример #5
0
 public movePicker(Position inputBoard, int ply, int hashMove)
 {
     board = inputBoard;
     this.ply = ply;
     this.hashMove = hashMove;
     moveList = this.moveGenerator();
 }