示例#1
0
 //*********************************************************     
 //
 /// <summary>
 /// Default constructor
 /// </summary>
 //
 //*********************************************************     
 public frmPGNGamePicker() {
     InitializeComponent();
     m_pgnUtil               = new PgnUtil();
     m_strSelectedGame       = null;
     m_eStartingColor        = ChessBoard.PlayerColorE.White;
     m_chessBoardStarting    = null;
 }
示例#2
0
 //*********************************************************     
 //
 /// <summary>
 /// Class constructor
 /// </summary>
 //  
 //*********************************************************     
 public MoveViewer() {
     InitializeComponent();
     listViewMoveList.SelectedIndexChanged += new EventHandler(listViewMoveList_SelectedIndexChanged);
     m_chessBoard        = null;
     m_eDisplayMode      = DisplayModeE.MovePos;
     m_bIgnoreChg        = false;
 }
 //*********************************************************     
 //
 /// <summary>
 /// Evaluates a board. The number of point is greater than 0 if white is in advantage, less than 0 if black is.
 /// </summary>
 /// <param name="pBoard">           Board.</param>
 /// <param name="piPiecesCount">    Number of each pieces</param>
 /// <param name="iAttackedPos">     Number of square attacked by all pieces. (Value computed before the last move for performance reason)</param>
 /// <param name="iAttackedPieces">  Number of enemy pieces attacked by all pieces. (Value computed before the last move for performance reason)</param>
 /// <param name="iWhiteKingPos">    Position of the white king</param>
 /// <param name="iBlackKingPos">    Position of the black king</param>
 /// <param name="bWhiteCastle">     White has castled</param>
 /// <param name="bBlackCastle">     Black has castled</param>
 /// <param name="iMoveCountDelta">  Number of possible white move - Number of possible black move</param>
 /// <returns>
 /// Points
 /// </returns>
 //  
 //*********************************************************     
 public virtual int Points(ChessBoard.PieceE[]   pBoard,
                           int[]                 piPiecesCount,
                           int                   iAttackedPos,
                           int                   iAttackedPieces,
                           int                   iWhiteKingPos,
                           int                   iBlackKingPos,
                           bool                  bWhiteCastle,
                           bool                  bBlackCastle,
                           int                   iMoveCountDelta) {
     int     iRetVal = 0;
     
     for (int iIndex = 0; iIndex < piPiecesCount.Length; iIndex++) {
         iRetVal += m_piPiecePoint[iIndex] * piPiecesCount[iIndex];
     }
     if (pBoard[12] == ChessBoard.PieceE.Pawn) {
         iRetVal -= 4;
     }
     if (pBoard[52] == (ChessBoard.PieceE.Pawn | ChessBoard.PieceE.Black)) {
         iRetVal += 4;
     }
     if (bWhiteCastle) {
         iRetVal += 10;
     }
     if (bBlackCastle) {
         iRetVal -= 10;
     }
     iRetVal += iMoveCountDelta;
     iRetVal += iAttackedPos + iAttackedPieces * 2;
     return(iRetVal);
 }
示例#4
0
 //*********************************************************     
 //
 /// <summary>
 /// Update the Zobrist key using the specified move
 /// </summary>
 /// <param name="i64ZobristKey">Zobrist key</param>
 /// <param name="iPos">         Piece position</param>
 /// <param name="eOldPiece">    Old value</param>
 /// <param name="eNewPiece">    New value</param>
 //  
 //*********************************************************     
 public static long UpdateZobristKey(long i64ZobristKey, int iPos, ChessBoard.PieceE eOldPiece, ChessBoard.PieceE eNewPiece) {
     int     iBaseIndex;
     
     iBaseIndex     = iPos << 4;
     i64ZobristKey ^= m_pi64RndTable[iBaseIndex + ((int)eOldPiece)] ^
                      m_pi64RndTable[iBaseIndex + ((int)eNewPiece)];
     return(i64ZobristKey);                             
 }
示例#5
0
 //*********************************************************     
 //
 /// <summary>
 /// Minimum/maximum depth first search
 /// </summary>
 /// <param name="chessBoard">       Chess board</param>
 /// <param name="searchMode">       Search mode</param>
 /// <param name="ePlayerColor">     Color doing the move</param>
 /// <param name="iDepth">           Actual search depth</param>
 /// <param name="iWhiteMoveCount">  Number of moves white can do</param>
 /// <param name="iBlackMoveCount">  Number of moves black can do</param>
 /// <param name="iPermCount">       Total permutation evaluated</param>
 /// <returns>
 /// Points to give for this move
 /// </returns>
 //  
 //*********************************************************     
 private int MinMax(ChessBoard chessBoard, SearchMode searchMode, ChessBoard.PlayerColorE ePlayerColor, int iDepth, int iWhiteMoveCount, int iBlackMoveCount, ref int iPermCount) {
     int                         iRetVal;
     int                         iMoveCount;
     int                         iPts;
     List<ChessBoard.MovePosS>   moveList;
     ChessBoard.RepeatResultE    eResult;
     
     if (chessBoard.IsEnoughPieceForCheckMate()) {
         if (iDepth == 0 || m_bCancelSearch) {
             iRetVal = (ePlayerColor == ChessBoard.PlayerColorE.Black) ? -chessBoard.Points(searchMode, ePlayerColor, iWhiteMoveCount - iBlackMoveCount, 0, 0) :
                                                                          chessBoard.Points(searchMode, ePlayerColor, iWhiteMoveCount - iBlackMoveCount, 0, 0);
             iPermCount++;
         } else {
             moveList    = chessBoard.EnumMoveList(ePlayerColor);
             iMoveCount  = moveList.Count;
             if (ePlayerColor == ChessBoard.PlayerColorE.White) {
                 iWhiteMoveCount = iMoveCount;
             } else {
                 iBlackMoveCount = iMoveCount;
             }
             if (iMoveCount == 0) {
                 if (chessBoard.IsCheck(ePlayerColor)) {
                     iRetVal = -1000000 - iDepth;
                 } else {
                     iRetVal = 0; // Draw
                 }
             } else {
                 iRetVal  = Int32.MinValue;
                 foreach (ChessBoard.MovePosS move in moveList) {
                     eResult = chessBoard.DoMoveNoLog(move);
                     if (eResult == ChessBoard.RepeatResultE.NoRepeat) {
                         iPts = -MinMax(chessBoard,
                                        searchMode,
                                        (ePlayerColor == ChessBoard.PlayerColorE.Black) ? ChessBoard.PlayerColorE.White : ChessBoard.PlayerColorE.Black,
                                        iDepth - 1,
                                        iWhiteMoveCount,
                                        iBlackMoveCount,
                                        ref iPermCount);
                     } else {
                         iPts = 0;
                     }
                     chessBoard.UndoMoveNoLog(move);
                     if (iPts > iRetVal) {
                         iRetVal = iPts;
                     }
                 }
             }
         }
     } else {
         iRetVal = 0;
     }
     return(iRetVal);
 }
