/// <summary> /// Load opening book (hash table ) /// </summary> /// <param name="player"> /// The player. /// </param> /// <param name="xmlnodeParent"> /// The xmlnode parent. /// </param> /// <returns> /// The move score. /// </returns> private static int ScanPly(Player player, XmlElement xmlnodeParent) { int intReturnScore = 0; int intReturnMove = 0; foreach (XmlElement xmlnodeMove in xmlnodeParent.ChildNodes) { Move.MoveNames movename = xmlnodeMove.GetAttribute("N") == null ? Move.MoveNames.Standard : Move.MoveNameFromString(xmlnodeMove.GetAttribute("N")); Square from = Board.GetSquare(xmlnodeMove.GetAttribute("F")); Square to = Board.GetSquare(xmlnodeMove.GetAttribute("T")); Piece piece = from.Piece; int intScore = Convert.ToInt32(xmlnodeMove.GetAttribute(player.Colour == Player.PlayerColourNames.White ? "W" : "B")); if (intScore > intReturnScore) { intReturnScore = intScore; intReturnMove = from.Ordinal << 8 | to.Ordinal; } Move moveUndo = piece.Move(movename, to); int intScanMove = ScanPly(player.OpposingPlayer, xmlnodeMove); if (intScanMove != 0) { RecordHash(Board.HashCodeA, Board.HashCodeB, (byte)(intScanMove >> 8 & 0xff), (byte)(intScanMove & 0xff), movename, player.OpposingPlayer.Colour); } Move.Undo(moveUndo); } return(intReturnMove); }
/// <summary> /// Record a hash new hash entry in the hash table. /// </summary> /// <param name="hashCodeA"> /// Hash Code for Board position A /// </param> /// <param name="hashCodeB"> /// Hash Code for Board position B /// </param> /// <param name="from"> /// From square ordinal. /// </param> /// <param name="to"> /// To square ordinal. /// </param> /// <param name="moveName"> /// The move name. /// </param> /// <param name="colour"> /// The player colour. /// </param> private static unsafe void RecordHash(ulong hashCodeA, ulong hashCodeB, byte from, byte to, Move.MoveNames moveName, Player.PlayerColourNames colour) { if (colour == Player.PlayerColourNames.Black) { hashCodeA |= 0x1; hashCodeB |= 0x1; } else { hashCodeA &= 0xFFFFFFFFFFFFFFFE; hashCodeB &= 0xFFFFFFFFFFFFFFFE; } fixed(HashEntry *phashBase = &HashTableEntries[0]) { HashEntry *phashEntry = phashBase; phashEntry += (uint)(hashCodeA % HashTableSize); phashEntry->HashCodeA = hashCodeA; phashEntry->HashCodeB = hashCodeB; phashEntry->From = from; phashEntry->To = to; phashEntry->MoveName = moveName; } }
/// <summary> /// Make a move. /// </summary> /// <param name="moveName"> The move name. </param> /// <param name="piece"> The piece to move. </param> /// <param name="square"> The square to move to. </param> public static void MakeAMove(Move.MoveNames moveName, Piece piece, Square square) { SuspendPondering(); MakeAMoveInternal(moveName, piece, square); SaveBackup(); SendBoardPositionChangeEvent(); CheckIfAutoNextMove(); }
/// <summary> /// Make the specified move. For internal use only. /// </summary> /// <param name="moveName"> The move name. </param> /// <param name="piece"> The piece to move. </param> /// <param name="square"> The square to move to. </param> private static void MakeAMoveInternal(Move.MoveNames moveName, Piece piece, Square square) { MoveRedoList.Clear(); Move move = piece.Move(moveName, square); move.EnemyStatus = move.Piece.Player.OpposingPlayer.Status; PlayerToPlay.Clock.Stop(); MoveHistory.Last.TimeStamp = PlayerToPlay.Clock.TimeElapsed; if (PlayerToPlay.Intellegence == Player.PlayerIntellegenceNames.Computer) { WinBoard.SendMove(move); if (!PlayerToPlay.OpposingPlayer.CanMove) { if (PlayerToPlay.OpposingPlayer.IsInCheckMate) { WinBoard.SendCheckMate(); } else if (!PlayerToPlay.OpposingPlayer.IsInCheck) { WinBoard.SendCheckStaleMate(); } } else if (PlayerToPlay.OpposingPlayer.CanClaimThreeMoveRepetitionDraw == true) { WinBoard.SendDrawByRepetition(); } else if (PlayerToPlay.OpposingPlayer.CanClaimFiftyMoveDraw == true) { WinBoard.SendDrawByFiftyMoveRule(); } else if (PlayerToPlay.OpposingPlayer.CanClaimInsufficientMaterialDraw == true) { WinBoard.SendDrawByInsufficientMaterial(); } } BroadcastMovedName(move); CheckGameStatus(); PlayerToPlay = PlayerToPlay.OpposingPlayer; PlayerToPlay.Clock.Start(); }
/// <summary> /// The pic piece_ click. /// </summary> /// <param name="sender"> /// The sender. /// </param> /// <param name="e"> /// The e. /// </param> private void picPiece_Click(object sender, EventArgs e) { switch ((string)((PictureBox)sender).Tag) { case "Queen": this.m_MoveNameSelected = Model.Move.MoveNames.PawnPromotionQueen; break; case "Rook": this.m_MoveNameSelected = Model.Move.MoveNames.PawnPromotionRook; break; case "Bishop": this.m_MoveNameSelected = Model.Move.MoveNames.PawnPromotionBishop; break; case "Knight": this.m_MoveNameSelected = Model.Move.MoveNames.PawnPromotionKnight; break; } this.Close(); }
/// <summary> /// Record a hash new hash entry in the hash table. /// </summary> /// <param name="hashCodeA"> /// Hash Code for Board position A /// </param> /// <param name="hashCodeB"> /// Hash Code for Board position B /// </param> /// <param name="depth"> /// The search depth. /// </param> /// <param name="val"> /// The score of the position to record. /// </param> /// <param name="type"> /// The position type: alpha, beta or exact value. /// </param> /// <param name="from"> /// From square ordinal. /// </param> /// <param name="to"> /// To square ordinal. /// </param> /// <param name="moveName"> /// The move name. /// </param> /// <param name="colour"> /// The player colour. /// </param> public static unsafe void RecordHash( ulong hashCodeA, ulong hashCodeB, int depth, int val, HashTypeNames type, int from, int to, Move.MoveNames moveName, Player.PlayerColourNames colour) { Writes++; fixed(HashEntry *phashBase = &hashTableEntries[0]) { HashEntry *phashEntry = phashBase; phashEntry += (uint)(hashCodeA % hashTableSize); int intAttempt = 0; while (phashEntry >= phashBase && phashEntry->HashCodeA != 0 && phashEntry->Depth > depth) { phashEntry--; intAttempt++; if (intAttempt == HashTableSlotDepth) { break; } } if (phashEntry < phashBase) { phashEntry = phashBase; } if (phashEntry->HashCodeA != 0) { Collisions++; if (phashEntry->HashCodeA != hashCodeA || phashEntry->HashCodeB != hashCodeB) { Overwrites++; phashEntry->WhiteFrom = -1; phashEntry->BlackFrom = -1; } } phashEntry->HashCodeA = hashCodeA; phashEntry->HashCodeB = hashCodeB; phashEntry->Result = val; phashEntry->Type = type; phashEntry->Depth = (sbyte)depth; phashEntry->Colour = colour; if (from > -1) { if (colour == Player.PlayerColourNames.White) { phashEntry->WhiteMoveName = moveName; phashEntry->WhiteFrom = (sbyte)from; phashEntry->WhiteTo = (sbyte)to; } else { phashEntry->BlackMoveName = moveName; phashEntry->BlackFrom = (sbyte)from; phashEntry->BlackTo = (sbyte)to; } } } }
/// <summary> /// Move the piece to a new square. /// </summary> /// <param name="moveName"> /// The move name. /// </param> /// <param name="square"> /// The square. /// </param> /// <returns> /// Move made. /// </returns> public Move Move(Move.MoveNames moveName, Square square) { Square squarepieceCaptured = square; if (moveName == Model.Move.MoveNames.EnPassent) { // Override when en passent squarepieceCaptured = Board.GetSquare(square.Ordinal - this.Player.PawnForwardOffset); } Board.HashCodeA ^= this.HashCodeA; // Un-XOR current piece position Board.HashCodeB ^= this.HashCodeB; // Un-XOR current piece position if (this.Name == PieceNames.Pawn) { Board.PawnHashCodeA ^= this.HashCodeA; Board.PawnHashCodeB ^= this.HashCodeB; } Move move = new Move( Game.TurnNo, this.LastMoveTurnNo, moveName, this, this.Square, square, squarepieceCaptured.Piece, squarepieceCaptured.Piece == null ? -1 : squarepieceCaptured.Piece.Player.Pieces.IndexOf(squarepieceCaptured.Piece), 0); if (square.Piece != null) { if (squarepieceCaptured.Piece != null) { Board.HashCodeA ^= squarepieceCaptured.Piece.HashCodeA; // un-XOR the piece taken Board.HashCodeB ^= squarepieceCaptured.Piece.HashCodeB; // un-XOR the piece taken if (squarepieceCaptured.Piece.Name == PieceNames.Pawn) { Board.PawnHashCodeA ^= squarepieceCaptured.Piece.HashCodeA; Board.PawnHashCodeB ^= squarepieceCaptured.Piece.HashCodeB; } squarepieceCaptured.Piece.Capture(); } } Game.TurnNo++; this.Square.Piece = null; square.Piece = this; this.Square = square; this.LastMoveTurnNo = Game.TurnNo; this.NoOfMoves++; Piece pieceRook; switch (moveName) { case Model.Move.MoveNames.CastleKingSide: pieceRook = move.Piece.Player.Colour == Player.PlayerColourNames.White ? Board.GetPiece(7, 0) : Board.GetPiece(7, 7); Board.HashCodeA ^= pieceRook.HashCodeA; Board.HashCodeB ^= pieceRook.HashCodeB; pieceRook.Square.Piece = null; pieceRook.LastMoveTurnNo = Game.TurnNo; pieceRook.NoOfMoves++; Board.GetSquare(5, square.Rank).Piece = pieceRook; pieceRook.Square = Board.GetSquare(5, square.Rank); Board.HashCodeA ^= pieceRook.HashCodeA; Board.HashCodeB ^= pieceRook.HashCodeB; this.Player.HasCastled = true; break; case Model.Move.MoveNames.CastleQueenSide: pieceRook = move.Piece.Player.Colour == Player.PlayerColourNames.White ? Board.GetPiece(0, 0) : Board.GetPiece(0, 7); Board.HashCodeA ^= pieceRook.HashCodeA; Board.HashCodeB ^= pieceRook.HashCodeB; pieceRook.Square.Piece = null; pieceRook.LastMoveTurnNo = Game.TurnNo; pieceRook.NoOfMoves++; Board.GetSquare(3, square.Rank).Piece = pieceRook; pieceRook.Square = Board.GetSquare(3, square.Rank); Board.HashCodeA ^= pieceRook.HashCodeA; Board.HashCodeB ^= pieceRook.HashCodeB; this.Player.HasCastled = true; break; case Model.Move.MoveNames.PawnPromotionQueen: this.Promote(PieceNames.Queen); break; case Model.Move.MoveNames.PawnPromotionRook: this.Promote(PieceNames.Rook); break; case Model.Move.MoveNames.PawnPromotionBishop: this.Promote(PieceNames.Bishop); break; case Model.Move.MoveNames.PawnPromotionKnight: this.Promote(PieceNames.Knight); break; case Model.Move.MoveNames.EnPassent: Board.HashCodeA ^= Board.GetPiece(this.Square.Ordinal - this.Player.PawnForwardOffset).HashCodeA; Board.HashCodeB ^= Board.GetPiece(this.Square.Ordinal - this.Player.PawnForwardOffset).HashCodeB; Board.PawnHashCodeA ^= Board.GetPiece(this.Square.Ordinal - this.Player.PawnForwardOffset).HashCodeA; Board.PawnHashCodeB ^= Board.GetPiece(this.Square.Ordinal - this.Player.PawnForwardOffset).HashCodeB; Board.GetPiece(this.Square.Ordinal - this.Player.PawnForwardOffset).Capture(); // Take enemy pawn that is now behind us break; } Board.HashCodeA ^= this.HashCodeA; // XOR piece into new piece position Board.HashCodeB ^= this.HashCodeB; // XOR piece into new piece position if (this.Name == PieceNames.Pawn) { Board.PawnHashCodeA ^= this.HashCodeA; Board.PawnHashCodeB ^= this.HashCodeB; } move.IsInCheck = move.Piece.Player.IsInCheck; move.IsEnemyInCheck = move.Piece.Player.OpposingPlayer.IsInCheck; move.HashCodeA = Board.HashCodeA; move.HashCodeB = Board.HashCodeB; Game.MoveHistory.Add(move); if (move.Piece.Player.CanClaimThreeMoveRepetitionDraw) { Board.HashCodeA ^= 31; Board.HashCodeB ^= 29; move.HashCodeA = Board.HashCodeA; move.HashCodeB = Board.HashCodeB; move.IsThreeMoveRepetition = true; } return(move); }
/// <summary> /// Move the piece to a new square, after testing that the move is valid. /// </summary> /// <param name="moveName"> /// The move name. /// </param> /// <param name="square"> /// The square. /// </param> /// <returns> /// Move made, or null if move is not valid. /// </returns> public Move TestAndMakeMove(Move.MoveNames moveName, Square square) { return(null); }
public InvalidPromotionException(Move.MoveNames attemptedPromotion) : base(INVALID_PROMOTION_MESSAGE) { AttemptedPromotion = attemptedPromotion; }
/// <summary> /// The add. /// </summary> /// <param name="turnNo"> /// The turn no. /// </param> /// <param name="lastMoveTurnNo"> /// The last move turn no. /// </param> /// <param name="moveName"> /// The move name. /// </param> /// <param name="piece"> /// The piece moving. /// </param> /// <param name="from"> /// The square the peice is moving from. /// </param> /// <param name="to"> /// The square the peice is moving to. /// </param> /// <param name="pieceCaptured"> /// The piece being captured. /// </param> /// <param name="pieceCapturedOrdinal"> /// Ordinal position of the piece being captured. /// </param> /// <param name="score"> /// The positional score. /// </param> public void Add(int turnNo, int lastMoveTurnNo, Move.MoveNames moveName, Piece piece, Square from, Square to, Piece pieceCaptured, int pieceCapturedOrdinal, int score) { this.moves.Add(new Move(turnNo, lastMoveTurnNo, moveName, piece, from, to, pieceCaptured, pieceCapturedOrdinal, score)); }