private List<move> getExpectedMoveSquares(square srcSquare)
 {
     List<move> expectedmoves = new List<move>
                                    {
                                        new move(srcSquare, new square(3, 7)),
                                        new move(srcSquare, new square(3, 6)),
                                        new move(srcSquare, new square(3, 5)),
                                        new move(srcSquare, new square(3, 4)),
                                        new move(srcSquare, new square(3, 2)),
                                        new move(srcSquare, new square(3, 1)),
                                        new move(srcSquare, new square(3, 0)),
                                        new move(srcSquare, new square(0, 3)),
                                        new move(srcSquare, new square(1, 3)),
                                        new move(srcSquare, new square(2, 3)),
                                        new move(srcSquare, new square(4, 3)),
                                        new move(srcSquare, new square(5, 3)),
                                        new move(srcSquare, new square(6, 3)),
                                        new move(srcSquare, new square(7, 3)),
                                        new move(srcSquare, new square(0, 0)),
                                        new move(srcSquare, new square(1, 1)),
                                        new move(srcSquare, new square(2, 2)),
                                        new move(srcSquare, new square(4, 4)),
                                        new move(srcSquare, new square(5, 5)),
                                        new move(srcSquare, new square(6, 6)),
                                        new move(srcSquare, new square(7, 7)),
                                        new move(srcSquare, new square(0, 6)),
                                        new move(srcSquare, new square(1, 5)),
                                        new move(srcSquare, new square(2, 4)),
                                        new move(srcSquare, new square(4, 2)),
                                        new move(srcSquare, new square(5, 1)),
                                        new move(srcSquare, new square(6, 0))
                                    };
     return expectedmoves;
 }
Beispiel #2
0
        public move(square src, square dst, pieceType toPromoteTo)
        {
            srcPos = src.position;
            dstPos = dst.position;
            _srcSquare = src;

            if (src.type != pieceType.pawn)
                throw new Exception("Attempt to promote non-pawn");
            if (toPromoteTo == pieceType.pawn)
                throw new Exception("Attempt to promote a pawn to a pawn");
            if (toPromoteTo == pieceType.none)
                throw new Exception("Attempt to promote a pawn to an empty space");

            isPawnPromotion = true;
            typeToPromoteTo = toPromoteTo;

            if (dst.type != pieceType.none)
            {
                isCapture = true;
                capturedSquare = dst;
                capturedSquarePos = dst.position;
            }

            if (src.type == pieceType.king)
                findCastlingRookPositions();
        }
        public void testPieceMoveNotation()
        {
            DoktorChessAIBoard ourBoard = new DoktorChessAIBoard(gameType.normal, boardSearchConfig.getDebugConfig());
            square bish = new bishopSquare(new squarePos(0, 0), pieceColour.black);
            square targetSpace = new square( new squarePos(0, 1) );

            move theMove = new move(bish, targetSpace);

            Assert.AreEqual("Ba2", theMove.ToString(moveStringStyle.chessNotation));
        }
Beispiel #4
0
        /// <summary>
        /// Create a new empty board using the supplied rule set.
        /// </summary>
        /// <param name="newType">gameType to make</param>
        protected baseBoard(gameType newType)
        {
            // Set the game type
            _type = newType;

            // Spawn all our squares
            for (int y = 0; y < sizeY; y++)
            {
                for (int x = 0; x < sizeX; x++)
                    _squares[x, y] = new square(new squarePos(x, y));
            }
        }
Beispiel #5
0
        public move(square src, square dst)
        {
            srcPos = src.position;
            dstPos = dst.position;
            _srcSquare = src;

            // If we are capturing, fill in relevant info.
            if (dst.type != pieceType.none)
            {
                isCapture = true;
                capturedSquare = dst;
                capturedSquarePos = dst.position;
            }

            if (src.type == pieceType.king)
                findCastlingRookPositions();
        }