示例#6
0
 //*********************************************************     
 //
 /// <summary>
 /// Gets the description of a move
 /// </summary>
 /// <param name="movePos">  Move to describe</param>
 /// <returns>
 /// Move description
 /// </returns>
 //  
 //*********************************************************     
 private string GetMoveDesc(ChessBoard.MovePosS movePos) {
     string  strRetVal;
     
     if (m_eDisplayMode == DisplayModeE.MovePos) {
         strRetVal = ChessBoard.GetHumanPos(movePos);
     } else {
         strRetVal = PgnUtil.GetPGNMoveFromMove(m_chessBoard, movePos, false);
         if ((movePos.Type & ChessBoard.MoveTypeE.MoveFromBook) == ChessBoard.MoveTypeE.MoveFromBook) {
             strRetVal = "(" + strRetVal + ")";
         }
     }
     return(strRetVal);
 }
示例#7
0
 //*********************************************************     
 //
 /// <summary>
 /// Update the Zobrist key using the specified move
 /// </summary>
 /// <param name="i64ZobristKey">Zobrist key</param>
 /// <param name="iPos1">        Piece position</param>
 /// <param name="eOldPiece1">   Old value</param>
 /// <param name="eNewPiece1">   New value</param>
 /// <param name="iPos2">        Piece position</param>
 /// <param name="eOldPiece2">   Old value</param>
 /// <param name="eNewPiece2">   New value</param>
 //  
 //*********************************************************     
 public static long UpdateZobristKey(long               i64ZobristKey,
                                     int                iPos1,
                                     ChessBoard.PieceE  eOldPiece1,
                                     ChessBoard.PieceE  eNewPiece1,
                                     int                iPos2,
                                     ChessBoard.PieceE  eOldPiece2,
                                     ChessBoard.PieceE  eNewPiece2) {
     int     iBaseIndex1;
     int     iBaseIndex2;
     
     iBaseIndex1    = iPos1 << 4;
     iBaseIndex2    = iPos2 << 4;
     i64ZobristKey ^= m_pi64RndTable[iBaseIndex1 + ((int)eOldPiece1)] ^
                      m_pi64RndTable[iBaseIndex1 + ((int)eNewPiece1)] ^
                      m_pi64RndTable[iBaseIndex2 + ((int)eOldPiece2)] ^
                      m_pi64RndTable[iBaseIndex2 + ((int)eNewPiece2)];
     return(i64ZobristKey);                             
 }
        //*********************************************************     
        //
        /// <summary>
        /// Alpha Beta pruning function.
        /// </summary>
        /// <param name="chessBoard">       Chess board</param>
        /// <param name="ePlayerColor">     Color doing the move</param>
        /// <param name="iDepth">           Actual search depth</param>
        /// <param name="iAlpha">           Alpha limit</param>
        /// <param name="iBeta">            Beta limit</param>
        /// <param name="iWhiteMoveCount">  Number of moves white can do</param>
        /// <param name="iBlackMoveCount">  Number of moves black can do</param>
        /// <param name="abInfo">           Supplemental information</param>
        /// <returns>
        /// Points to give for this move or Int32.MinValue for timed out
        /// </returns>
        //  
        //*********************************************************     
        private int AlphaBeta(ChessBoard chessBoard, ChessBoard.PlayerColorE ePlayerColor, int iDepth, int iAlpha, int iBeta, int iWhiteMoveCount, int iBlackMoveCount, AlphaBetaInfo abInfo) {
            int                         iRetVal;
            List<ChessBoard.MovePosS>   moveList;
            int                         iPts;
            int                         iMoveCount;
            int                         iAttackedPos;
            int                         iAttackedPieces;
            TransEntryTypeE             eType = TransEntryTypeE.Alpha;
            ChessBoard.BoardStateMaskE  eBoardExtraInfo;
            ChessBoard.RepeatResultE    eResult;

            if (abInfo.m_dtTimeOut != DateTime.MaxValue && DateTime.Now >= abInfo.m_dtTimeOut) {
                iRetVal = Int32.MinValue;   // Time out!
            } else if (chessBoard.IsEnoughPieceForCheckMate()) {
                eBoardExtraInfo = chessBoard.ComputeBoardExtraInfo(ePlayerColor, true);
                iRetVal         = (abInfo.m_transTable != null) ? abInfo.m_transTable.ProbeEntry(chessBoard.CurrentZobristKey, eBoardExtraInfo, iDepth, iAlpha, iBeta) : Int32.MaxValue;
                if (iRetVal == Int32.MaxValue) {
                    if (iDepth == 0 || m_bCancelSearch) {
                        if (ePlayerColor == ChessBoard.PlayerColorE.White) {
                            iAttackedPos    = abInfo.m_iAttackedPos;
                            iAttackedPieces = abInfo.m_iAttackedPieces;
                        } else {
                            iAttackedPos    = -abInfo.m_iAttackedPos;
                            iAttackedPieces = -abInfo.m_iAttackedPieces;
                        }
                        iRetVal = (ePlayerColor == ChessBoard.PlayerColorE.Black) ? -chessBoard.Points(abInfo.m_searchMode, ePlayerColor, iWhiteMoveCount - iBlackMoveCount, iAttackedPos, iAttackedPieces) : 
                                                                                     chessBoard.Points(abInfo.m_searchMode, ePlayerColor, iWhiteMoveCount - iBlackMoveCount, iAttackedPos, iAttackedPieces);
                        abInfo.m_iPermCount++;
                        if (abInfo.m_transTable != null) {
                            abInfo.m_transTable.RecordEntry(chessBoard.CurrentZobristKey, eBoardExtraInfo, iDepth, iRetVal, TransEntryTypeE.Exact);
                        }
                    } else {
                        moveList    = chessBoard.EnumMoveList(ePlayerColor, true, out abInfo.m_iAttackedPos, out abInfo.m_iAttackedPieces);
                        iMoveCount  = moveList.Count;
                        if (ePlayerColor == ChessBoard.PlayerColorE.White) {
                            iWhiteMoveCount = iMoveCount;
                        } else {
                            iBlackMoveCount = iMoveCount;
                        }
                        if (iMoveCount == 0) {
                            if (chessBoard.IsCheck(ePlayerColor)) {
                                iRetVal = -1000000 - iDepth;
                            } else {
                                iRetVal = 0;    // Draw
                            }
                            if (abInfo.m_transTable != null) {
                                abInfo.m_transTable.RecordEntry(chessBoard.CurrentZobristKey, eBoardExtraInfo, iDepth, iRetVal, TransEntryTypeE.Exact);
                            }
                        } else {
                            iRetVal = iAlpha;
                            foreach (ChessBoard.MovePosS move in moveList) {
                                eResult = chessBoard.DoMoveNoLog(move);
                                abInfo.m_arrMovePos[iDepth - 1] = move;
                                if (eResult == ChessBoard.RepeatResultE.NoRepeat) {
                                    iPts = -AlphaBeta(chessBoard,
                                                      (ePlayerColor == ChessBoard.PlayerColorE.Black) ? ChessBoard.PlayerColorE.White : ChessBoard.PlayerColorE.Black,
                                                      iDepth - 1,
                                                      -iBeta,
                                                      -iRetVal,
                                                      iWhiteMoveCount,
                                                      iBlackMoveCount,
                                                      abInfo);
                                } else {
                                    iPts = 0;
                                }
                                chessBoard.UndoMoveNoLog(move);
                                if (iPts == Int32.MinValue) {
                                    iRetVal = iPts;
                                    break;
                                } else {
                                    if (iPts > iRetVal) {
                                        iRetVal = iPts;
                                        eType   = TransEntryTypeE.Exact;
                                    }
                                    if (iRetVal >= iBeta) {
                                        iRetVal = iBeta;
                                        eType   = TransEntryTypeE.Beta;
                                        break;
                                    }
                                }
                            }
                            if (abInfo.m_transTable != null && iRetVal != Int32.MinValue) {
                                abInfo.m_transTable.RecordEntry(chessBoard.CurrentZobristKey, eBoardExtraInfo, iDepth, iRetVal, eType);
                            }
                        }
                    }
                }
            } else {
                iRetVal = 0;
            }
            return(iRetVal);
        }
