public List <Move> OrderedMoves(bool isWhitePlayer)
        {
            var retVal = new List <Move>();
            var tempList = new List <Move>();
            plm ownPlacement, opponentPlacement;

            if (isWhitePlayer)
            {
                ownPlacement      = GameBoard.state.WhiteFigurePlacement;
                opponentPlacement = GameBoard.state.BlackFigurePlacement;
            }
            else
            {
                ownPlacement      = GameBoard.state.BlackFigurePlacement;
                opponentPlacement = GameBoard.state.WhiteFigurePlacement;
            }
            //----------------------------------------------
            //Step 0: Get all possible moves available to Player.
            //----------------------------------------------
            foreach (var plac in ownPlacement)
            {
                foreach (var pofimo in Logic.PossibleFieldsToMove(plac))
                {
                    if (FieldsReachableByWhom.ContainsKey(pofimo))
                    {
                        FieldsReachableByWhom[pofimo].Add(plac);
                    }
                    else
                    {
                        FieldsReachableByWhom.Add(pofimo, new List <plac>()
                        {
                            plac
                        });
                    }
                }
            }
            //----------------------------------------------
            //Step 1: Order by moves that capture.
            //Step 1.1: First low value pieces capturing high value pieces. Then HVP capturing LVP.
            //      (If possible here or later, explicitly try to capture the last moved figure by the enemy first)
            //----------------------------------------------
            foreach (var plac in opponentPlacement)
            {
                if (FieldsReachableByWhom.ContainsKey(plac.Key))
                {
                    //A piece can be captured.
                    foreach (var captor in FieldsReachableByWhom[plac.Key])
                    {
                        tempList.Add(new Move(captor.Key, plac.Key, captor.Value, plac.Value));
                    }
                    //Remove to not have duplicates and accelerate later searches:
                    FieldsReachableByWhom.Remove(plac.Key);
                }
            }
            retVal.AddRange(tempList.OrderByDescending(x => Logic.IDtoFigure[x.removedID].worth - Logic.IDtoFigure[x.movedID].worth));
            tempList.Clear();
            //----------------------------------------------
            //Step 2: Order by moving in general direction of opponent.
            //----------------------------------------------
            var temp = new List <Move>();

            foreach (var fieldKey in FieldsReachableByWhom)
            {
                foreach (var kvp in fieldKey.Value)
                {
                    tempList.Add(new Move(kvp.Key, fieldKey.Key, kvp.Value, FigID.empty));
                }
            }

            if (isWhitePlayer)
            {
                retVal.AddRange(tempList.OrderByDescending(y => y.newPos.Item2 - y.oldPos.Item2).ToList());
            }
            else
            {
                retVal.AddRange(tempList.OrderBy(y => y.newPos.Item2 - y.oldPos.Item2).ToList());
            }
            //Clean up:
            FieldsReachableByWhom.Clear();

            return(retVal);
        }
