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); }
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."); } } }