示例#9
0
 //*********************************************************     
 //
 /// <summary>
 /// Reset the control so it represents the specified chessboard
 /// </summary>
 /// <param name="chessBoard">   Chess board. Starting one if null</param>
 //  
 //*********************************************************     
 public void Reset(ChessBoard chessBoard) {
     int     iCurPos;
     int     iCount;
     
     listViewMoveList.Items.Clear();
     m_chessBoard    = chessBoard;
     iCurPos         = chessBoard.MovePosStack.PositionInList;
     iCount          = chessBoard.MovePosStack.Count;
     chessBoard.UndoAllMoves();
     for (int iIndex = 0; iIndex < iCount; iIndex++) {
         chessBoard.RedoMove();
         AddCurrentMove();
     }
     SelectCurrentMove();
 }
示例#10
0
 //*********************************************************     
 //
 /// <summary>
 /// Compute the current packed representation of a board
 /// </summary>
 /// <param name="peBoard">              Board array</param>
 /// <param name="eInfo">                Board extra info</param>
 //  
 //*********************************************************     
 private void ComputeCurrentPackedBoard(ChessBoard.PieceE[] peBoard, ChessBoard.BoardStateMaskE eInfo) {
     m_packedBoardCurrent = ComputePackedBoard(peBoard, eInfo);
 }
 //*********************************************************     
 //
 /// <summary>
 /// Find the best move for a player using alpha-beta
 /// </summary>
 /// <param name="chessBoard">       Chess board</param>
 /// <param name="searchMode">       Search mode</param>
 /// <param name="ePlayerColor">     Color doing the move</param>
 /// <param name="moveList">         Move list</param>
 /// <param name="arrIndex">         Order of evaluation of the moves</param>
 /// <param name="moveBest">         Best move found</param>
 /// <param name="iPermCount">       Total permutation evaluated</param>
 /// <param name="iCacheHit">        Number of moves found in the translation table cache</param>
 /// <param name="iMaxDepth">        Maximum depth to use</param>
 /// <returns>
 /// true if a move has been found
 /// </returns>
 //  
 //*********************************************************     
 protected override bool FindBestMove(ChessBoard                 chessBoard,
                                      SearchEngine.SearchMode    searchMode,
                                      ChessBoard.PlayerColorE    ePlayerColor,
                                      List<ChessBoard.MovePosS>  moveList,
                                      int[]                      arrIndex, 
                                      ref ChessBoard.MovePosS    moveBest,
                                      out int                    iPermCount,
                                      out int                    iCacheHit,
                                      out int                    iMaxDepth) {
     bool                                    bRetVal = false;
     bool                                    bMultipleThread;
     bool                                    bUseTransTable;
     ChessBoard[]                            arrChessBoard;
     FindBestMoveUsingAlphaBetaAsyncDel[]    arrDelFindBestMoveUsingAlphaBetaAsync;
     IAsyncResult[]                          arrAsyncResult;
     List<ChessBoard.MovePosS>[]             arrMoveList;
     ChessBoard.MovePosS                     movePosTmp;
     int                                     iPts;
     int                                     iAlpha;
     int                                     iBeta;
     int                                     iThreadCount;
     int                                     iMovePermCount;
     int                                     iMaxDepthTmp;
     
     //TODO Enable transposition table when bug on 3 repetition move draw will be found.
     searchMode.m_eOption       &= ~SearchMode.OptionE.UseTransTable;
     bUseTransTable              = ((searchMode.m_eOption & SearchMode.OptionE.UseTransTable) != 0);
     iCacheHit                   = 0;
     iMaxDepth                   = 0;
     iPermCount                  = 0;
     iAlpha                      = -10000000;
     iBeta                       = +10000000;
     bMultipleThread             = (searchMode.m_eThreadingMode == SearchMode.ThreadingModeE.OnePerProcessorForSearch);
     iThreadCount                = System.Environment.ProcessorCount;
     if (bMultipleThread && iThreadCount < 2) {
         bMultipleThread = false;    // No reason to go with multi-threading if only one processor
     }
     if (bMultipleThread) {
         arrChessBoard                           = new ChessBoard[iThreadCount];
         arrAsyncResult                          = new IAsyncResult[iThreadCount];
         arrDelFindBestMoveUsingAlphaBetaAsync   = new FindBestMoveUsingAlphaBetaAsyncDel[iThreadCount];
         arrMoveList                             = new List<ChessBoard.MovePosS>[iThreadCount];
         for (int iIndex = 0; iIndex < iThreadCount; iIndex++) {
             arrChessBoard[iIndex]                           = chessBoard.Clone();
             arrDelFindBestMoveUsingAlphaBetaAsync[iIndex]   = new FindBestMoveUsingAlphaBetaAsyncDel(FindBestMoveUsingAlphaBetaAsync);
             arrMoveList[iIndex]                             = new List<ChessBoard.MovePosS>(moveList.Count / iThreadCount + 1);
             for (int iStep = iIndex; iStep < moveList.Count; iStep += iThreadCount) {
                 arrMoveList[iIndex].Add(moveList[arrIndex[iStep]]);
             }
         }
         for (int iStep = 0; iStep < iThreadCount; iStep++) {
             arrAsyncResult[iStep]  = arrDelFindBestMoveUsingAlphaBetaAsync[iStep].BeginInvoke(arrChessBoard[iStep],
                                                                                               searchMode,
                                                                                               ePlayerColor,
                                                                                               iStep,
                                                                                               arrMoveList[iStep],
                                                                                               moveList.Count,
                                                                                               iAlpha,
                                                                                               iBeta,
                                                                                               out iMovePermCount,
                                                                                               out movePosTmp,
                                                                                               out iMaxDepth,
                                                                                               null,
                                                                                               null);
         }
         iMaxDepth = 999;
         for (int iStep = 0; iStep < iThreadCount; iStep++) {
             iPts  = arrDelFindBestMoveUsingAlphaBetaAsync[iStep].EndInvoke(out iMovePermCount, out movePosTmp, out iMaxDepthTmp, arrAsyncResult[iStep]);
             if (movePosTmp.StartPos != 255) {
                 iPermCount += iMovePermCount;
                 iMaxDepth   = Math.Min(iMaxDepth, iMaxDepthTmp);
                 if (bUseTransTable) {
                     iCacheHit  +=  TransTable.GetTransTable(iStep).CacheHit;
                 }
                 if (iPts > iAlpha) {
                     iAlpha      = iPts;
                     moveBest    = movePosTmp;
                     bRetVal     = true;
                 }
             }
         }
         if (iMaxDepth == 999) {
             iMaxDepth = -1;
         }
     } else {
         ChessBoard                  chessBoardTmp;
         List<ChessBoard.MovePosS>   moveListTmp;
         
         chessBoardTmp = chessBoard.Clone();
         moveListTmp   = new List<ChessBoard.MovePosS>(moveList.Count);
         for (int iIndex = 0; iIndex < moveList.Count; iIndex++) {
             moveListTmp.Add(moveList[arrIndex[iIndex]]);
         }
         iPts  = FindBestMoveUsingAlphaBetaAsync(chessBoardTmp,
                                                 searchMode,
                                                 ePlayerColor,
                                                 0,  // ThreadId
                                                 moveListTmp,
                                                 moveList.Count,
                                                 iAlpha,
                                                 iBeta,
                                                 out iPermCount,
                                                 out movePosTmp,
                                                 out iMaxDepth);
         if (movePosTmp.StartPos != 255) {
             if (bUseTransTable) {
                 iCacheHit  +=  TransTable.GetTransTable(0).CacheHit;
             }
             moveBest    = movePosTmp;
             bRetVal     = true;
         }
     }
     return(bRetVal);
 }
