Exemple #1
0
        static void Main(string[] args)
        {
            /*
             * TO DO:
             *
             * Chess Essentials:
             * [DONE] Pawn Promotion
             * [DONE] Castling
             * [DONE] En Passant
             * [DONE] Draw by repetition
             *
             * Speed Enhancers:
             * [DONE] Transposition Tables (Zobrist Hashing)
             * [DONE] Principle Variation
             * [DONE] Aspiration Windows
             * [DONE] Null Move Pruning (disable towards end game to avoid zugzwang positions)
             *
             * Accuracy Enhancers:
             * [DONE] "Hole" detection and bonuses if knight occupies hole
             * [DONE] Space (based on pawn structure)
             * [DONE] Bonuses for rooks on open or semi open files
             * [DONE] Bonuses for bishops that are on same color as opposing pawn, opposite color of friendly pawn
             * [DONE] Deductions for poor king safety prior to end game
             * [DONE] Deductions for weak pawns
             *
             * General Purpose:
             * [DONE] Change engine to have a time limit as well as a depth limit (stops at whichever comes first)
             * [DONE] Add Syzgy Table bases
             * [DONE] End game detection & King bonus square adjustments in end game
             * [DONE] Bug Fixes (run full game with VerifyBoard enabled in BoardData to look for bugs)
             * [DONE] Optimizations (all but move gen have been optimized)
             *
             */

            //for testing
            //String test = "2B5/PKP5/2P5/8/8/8/k7/8 w - - 0 1";
            //starting position
            String test = "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq h8 0 1";


            BoardData  board = new BoardData(test);
            Conversion c     = new Conversion();

            board.DisplayBoard();

            Engine com = new Engine(board);

            int depth     = 8;
            int stop_time = 4000;

            /*
             * //---------------------------------------------------------------------------------------------------------------------------
             * //uncomment this if you want to perform an efficiency test. Tip: More tests = more accurate results
             *
             * double numTests = 10000;
             * var timer1 = System.Diagnostics.Stopwatch.StartNew();
             * for (int i = 0; i < numTests; i++)
             * {
             *  com.GetBestMove(1, 1000);
             * }
             * timer1.Stop();
             * double time1 = timer1.ElapsedMilliseconds;
             * Console.WriteLine("\nTime taken: " + time1 + "ms, or an average of " + numTests * 1000 / time1 + " calls per second.");
             *
             * //% of total time is under the assumption that the time taken for the computer to choose a move is 5 seconds
             * //Only accurate if numTests is close to the amount of times the tested operation is performed when choosing a move
             * Console.WriteLine("Roughly " + (time1 * 100 / 5000) + "% of total time taken.");
             * Console.WriteLine();
             *
             * //---------------------------------------------------------------------------------------------------------------------------
             */

            //numMoves is a necessary precaution, as there is currently no detection for draw by lack of material
            int numMoves = 0;

            //this while loop simulates a chess game.
            while (numMoves < 300)
            {
                Console.WriteLine("Enter a command: ");
                String command = Console.ReadLine();
                //h command denotes a "human" move; simply plays the move entered
                //format: "h " + [beforeSquare] + [afterSquare] + [Enpassant Flag]"
                //Enpassant flag = (isEnPassantMove ? [any character] : [null])
                if (command.Substring(0, 1).Equals("h"))
                {
                    Console.WriteLine("\nMove number: " + ++numMoves);
                    string hmove = command.Substring(2, command.Length - 2);
                    com.DoMove(c.MoveToNum(hmove, board));
                }
                //c command denotes a "computer" move; computer calculates and plays move for whichever player's turn it is
                else if (command.Equals("c"))
                {
                    Console.WriteLine("\n\nThinking... ");
                    var timer3 = System.Diagnostics.Stopwatch.StartNew();
                    int move   = com.PerformBestMove(depth, stop_time);
                    timer3.Stop();
                    double time3 = timer3.ElapsedMilliseconds;
                    Console.WriteLine("\nMove number: " + ++numMoves);
                    Console.WriteLine("Nodes visited: " + com.numNodes);
                    Console.WriteLine("Time taken: " + time3 / 1000.0 + " seconds");
                    Console.WriteLine("Nodes/s: " + com.numNodes / (time3 / 1000));
                    com.numNodes = 0;
                }
                //auto command denotes an auto finish. Computer will play for both sides for the remainder of the game
                else if (command.Equals("auto"))
                {
                    while (numMoves < 300)
                    {
                        Console.WriteLine("\n\nThinking... ");
                        var timer3 = System.Diagnostics.Stopwatch.StartNew();
                        int move   = com.PerformBestMove(depth, stop_time);
                        timer3.Stop();
                        double time3 = timer3.ElapsedMilliseconds;
                        Console.WriteLine("\nMove number: " + ++numMoves);
                        Console.WriteLine("Nodes visited: " + com.numNodes);
                        Console.WriteLine("Time taken: " + time3 / 1000.0 + " seconds");
                        Console.WriteLine("Nodes/s: " + com.numNodes / (time3 / 1000));
                        com.numNodes = 0;
                        board.DisplayBoard();
                        Console.WriteLine();
                        if (com.isMate || com.DBR)
                        {
                            break;
                        }
                    }
                    break;
                }
                else
                {
                    Console.WriteLine("Invalid command.\n");
                    continue;
                }
                board.DisplayBoard();
                Console.WriteLine();
                if (com.isMate || com.DBR)
                {
                    break;
                }
            }

            if (numMoves >= 300)
            {
                Console.WriteLine("The move limit of 300 was reached");
            }
            else if (com.DBR)
            {
                Console.WriteLine("Draw By Repetition");
            }
            else if (com.isMate)
            {
                Console.WriteLine("You have been checkmated");
            }
            else
            {
                Console.WriteLine("Stalemate");
            }


            Console.ReadKey();
        }