Пример #1
0
// returns 0 if NOT in check after the move
// return 1 if in check after the move
int simCheck(struct board * b, struct piece * p, struct pos * move, struct piece * k )
{
	struct piece * inactivePiece = NULL;
	struct pos * tempLoc;
	struct board * nBoard = copyBoard(b);

	struct pos * nMove = makeLoc(move->x, move->y);
	nMove->type = move->type;
	if(move->type ==4)
	{
		nMove->additionalM1 = move->additionalM1;
		nMove->additionalM2 = move->additionalM2;
		nMove->additionalP = getSpace(nBoard, move->x, move->y);
	}
 	int temp = getOrder(b, p);
	int temp1;
	if(move->taken != NULL)
	{
		temp1 = getOrder(b,move->taken);
		nMove->taken = nBoard->pieces[temp1];
	}
	else{
		nMove->taken = NULL;
	}

//	printAllMoves(nBoard);
	movePiece(nBoard,nBoard->pieces[temp],nMove);
	updateAllMovesSim(nBoard);
	free(nMove);

	if(move->type == 4)
	{
		if(incheckCheck(nBoard,move->additionalP,move->additionalP->loc) == 1)
		{
			deleteBoard(nBoard);
			return 1;
		}
		deleteBoard(nBoard);
		return 0;
	}
	if(incheckCheck(nBoard,k,k->loc) == 1)
	{
		deleteBoard(nBoard);
		return 1;
	}
	deleteBoard(nBoard);
	return 0;
}
Пример #2
0
void AIMediocrePlayer::requestMove(PieceColor moveType)
{
    assert(m_array);
    auto gameLogic = m_gameLogic.lock();

    std::vector<int> scores;
    auto lockedGameLogic = m_gameLogic.lock();
    std::vector<PieceMove> moves = lockedGameLogic->getAllPossibleMoves(*m_array, moveType);

    std::vector<std::future<int>> futures;
    for(const auto& move: moves)
    {
        Array copyOfArray = *m_array;
        copyOfArray.move(move.source().m_row, move.source().m_col, move.destination().m_row, move.destination().m_col);
        for(const auto& pos: move.capturedPieces())
        {
            copyOfArray.erase(pos.m_row, pos.m_col);
        }

        int newScore = move.numberOfCapturedPieces();

        auto score = std::async(std::launch::async,
                                &minMaxWithAlphaBetaPruning,
                                lockedGameLogic,
                                copyOfArray,
                                m_maxDepth,
                                newScore,
                                getOppositeColor(moveType),
                                moveType,
                                gMinusInfinity,
                                gPlusInfinity);
        futures.push_back(std::move(score));
    }

    for(auto& future: futures)
    {
        auto result = future.get();
        scores.push_back(result);
    }

    auto it = std::max_element(scores.begin(), scores.end());

    PieceMove move = moves.at(std::distance(scores.begin(), it));
    std::vector<Position> subMoves{move.subMoves().begin()+1, move.subMoves().end()};

    lockedGameLogic->movePiece(move.source(), subMoves, moveType);
}
Пример #3
0
bool AI::makeMove(SDL_Event *event){

    // Init enemyTeam that this class can use
    getEnemyTeam();

    for(int index=0;index<team.size();index++){
        currentIndex = index;

        team[index].directionValues[0] = maxValue(Board->virtualBoard, team, enemyTeam, MAX_DEPTH, LEFT);
        team[index].directionValues[1] = maxValue(Board->virtualBoard, team, enemyTeam, MAX_DEPTH, RIGHT);

        if (team[index].isKing()) {
            team[index].directionValues[3] = maxValue(Board->virtualBoard, team, enemyTeam, MAX_DEPTH, BACK_RIGHT);
            team[index].directionValues[2] = maxValue(Board->virtualBoard, team, enemyTeam, MAX_DEPTH, BACK_LEFT);
        }
        cout<<"Index: "<<index<<" ("<< team[index].x << "," << team[index].y;
        cout<<") Left: "<<team[index].directionValues[0]<<" Right: "<<team[index].directionValues[1];
        cout<<" bLeft: "<<team[index].directionValues[2]<<" bRight: "<<team[index].directionValues[3]<<endl;

        team[index].findBestDirection();
        team[index].findLargestPotenial();
    }

    int bestPieceIndex = bestPiece(team);
    cout<< "The chosen one: " << bestPieceIndex << " -> ("<< team[bestPieceIndex].x << "," << team[bestPieceIndex].y;

    int x = team[bestPieceIndex].x;
    int y = team[bestPieceIndex].y;

    // Makes sure the move isnt out of bounds //
    if (team[bestPieceIndex].potential != OUT_OF_BOUND) {

        changeWithDirection(x, y, team[bestPieceIndex].bestDirection, false);

        if(sameTeam(Board->virtualBoard[x][y],ENEMY_TEAM_NUMBER)){
            // Changes it again for moving 2 units diagonally //
            changeWithDirection(x, y, team[bestPieceIndex].bestDirection, false);
        }
        cout<<") best move: (" << x << "," << y <<")"<< endl;
        movePiece(Board->virtualBoard, team, bestPieceIndex, x, y);
        return true;
    }
    return false;
}
Пример #4
0
int AI::minValue(vector<vector<int>> tempBoard, vector<Piece> teamCopy, vector<Piece> enemyTeamCopy, int depth, Directions direction){

    bool killMove = false;

    if(!checkNode(tempBoard, teamCopy, enemyTeamCopy, direction, true)){
        return OUT_OF_BOUND;
    }

    int x = enemyTeamCopy[enemyCurrentIndex].x;
    int y = enemyTeamCopy[enemyCurrentIndex].y;

    changeWithDirection(x, y, direction, true);
    if(sameTeam(tempBoard[x][y],TEAM_NUMBER)){
        if(!killCheckArea(tempBoard, x, y, direction, true)){
            return OUT_OF_BOUND;
        }
        else{
            changeWithDirection(x, y, direction, true);
            killMove = true;
        }
    }

    //This should move on the tempBoard
    movePiece(tempBoard, enemyTeamCopy, enemyCurrentIndex, x, y);
    updateKings(tempBoard, enemyTeamCopy, true);
    if (killMove) {
        updateTeam(tempBoard, teamCopy, false);
        if (teamCopy.size()<=0) {
            //smallest number
            return -1 * WIN_VALUE;
        }
    }

    if (depth <= 0) {
        return valueCalculator(teamCopy, enemyTeamCopy);
    }
    else{
        return maxMove(tempBoard, teamCopy, enemyTeamCopy, depth-1);
    }

}
Пример #5
0
/* returns 2 if the move caused a promotion
 * returns 1 if valid
 * returns -1 if invalid m1
 * returns -2 if invalid m2
 * returns -3 if not your turn
 */