示例#12
0
        //*********************************************************     
        //
        /// <summary>
        /// Gets the position express in a human form
        /// </summary>
        /// <param name="move">     Move</param>
        /// <returns>
        /// Human form position
        /// </returns>
        //  
        //*********************************************************     
        static public string GetHumanPos(ChessBoard.MovePosS move) {
            string  strRetVal;
            
            strRetVal  = GetHumanPos(move.StartPos);
            strRetVal += ((move.Type & MoveTypeE.PieceEaten) == MoveTypeE.PieceEaten) ? "x" : "-";
            strRetVal += GetHumanPos(move.EndPos);

            if ((move.Type & ChessBoard.MoveTypeE.MoveFromBook) == ChessBoard.MoveTypeE.MoveFromBook) {
                strRetVal = "(" + strRetVal + ")";
            }
            switch(move.Type & ChessBoard.MoveTypeE.MoveTypeMask) {
            case ChessBoard.MoveTypeE.PawnPromotionToQueen:
                strRetVal += "=Q";
                break;
            case ChessBoard.MoveTypeE.PawnPromotionToRook:
                strRetVal += "=R";
                break;
            case ChessBoard.MoveTypeE.PawnPromotionToBishop:
                strRetVal += "=B";
                break;
            case ChessBoard.MoveTypeE.PawnPromotionToKnight:
                strRetVal += "=N";
                break;
            case ChessBoard.MoveTypeE.PawnPromotionToPawn:
                strRetVal += "=P";
                break;
            default:
                break;
            }
            return(strRetVal);
        }