Beispiel #6
0
        public move(square src, square dst, square captured)
        {
            srcPos = src.position;
            dstPos = dst.position;
            _srcSquare = src;

            Debug.Assert(dst.type == pieceType.none);

            if (captured.type != pieceType.none)
            {
                isCapture = true;
                capturedSquare = captured;
                capturedSquarePos = captured.position;
            }

            if (src.type == pieceType.king)
                findCastlingRookPositions();
        }
        /// <summary>
        /// Check a list of moves contains only one capture, which has the supplied src and dst/enemysquare.
        /// </summary>
        /// <param name="possibleMoves"></param>
        /// <param name="ourPiece"></param>
        /// <param name="enemyPiece"></param>
        /// <returns></returns>
        public move checkContainsSingleCapture(move[] possibleMoves, square ourPiece, square enemyPiece)
        {
            bool captureFound = false;
            move capture = null;

            foreach (move thisMove in possibleMoves)
            {
                if (thisMove.isCapture)
                {
                    Assert.IsTrue(thisMove.srcPos.isSameSquareAs(ourPiece.position));
                    Assert.IsTrue(thisMove.dstPos.isSameSquareAs(enemyPiece.position));
                    Assert.AreEqual(thisMove.dstPos, enemyPiece.position);
                    Assert.AreEqual(thisMove.capturedSquare, enemyPiece);

                    if (captureFound)
                        throw new AssertFailedException("Multiple captures found, one expected");
                    captureFound = true;
                    capture = thisMove;
                }
            }
            if (!captureFound)
                throw new AssertFailedException("No captures found, one expected");
            return capture;
        }
Beispiel #8
0
        public static square makeSquare(pieceType newType, pieceColour newColour, squarePos newPos)
        {
            square toRet ;
            switch (newType)
            {
                case pieceType.none:
                    toRet = new square(newPos);
                    break;
                case pieceType.pawn:
                    toRet = new pawnSquare(newPos, newColour);
                    break;
                case pieceType.rook:
                    toRet = new rookSquare(newPos, newColour);
                    break;
                case pieceType.bishop:
                    toRet = new bishopSquare(newPos, newColour);
                    break;
                case pieceType.knight:
                    toRet = new knightSquare(newPos, newColour);
                    break;
                case pieceType.queen:
                    toRet = new queenSquare(newPos, newColour);
                    break;
                case pieceType.king:
                    toRet = new kingSquare(newPos, newColour);
                    break;
                default:
                    throw new ArgumentOutOfRangeException();
            }

            return toRet;
        }
Beispiel #9
0
        private bool canEnPassantTo(square adjacent, baseBoard theBoard)
        {
            // We can capture via en passant if:
            // * An enemy pawn is on our right/left
            // * The enemy pawn has moved only once
            // * The enemy pawn moved last move
            // * The enemy pawn (and us) are on the 4th/5th rank (according to player colour)
            // * The space behind the enemy pawn is empty.
            if (        adjacent.containsPieceNotOfColour(colour)          // Is an enemy piece
                    && adjacent.type == pieceType.pawn                 // Is an enemy pawn
                    && adjacent.movedCount == 1                        // Has moved only once
                    && adjacent.moveNumbers.Peek() == theBoard.moveCount-1 // Moved last move
                    && adjacent.position.y == (colour == pieceColour.white ? 4 : 3) // is on start row
                    && theBoard[ adjacent.position.up(colour == pieceColour.white ? 1 : -1) ].type == pieceType.none )
                return true;

            return false;
        }
Beispiel #10
0
        private void addPawnMovesToSquare(sizableArray<move> moveList, square src, square dst)
        {
            // If we are moving in to the end row, we should promote. Handle this.
            if (dst.position.y == (colour == pieceColour.white ? 7 : 0) )
            {
                // OK. Promotions it is.
                pieceType[] promotionOptions = new[] {
                                                      pieceType.queen,
                                                      pieceType.rook,
                                                      pieceType.knight,
                                                      pieceType.bishop
                                                  };

                foreach (pieceType promotionOption in promotionOptions)
                {
                    moveList.Add(new move(src, dst, promotionOption));
                }
            }
            else
            {
                moveList.Add(new move(src, dst));
            }
        }
 public int getCoverLevel(square squareToCheck, pieceColour sideToExamine)
 {
     return getCoverLevel(squareToCheck.position, sideToExamine);
 }
        protected override void movePiece(square toMove, squarePos destPos)
        {
            squarePos srcPos = toMove.position;

            coverLevel.remove(toMove);
            this[destPos] = toMove;
            this[destPos].position = destPos;
            this[srcPos] = new square(srcPos);
            coverLevel.add(destPos);
        }
Beispiel #13
0
 public static int getMaterialAdvantage(square square)
 {
     return getMaterialAdvantage(square.type);
 }
 public void remove(square toRemove)
 {
 }
