public override sizableArray<move> getPossibleMoves(baseBoard onThis) { sizableArray<move> possibleMoves = new sizableArray<move>(potentialSquares.Length + 2); findFreeOrCapturableIfOnBoard(possibleMoves, onThis, potentialSquares); if (canCastle(onThis, true)) { // Castling kingside is possible. It is represented as a two-space move by the king. possibleMoves.Add(new move(this, onThis[position.right(2)])); } if (canCastle(onThis, false)) { // Likewise, queenside. possibleMoves.Add(new move(this, onThis[position.left(2)])); } return possibleMoves; }
public override sizableArray<square> getCoveredSquares(baseBoard parentBoard) { sizableArray<square> toRet = new sizableArray<square>(2); int direction = (colour == pieceColour.white) ? 1 : -1; if ((position.y + direction < baseBoard.sizeY) && (position.y + direction > -1)) { // Check the two diagonals if (position.x > 0) { toRet.Add( parentBoard[position.up(direction).leftOne()] ); } if (position.x < baseBoard.sizeX - 1) { toRet.Add( parentBoard[position.up(direction).rightOne()] ); } } return toRet; }
public void testIterator() { sizableArray<move> foo = new sizableArray<move>(5); move move1 = new move(new square(0,0), new square(1,1)); move move2 = new move(new square(1,1), new square(2,2)); foo.Add(move1); foo.Add(move2); bool move1seen = false; bool move2seen = false; foreach (move iterated in foo) { Debug.WriteLine("Iterated object " + iterated); if (iterated == move1) { if (move1seen) throw new Exception("Move one iterated twice"); move1seen = true; } else if (iterated == move2) { if (move2seen) throw new Exception("Move two iterated twice"); move2seen = true; } else if (iterated == null) throw new Exception("Iterator returned null"); else throw new Exception("Iterator returned something crazy"); } if (!move1seen || !move2seen) throw new Exception("Iterator did not iterate over all elements"); }
public override sizableArray<square> getCoveredSquares(baseBoard parentBoard) { sizableArray<square> toRet = new sizableArray<square>(8); foreach (squarePosOffset potentialSquare in potentialSquares) { int posX = position.x + potentialSquare.x; int posY = position.y + potentialSquare.y; if (IsOnBoard(potentialSquare.x, potentialSquare.y)) toRet.Add( parentBoard[posX, posY] ); } return toRet; }
public override lineAndScore findBestMove() { sizableArray<move> movesToConsider = getMoves(colToMove); // Filter out any moves in to check sizableArray<move> movesNotIntoCheck = new sizableArray<move>(movesToConsider.Length); pieceColour movingCol = colToMove; foreach (move consideredMove in movesToConsider) { doMove(consideredMove); if (!isPlayerInCheck(movingCol)) movesNotIntoCheck.Add(consideredMove); undoMove(consideredMove); } // and then select a random move. int rndNum = rnd.Next(movesNotIntoCheck.Length); move randomMove = movesNotIntoCheck[rndNum]; return new lineAndScore(new move[] { randomMove }, 0, null); }
public override sizableArray<move> getPossibleMoves(baseBoard onThis) { sizableArray<move> toRet = new sizableArray<move>(40); int direction; if (colour == pieceColour.white) direction = +1; else direction = -1; // We can capture upward diagonally, if immediate diagonal upward squares // contain an enemy piece. if ((position.y + direction < baseBoard.sizeY) && (position.y + direction > -1) ) { // Check for en passant. En passant can never cause a promotion. if (position.x > 0) { square adjacentLeft = onThis[position.leftOne()]; if (canEnPassantTo(adjacentLeft, onThis)) toRet.Add(new move(onThis[position], onThis[position.up(direction).leftOne()], adjacentLeft)); } if (position.x < baseBoard.sizeX - 1) { square adjacentRight = onThis[position.rightOne()]; if (canEnPassantTo(adjacentRight, onThis)) toRet.Add(new move(onThis[position], onThis[position.up(direction).rightOne()], adjacentRight)); } // And we can move forward two if we haven't moved this piece yet, and both // squares are empty. It is assumed that this can't cause a promotion, so explicitly // prevent this move from moving in to the back row. if (movedCount == 0) { if (position.y + (direction * 2) < baseBoard.sizeY && position.y + (direction * 2) > -1) { // check back row if (position.y != (colour == pieceColour.white ? 7 : 0)) { if (onThis[position.up(direction * 2)].type == pieceType.none && onThis[position.up(direction * 1)].type == pieceType.none) toRet.Add(new move(onThis[position], onThis[position.up(direction*2)])); } } } // All of the other moves could cause a promotion, so call addPawnMovesToSquare so that // promoting moves are added. // Check the two diagonals if (position.x > 0) { if (onThis[position.up(direction).leftOne()].containsPieceNotOfColour(colour)) addPawnMovesToSquare(toRet, onThis[position], onThis[position.up(direction).leftOne()]); } if (position.x < baseBoard.sizeX - 1) { if (onThis[position.up(direction).rightOne()].containsPieceNotOfColour(colour)) addPawnMovesToSquare(toRet, onThis[position], onThis[position.up(direction).rightOne()]); } // We can move forward one if that square is empty. if (onThis[position.up(direction)].type == pieceType.none) { if (onThis[position.up(direction)].type == pieceType.none) addPawnMovesToSquare(toRet, onThis[position], onThis[position.up(direction)]); } } return toRet; }
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)); } }