示例#13
0
 //*********************************************************     
 //
 /// <summary>
 /// Copy the state of the board from the specified one.
 /// </summary>
 /// <param name="chessBoard">   Board to copy from</param>
 //  
 //*********************************************************     
 public void CopyFrom(ChessBoard chessBoard) {
     chessBoard.m_pBoard.CopyTo(m_pBoard, 0);
     chessBoard.m_piPiecesCount.CopyTo(m_piPiecesCount, 0);
     m_stackPossibleEnPassantAt  = new Stack<int>(chessBoard.m_stackPossibleEnPassantAt.ToArray());
     m_book                      = chessBoard.m_book;
     m_iBlackKingPos             = chessBoard.m_iBlackKingPos;
     m_iWhiteKingPos             = chessBoard.m_iWhiteKingPos;
     m_rnd                       = chessBoard.m_rnd;
     m_rndRep                    = chessBoard.m_rndRep;
     m_iRBlackRookMoveCount      = chessBoard.m_iRBlackRookMoveCount;
     m_iLBlackRookMoveCount      = chessBoard.m_iLBlackRookMoveCount;
     m_iBlackKingMoveCount       = chessBoard.m_iBlackKingMoveCount;
     m_iRWhiteRookMoveCount      = chessBoard.m_iRWhiteRookMoveCount;
     m_iLWhiteRookMoveCount      = chessBoard.m_iLWhiteRookMoveCount;
     m_iWhiteKingMoveCount       = chessBoard.m_iWhiteKingMoveCount;
     m_bWhiteCastle              = chessBoard.m_bWhiteCastle;
     m_bBlackCastle              = chessBoard.m_bBlackCastle;
     m_iPossibleEnPassantAt      = chessBoard.m_iPossibleEnPassantAt;
     m_i64ZobristKey             = chessBoard.m_i64ZobristKey;
     m_trace                     = chessBoard.m_trace;
     m_moveStack                 = chessBoard.m_moveStack.Clone();
     m_moveHistory               = chessBoard.m_moveHistory.Clone();
     m_eNextMoveColor            = chessBoard.m_eNextMoveColor;
 }
示例#14
0
 //*********************************************************     
 //
 /// <summary>
 /// Compute a packed value of 16 pieces
 /// </summary>
 /// <param name="peBoard">              Board array</param>
 /// <param name="iStartPos">            Pieces starting position</param>
 /// <returns>
 /// Packed value of the 16 pieces
 /// </returns>
 //  
 //*********************************************************     
 private static long ComputePackedValue(ChessBoard.PieceE[] peBoard, int iStartPos) {
     long    lRetVal = 0;
     
     for (int iIndex = 0; iIndex < 16; iIndex++) {
         lRetVal |= ((long)peBoard[iStartPos + iIndex] & 15) << (iIndex << 2);
     }
     return(lRetVal);
 }
示例#15
0
 //*********************************************************     
 //
 /// <summary>
 /// Create a new game using the specified list of moves
 /// </summary>
 /// <param name="chessBoardStarting">   Starting board or null if standard board</param>
 /// <param name="listMove">             List of moves</param>
 /// <param name="eNextMoveColor">       Color starting to play</param>
 /// <param name="strWhitePlayerName">   Name of the player playing white pieces</param>
 /// <param name="strBlackPlayerName">   Name of the player playing black pieces</param>
 /// <param name="eWhitePlayerType">     Type of player playing white pieces</param>
 /// <param name="eBlackPlayerType">     Type of player playing black pieces</param>
 /// <param name="spanPlayerWhite">      Timer for white</param>
 /// <param name="spanPlayerBlack">      Timer for black</param>
 //  
 //*********************************************************     
 public virtual void CreateGameFromMove(ChessBoard                   chessBoardStarting,
                                        List<ChessBoard.MovePosS>    listMove,
                                        ChessBoard.PlayerColorE      eNextMoveColor,
                                        string                       strWhitePlayerName,
                                        string                       strBlackPlayerName,
                                        PgnParser.PlayerTypeE        eWhitePlayerType,
                                        PgnParser.PlayerTypeE        eBlackPlayerType,
                                        TimeSpan                     spanPlayerWhite,
                                        TimeSpan                     spanPlayerBlack) {
     m_board.CreateGameFromMove(chessBoardStarting,
                                listMove,
                                eNextMoveColor);
     if (m_moveListUI != null) {
         m_moveListUI.Reset(m_board);
     }
     WhitePlayerName = strWhitePlayerName;
     BlackPlayerName = strBlackPlayerName;
     WhitePlayerType = eWhitePlayerType;
     BlackPlayerType = eBlackPlayerType;
     OnUpdateCmdState(System.EventArgs.Empty);
     m_gameTimer.ResetTo(m_board.NextMoveColor,
                         spanPlayerWhite.Ticks,
                         spanPlayerBlack.Ticks);
     m_gameTimer.Enabled = true;
     Invalidate();
 }
示例#16
0
 //*********************************************************     
 //
 /// <summary>
 /// Update the current board packing
 /// </summary>
 /// <param name="iPos">                 Position of the new piece</param>
 /// <param name="eNewPiece">            New piece</param>
 //  
 //*********************************************************     
 public void UpdateCurrentPackedBoard(int iPos, ChessBoard.PieceE eNewPiece) {
     long    lNewPiece;
     long    lMask;
     int     iSlotInValue;
     
     iSlotInValue    = (iPos & 15) << 2;
     lNewPiece       = ((long)eNewPiece & 15) << iSlotInValue;
     lMask           = (long)15 << iSlotInValue;
     if (iPos < 16) {
         m_packedBoardCurrent.m_lVal1 = (m_packedBoardCurrent.m_lVal1 & ~lMask) | lNewPiece;
     } else if (iPos < 32) {
         m_packedBoardCurrent.m_lVal2 = (m_packedBoardCurrent.m_lVal2 & ~lMask) | lNewPiece;
     } else if (iPos < 48) {
         m_packedBoardCurrent.m_lVal3 = (m_packedBoardCurrent.m_lVal3 & ~lMask) | lNewPiece;
     } else {
         m_packedBoardCurrent.m_lVal4 = (m_packedBoardCurrent.m_lVal4 & ~lMask) | lNewPiece;
     }
 }