Beispiel #15
0
        /// <summary>
        /// Add a piece to this board
        /// </summary>
        /// <param name="newSquare">square containing piece to add</param>
        /// <param name="newSquarePos">location to add the specified square at</param>
        protected virtual void addPiece(square newSquare, squarePos newSquarePos)
        {
            newSquare.position = newSquarePos;
            this[newSquarePos] = newSquare;

            addToArrays(newSquare);
        }
 public override bool isThreatenedHint(square squareToCheck, pieceColour sideToExamine)
 {
     // Return true if the square is covered by at least one enemy piece. Ignore if we are
     // covering it or not.
     return coverLevel.isThreatened(squareToCheck, sideToExamine);
 }
Beispiel #17
0
 /// <summary>
 /// Is the specified square 'covered' by the specified colour? Note that this is just
 /// a hint, and may be incorrect under certain circumstances.
 /// </summary>
 /// <param name="squareToCheck"></param>
 /// <param name="sideToExamine"></param>
 /// <returns></returns>
 public virtual bool isThreatenedHint(square squareToCheck, pieceColour sideToExamine)
 {
     // This base class does not provide an implementation.
     return false;
 }
        private void removeNewPieceFromArrays(square newSq)
        {
            switch (newSq.colour)
            {
                case pieceColour.white:
                    whiteMaterialAdvantage -= BoardScorer.getMaterialAdvantage(newSq);
                    break;
                case pieceColour.black:
                    blackMaterialAdvantage -= BoardScorer.getMaterialAdvantage(newSq);
                    break;
                default:
                    throw new ArgumentException();
            }

            if (newSq.type == pieceType.king)
            {
                if (newSq.colour == pieceColour.black)
                    _blackKingCaptured = true;
                else if (newSq.colour == pieceColour.white)
                    _whiteKingCaptured = true;
                else
                    throw new ArgumentException();
            }
        }
        protected override void removePiece(square toRemove)
        {
            coverLevel.remove(toRemove);
            removeNewPieceFromArrays(toRemove);

            base.removePiece(toRemove);
        }
Beispiel #20
0
 public bool isThreatened(square squareToCheck, pieceColour sideToExamine)
 {
     // Return true if the square is covered by at least one enemy piece. Ignore if we are
     // covering it or not.
     pieceColour otherSide = DoktorChessAIBoard.getOtherSide(sideToExamine);
     return piecesWhichThreatenSquare[squareToCheck.position.x, squareToCheck.position.y].Any(sp => _parentBoard[squarePos.unflatten(sp)].colour == otherSide);
 }
Beispiel #21
0
        /// <summary>
        /// Move a piece on the board back to its original position, without reverting the entire
        /// move.
        /// </summary>
        /// <param name="srcPos">Square to move from</param>
        /// <param name="dstPos">Square to move to</param>
        protected virtual void unmovePiece(squarePos srcPos, squarePos dstPos)
        {
            // store the piece which is moving before we erase it
            square movingPiece = this[dstPos];

            // Erase the old destination
            this[dstPos] = new square(dstPos);

            // Move our piece back to its source square
            this[srcPos] = movingPiece;
            this[srcPos].position = srcPos;
        }
