Example #1
0
static void getCastlingMoves(const position * const pos, const int player, move store[], int *numMoves)
{
    int colour;
    int sq;
    move m;
    sq = pos->kingSquare[player];
    colour = COLOUR(pos->board[sq]);
    m.from = sq;
    m.flags = CASTLE;
    m.thisPiece = pos->board[sq];
    m.promoteTo = 0;
    m.capturedPiece = 0;
    m.eval = 0;
    if(WHITE == player && !inCheck(pos, WHITE, pos->kingSquare[WHITE])) {
        if((pos->castleFlags & CASTLE_WK) && (0 == pos->board[1]) && (0 == pos->board[2])) {
              if(!inCheck(pos, WHITE, 1) && !inCheck(pos, WHITE, 2)) {

                    assert(WHITE_ROOK == pos->board[0]);

                    m.to = 1;
                    storeMoveIfLegal(pos, &m, WHITE, store, numMoves);
              }
        }
        if((pos->castleFlags & CASTLE_WQ) && (0 == pos->board[4]) && (0 == pos->board[5]) && (0 == pos->board[6])) {
              if(!inCheck(pos, WHITE, 4) && !inCheck(pos, WHITE, 5)) {

                    assert(WHITE_ROOK == pos->board[7]);

                    m.to = 5;
                    storeMoveIfLegal(pos, &m, WHITE, store, numMoves);
              }
        }
    }
    else if(!inCheck(pos, BLACK, pos->kingSquare[BLACK])) {
        if((pos->castleFlags & CASTLE_BK) && (0 == pos->board[57]) && (0 == pos->board[58])) {
              if(!inCheck(pos, BLACK, 57) && !inCheck(pos, BLACK, 58)) {

                    assert(BLACK_ROOK == pos->board[56]);

                    m.to = 57;
                    storeMoveIfLegal(pos, &m, BLACK, store, numMoves);
              }
        }
        if((pos->castleFlags & CASTLE_BQ) && (0 == pos->board[62]) && (0 == pos->board[61]) && (0 == pos->board[60])) {
              if(!inCheck(pos, BLACK, 61) && !inCheck(pos, BLACK, 60)) {

                    assert(BLACK_ROOK == pos->board[63]);

                    m.to = 61;
                    storeMoveIfLegal(pos, &m, BLACK, store, numMoves);
              }
        }
    }
}
Example #2
0
void OukBoard::generateMovesForPiece(QVarLengthArray< Move >& moves,
					  int pieceType,
					  int square) const
{
	MakrukBoard::generateMovesForPiece(moves, pieceType, square);

	Side side = sideToMove();

	// Only consider King and Neang on their initial squares
	if ((pieceType != King || square != m_initialSquare[side][King])
	&&  (pieceType != Maiden || square != m_initialSquare[side][Maiden]))
		return;
	// Return if the piece has moved already
	if (m_moveCount[side].value((OukPieceType)pieceType, -1) != 0)
		return;
	// No special moves for King in check
	if (pieceType == King && inCheck(side))
		return;

	// Generate initial move option for King (leap of Horse)
	// and for Neang (forward two squares)
	int sign = (side == Side::White) ? 1 : -1;

	for (const auto& i: m_initialOffsets)
	{
		if (pieceType != i.type)
			continue;

		int target = square - i.offset * sign;
		const Piece& piece = pieceAt(target);

		if  (piece.isEmpty())
			moves.append(Move(square, target));
	}
}
Example #3
0
int getMoves(const position * const pos, const int player, const int piece, const int type, move store[])
{
    bitboard rawMoves = 0;
    int sq;
    int numMoves = 0;
    int opponent;
    bitboard pieces;
    opponent = OPPONENT(player);
    /* opponent in check = player won. should be checked somewhere before this */
    assert(!inCheck(pos, opponent, pos->kingSquare[opponent]));
    pieces = getPieceBitboard(pos, piece);
    sq = 0;
    if(IS_KING(piece)) {
        /* we already know the location of the king */
        sq = pos->kingSquare[player];
        pieces = pieces >> sq;
        assert(pieces != 0); /* we should not move the king off the board */
    }
    while(pieces != 0) {
        if(LSB_SET(pieces)) {
            rawMoves = getRawMoves(pos, player, piece, type, sq);
            numMoves += getPieceMoves(pos, player, type, rawMoves, sq, &store[numMoves]);
        }
        pieces = pieces >> 1;
        sq++;
    }
    return numMoves;
}
bool RacingKingsBoard::isLegalPosition()
{
	Side side = sideToMove();
	if (inCheck(side))
		return false;

	return WesternBoard::isLegalPosition();
}
Example #5
0
Result KarOukBoard::result()
{
	Side side = sideToMove();
	if (!inCheck(side))
		return OukBoard::result();

	Side opp = side.opposite();
	QString str = tr("%1 wins by giving check").arg(opp.toString());
	return Result(Result::Win, opp, str);
}
Example #6
0
static void storeMoveIfLegal(const position* const pos, move* m, const int player, move store[], int *numMoves)
{
    position newPosition;
    int status;
    int opponent;
    status = playMove(pos, &newPosition, m, player);

    if(status != ILLEGAL) { /* move is legal */
        /* check that the move does not put players king in check, which would be illegal */
        if(!inCheck(&newPosition, player, newPosition.kingSquare[player])) {
            /* calculate evaluation */
            opponent = OPPONENT(player);
            if(inCheck(&newPosition, opponent, newPosition.kingSquare[opponent])) {
                m->flags |= CHECK;
                m->eval += EVAL_CHECK;
            }
            store[(*numMoves)++] = *m;
        }
    }
}
Example #7
0
/*
	in: 	Pointer to the line of input
	args: 	String array to place arguments
*/
void getArgs(char* in, char** args) {
    //Working pointer to args
    char** arg;
    arg = args;

    //Get the first token and continue through string placing
    //tokens in args, last token will be NULL
    *arg++ = strtok(in, DELIMITERS);
    while((*arg++ = strtok(NULL, DELIMITERS)));

    inCheck(args);
}
Example #8
0
int getAllMoves(const position * const pos, const int player, const int storeIndex)
{
    int numMoves = 0;

    if(WHITE == player) {
        numMoves += getMoves(pos, player, WHITE_KING, CAPTURE, &_moveStore[storeIndex][numMoves]);
        numMoves += getMoves(pos, player, WHITE_PAWN, CAPTURE, &_moveStore[storeIndex][numMoves]);
        numMoves += getMoves(pos, player, WHITE_KNIGHT, CAPTURE, &_moveStore[storeIndex][numMoves]);
        numMoves += getMoves(pos, player, WHITE_BISHOP, CAPTURE, &_moveStore[storeIndex][numMoves]);
        numMoves += getMoves(pos, player, WHITE_ROOK, CAPTURE, &_moveStore[storeIndex][numMoves]);
        numMoves += getMoves(pos, player, WHITE_QUEEN, CAPTURE, &_moveStore[storeIndex][numMoves]);
        numMoves += getMoves(pos, player, WHITE_KING, NORMAL, &_moveStore[storeIndex][numMoves]);
        numMoves += getMoves(pos, player, WHITE_PAWN, NORMAL, &_moveStore[storeIndex][numMoves]);
        numMoves += getMoves(pos, player, WHITE_KNIGHT, NORMAL, &_moveStore[storeIndex][numMoves]);
        numMoves += getMoves(pos, player, WHITE_BISHOP, NORMAL, &_moveStore[storeIndex][numMoves]);
        numMoves += getMoves(pos, player, WHITE_ROOK, NORMAL, &_moveStore[storeIndex][numMoves]);
        numMoves += getMoves(pos, player, WHITE_QUEEN, NORMAL, &_moveStore[storeIndex][numMoves]);
    }
    else {
        numMoves += getMoves(pos, player, BLACK_KING, CAPTURE, &_moveStore[storeIndex][numMoves]);
        numMoves += getMoves(pos, player, BLACK_PAWN, CAPTURE, &_moveStore[storeIndex][numMoves]);
        numMoves += getMoves(pos, player, BLACK_KNIGHT, CAPTURE, &_moveStore[storeIndex][numMoves]);
        numMoves += getMoves(pos, player, BLACK_BISHOP, CAPTURE, &_moveStore[storeIndex][numMoves]);
        numMoves += getMoves(pos, player, BLACK_ROOK, CAPTURE, &_moveStore[storeIndex][numMoves]);
        numMoves += getMoves(pos, player, BLACK_QUEEN, CAPTURE, &_moveStore[storeIndex][numMoves]);
        numMoves += getMoves(pos, player, BLACK_KING, NORMAL, &_moveStore[storeIndex][numMoves]);
        numMoves += getMoves(pos, player, BLACK_PAWN, NORMAL, &_moveStore[storeIndex][numMoves]);
        numMoves += getMoves(pos, player, BLACK_KNIGHT, NORMAL, &_moveStore[storeIndex][numMoves]);
        numMoves += getMoves(pos, player, BLACK_BISHOP, NORMAL, &_moveStore[storeIndex][numMoves]);
        numMoves += getMoves(pos, player, BLACK_ROOK, NORMAL, &_moveStore[storeIndex][numMoves]);
        numMoves += getMoves(pos, player, BLACK_QUEEN, NORMAL, &_moveStore[storeIndex][numMoves]);
    }

    if(0 == numMoves) { /* no moves */
        if(inCheck(pos, player, pos->kingSquare[player])) {
            return LOST;
        }
        else {
            return STALEMATE;
        }
    }

    counterMove += numMoves;

    return numMoves;
}
Example #9
0
/*
    Types of moves:
    1) King normal move
    2) King captures
    3) King castles
    4)
*/
int playMove(const position * const pos, position *newPosition, const move * const m, const int player)
{
    int opponent;
    opponent = OPPONENT(player);
    /* assert consistency of position */
    assertPosition(pos);
    /* opponent cannot be check, this should be handled elsewhere */
    assert(!inCheck(pos, opponent, pos->kingSquare[opponent]));
    /* init new position to old position */
    *newPosition = *pos;
    /* opponent has to play in the new position */
    newPosition->toPlay = opponent;
    movePiece(newPosition, m, player);
    if(IS_CAPTURE(m)) {
        /* clear bitmask for captured piece */
        clearCapturedPiece(newPosition, m);
    }
    /* ep is disabled after any move played */
    DISABLE_EP(newPosition);
    /* assert consistency of new position */
    assertPosition(newPosition);
    return 0;
}
Example #10
0
bool OukBoard::inCheck(Side side, int square) const
{
	int sign = (side == Side::White) ? 1 : -1;
	Side opSide = side.opposite();
	if (square == 0)
		square = kingSquare(side);

	// Attack by Advisor (Maiden, Neang), initial move
	if (!m_moveCount[opSide][Maiden]
	&&  m_initialSquare[opSide][Maiden] == square - 2 * sign * (width() + 2))
		return true;

	// Attack by King, initial move
	int ksq = kingSquare(opSide);
	bool attacked = (ksq == square - 8 * sign || ksq == square - 12 * sign);

	if (!m_moveCount[opSide][King] && attacked)
	{
		if (square == kingSquare(side)
		|| !inCheck(opSide))
			return true;
	}
	return MakrukBoard::inCheck(side, square);
}
Example #11
0
int Board::alphaBeta(int depthLeft, int alpha, int beta, int doNullMove) {
	int check = 0;
	int oldAlpha = alpha;
	int numSearched = 0;
	int bestMove = 0;
	int hashMove = 0;
	int stage;
	int i = currentState->firstMove;
	int result;

	nodes++;
	nodesUntilUpdate--;
	if(nodesUntilUpdate <= 0) {
		switch(game->interfaceUpdate()) {
			case OUT_OF_TIME:

				abortingSearch = 1;
				return 0;
			break;

			case STOP_SEARCH:
				abortingSearch = 1;
				return 0;
			break;
		}

		nodesUntilUpdate = nodesPerUpdate;
	}



	if(isRepetition()) {
		returnMove = 0;
		return DRAW;
	}


	HashEntry *e;
	e = hash->probe(currentState->hashKey);

	if(e!=NULL) {
		hashHits++;
		//Is it useful for replacing this search - otherwise just find a best move
		hashMove = e->bestMove;
		returnMove = hashMove;

#ifndef DISABLE_HASH
		if(depth > 0 && e->depth >= depthLeft) {
			switch(e->flags & 3) {
				case HASH_EXACT:
					return e->score;
				break;

				case HASH_LOWER:
					if(e->score >= beta) return e->score;
					if(e->score > alpha) alpha = e->score;
				break;

				case HASH_UPPER:
					if(e->score <= alpha) return e->score;
					if(e->score < beta) beta = e->score;
				break;
			}

			if(e->flags & HASH_NO_NULL) {
				doNullMove = 0;
			}
		}
#endif
	}

#ifdef DEBUG_HASH
	if(hashMove > 0 && !testLegality(hashMove)) {
		print();
		cout << "Illegal hash move! ";
		printMove(hashMove);
		cout << endl;
	}
#endif


	if(depthLeft == 0) {
		int value =  quiescence(alpha, beta);
		//hash->store(0, value, 0, HASH_EXACT);
		return value;
	}


	check = inCheck();

/*
	if(doNullMove && !check && !nullRisk() && depth >= 2) {
		int nullDepth = depthLeft - 2;

		makeNullMove();

		if(nullDepth > 0) {
			result = alphaBeta(nullDepth, -beta, -beta+1, NO_NULL_MOVE);
		} else {
			result = quiescence(-beta, -beta+1);
		}

		retractNullMove();

		if(nullDepth > 0 && result >= beta) {
			result = alphaBeta(nullDepth, beta-1, beta, DO_NULL_MOVE);
			numMoves = currentState->firstMove;
		}


		if(result >= beta) {
			returnMove = 0;
			return beta;
		}
	}
*/

	if(!hashMove && depthLeft >= 3) {
		result = alphaBeta(depthLeft - 2, alpha, beta, DO_NULL_MOVE);
		numMoves = currentState->firstMove;

		//Failed low so have to research with new bounds
		if(result <= alpha) result = alphaBeta(depthLeft - 2, -MATE, alpha + 1, DO_NULL_MOVE);
		numMoves = currentState->firstMove;

		hashMove = returnMove;
	}

	if(hashMove > 0) {
		stage = HASH_MOVE;
	}	else {
		stage = ALL_MOVES;
	}

	while(stage != FINISHED) {
		switch(stage) {
			case HASH_MOVE:
				moveStack[numMoves++] = hashMove;
				stage = ALL_MOVES;
			break;
			case  ALL_MOVES:
				if(check) {
					generateCheckEvasions();
					sortNonCaptures(i, hashMove);
					stage = FINISHED;
				} else {
					generateCaptures();
					sortCaptures(i, hashMove);
					stage = NON_CAPTURES;
				}
			break;
			case NON_CAPTURES:
				generateNonCaptures();
				sortNonCaptures(i, hashMove);
				stage = FINISHED;
			break;
		}

	for(; i<numMoves; i++) {
			int move = moveStack[i];
			makeMove(move);

#ifdef DEBUG_BITBOARDS
				if(isMessedUp()) {
					printMoves();
					print();
					cout << "Hash move = "; printMove(hashMove); cout << endl;
					cout << "MakeMove" << endl;
					exit(0);
				}
#endif

			if(isLegal())  {
				numSearched++;

				result = -alphaBeta(depthLeft - 1, -beta, -alpha, DO_NULL_MOVE);
				retractMove(move);

				if(abortingSearch) {
					returnMove = bestMove;
					return result;
				}

				if(result > alpha) {
					if(result >= beta) {
						returnMove = move;
						hash->store(move, result, depthLeft, HASH_LOWER);

#ifdef EXTRA_STATS
						cutoffs++;
						if(i == currentState->firstMove) firstCutoffs++;
#endif
						return result;
					}


/*					if(depth == 0) {
						printMove(move);
						cout << " ";
						printScore(result);
						cout << " hashMove: ";
						printMove(hashMove);
						cout << endl;
					}*/

					alpha = result;
					bestMove = move;
				}


			} else { //Illegal move
				retractMove(move);
			}
#ifdef DEBUG_BITBOARDS
			if(isMessedUp()) {
				printMoves();
				print();
				cout << "Hash move = "; printMove(hashMove); cout << endl;
				cout << "RetractMove" << endl;
				exit(0);
			}
#endif
		}
	}		//While we have moves

		//No legal moves..
	if(numSearched ==0) {
		returnMove = 0;

		if(check)	{
			 return -(MATE - depth);
		} else {
			return DRAW;
		}
	}


	if(alpha == oldAlpha) {
		hash->store(bestMove, alpha, depthLeft, HASH_UPPER);

	} else {
		hash->store(bestMove, alpha, depthLeft, HASH_EXACT);
	}

	returnMove = bestMove;
	return alpha;
}
Example #12
0
bool Position::doMove(Move &theMove) {
	
	//save history
	updateHistory();

	//First up: move the piece on the board, update piecelist
	board[theMove.toSpace] = theMove.piece;
	board[theMove.fromSpace] = EMPTY;
	updatePiece(theMove.fromSpace, theMove.toSpace, toMove);
	updatePieceHash(theMove.fromSpace, theMove.toSpace, theMove.piece);

	//If it is a capture, let's delete the dead guy from the proper piecelist
	if (theMove.capture != 0) {
		//For enpassant captures
		if(theMove.enPassant == true) {
			removePiece(enPassant + 10*toMove, -toMove);
			updatePieceHash(enPassant + 10*toMove, 0, theMove.capture);
			board[enPassant + 10*toMove] = EMPTY;
		}
		else {
			removePiece(theMove.toSpace, -toMove);
			updatePieceHash(theMove.toSpace, 0, theMove.capture);
		}

		//If a rook is captured, update castle info.
		if(abs(theMove.capture) == ROOK) {
			if (castleWK && theMove.toSpace == 98) {
				castleWK = false;
				hash = hash ^ castleKeys[0];
			}
			else if (castleWQ && theMove.toSpace == 91) {
				castleWQ = false;
				hash = hash ^ castleKeys[1];
			}
			else if (castleBK && theMove.toSpace == 28) {
				castleBK = false;
				hash = hash ^ castleKeys[2];
			}
			else if (castleBQ && theMove.toSpace == 21) {
				hash = hash ^ castleKeys[3];
				castleBQ = false;
			}
		}
	}

	//Speaking of en passant captures...
	if (enPassant != 0) hash = hash ^ enpassantKeys[enPassant%10 - 1];
	if (theMove.jump) {
		enPassant = theMove.fromSpace - 10*toMove;
		hash = hash ^ enpassantKeys[enPassant%10 - 1];
	}
	else enPassant = 0;

	//For promotions, we must bring a piece to LIFE!
	if (theMove.promotion != 0) {
		board[theMove.toSpace] = theMove.promotion*toMove;
		updatePieceHash(0, theMove.toSpace, theMove.promotion*toMove);
		updatePieceHash(theMove.toSpace, 0, theMove.piece);
	}
	
	//Castling. Hooray. Move the rooks, update piecelists.
	if (theMove.castle != 0) {
		if (theMove.castle == 1) {
			if (toMove == WHITE) {
				board[98] = EMPTY; board[96] = ROOK;
				updatePiece(98, 96, WHITE);
				updatePieceHash(98, 96, ROOK);
			}
			else {
				board[28] = EMPTY; board[26] = -ROOK;
				updatePiece(28, 26, BLACK);
				updatePieceHash(28, 26, -ROOK);
			}
		}
		else {
			if (toMove == WHITE) {
				board[91] = EMPTY; board[94] = ROOK;
				updatePiece(91, 94, WHITE);
				updatePieceHash(91, 94, ROOK);
			}
			else {
				board[21] = EMPTY; board[24] = -ROOK;
				updatePiece(21, 24, BLACK);
				updatePieceHash(21, 24, -ROOK);
			}
		}
	}

	//Update king locations
	if (abs(theMove.piece) == KING) {
		if (toMove == WHITE) {
			whiteKing = theMove.toSpace;
			if (castleWK) {
				castleWK = false; 
				hash = hash ^ castleKeys[0];
			}
			if (castleWQ) {
				castleWQ = false;
				hash = hash ^ castleKeys[1];
			}
		}
		else {
			blackKing = theMove.toSpace;
			if (castleBK) {
				castleBK = false;
				hash = hash ^ castleKeys[2];
			}
			if (castleBQ) {
				castleBQ = false;
				hash = hash ^ castleKeys[3];
			}
		}
	}

	//Update castling rights for rook moves
	if (theMove.piece == ROOK) {
		if (theMove.fromSpace == 91 && castleWQ) {
			castleWQ = false;
			hash = hash ^ castleKeys[1];
		}
		else if (theMove.fromSpace == 98 && castleWK){
			castleWK = false;
			hash = hash ^ castleKeys[0];
		}
	}
	else if (theMove.piece == -ROOK) {
		if (theMove.fromSpace == 21 && castleBQ){
			castleBQ = false;
			hash = hash ^ castleKeys[3];
		}
		else if (theMove.fromSpace == 28 && castleBK){
			castleBK = false;
			hash = hash ^ castleKeys[2];
		}
	}

	//Adjust fifty move rule counter
	if (abs(theMove.piece) == PAWN || theMove.capture != 0) fiftyMove = 0;
	else fiftyMove++;

	if (toMove == BLACK) totalMoves++;
	halfMoves++;
	bool check = inCheck();
	toMove = -toMove;
	hash = hash ^ blackKey;

	//update moves made and history
	movesMade.add(theMove);
	return check;
}