示例#17
0
 //*********************************************************     
 //
 /// <summary>
 /// Update the current board packing
 /// </summary>
 /// <param name="eInfo">        Board extra info</param>
 //  
 //*********************************************************     
 public void UpdateCurrentPackedBoard(ChessBoard.BoardStateMaskE eInfo) {
     m_packedBoardCurrent.m_eInfo = eInfo & ~ChessBoard.BoardStateMaskE.BlackToMove;
 }
示例#18
0
 //*********************************************************     
 //
 /// <summary>
 /// Reset the move history
 /// </summary>
 /// <param name="peBoard">              Board array</param>
 /// <param name="eInfo">                Board extra info</param>
 //  
 //*********************************************************     
 public void Reset(ChessBoard.PieceE[] peBoard, ChessBoard.BoardStateMaskE eInfo) {
     m_arrCountMove[0] = 0;
     m_iCountMoveDepth = 0;
     m_iMoveCount      = 0;
     Array.Clear(m_arrHashCount, 0, m_arrHashCount.Length);
     ComputeCurrentPackedBoard(peBoard, eInfo);
 }
示例#19
0
 //*********************************************************     
 //
 /// <summary>
 /// Unpack a packed board to a board
 /// </summary>
 /// <param name="packedBoard">          Packed board</param>
 /// <param name="peBoard">              Board array</param>
 //  
 //*********************************************************     
 public static void UnpackBoard(PackedBoard packedBoard, ChessBoard.PieceE[] peBoard) {
     UnpackBoardValue(packedBoard.m_lVal1, peBoard, 0);
     UnpackBoardValue(packedBoard.m_lVal2, peBoard, 16);
     UnpackBoardValue(packedBoard.m_lVal3, peBoard, 32);
     UnpackBoardValue(packedBoard.m_lVal4, peBoard, 48);
 }
示例#20
0
 //*********************************************************     
 //
 /// <summary>
 /// Unpack a packed board value to a board
 /// </summary>
 /// <param name="lVal">                 Packed board value</param>
 /// <param name="peBoard">              Board array</param>
 /// <param name="iStartPos">            Offset in the board</param>
 //  
 //*********************************************************     
 private static void UnpackBoardValue(long lVal, ChessBoard.PieceE[] peBoard, int iStartPos) {
     for (int iIndex = 0; iIndex < 16; iIndex++) {
         peBoard[iStartPos + iIndex] = (ChessBoard.PieceE)((lVal >> (iIndex << 2)) & 15);
     }
 }
示例#21
0
 /// <summary>
 /// Constructor
 /// </summary>
 /// <param name="move">     Move position</param>
 public                      MoveSelectedEventArgs(ChessBoard.MovePosS move) { Move = move; }
示例#22
0
 //*********************************************************     
 //
 /// <summary>
 /// Set the piece in a case. Can only be used in design mode.
 /// </summary>
 //  
 //*********************************************************     
 public void SetCaseValue(int iPos, ChessBoard.PieceE ePiece) {
     Graphics    gr;
     int         iY;
     int         iX;
     
     if (BoardDesignMode) {
         iY = iPos >> 3;
         iX = iPos & 7;
         m_board[iPos] = ePiece;
         using(gr = CreateGraphics()) {
             DrawCase(gr, iY, iX, false);
         }
     }
 }
示例#23
0
 //*********************************************************     
 //
 /// <summary>
 /// Trace a permutation. Can be used for debugging.
 /// </summary>
 /// <param name="iDepth">       Current depth of the search</param>
 /// <param name="ePlayerColor"> Color who play</param>
 /// <param name="move">         Move</param>
 /// <param name="iPts">         Points for this move</param>
 //  
 //*********************************************************     
 public virtual void TraceSearch(int iDepth, ChessBoard.PlayerColorE ePlayerColor, ChessBoard.MovePosS move, int iPts) {
 }
示例#24
0
 //*********************************************************     
 //
 /// <summary>
 /// Compute the zobrist key for a board
 /// </summary>
 /// <param name="peBoard">      Board</param>
 //  
 //*********************************************************     
 public static long ComputeBoardZobristKey(ChessBoard.PieceE[] peBoard) {
     long    lRetVal = 0;
     
     for (int iIndex = 0; iIndex < 64; iIndex++) {
         lRetVal ^= m_pi64RndTable[(iIndex << 4) + (int)peBoard[iIndex]];
     }
     return(lRetVal);
 }