Example #2
0
        static void Main()
        {
            Console.Title = Assembly.GetExecutingAssembly().GetName().Name + " " +
                            Assembly.GetExecutingAssembly().GetName().Version;
            //-----------------------------
            // Step 1: Initialise Board and all Chess Pieces:
            //-----------------------------
            var StartingState = new StdChessStartState();
            var GameBoard     = new Board(StartingState);
            var Logic         = new MovementLogic(StartingState);
            var TransTable    = new TranspositionTable();
            var MiniMaxi      = new MinMax(GameBoard, Logic, TransTable);

            Console.WriteLine("Hi, the game has started. You are playing the white player.");
            Console.WriteLine("K = King | Q = Queen | N = Knight | R = Rook | B = Bishop | P = Pawn");
            Console.WriteLine(@"Please give your moves like ""Nb1,c3""." + "\n");
            Task Worker = null;

            //var ply_1 = GameBoard.TryMove(new pos(1, 0), new pos(2, 2), FigID.wKnight);
            //var ply_2 = GameBoard.TryMove(new pos(1, 7), new pos(2, 5), FigID.bKnight);
            //var ply_3 = GameBoard.TryMove(new pos(3, 1), new pos(3, 3), FigID.wPawn);
            //var ply_4 = GameBoard.TryMove(new pos(4, 6), new pos(4, 5), FigID.bPawn);
            //var ply_5 = GameBoard.TryMove(new pos(2, 0), new pos(5, 3), FigID.wBishop);
            ////1. Nc3 Nc6  2. d4 e6  3. Bf4
            //GameBoard.ClearLoggedMoves();

            while (true)
            {
                try
                {
                    while (true)
                    {
                        var input = Console.ReadLine();
                        if (input != "nothing")
                        {
                            //Wait for Worker if still busy:
                            if (Worker != null)
                            {
                                Worker.Wait();
                            }
                            var(notationFrom, notationTo, notationFigID) = Notation.ConsoleInputToInternal(input);
                            if (Logic.PossibleFieldsToMove(new KeyValuePair <pos, FigID>(notationFrom, notationFigID)).Contains(notationTo))
                            {
                                if (!GameBoard.TryMove(notationFrom, notationTo, notationFigID))
                                {
                                    Console.WriteLine("Your input was erroneous and was not executed.");
                                }
                                else
                                {
                                    Console.WriteLine("White Player plays: " + input);
                                    break;
                                }
                            }
                            else
                            {
                                Console.WriteLine("Your input was erroneous and was not executed.");
                            }
                        }
                        else
                        {
                            break;
                        }
                    }
                    //Clear Stack:
                    GameBoard.ClearLoggedMoves();
                    //-----------------------------
                    // Step 1.5: Only for debugging:
                    //-----------------------------
                    //var ply_1 = GameBoard.TryMove(new pos(1, 0), new pos(2, 2), FigID.wKnight);
                    //var ply_2 = GameBoard.TryMove(new pos(1, 7), new pos(2, 5), FigID.bKnight);
                    //var ply_3 = GameBoard.TryMove(new pos(3, 1), new pos(3, 3), FigID.wPawn);
                    //var ply_4 = GameBoard.TryMove(new pos(4, 6), new pos(4, 5), FigID.bPawn);
                    //var ply_5 = GameBoard.TryMove(new pos(2, 0), new pos(5, 3), FigID.wBishop);
                    ////1. Nc3 Nc6  2. d4 e6  3. Bf4
                    ////Expected by other chess engines:
                    ////var ply_6 = GameBoard.TryMove(new pos(3, 6), new pos(3, 5), FigID.bPawn); (Level 10 CPU)
                    ////var ply_6 = GameBoard.TryMove(new pos(5, 7), new pos(1, 3), FigID.bBishop); (Stockfish 11)
                    ////var ply_6 = GameBoard.TryMove(new pos(6, 7), new pos(5, 5), FigID.bKnight); (Stockfish 11, very close to above)
                    ////var ply_6 = GameBoard.TryMove(new pos(5, 7), new pos(1, 3), FigID.bBishop); (GNU Chess 6.2.5)
                    ////var ply_6 = GameBoard.TryMove(new pos(5, 7), new pos(1, 3), FigID.bBishop); (LCZero 0.26.0)

                    //GameBoard.ClearLoggedMoves();
                    //-----------------------------
                    // Step 2: Find Move:
                    //-----------------------------
                    var(bestMove, bestCounterMove) = MiniMaxi.CalculateBestMove(6, false);
                    MiniMaxi.currentAge++;
                    //-----------------------------
                    // Step 3: Play Move and put out on console:
                    //-----------------------------
                    //Play it:
                    GameBoard.TryMove(bestMove);

                    var output = Notation.InternalToConsoleOutput(bestMove.oldPos, bestMove.newPos, bestMove.movedID);
                    Console.WriteLine("Black Player plays: " + output);
                    //Clear Stack:
                    GameBoard.ClearLoggedMoves();

                    Worker = Task.Run(() =>
                    {
                        //GameBoard.TryMove(bestCounterMove);
                        //MiniMaxi.CalculateBestMove(6, false);
                        //MiniMaxi.currentAge++;
                        TransTable.TryFreeMemory();
                        //GameBoard.TryRevertLastMove();
                    });
                }
                catch (Exception e)
                {
                    Console.WriteLine("Your input was erroneous and was not executed.");
                }
            }
        }