int tryMove(struct board* b,int x1,int y1,int x2,int y2, int player)
{
	if(player != b->currentPlayer)
	{
		return -3;
	}

	struct pos * m1 = makeLoc(x1,y1);
	struct pos * m2 = makeLoc(x2,y2);

	struct piece * mover = getSpace(b,x1,y1);
	if(mover == NULL)
	{
				return -1;
	}
	if(mover->player != b->currentPlayer)
		return -1;

	struct pos * m3 = validMoveForPiece(mover,m2);

	free(m1);
	free(m2);

	if(m3 != NULL)
	{
		movePiece(b, mover, m3);
		updateAllMoves(b);

		if(checkPromotion(b))
		{
			b->currentPlayer = (b->currentPlayer+1)%2;
			return 2;
		}
		return 1;
	}
	else
	{
		return -2;
	}
}
Пример #6
0
int Game::update()
{
	//This is probably graphical stuff and thus commented out
	//int currTime = (int)clock.getElapsedTime().asSeconds() + timeOffset;
	// Update clockstring
	//This is probably graphical stuff and thus commented out
	//clockText.setString(std::to_string(currTime / 60) + ":" + std::to_string(currTime % 60));
	 // Make sure that no moves is asked after checkmate or stalemate
			// Start new thread and calculate time elapsed for algorithm
			//clock.restart();
	std::pair<int, int> aimove = getAiMove();
	movePiece(aimove);
	//std::cout << "AI(lvl:" << playerOnTurn->getLevel() << ") calculated next turn in " << std::endl;



	


	return changeTurn();

}
Пример #7
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;
}
Пример #8
0
int		       	Game::play()
{
  while (m_running)
    {
      if (m_falling == false)
	addNewPiece();
      if (pieceCanFall())
	applyFalling();
      else
	{
	  fixPiece();
	  cleanLines();
	}
      display();
      movePiece(m_controler.getEvent());
      display();
      usleep((1000000 / 10) * (m_speed / m_speedup));
      m_turn++;
      std::cout << m_turn << " => " << m_piece.getY() << std::endl;
      if (m_turn % SPEED_UP_DELAY == 0 && m_speed > 1)
	m_speed--;
    }
  return (0);
}
Пример #9
0
int main(){
	int in_game=0;
	int turnPre=0;
	int mode=-1;	 	/*range 1-3*/
	int diff=-1; 		/*range 0-3, 0 if pvp*/
	int timer=-1;		/*range 0, 5, 10, 20*/
	int side=-1;        /*range '0' for white, '1' for black*/
	int all41 = -1;		/* range 0-5 depending on piece */
	char confirm='n';	/*range 'n', 'y'*/
	char modeS[26];
	char diffS[26];
	char timerS[26];
	board *board = createNewGame();
	int timer1 = 0;
	int timer2 = 0;
	int timer3 = 0;
	int timer4 = 0;
	int timer5 = 0;
	int altcounter = 1;
	do{	/*game setup*/
		printf("\nChess v1.0 by nøl / C Gets Degrees\n\n");
		while (mode < 1){
			printf("Please select game mode:\n");
			printf("1. Player versus Player\n");
			printf("2. Player versus Computer\n");
			printf("3. Computer versus Computer\n\n");
			scanf("%d", &mode);
			switch(mode){
				case 1:
					printf("Player versus Player selected\n");
					break;
				case 2:
					printf("Player versus Computer selected\n\n");
					printf("Choose a side: White(0) or Black(1)?\n");
					scanf("%d", &side);
					switch(side){
						case 0:
							printf("White selected\n");
							break;
						case 1:
							printf("Black selected\n");
							break;
						default:
							printe(selection);
							side = -1;
							break;
					}
					break;
				case 3:
					printf("Computer versus Computer selected\n");
					break;
				default:
					printe(selection);
					mode = -1;
					break;
			}
		}
		while (all41 < 0){
			printf("\nPlease select game type. All-for-One mode creates all pieces of the same type!\n");
			printf("0. Standard Chess\n");
			printf("1. All-for-Pawn\n");
			printf("2. All-for-Knight\n");
			printf("3. All-for-Queen\n");
			printf("4. All-for-Rook\n");
			printf("5. All-for-Bishop\n");
			scanf("%d", &all41);
			switch(all41){
				case 0:
					printf("Standard chess selected\n");
					break;
				case 1:
					printf("All-for-Pawn selected\n");
					break;
				case 2:
					printf("All-for-Knight selected\n");
					break;
				case 3:
					printf("All-for-Queen selected\n");
					break;
				case 4:
					printf("All-for-Rook selected\n");
					break;
				case 5:
					printf("All-for-Bishop selected\n");
					break;
				default:
					printe(selection);
					all41 = -1;
					break;
			}
		}
		while (diff < 0){
			if (mode == 1){
				diff = 0;
				break;
			}
			printf("\nPlease select computer difficulty:\n");
			printf("1. Easy\n");
			printf("2. Medium\n");
			printf("3. Hard\n\n");
			scanf("%d", &diff);
			switch(diff){
				case 1:
					printf("Easy selected\n");
					break;
				case 2:
					printf("Medium selected\n");
					break;
				case 3:
					printf("Hard selected\n");
					break;
				default:
					printe(selection);
					diff = -1;
					break;
			}
		}
		while (timer < 0){
			printf("\nPlease select game timer length:\n");
			printf("0. No limit\n");
			printf("5. 5 minutes\n");
			printf("10. 10 minutes\n");
			printf("20. 20 minutes\n\n");
			scanf("%d", &timer);
			switch(timer){
				case 0:
					printf("No limit selected\n");
					timer = 0;
					break;
				case 5:
					printf("5 minutes selected\n");
					timer1 = timer*60;
					timer3 = timer*60;
					break;
				case 10:
					printf("10 minutes selected\n");
					timer1 = timer*60;
					timer3 = timer*60;
					break;
				case 20:
					printf("20 minutes selected\n");
					timer1 = timer*60;
					timer3 = timer*60;
					break;
				default:
					printe(selection);
					timer1 = 0;
					timer3 = 0;
					timer = -1;
					break;
			}
		}
		/*CREATE STRINGS FOR SELECTIONS*/
		switch(mode){
			case 1:
				strcpy(modeS, "Player versus Player");
				break;
			case 2:
				strcpy(modeS, "Player versus Computer");
				break;
			case 3:
				strcpy(modeS, "Computer versus Computer");
				break;
		}
		switch(diff){
			case 0:
				strcpy(diffS, "");
				break;
			case 1:
				strcpy(diffS, "\nDifficulty: Easy");
				break;
			case 2:
				strcpy(diffS, "\nDifficulty: Medium");
				break;
			case 3:
				strcpy(diffS, "\nDifficulty: Hard");
				break;
		}
		switch(timer){
			case 0:
				strcpy(timerS, "No time limit");
				break;
			case 5:
				strcpy(timerS, "5 minutes");
				break;
			case 10:
				strcpy(timerS, "10 minutes");
				break;
			case 20:
				strcpy(timerS, "20 minutes");
				break;
		}
		/*CONFIRM SELECTIONS*/
		printf("\n\nPlease confirm selections: [y/n]\n\n");
		printf("Mode: %s", modeS);
		printf("%s", diffS);
		printf("\nTimer: %s\n\n", timerS);
		scanf(" %c", &confirm);

		if (confirm == 'y' || confirm == 'Y'){
			in_game = 1;
			fgetc(stdin); /* absorb the /n produced by the last scanf */
			createMoveLog();
		}
		else if (confirm == 'n' || confirm == 'N'){
			mode = -1;
			side = -1;
			diff = -1;
			timer = -1;
			all41 = -1;
		}
		else{
			printe(selection);
		}
		
		int aiTeam1, aiTeam2;
		if(mode == 2){ /* Inverts input value 0 -> 1, 1 -> 0, other input will cause assertion failure */
			aiTeam1 = oppTeam(side); /* oppTeam function comes from ai.c. Reads an int, returns an int. */
		}
		if(mode == 3){ /* Default for CPU vs CPU */
			aiTeam1 = 0;
			aiTeam2 = 1;
		}
		
		while(in_game){ /* if side = 1, player is black */
			if (timer != 0){
				/* set up timer */
				if (altcounter % 2 != 0){
					timer5 = timer4 - timer2;
					timer1 = timer1 - timer5;
					altcounter = altcounter+1;
				}
				else{
					timer5 = timer4 - timer2;
					timer3 = timer3 - timer5;
					altcounter = altcounter+1;
				}
				if (timer1 <= 0){
				printf("\nWhite has run out of time!\n");
				exit(0);
				}
				if (timer3 <= 0){
					printf("\nBlack has run out of time!\n");
					exit(0);
				}
			}
			int alpha;
			cell *tmp1;
			switch(all41){
				case 0:
				break;
				case 1:
					for(alpha = 0; alpha <64; alpha++){
						tmp1 = getCell(alpha, board);
						if (tmp1->piece != NULL && tmp1->piece->type != king){
							tmp1->piece->type = pawn;
							updatePrintPiece(tmp1);
						}
					}
					break;
				case 2:
					for(alpha = 0; alpha <64; alpha++){
						tmp1 = getCell(alpha, board);
						if (tmp1->piece != NULL && tmp1->piece->type != king){
							tmp1->piece->type = knight;
							updatePrintPiece(tmp1);
						}
					}
					break;
				case 3:
					for(alpha = 0; alpha <64; alpha++){
						tmp1 = getCell(alpha, board);
						if (tmp1->piece != NULL && tmp1->piece->type != king){
							tmp1->piece->type = queen;
							updatePrintPiece(tmp1);
						}
					}
					break;
				case 4:
					for(alpha = 0; alpha <64; alpha++){
						tmp1 = getCell(alpha, board);
						if (tmp1->piece != NULL && tmp1->piece->type != king){
							tmp1->piece->type = rook;
							updatePrintPiece(tmp1);
						}
					}
					break;
				case 5:
					for(alpha = 0; alpha <64; alpha++){
						tmp1 = getCell(alpha, board);
						if (tmp1->piece != NULL && tmp1->piece->type != king){
							tmp1->piece->type = bishop;
							updatePrintPiece(tmp1);
						}
					}
					break;
			}
			
			turnPre = board->turn;
			timer2 = (int) time(NULL);
			updateGameDisplay(board); /* display the entire board only when its a new turn */
			while (turnPre == board->turn){
				cell *temp;
				switch(mode){
					case 1: /* PvP */ 
						updateMessage(board);
						/*board->turn++;*/
						break;
					case 2: /* P vs AI */
						if(board->turn%2 == aiTeam1){ /* AI's turn */
							printMessage(board->turn);
							if (board->turn == 0){
								temp = getCell(12, board);
								movePiece(temp->piece, getCell(20, board));
								temp = NULL;
							}
							else if (board->turn == 1){
								temp = getCell(52, board);
								movePiece(temp->piece, getCell(44, board));
							}
							else if (board->turn == 2){
								temp = getCell(3, board);
								movePiece(temp->piece, getCell(21, board));
							}
							else if (board->turn == 3){
								temp = getCell(59, board);
								movePiece(temp->piece, getCell(45, board));
							}
							else if (board->turn == 4){
								temp = getCell(5, board);
								movePiece(temp->piece, getCell(26, board));
							}
							else if (board->turn == 5){
								temp = getCell(61, board);
								movePiece(temp->piece, getCell(34, board));
							}
							else if (board->turn == 6){
								temp = getCell(21, board);
								movePiece(temp->piece, getCell(53, board));
							}
							else if (board->turn == 7){
								temp = getCell(45, board);
								movePiece(temp->piece, getCell(13, board));
							}
							else{
								aiMove(diff, aiTeam1, board);
							}
						}
						else{
							/* player's turn */
							updateMessage(board);
							/*board->turn++;*/
						}
						break;
					case 3: /* AI vs AI*/
						if(board->turn%2 == 0){ /* White's turn */
							/* aiTeam1 goes */
							printMessage(board->turn);
							aiMove(diff, aiTeam1, board);
							/*board->turn++;*/
						}
						else{ /* Black's turn */
							/* aiTeam2 goes */
							printMessage(board->turn);
							aiMove(diff, aiTeam2, board);
							/*board->turn++;*/
						}
						break;
				}
				/* Exits loop when turn is finished */
			}
			timer4 = (int) time(NULL);
			if (timer != 0 && board->turn > 1){
				printf("DEBUG: Current time: %d\n", timer4);
				printf("DEBUG: Current time: %d\n", timer2);
				printf("Time remaining for Player 1: %d seconds.\n", timer1);
				printf("Time remaining for Player 2: %d seconds.\n", timer3);
			}
		}
			
	}
	while(!in_game);
	
		
	return 0;
}
Пример #10
0
void IPiece::resetPiece(Place *place)
{
    movePiece(place);
    isFirstMove = true;
}
Пример #11
0
/*
 * Executes a command given by the user
 *
 * @params: (command) - the command given by the user
 * @return: relevant exitcode
 */