示例#25
0
 //*********************************************************     
 //
 /// <summary>
 /// Find a move from the opening book
 /// </summary>
 /// <param name="searchMode">       Search mode</param>
 /// <param name="ePlayerColor">     Color doing the move</param>
 /// <param name="arrPrevMove">      Previous move</param>
 /// <param name="move">             Found move</param>
 /// <returns>
 /// true if succeed, false if no move found in book
 /// </returns>
 //  
 //*********************************************************     
 public bool FindBookMove(SearchEngine.SearchMode searchMode, PlayerColorE ePlayerColor, MovePosS[] arrPrevMove, out ChessBoard.MovePosS move) {
     bool        bRetVal;
     int         iMove;
     Random      rnd;
     
     if (searchMode.m_eRandomMode == SearchEngine.SearchMode.RandomModeE.Off) {
         rnd = null;
     } else if (searchMode.m_eRandomMode == SearchEngine.SearchMode.RandomModeE.OnRepetitive) {
         rnd = m_rndRep;
     } else {
         rnd = m_rnd;
     }
     move.OriginalPiece  = PieceE.None;
     move.StartPos       = 255;
     move.EndPos         = 255;
     move.Type           = ChessBoard.MoveTypeE.Normal;
     iMove               = m_book.FindMoveInBook(arrPrevMove, rnd);
     if (iMove == -1) {
         bRetVal = false;
     } else {
         move        = FindIfValid(ePlayerColor, iMove & 255, iMove >> 8);
         move.Type  |= MoveTypeE.MoveFromBook;
         bRetVal     = (move.StartPos != 255);
     }
     return(bRetVal);
 }
 //*********************************************************     
 //
 /// <summary>
 /// Find the best move for a player using alpha-beta for a given depth
 /// </summary>
 /// <param name="chessBoard">       Chess board</param>
 /// <param name="searchMode">       Search mode</param>
 /// <param name="ePlayerColor">     Color doing the move</param>
 /// <param name="moveList">         List of move to try</param>
 /// <param name="iTotalMoveCount">  Total list of moves</param>
 /// <param name="iDepth">           Maximum depth</param>
 /// <param name="iAlpha">           Alpha bound</param>
 /// <param name="iBeta">            Beta bound</param>
 /// <param name="transTable">       Transposition table or null if not using one</param>
 /// <param name="dtTimeOut">        Time limit (DateTime.MaxValue for no time limit)</param>
 /// <param name="iPermCount">       Total permutation evaluated</param>
 /// <param name="iBestMoveIndex">   Index of the best move</param>
 /// <param name="bTimeOut">         Return true if time out</param>
 /// <param name="arrPoints">        Returns point of each move in move list</param>
 /// <returns>
 /// Points
 /// </returns>
 //  
 //*********************************************************     
 private int FindBestMoveUsingAlphaBetaAtDepth(ChessBoard chessBoard, SearchMode searchMode, ChessBoard.PlayerColorE ePlayerColor, List<ChessBoard.MovePosS> moveList, int iTotalMoveCount, int iDepth, int iAlpha, int iBeta, TransTable transTable, DateTime dtTimeOut, out int iPermCount, out int iBestMoveIndex, out bool bTimeOut, out int[] arrPoints) {
     int                         iRetVal = -10000000;
     int                         iWhiteMoveCount;
     int                         iBlackMoveCount;
     int                         iMoveCount;
     int                         iIndex;
     int                         iPts;
     ChessBoard.MovePosS         move;
     AlphaBetaInfo               abInfo;
     ChessBoard.RepeatResultE    eResult;
                 
     bTimeOut                    = false;
     abInfo                      = new AlphaBetaInfo();
     abInfo.m_arrMovePos         = new ChessBoard.MovePosS[iDepth];
     abInfo.m_iPermCount         = 0;
     abInfo.m_dtTimeOut          = dtTimeOut;
     abInfo.m_transTable         = transTable;
     abInfo.m_iMaxDepth          = iDepth;
     abInfo.m_searchMode         = searchMode;
     abInfo.m_iAttackedPos       = 0;
     abInfo.m_iAttackedPieces    = 0;
     iBestMoveIndex              = -1;
     arrPoints                   = new int[moveList.Count];
     if (ePlayerColor == ChessBoard.PlayerColorE.White) {
         iWhiteMoveCount = iTotalMoveCount;
         iBlackMoveCount = 0;
     } else {
         iWhiteMoveCount = 0;
         iBlackMoveCount = iTotalMoveCount;
     }
     iMoveCount = moveList.Count;
     iIndex     = 0;
     iRetVal    = iAlpha;
     while (iIndex < iMoveCount && !bTimeOut) {
         move                            = moveList[iIndex];
         eResult                         = chessBoard.DoMoveNoLog(move);
         abInfo.m_arrMovePos[iDepth - 1] = move;
         if (eResult == ChessBoard.RepeatResultE.NoRepeat) {
             iPts = -AlphaBeta(chessBoard,
                               (ePlayerColor == ChessBoard.PlayerColorE.Black) ? ChessBoard.PlayerColorE.White : ChessBoard.PlayerColorE.Black,
                               iDepth - 1,
                               -iBeta,
                               -iRetVal,
                               iWhiteMoveCount,
                               iBlackMoveCount,
                               abInfo);
         } else {
             iPts = 0;
         }                                         
         arrPoints[iIndex] = iPts;
         chessBoard.UndoMoveNoLog(move);
         if (iPts == Int32.MinValue) {
             iRetVal  = iPts;
             bTimeOut = true;
         } else {
             if (iPts > iRetVal) {
                 TraceSearch(iDepth, ePlayerColor, move, iPts);
                 iRetVal         = iPts;
                 iBestMoveIndex  = iIndex;
             }
         }
         iIndex++;
     }
     iPermCount = abInfo.m_iPermCount;
     return(iRetVal);
 }