Beispiel #22
0
        public void remove(square toRemove)
        {
            int posDirection = toRemove.colour == pieceColour.white ? 1 : -1;

            // Remove the actual piece, and what it threatens.
            foreach (int threatenedSquareFlat in toRemove.coveredSquares )
            {
                squarePos threatenedSquare = squarePos.unflatten(threatenedSquareFlat);

                this[threatenedSquare] -= posDirection;

                // The removed piece no longer threatens this square.
                piecesWhichThreatenSquare[threatenedSquare.x, threatenedSquare.y][toRemove.position] = false;
            }
            toRemove.coveredSquares.Clear();

            // and now force a re-evaluation of things that threatened this square.
            sizableArray<int> piecesToRecalc = new sizableArray<int>(piecesWhichThreatenSquare[toRemove.position.x, toRemove.position.y].Count);
            piecesToRecalc.AddRange(piecesWhichThreatenSquare[toRemove.position.x, toRemove.position.y]);

            foreach (int toRecalcFlat in piecesToRecalc)
            {
                square toRecalc = _parentBoard[squarePos.unflatten(toRecalcFlat)];

                // Knights can never be blocked from accessing squares.
                if (toRecalc.type == pieceType.knight)
                    continue;

                //Pawns can always access their two attack squares.
                if (toRecalc.type == pieceType.pawn)
                    continue;

                int toRecalcAddition = toRecalc.colour == pieceColour.white ? 1 : -1;

                // Remove covered squares which are on the other 'side' of us - for example, if a rook
                // is to our left, remove squares to our right from it.
                int offX = toRecalc.position.x - toRemove.position.x;
                int offY = toRecalc.position.y - toRemove.position.y;

                int sx;
                if (offX < 0)
                    sx = +1;
                else if (offX > 0)
                    sx = -1;
                else
                    sx = 0;

                int sy;
                if (offY < 0)
                    sy = +1;
                else if (offY > 0)
                    sy = -1;
                else
                    sy = 0;

                // Look right up to the edge for all pieces apart from the king, which can look only
                // one square in each direction.
                int limitx = DoktorChessAIBoard.sizeX;
                int limity = DoktorChessAIBoard.sizeY;
                if (toRecalc.type == pieceType.king)
                {
                    limitx = toRecalc.position.x + (2 * sx);
                    limity = toRecalc.position.x + (2 * sx);

                    if (limitx > DoktorChessAIBoard.sizeX)
                        limitx = DoktorChessAIBoard.sizeX;
                    if (limity > DoktorChessAIBoard.sizeY)
                        limity = DoktorChessAIBoard.sizeY;
                }

                //Debug.WriteLine(toRecalc.type + " @ " + toRecalc.position + ":");
                int removex = toRemove.position.x + sx;
                int removey = toRemove.position.y + sy;
                while(removex >= 0 && removex < limitx &&
                      removey >= 0 && removey < limity   )
                {
                    squarePos pos = new squarePos(removex, removey);

                    this[pos] += toRecalcAddition;
                    piecesWhichThreatenSquare[removex, removey][toRecalc.position] = true;
                    toRecalc.coveredSquares[pos.flatten()] = true;

                    //Debug.WriteLine("Added discovered " + pos);

                    // we can threaten one piece, but no farther.
                    if (_parentBoard[removex, removey].type != pieceType.none)
                        break;

                    removex += sx;
                    removey += sy;

                }
            }
            sanityCheck();
        }
Beispiel #23
0
        /// <summary>
        /// Add the given piece to the whitePieceSquares or blackPieceSquares array.
        /// </summary>
        /// <param name="newSquare"></param>
        private void addToArrays(square newSquare)
        {
            #if DEBUG
            if (whitePieceSquares.Contains(newSquare) ||
                blackPieceSquares.Contains(newSquare))
                throw new Exception("Duplicate square at " + newSquare.position.ToString());
            #endif

            switch (newSquare.colour)
            {
                case pieceColour.white:
                    whitePieceSquares.Add(newSquare);
                    break;
                case pieceColour.black:
                    blackPieceSquares.Add(newSquare);
                    break;
                default:
                    throw new ArgumentException();
            }
        }
Beispiel #24
0
        /// <summary>
        /// Move a piece on the board, without performing the move itself (eg castling, or a capture)
        /// </summary>
        /// <param name="toMove">The piece to move</param>
        /// <param name="destPos">The location to move to</param>
        protected virtual void movePiece(square toMove, squarePos destPos)
        {
            squarePos srcPos = toMove.position;

            this[destPos] = toMove;
            this[destPos].position = destPos;
            this[srcPos] = new square(srcPos);
        }
        protected override void addPiece(square newSquare, squarePos newSquarePos)
        {
            base.addPiece(newSquare, newSquarePos);

            addNewPieceToArrays(this[newSquarePos]);
            coverLevel.add(newSquarePos.x, newSquarePos.y);
        }
Beispiel #26
0
        /// <summary>
        /// Remove the specified piece from the board without updating board status arrays
        /// </summary>
        /// <param name="toRemove"></param>
        protected virtual void removePiece(square toRemove)
        {
            this[toRemove.position] = new square(toRemove.position);

            switch (toRemove.colour)
            {
                case pieceColour.white:
                    whitePieceSquares.Remove(toRemove);
                    break;
                case pieceColour.black:
                    blackPieceSquares.Remove(toRemove);
                    break;
                default:
                    throw new ArgumentException();
            }
        }
 public bool isThreatened(square squareToCheck, pieceColour sideToExamine)
 {
     return false;
 }