int executeCommand(char* command){
	char str[64];
	sscanf(command, "%s", str);
	if (str_equals(str, "quit")){
		exit(0);
	}	
	if (state == SETTINGS){
		if (str_equals(str, "game_mode")){
			return setGameMode(command);
		}
		if (str_equals(str, "difficulty")){
			return setDifficulty(command);
		}
		if (str_equals(str, "user_color")){
			return setUserColor(command);
		}
		if (str_equals(str, "load")){
			return loadGameByCommand(command);
		}
		if (str_equals(str, "clear")){
			Board_clear(&board);
			PieceCounter_reset(counter);
			return 0;
		}
		if (str_equals(str, "next_player")){
			return setFirstPlayer(command);
		}
		if (str_equals(str, "rm")){
			return removePiece(command);
		}
		if (str_equals(str, "set")){
			return setPiece(command);
		}
		if (str_equals(str, "print")){
			display();
			return 0;
		}
		if (str_equals(str, "start")){
			if(PieceCounter_kingIsMissing(counter)){
				return -7;
			}	
			turn = first;
			state = GAME;
			return 2; //special value to break the humanTurn loop so the initial board will always be checked for immediate loss or tie conditions
		}
	}
	else{
		if (str_equals(str, "get_moves")){
			return printMovesOfPiece(command);
		}
		if (str_equals(str, "move")){
			return movePiece(command);
		}
		if (str_equals(str, "castle")){
			return castleRook(command);
		}
		if (str_equals(str, "get_best_moves")){
			return printBestMoves(command);
		}
		if (str_equals(str, "get_score")){
			return printMoveValue(command);
		}	
		if (str_equals(str,"save")){
			return saveGameByCommand(command);
		}
	}
	return -1;
}
Пример #12
0
// Undo a previously made move.
void unmove(board_t *b, const revMove_t m)
{

	piece_t pieceMoved;

	int to = m.move.to;
	int from = m.move.from;

	int priorCastleBits = m.priorCastleBits;
	int priorEnPassant = m.priorEnPassant;
	int priorZobristEnPassant = m.priorZobristEnPassantCol;
	int priorHalfMoveCount = m.priorHalfMoveCnt;

	piece_t promote = (piece_t)(m.move.promote);
	piece_t captured = (piece_t)(m.captured);

	color_t oppositeColor = (b->toMove == WHITE ? BLACK : WHITE);



	// STEP 1: Remove the piece at the destination square, return to source square...

	// SPECIAL CASE: A pawn was promoted.  Remove the promoted piece....
	if(promote != PIECE_NONE)
	{
		removePiece(b, to, promote, oppositeColor);
		addPiece(b, from, PAWN, oppositeColor);
		pieceMoved = PAWN;
	}
	else
	{
		// Determine which piece is there....
		pieceMoved = ( (b->pieces[PAWN]   & squareMask[to]) ? PAWN : (
					   (b->pieces[KNIGHT] & squareMask[to]) ? KNIGHT : (
					   (b->pieces[BISHOP] & squareMask[to]) ? BISHOP : (
					   (b->pieces[ROOK]   & squareMask[to]) ? ROOK : (
					   (b->pieces[QUEEN]  & squareMask[to]) ? QUEEN : KING)))));
		movePiece(b, to, from, pieceMoved, oppositeColor);
	}

	// STEP 2:  Return captured piece if any

	// If a piece was captured last turn
	if(captured != PIECE_NONE)
	{
		int offset = 0;

		// If it was captured on the enPassant square, assess an offset to where the piece will be returned.
		if( (to % 8 == priorEnPassant) && ( (to / 8) == (b->toMove == BLACK ? 2 : 5) ) )
		{
			offset = (oppositeColor == BLACK ? -8 : 8);
		}
		addPiece(b, to + offset, captured, b->toMove);
	}

	// STEP 3: Undo rook moves from any castles...
   // TODO CHESS960

	if(pieceMoved == KING)
	{
		if(abs(to-from) == 2)
		{
			if(to == C1)
			{
				movePiece(b, D1, A1, ROOK, WHITE);
			}
			else if(to == G1)
			{
				movePiece(b, F1, H1, ROOK, WHITE);
			}
			else if(to == C8)
			{
				movePiece(b, D8, A8, ROOK, BLACK);
			}
			else if(to == G8)
			{
				movePiece(b, F8, H8, ROOK, BLACK);
			}
			else
			{
				ASSERT(0);
			}
		}
	}

  // Revert castling status if necessary

	if( (priorCastleBits & WHITE_CASTLE_SHORT) != (b->castleBits & WHITE_CASTLE_SHORT) )
	{
		b->hash ^= Z_WHITE_SHORT_KEY;
	}
	if( (priorCastleBits & WHITE_CASTLE_LONG) != (b->castleBits & WHITE_CASTLE_LONG) )
	{
		b->hash ^= Z_WHITE_LONG_KEY;
	}
	if( (priorCastleBits & BLACK_CASTLE_SHORT) != (b->castleBits & BLACK_CASTLE_SHORT) )
	{
		b->hash ^= Z_BLACK_SHORT_KEY;
	}
	if( (priorCastleBits & BLACK_CASTLE_LONG) != (b->castleBits & BLACK_CASTLE_LONG) )
	{
		b->hash ^= Z_BLACK_LONG_KEY;
	}

	b->castleBits = priorCastleBits;

  // Revert enPassant row if necessary

	// If current doesn't match prior
    if(priorZobristEnPassant != b->zobristEnPassantCol)
    {
        if(priorZobristEnPassant != 8)
	    {
	        b->hash  ^= Z_ENPASSANT_COL_KEY(priorZobristEnPassant);
	    }

        if( b->zobristEnPassantCol != 8)
        {
	        b->hash  ^= Z_ENPASSANT_COL_KEY(b->zobristEnPassantCol);
        }
    }

	b->zobristEnPassantCol = priorZobristEnPassant;
	b->enPassantCol = priorEnPassant;

	if(b->toMove == WHITE)
	{
		b->toMove = BLACK;
		b->moveNumber--;
	}
	else
	{
		b->toMove = WHITE;
	}
	b->hash ^= Z_WHITE_TURN_KEY; // Either side to move will trigger this toggle.

	b->halfMoves = priorHalfMoveCount;

    positionIndex--;

    if(positionIndex < 0)
    {
        positionIndex = POSITION_HISTORY_SIZE - 1;
    }

}
Пример #13
0
// Move assumed valid for this board.
// Add/remove functions will ASSERT adds are to empty squares and removes have expected piece there...
// Castling moves assumed legal (if to/from square and piece moved match a castle for king), rook is also moved with king
revMove_t move(board_t *b, const move_t m)
{

	unsigned char to = m.to;
	unsigned char from = m.from;

	int offset = 0;

	revMove_t retValue;

	// A place holder for the side to move (saves repeated pointer access)
	color_t toMove = b->toMove;

	// A place to hold the "opposite color" calculation
	color_t oppositeColor = (toMove == WHITE ? BLACK : WHITE);

	// promotion piece (if any)
	piece_t promote = (piece_t)(m.promote);

	// handy marker for piece moved
	piece_t pieceMoved = ( (b->pieces[PAWN]   & squareMask[from]) ? PAWN : (
						   (b->pieces[KNIGHT] & squareMask[from]) ? KNIGHT : (
						   (b->pieces[BISHOP] & squareMask[from]) ? BISHOP : (
						   (b->pieces[ROOK]   & squareMask[from]) ? ROOK : (
						   (b->pieces[QUEEN]  & squareMask[from]) ? QUEEN : KING)))));



	// Test that side to move has proper value
	ASSERT( (toMove == WHITE) || (toMove == BLACK) );

	// Check that a piece of the side to move exists at the origin
	ASSERT( (b->colors[toMove] & squareMask[from]) != 0);




	// Prepare the return value...
	retValue.move.from    = from;
	retValue.move.to      = to;
	retValue.move.promote = promote;
	retValue.priorCastleBits = b->castleBits;
	retValue.priorEnPassant  = b->enPassantCol;
	retValue.priorHalfMoveCnt = b->halfMoves;
	retValue.priorZobristEnPassantCol = b->zobristEnPassantCol;

	retValue.captured = b->colors[oppositeColor] & squareMask[to] ?
							( (b->pieces[PAWN]   & squareMask[to]) ? PAWN : (
						     (b->pieces[KNIGHT] & squareMask[to]) ? KNIGHT : (
						     (b->pieces[BISHOP] & squareMask[to]) ? BISHOP : (
						     (b->pieces[ROOK]   & squareMask[to]) ? ROOK : QUEEN)))) : PIECE_NONE;

	// Check for capture enPassant...
	if( (pieceMoved == PAWN)       &&  // moved a pawn
	    ( (to % 8) != (from % 8) ) &&  // to and from files are different
	    ( (squareMask[to] & b->colors[oppositeColor]) == 0) // target square doesn't have enemy piece
	  )
	{
		offset = (toMove == WHITE ? 8 : -8);
		retValue.captured = PAWN;
	}

	// First remove any captured piece from the board
	if(retValue.captured != PIECE_NONE)
	{
		removePiece(b, to + offset, retValue.captured, oppositeColor );
	}

	if(promote == PIECE_NONE)
	{
		// Simply move the piece back
		movePiece(b, from, to, pieceMoved, toMove);
	}
	else
	{
		ASSERT( ( ( (to < 8) && toMove) == WHITE) || ( (to > 55) && toMove == BLACK ) );

		ASSERT( pieceMoved == PAWN);

		// Remove pawn
		removePiece(b, from, pieceMoved, toMove);

		// Add promoted piece
		addPiece(b, to, promote, toMove);

	}

	// If this was a castling move, move the rook too...
	if(pieceMoved == KING)
	{
		if(from == E1)
		{
			if(to == C1)
			{
				movePiece(b, A1, D1, ROOK, toMove);
			}
			else if(to == G1)
			{
				movePiece(b, H1, F1, ROOK, toMove);
			}
		}
		else if(from == E8)
		{
			if(to == C8)
			{
				movePiece(b, A8, D8, ROOK, toMove);
			}
			else if(to == G8)
			{
				movePiece(b, H8, F8, ROOK, toMove);
			}
		}
	}

   // TODO CHESS960
	// Adjust Castling possibilities if needed
	if( pieceMoved == KING )
	{
		if( toMove == WHITE)
		{
			if(b->castleBits & WHITE_CASTLE_LONG)
			{
				b->hash ^= Z_WHITE_LONG_KEY;
			}
			if(b->castleBits & WHITE_CASTLE_SHORT)
			{
				b->hash ^= Z_WHITE_SHORT_KEY;
			}
			b->castleBits &= ~(WHITE_CASTLE_LONG | WHITE_CASTLE_SHORT);
		}
		else
		{
			if(b->castleBits & BLACK_CASTLE_LONG)
			{
				b->hash ^= Z_BLACK_LONG_KEY;
			}
			if(b->castleBits & BLACK_CASTLE_SHORT)
			{
				b->hash ^= Z_BLACK_SHORT_KEY;
			}
			b->castleBits &= ~(BLACK_CASTLE_LONG | BLACK_CASTLE_SHORT);
		}
	}

	if( pieceMoved == ROOK )
	{
		if(from == A1 && b->castleBits & WHITE_CASTLE_LONG)
		{
			b->hash ^= Z_WHITE_LONG_KEY;
			b->castleBits &= ~WHITE_CASTLE_LONG;
		}
		else if (from == H1 && b->castleBits & WHITE_CASTLE_SHORT)
		{
			b->hash ^= Z_WHITE_SHORT_KEY;
			b->castleBits &= ~WHITE_CASTLE_SHORT;
		}
		else if(from == A8 && b->castleBits & BLACK_CASTLE_LONG)
		{
			b->hash ^= Z_BLACK_LONG_KEY;
			b->castleBits &= ~BLACK_CASTLE_LONG;
		}
		else if (from == H8 && b->castleBits & BLACK_CASTLE_SHORT)
		{
			b->hash ^= Z_BLACK_SHORT_KEY;
			b->castleBits &= ~BLACK_CASTLE_SHORT;
		}
	}

	// If a rook was captured, that affects castling too...
	if( retValue.captured == ROOK)
	{
		if( (to == A1) &&  (b->castleBits & WHITE_CASTLE_LONG) )
		{
			b->hash ^= Z_WHITE_LONG_KEY;
			b->castleBits &= ~WHITE_CASTLE_LONG;
		}
		else if( (to == H1) &&  (b->castleBits & WHITE_CASTLE_SHORT) )
		{
			b->hash ^= Z_WHITE_SHORT_KEY;
			b->castleBits &= ~WHITE_CASTLE_SHORT;
		}
		else if( (to == A8) &&  (b->castleBits & BLACK_CASTLE_LONG) )
		{
			b->hash ^= Z_BLACK_LONG_KEY;
			b->castleBits &= ~BLACK_CASTLE_LONG;
		}
		else if( (to == H8) &&  (b->castleBits & BLACK_CASTLE_SHORT) )
		{
			b->hash ^= Z_BLACK_SHORT_KEY;
			b->castleBits &= ~BLACK_CASTLE_SHORT;
		}
	}

	// Adjust halfmove count
	if( (pieceMoved == PAWN) || (retValue.captured != PIECE_NONE) )
	{
		b->halfMoves = 0;
	}
	else
	{
		b->halfMoves++;
	}

	// Adjust move number if black just moved
	if(toMove == BLACK)
	{
		b->moveNumber++;
	}

	// Adjust side to move
	b->toMove = oppositeColor;
	b->hash ^= Z_WHITE_TURN_KEY; // Either side to move will trigger this toggle.

	// Adjust enPassant col if we moved a pawn forward two

	if ( (pieceMoved == PAWN) && (abs(from - to) == 16) )
	{
		b->enPassantCol = to & 0x07;
		if( (shiftE(squareMask[to]) & b->pieces[PAWN] & b->colors[oppositeColor]) ||
		    (shiftW(squareMask[to]) & b->pieces[PAWN] & b->colors[oppositeColor]))
		{
		    b->zobristEnPassantCol = to & 0x07;
		}
		else
		{
		    b->zobristEnPassantCol = 8;
		}
	}
	else
	{
		b->enPassantCol = 8;
	    b->zobristEnPassantCol = 8;
	}

    if(retValue.priorZobristEnPassantCol != b->zobristEnPassantCol)
    {

        if(retValue.priorZobristEnPassantCol != 8)
	    {
	        b->hash  ^= Z_ENPASSANT_COL_KEY(retValue.priorZobristEnPassantCol);
	    }

        if( b->zobristEnPassantCol != 8)
        {
	        b->hash  ^= Z_ENPASSANT_COL_KEY(b->zobristEnPassantCol);
        }

    }

    ASSERT(positionIndex < POSITION_HISTORY_SIZE);
    ASSERT(positionIndex >= 0);


	positionHistory[positionIndex++] = b->hash;

	if(positionIndex == POSITION_HISTORY_SIZE)
	{
	    positionIndex = 0;
	}

	return retValue;
}
Пример #14
0
TEST_F(GameLogicTests, ShouldFinishByDraw)
{
    Array defaultArray = createArray10x10({{o,WQ, o, o, o, o, o, o, o, o}
                                          ,{o, o, o, o, o, o, o, o, o, o}
                                          ,{o, o, o, o, o, o, o, o, o, o}
                                          ,{o, o, o, o, o, o, o, o, o, o}
                                          ,{o, o, o, o, o, o, o, o, o, o}
                                          ,{o, o, o, o, o, o, o, o, o, o}
                                          ,{o, o, o, o, o, o, o, o, o, o}
                                          ,{o, o, o, o, o, o, o, o, o, o}
                                          ,{o, o, o, o, o, o, o, o, o, o}
                                          ,{o, o, o, o, o,BQ, o, o, o, o}});

    auto game = createAndStartGame(defaultArray, Table::TableVersion::Version_100, PieceColor::White);

    Array array2 = createArray10x10({{o, o, o, o, o, o, o, o, o, o}
                                    ,{o, o,WQ, o, o, o, o, o, o, o}
                                    ,{o, o, o, o, o, o, o, o, o, o}
                                    ,{o, o, o, o, o, o, o, o, o, o}
                                    ,{o, o, o, o, o, o, o, o, o, o}
                                    ,{o, o, o, o, o, o, o, o, o, o}
                                    ,{o, o, o, o, o, o, o, o, o, o}
                                    ,{o, o, o, o, o, o, o, o, o, o}
                                    ,{o, o, o, o, o, o, o, o, o, o}
                                    ,{o, o, o, o, o,BQ, o, o, o, o}});

    EXPECT_NO_FATAL_FAILURE(movePiece(game, Position(0,1), {Position(1,2)}, array2, PieceColor::White, PieceColor::Black));

    Array array3 = createArray10x10({{o, o, o, o, o, o, o, o, o, o}
                                    ,{o, o, WQ, o, o, o, o, o, o, o}
                                    ,{o, o, o, o, o, o, o, o, o, o}
                                    ,{o, o, o, o, o, o, o, o, o, o}
                                    ,{o, o, o, o, o, o, o, o, o, o}
                                    ,{o, o, o, o, o, o, o, o, o, o}
                                    ,{o, o, o, o, o, o, o, o, o, o}
                                    ,{o, o, o, o, o, o, o, o, o, o}
                                    ,{o, o, o, o, BQ, o, o, o, o, o}
                                    ,{o, o, o, o, o, o, o, o, o, o}});

    EXPECT_NO_FATAL_FAILURE(movePiece(game, Position(9,5), {Position(8,4)}, array3, PieceColor::Black, PieceColor::White));

    Array array4 = createArray10x10({{o, WQ, o, o, o, o, o, o, o, o}
                                    ,{o, o, o, o, o, o, o, o, o, o}
                                    ,{o, o, o, o, o, o, o, o, o, o}
                                    ,{o, o, o, o, o, o, o, o, o, o}
                                    ,{o, o, o, o, o, o, o, o, o, o}
                                    ,{o, o, o, o, o, o, o, o, o, o}
                                    ,{o, o, o, o, o, o, o, o, o, o}
                                    ,{o, o, o, o, o, o, o, o, o, o}
                                    ,{o, o, o, o,BQ, o, o, o, o, o}
                                    ,{o, o, o, o, o, o, o, o, o, o}});

    EXPECT_NO_FATAL_FAILURE(movePiece(game, Position(1,2), {Position(0,1)}, array4, PieceColor::White, PieceColor::Black));

    Array array5 = createArray10x10({{o, WQ, o, o, o, o, o, o, o, o}
                                    ,{o, o, o, o, o, o, o, o, o, o}
                                    ,{o, o, o, o, o, o, o, o, o, o}
                                    ,{o, o, o, o, o, o, o, o, o, o}
                                    ,{o, o, o, o, o, o, o, o, o, o}
                                    ,{o, o, o, o, o, o, o, o, o, o}
                                    ,{o, o, o, o, o, o, o, o, o, o}
                                    ,{o, o, o, o, o, o, o, o, o, o}
                                    ,{o, o, o, o, o, o, o, o, o, o}
                                    ,{o, o, o, o, o,BQ, o, o, o, o}});

    EXPECT_NO_FATAL_FAILURE(movePiece(game, Position(8,4), {Position(9,5)}, array5, PieceColor::Black, PieceColor::White));

    Array array6 = createArray10x10({{o, o, o, o, o, o, o, o, o, o}
                                    ,{o, o, WQ, o, o, o, o, o, o, o}
                                    ,{o, o, o, o, o, o, o, o, o, o}
                                    ,{o, o, o, o, o, o, o, o, o, o}
                                    ,{o, o, o, o, o, o, o, o, o, o}
                                    ,{o, o, o, o, o, o, o, o, o, o}
                                    ,{o, o, o, o, o, o, o, o, o, o}
                                    ,{o, o, o, o, o, o, o, o, o, o}
                                    ,{o, o, o, o, o, o, o, o, o, o}
                                    ,{o, o, o, o, o,BQ, o, o, o, o}});

    EXPECT_NO_FATAL_FAILURE(movePiece(game, Position(0,1), {Position(1,2)}, array6, PieceColor::White, PieceColor::Black));

    Array array7 = createArray10x10({{o, o, o, o, o, o, o, o, o, o}
                                    ,{o, o, WQ, o, o, o, o, o, o, o}
                                    ,{o, o, o, o, o, o, o, o, o, o}
                                    ,{o, o, o, o, o, o, o, o, o, o}
                                    ,{o, o, o, o, o, o, o, o, o, o}
                                    ,{o, o, o, o, o, o, o, o, o, o}
                                    ,{o, o, o, o, o, o, o, o, o, o}
                                    ,{o, o, o, o, o, o, o, o, o, o}
                                    ,{o, o, o, o, BQ, o, o, o, o, o}
                                    ,{o, o, o, o, o, o, o, o, o, o}});

    EXPECT_NO_FATAL_FAILURE(movePiece(game, Position(9,5), {Position(8,4)}, array7, PieceColor::Black, PieceColor::White));

    Array array8 = createArray10x10({{o, WQ, o, o, o, o, o, o, o, o}
                                    ,{o, o, o, o, o, o, o, o, o, o}
                                    ,{o, o, o, o, o, o, o, o, o, o}
                                    ,{o, o, o, o, o, o, o, o, o, o}
                                    ,{o, o, o, o, o, o, o, o, o, o}
                                    ,{o, o, o, o, o, o, o, o, o, o}
                                    ,{o, o, o, o, o, o, o, o, o, o}
                                    ,{o, o, o, o, o, o, o, o, o, o}
                                    ,{o, o, o, o,BQ, o, o, o, o, o}
                                    ,{o, o, o, o, o, o, o, o, o, o}});

    EXPECT_NO_FATAL_FAILURE(movePiece(game, Position(1,2), {Position(0,1)}, array8, PieceColor::White, PieceColor::Black));

    Array array9 = createArray10x10({{o, WQ, o, o, o, o, o, o, o, o}
                                    ,{o, o, o, o, o, o, o, o, o, o}
                                    ,{o, o, o, o, o, o, o, o, o, o}
                                    ,{o, o, o, o, o, o, o, o, o, o}
                                    ,{o, o, o, o, o, o, o, o, o, o}
                                    ,{o, o, o, o, o, o, o, o, o, o}
                                    ,{o, o, o, o, o, o, o, o, o, o}
                                    ,{o, o, o, o, o, o, o, o, o, o}
                                    ,{o, o, o, o, o, o, o, o, o, o}
                                    ,{o, o, o, o, o,BQ, o, o, o, o}});

    EXPECT_NO_FATAL_FAILURE(movePiece(game, Position(8,4), {Position(9,5)}, array9, PieceColor::Black, PieceColor::White));

    Array array10 = createArray10x10({{o, o, o, o, o, o, o, o, o, o}
                                    ,{o, o, WQ, o, o, o, o, o, o, o}
                                    ,{o, o, o, o, o, o, o, o, o, o}
                                    ,{o, o, o, o, o, o, o, o, o, o}
                                    ,{o, o, o, o, o, o, o, o, o, o}
                                    ,{o, o, o, o, o, o, o, o, o, o}
                                    ,{o, o, o, o, o, o, o, o, o, o}
                                    ,{o, o, o, o, o, o, o, o, o, o}
                                    ,{o, o, o, o, o, o, o, o, o, o}
                                    ,{o, o, o, o, o,BQ, o, o, o, o}});

    EXPECT_NO_FATAL_FAILURE(movePiece(game, Position(0,1), {Position(1,2)}, array10, PieceColor::White, PieceColor::Black));

    Array array11 = createArray10x10({{o, o, o, o, o, o, o, o, o, o}
                                    ,{o, o, WQ, o, o, o, o, o, o, o}
                                    ,{o, o, o, o, o, o, o, o, o, o}
                                    ,{o, o, o, o, o, o, o, o, o, o}
                                    ,{o, o, o, o, o, o, o, o, o, o}
                                    ,{o, o, o, o, o, o, o, o, o, o}
                                    ,{o, o, o, o, o, o, o, o, o, o}
                                    ,{o, o, o, o, o, o, o, o, o, o}
                                    ,{o, o, o, o, BQ, o, o, o, o, o}
                                    ,{o, o, o, o, o, o, o, o, o, o}});

    EXPECT_NO_FATAL_FAILURE(movePiece(game, Position(9,5), {Position(8,4)}, array11, PieceColor::Black, PieceColor::White));

    Array array12 = createArray10x10({{o, WQ, o, o, o, o, o, o, o, o}
                                    ,{o, o, o, o, o, o, o, o, o, o}
                                    ,{o, o, o, o, o, o, o, o, o, o}
                                    ,{o, o, o, o, o, o, o, o, o, o}
                                    ,{o, o, o, o, o, o, o, o, o, o}
                                    ,{o, o, o, o, o, o, o, o, o, o}
                                    ,{o, o, o, o, o, o, o, o, o, o}
                                    ,{o, o, o, o, o, o, o, o, o, o}
                                    ,{o, o, o, o,BQ, o, o, o, o, o}
                                    ,{o, o, o, o, o, o, o, o, o, o}});

    EXPECT_NO_FATAL_FAILURE(movePiece(game, Position(1,2), {Position(0,1)}, array12, PieceColor::White, PieceColor::Black));

    Array array13 = createArray10x10({{o, WQ, o, o, o, o, o, o, o, o}
                                    ,{o, o, o, o, o, o, o, o, o, o}
                                    ,{o, o, o, o, o, o, o, o, o, o}
                                    ,{o, o, o, o, o, o, o, o, o, o}
                                    ,{o, o, o, o, o, o, o, o, o, o}
                                    ,{o, o, o, o, o, o, o, o, o, o}
                                    ,{o, o, o, o, o, o, o, o, o, o}
                                    ,{o, o, o, o, o, o, o, o, o, o}
                                    ,{o, o, o, o, o, o, o, o, o, o}
                                    ,{o, o, o, o, o,BQ, o, o, o, o}});

    EXPECT_NO_FATAL_FAILURE(movePiece(game, Position(8,4), {Position(9,5)}, array13, PieceColor::Black, PieceColor::White));

    Array array14 = createArray10x10({{o, o, o, o, o, o, o, o, o, o}
                                    ,{o, o, WQ, o, o, o, o, o, o, o}
                                    ,{o, o, o, o, o, o, o, o, o, o}
                                    ,{o, o, o, o, o, o, o, o, o, o}
                                    ,{o, o, o, o, o, o, o, o, o, o}
                                    ,{o, o, o, o, o, o, o, o, o, o}
                                    ,{o, o, o, o, o, o, o, o, o, o}
                                    ,{o, o, o, o, o, o, o, o, o, o}
                                    ,{o, o, o, o, o, o, o, o, o, o}
                                    ,{o, o, o, o, o,BQ, o, o, o, o}});

    EXPECT_NO_FATAL_FAILURE(movePiece(game, Position(0,1), {Position(1,2)}, array14, PieceColor::White, PieceColor::Black));

    Array array15 = createArray10x10({{o, o, o, o, o, o, o, o, o, o}
                                     ,{o, o,WQ, o, o, o, o, o, o, o}
                                     ,{o, o, o, o, o, o, o, o, o, o}
                                     ,{o, o, o, o, o, o, o, o, o, o}
                                     ,{o, o, o, o, o, o, o, o, o, o}
                                     ,{o, o, o, o, o, o, o, o, o, o}
                                     ,{o, o, o, o, o, o, o, o, o, o}
                                     ,{o, o, o, o, o, o, o, o, o, o}
                                     ,{o, o, o, o,BQ, o, o, o, o, o}
                                     ,{o, o, o, o, o, o, o, o, o, o}});


    EXPECT_CALL(*uiMock, onDraw());
    EXPECT_CALL(*uiMock, tableChanged(MatchArray(array15)));

    EXPECT_CALL(*uiMock, movePerformed(Position(9,5), std::vector<Position>{Position(8,4)}));
    game->movePiece(Position(9,5), {Position(8,4)}, PieceColor::Black);
}
Пример #15
0
void AIBestPlayer::requestMove(PieceColor moveType)
{
    assert(m_array);
    auto gameLogic = m_gameLogic.lock();


    std::vector<int> scores;
    auto lockedGameLogic = m_gameLogic.lock();
    std::vector<PieceMove> moves = lockedGameLogic->getAllPossibleMoves(*m_array, moveType);

    std::experimental::optional<std::pair<std::vector<Position>, int>> foundMove = bestMoves::findMove(*m_array, moveType);

    if(!foundMove || (foundMove && foundMove->second < m_maxDepth))
    {
        std::cout << "computation of best move" << std::endl;
        std::vector<std::future<int>> futures;
        for(const auto& move: moves)
        {
            Array copyOfArray = *m_array;
            copyOfArray.move(move.source().m_row, move.source().m_col, move.destination().m_row, move.destination().m_col);
            for(const auto& pos: move.capturedPieces())
            {
                copyOfArray.erase(pos.m_row, pos.m_col);
            }

            int newScore = move.numberOfCapturedPieces();

            auto score = std::async(std::launch::async,
                                    &minMaxWithAlphaBetaPruning,
                                    lockedGameLogic,
                                    copyOfArray,
                                    m_maxDepth,
                                    newScore,
                                    getOppositeColor(moveType),
                                    moveType,
                                    gMinusInfinity,
                                    gPlusInfinity);
            futures.push_back(std::move(score));
        }

        for(auto& future: futures)
        {
            auto result = future.get();
            scores.push_back(result);
        }

        auto it = std::max_element(scores.begin(), scores.end());

        PieceMove move = moves.at(std::distance(scores.begin(), it));
        std::vector<Position> subMoves{move.subMoves().begin()+1, move.subMoves().end()};
        lockedGameLogic->movePiece(move.source(), subMoves, moveType);
    }
    else
    {
        std::vector<Position>& positions = foundMove->first;
        for(const auto& move: moves)
        {
            if(positions == move.subMoves())
            {
                std::cout << "used saved best move" << std::endl;
                std::vector<Position> subMoves{move.subMoves().begin()+1, move.subMoves().end()};
                lockedGameLogic->movePiece(move.source(), subMoves, moveType);
            }
        }
    }
}