示例#27
0
 //*********************************************************     
 //
 /// <summary>
 /// Class constructor. Use to create a new clone
 /// </summary>
 /// <param name="chessBoard">   Board to copy from</param>
 //  
 //*********************************************************     
 private ChessBoard(ChessBoard chessBoard) : this(chessBoard.m_searchEngineAlphaBeta, chessBoard.m_searchEngineMinMax) {
     CopyFrom(chessBoard);
 }
 //*********************************************************     
 //
 /// <summary>
 /// Find the best move for a player using alpha-beta in a secondary thread
 /// </summary>
 /// <param name="chessBoard">       Chess board</param>
 /// <param name="searchMode">       Search mode</param>
 /// <param name="ePlayerColor">     Color doing the move</param>
 /// <param name="iThreadId">        Thread Id (0-n)</param>
 /// <param name="moveList">         List of move to try</param>
 /// <param name="iTotalMoveCount">  Total number of moves</param>
 /// <param name="iAlpha">           Alpha bound</param>
 /// <param name="iBeta">            Beta bound</param>
 /// <param name="iPermCount">       Total permutation evaluated</param>
 /// <param name="movePosBest">      Best move</param>
 /// <param name="iMaxDepth">        Maximum depth evaluated</param>
 /// <returns>
 /// Points
 /// </returns>
 //  
 //*********************************************************     
 private int FindBestMoveUsingAlphaBetaAsync(ChessBoard chessBoard, SearchMode searchMode, ChessBoard.PlayerColorE ePlayerColor, int iThreadId, List<ChessBoard.MovePosS> moveList, int iTotalMoveCount, int iAlpha, int iBeta, out int iPermCount, out ChessBoard.MovePosS movePosBest, out int iMaxDepth) {
     int                             iRetVal;
     DateTime                        dtTimeOut;
     int                             iDepth;
     int                             iPermCountAtLevel;
     int                             iPoint;
     int                             iBestMoveIndex;
     int                             iDepthLimit;
     int[]                           arrPoints;
     System.Threading.ThreadPriority eThreadPriority;
     TransTable                      transTable;
     bool                            bTimeOut;
     bool                            bIterativeDepthFirst;
     
     eThreadPriority                                = System.Threading.Thread.CurrentThread.Priority;
     System.Threading.Thread.CurrentThread.Priority = System.Threading.ThreadPriority.BelowNormal;
     if ((searchMode.m_eOption & SearchMode.OptionE.UseTransTable) != 0) {
         transTable = TransTable.GetTransTable(iThreadId);
         transTable.Reset();
     } else {
         transTable = null;
     }
     bIterativeDepthFirst        = ((searchMode.m_eOption & SearchMode.OptionE.UseIterativeDepthSearch) == SearchMode.OptionE.UseIterativeDepthSearch);
     movePosBest.StartPos        = 255;
     movePosBest.EndPos          = 255;
     movePosBest.OriginalPiece   = ChessBoard.PieceE.None;
     movePosBest.Type            = ChessBoard.MoveTypeE.Normal;
     try {
         iPermCount  = 0;
         if (searchMode.m_iSearchDepth == 0 || bIterativeDepthFirst) {
             dtTimeOut   = (bIterativeDepthFirst) ? DateTime.MaxValue : DateTime.Now + TimeSpan.FromSeconds(searchMode.m_iTimeOutInSec);
             iDepthLimit = (bIterativeDepthFirst) ? searchMode.m_iSearchDepth : 999;
             iDepth      = 1;
             iRetVal     = FindBestMoveUsingAlphaBetaAtDepth(chessBoard, searchMode, ePlayerColor, moveList, iTotalMoveCount, iDepth, iAlpha, iBeta, transTable, DateTime.MaxValue, out iPermCountAtLevel, out iBestMoveIndex, out bTimeOut, out arrPoints);
             if (iBestMoveIndex != -1) {
                 movePosBest = moveList[iBestMoveIndex];
             }
             iPermCount += iPermCountAtLevel;
             iMaxDepth   = iDepth;
             while (DateTime.Now < dtTimeOut && !m_bCancelSearch && !bTimeOut && iDepth < iDepthLimit) {
                 moveList = SortMoveList(moveList, arrPoints);
                 iDepth++;
                 iPoint  = FindBestMoveUsingAlphaBetaAtDepth(chessBoard, searchMode, ePlayerColor, moveList, iTotalMoveCount, iDepth, iAlpha, iBeta, transTable, dtTimeOut, out iPermCountAtLevel, out iBestMoveIndex, out bTimeOut, out arrPoints);
                 if (!bTimeOut) {
                     if (iBestMoveIndex != -1) {
                         movePosBest = moveList[iBestMoveIndex];
                     }
                     iPermCount    += iPermCountAtLevel;
                     iMaxDepth      = iDepth;
                     iRetVal        = iPoint;
                 }
             } 
         } else {
             iMaxDepth = searchMode.m_iSearchDepth;
             iRetVal   = FindBestMoveUsingAlphaBetaAtDepth(chessBoard, searchMode, ePlayerColor, moveList, iTotalMoveCount, iMaxDepth, iAlpha, iBeta, transTable, DateTime.MaxValue, out iPermCount, out iBestMoveIndex, out bTimeOut, out arrPoints);
             if (iBestMoveIndex != -1) {
                 movePosBest = moveList[iBestMoveIndex];
             }
         }
     } finally {
         System.Threading.Thread.CurrentThread.Priority = eThreadPriority;
     }
     return(iRetVal);
 }
示例#29
0
 //*********************************************************     
 //
 /// <summary>
 /// Create a new game using the specified list of moves
 /// </summary>
 /// <param name="chessBoardStarting">   Starting board or null if standard board</param>
 /// <param name="listMove">             List of moves</param>
 /// <param name="eStartingColor">       Board starting color</param>
 //  
 //*********************************************************     
 public void CreateGameFromMove(ChessBoard chessBoardStarting, List<MovePosS> listMove, PlayerColorE eStartingColor) {
     BoardStateMaskE  eMask;
     
     if (chessBoardStarting != null) {
         CopyFrom(chessBoardStarting);
         eMask = chessBoardStarting.ComputeBoardExtraInfo(PlayerColorE.White, false);
         ResetInitialBoardInfo(eStartingColor, false, eMask, chessBoardStarting.m_iPossibleEnPassantAt);
     } else {
         ResetBoard();
     }
     foreach (MovePosS movePos in listMove) {
         DoMove(movePos);
     }
 }
示例#30
0
 //*********************************************************     
 //
 /// <summary>
 /// Compute the packed representation of a board
 /// </summary>
 /// <param name="peBoard">              Board array</param>
 /// <param name="eInfo">                Board extra info</param>
 //  
 //*********************************************************     
 public static PackedBoard ComputePackedBoard(ChessBoard.PieceE[] peBoard, ChessBoard.BoardStateMaskE eInfo) {
     PackedBoard packedBoard;
     
     packedBoard.m_lVal1    = ComputePackedValue(peBoard, 0);
     packedBoard.m_lVal2    = ComputePackedValue(peBoard, 16);
     packedBoard.m_lVal3    = ComputePackedValue(peBoard, 32);
     packedBoard.m_lVal4    = ComputePackedValue(peBoard, 48);
     packedBoard.m_eInfo    = eInfo & ~ChessBoard.BoardStateMaskE.BlackToMove;
     return(packedBoard);
 }