/** When a target square is clicked, this event is prompted
*  (it is attached to every enabled target square button's onClick).
*	We execute the given move for the selected chess piece and clicked target using the
*	logic layer and mark them as possible targets on board.
*/
void onTargetClick(GuiButton* button)
{
	// Each target button caches a game square in its extent, so it can access the logic layer
	GameSquare* gameSquare = (GameSquare*)button->generalProperties.extent;

	if (NULL == gameSquare)
		return; // Avoid null extents

	GameControl* gameControl = gameSquare->gameControl;
	int guiStartX = boardRowIndexToGuiRowIndex(gameControl->selectedSquare->x);
	int guiTargetX = boardRowIndexToGuiRowIndex(gameSquare->x);

	// Build the move
	// Make sure to abort clicks on illegal moves
	Position initPos = { guiStartX, gameControl->selectedSquare->y };
	Position nextPos = { guiTargetX, gameSquare->y };
	Move* move = createMove(&initPos, &nextPos);
	if ((g_memError) || (NULL == move))
		return;

	// If a pawn have reached the other edge, we have a promotion move.
	// Show the promotion dialog and wait for results.
	// Since this event can only be prompted by a player, we can count on the isBlackPlayerEditable property
	if (isSquareOnOppositeEdge(gameControl->isBlackPlayerEditable, nextPos.x) &&
		isSquareOccupiedByPawn(gameControl->board, gameControl->isBlackPlayerEditable, initPos.x, initPos.y))
	{
		move->promotion = showPromotionDialog(button->generalProperties.window, gameControl->isBlackPlayerEditable);
	}

	// Black king is an error value of showPromotionDialog (this is an invalid promotion). We quit on errors.
	if (g_guiError || g_memError || (move->promotion == BLACK_K))
	{
		deleteMove(move);
		return;
	}

	// Validate the move is legal
	bool isValidMove = validateMove(gameControl->board, gameControl->isBlackPlayerEditable, move);
	if (!isValidMove)
	{
		printf("Error: Gui allowed user to interact with illegal move, but logic protected from executing this move.\n");
		deleteMove(move);
		return;
	}

	GuiWindow* window = (GuiWindow*)button->generalProperties.window;

	// Execute the move and update the gui. If the game is over, return.
	bool isGameOver = executeGuiTurn(window, gameControl, move);
	if (isGameOver)
		return;

	// When playing against the AI, execute the next turn
	if (g_gameMode == GAME_MODE_PLAYER_VS_AI)
		executeGuiNextComputerMove(window);
}
Exemple #2
0
/* Adds a move to a move list, after verifying it's legality */
void addMove(Board *brd, int from, int to, int cap, int prom, char castling, MoveList *list) {

    Move move;

    move = createMove(brd, from, to, cap, prom, castling);
    if (move.from != 0) {
        list->moves[list->numMoves] = move;
        list->numMoves++;
    }

}
Exemple #3
0
Move* parseMove(char* moveString) {
	char initialPosition[7];
	bool isDoubleDigits = moveString[4] != '>';
	if (isDoubleDigits) {
		strncpy(initialPosition, moveString, 6);
		initialPosition[6] = '\0';
	} else {
		strncpy(initialPosition, moveString, 5);
		initialPosition[5] = '\0';
	}	
	Position from = parsePosition(initialPosition);
	int lengthToSkip = isDoubleDigits ? 10 : 9;//<x,y>_to_
	PositionList* to = parseDestination(moveString + lengthToSkip);
	return createMove(from, to, NULL, 0);
}
Exemple #4
0
int createMoveFromString(char moveStr[], int fromType, int capture, int moveType2){
	assert(isMoveString(moveStr));
	char fromSquare[3], toSquare[3];
	fromSquare[0]= moveStr[0];
	fromSquare[1]= moveStr[1];
	fromSquare[2]= '\0';

	toSquare[0]= moveStr[2];
	toSquare[1]= moveStr[3];
	toSquare[2]= '\0';

	int fromIndex=getIndexFromSquare(fromSquare);
	int toIndex= getIndexFromSquare(toSquare);

	return createMove(fromType, fromIndex, toIndex, capture, moveType2, 0);
}
Exemple #5
0
/*
 * Add an available move for the player to the list of moves.
 * - Move is expected to be valid in terms of piece type constraints (e.g: a peon can only move to 3 possible squares).
 * - Additional validation will be done in this function (moves that result in a check status for the current player are
 *	 illegal).
 * --> If the move is legal, it is added to the list of possibleMoves. Otherwise nothing happens.
 * Input:
 *		board ~ The chess game board.
 *		possibleMoves ~ A list of possible moves by the current player, we aggregate it as we check
 *						possible eat / position change moves.
 *		isMovesForBlackPlayer ~ True if current player is black. False if white.
 *		startPos ~ Where the piece is currently located.
 *		targetX, targetY ~ Coordinates of where the piece will move to.
 *		kingPos ~ Current position of the current player's king (following the execution of the move).
 */
bool addPossibleMove(char board[BOARD_SIZE][BOARD_SIZE], LinkedList* possibleMoves, bool isMovesForBlackPlayer,
					 Position* startPos, int targetX, int targetY, Position* kingPos)
{
	// Check if the move doesn't cause the current player a check. If it does, we don't count it.
	if (!isValidMove(board, isMovesForBlackPlayer, startPos, targetX, targetY, kingPos))
		return false;

	Position targetPos = { targetX, targetY };

	Move* newMove = createMove(startPos, &targetPos);
	if (g_memError)
		return false;

	insertLast(possibleMoves, newMove);
	if (g_memError)
	{
		deleteMove((void*)newMove);
		return false;
	}

	return true;
}
Exemple #6
0
struct Moves* KingMoves(int x, int y, char some_board[BOARD_SIZE][BOARD_SIZE]){
	struct Moves* moves = calloc(1, sizeof(struct Moves));
	movesLeaks++;
	struct Move* move;
	if (isWhite(some_board[x][y])){ // white king eats piece ( or moves to an empty spot )
		if (x + 1 <= 7){
			if (y + 1 <= 7 && (isBlack(some_board[x + 1][y + 1]) || some_board[x + 1][y + 1] == EMPTY)){
				move = createMove(x, y, x + 1, y + 1, some_board, NULL);
				addMoveToMovesList(move, moves);
			}
			if (isBlack(some_board[x + 1][y]) || some_board[x + 1][y] == EMPTY){
				move = createMove(x, y, x + 1, y, some_board, NULL);
				addMoveToMovesList(move, moves);
			}
			if (y - 1 >= 0 && (isBlack(some_board[x + 1][y - 1]) || some_board[x + 1][y - 1] == EMPTY)){
				move = createMove(x, y, x + 1, y - 1, some_board, NULL);
				addMoveToMovesList(move, moves);
			}
		}
		if (y - 1 >= 0 && (isBlack(some_board[x][y - 1]) || some_board[x][y - 1] == EMPTY)){
			move = createMove(x, y, x, y - 1, some_board, NULL);
			addMoveToMovesList(move, moves);
		}
		if (y + 1 <= 7 && (isBlack(some_board[x][y + 1]) || some_board[x][y + 1] == EMPTY)){
			move = createMove(x, y, x, y + 1, some_board, NULL);
			addMoveToMovesList(move, moves);
		}
		if (x - 1 >= 0){
			if (y + 1 <= 7 && (isBlack(some_board[x - 1][y + 1]) || some_board[x - 1][y + 1] == EMPTY)){
				move = createMove(x, y, x - 1, y + 1, some_board, NULL);
				addMoveToMovesList(move, moves);
			}
			if (isBlack(some_board[x - 1][y]) || some_board[x - 1][y] == EMPTY){
				move = createMove(x, y, x - 1, y, some_board, NULL);
				addMoveToMovesList(move, moves);
			}
			if (y - 1 >= 0 && (isBlack(some_board[x - 1][y - 1]) || some_board[x - 1][y - 1] == EMPTY)){
				move = createMove(x, y, x - 1, y - 1, some_board, NULL);
				addMoveToMovesList(move, moves);
			}
		}
	}
	else{ // black king eats piece ( or moves to an empty spot )
		if (x + 1 <= 7){
			if (y + 1 <= 7 && (isWhite(some_board[x + 1][y + 1]) || some_board[x + 1][y + 1] == EMPTY)){
				move = createMove(x, y, x + 1, y + 1, some_board, NULL);
				addMoveToMovesList(move, moves);
			}
			if (isWhite(some_board[x + 1][y]) || some_board[x + 1][y] == EMPTY){
				move = createMove(x, y, x + 1, y, some_board, NULL);
				addMoveToMovesList(move, moves);
			}
			if (y - 1 >= 0 && (isWhite(some_board[x + 1][y - 1]) || some_board[x + 1][y - 1] == EMPTY)){
				move = createMove(x, y, x + 1, y - 1, some_board, NULL);
				addMoveToMovesList(move, moves);
			}
		}
		if (y - 1 >= 0 && (isWhite(some_board[x][y - 1]) || some_board[x][y - 1] == EMPTY)){
			move = createMove(x, y, x, y - 1, some_board, NULL);
			addMoveToMovesList(move, moves);
		}
		if (y + 1 <= 7 && (isWhite(some_board[x][y + 1]) || some_board[x][y + 1] == EMPTY)){
			move = createMove(x, y, x, y + 1, some_board, NULL);
			addMoveToMovesList(move, moves);
		}
		if (x - 1 >= 0){
			if (y + 1 <= 7 && (isWhite(some_board[x - 1][y + 1]) || some_board[x - 1][y + 1] == EMPTY)){
				move = createMove(x, y, x - 1, y + 1, some_board, NULL);
				addMoveToMovesList(move, moves);
			}
			if (isWhite(some_board[x - 1][y]) || some_board[x - 1][y] == EMPTY){
				move = createMove(x, y, x - 1, y, some_board, NULL);
				addMoveToMovesList(move, moves);
			}
			if (y - 1 >= 0 && (isWhite(some_board[x - 1][y - 1]) || some_board[x - 1][y - 1] == EMPTY)){
				move = createMove(x, y, x - 1, y - 1, some_board, NULL);
				addMoveToMovesList(move, moves);
			}
		}
	}
	return moves;
}
Exemple #7
0
struct Moves* KnightMoves(int x, int y, char some_board[BOARD_SIZE][BOARD_SIZE]){
	struct Moves* moves = calloc(1, sizeof(struct Moves));
	movesLeaks++;
	struct Move* move;
	if (isWhite(some_board[x][y])){ // knight piece is white
		if (x - 2 >= 0){
			if (y - 1 >= 0 && (isBlack(some_board[x - 2][y - 1]) || some_board[x - 2][y - 1] == EMPTY)){
				move = createMove(x, y, x - 2, y - 1, some_board, NULL);
				addMoveToMovesList(move, moves);
				free(move);
				moveLeaks--;
			}
			if (y + 1 <= 7 && (isBlack(some_board[x - 2][y + 1]) || some_board[x - 2][y + 1] == EMPTY)){
				move = createMove(x, y, x - 2, y + 1, some_board, NULL);
				addMoveToMovesList(move, moves);
				free(move);
				moveLeaks--;
			}
		}
		if (x +2 <= 7){
			if (y - 1 >= 0 && (isBlack(some_board[x + 2][y - 1]) || some_board[x - 2][y - 1] == EMPTY)){
				move = createMove(x, y, x + 2, y - 1, some_board, NULL);
				addMoveToMovesList(move, moves);
				free(move);
				moveLeaks--;
			}
			if (y + 1 <= 7 && (isBlack(some_board[x + 2][y + 1]) || some_board[x - 2][y + 1] == EMPTY)){
				move = createMove(x, y, x + 2, y + 1, some_board, NULL);
				addMoveToMovesList(move, moves);
				free(move);
				moveLeaks--;
			}
		}
		if (y + 2 <= 7){
			if (x - 1 >= 0 && (isBlack(some_board[x - 1][y + 2]) || some_board[x - 1][y + 2] == EMPTY)){
				move = createMove(x, y, x - 1, y + 2, some_board, NULL);
				addMoveToMovesList(move, moves);
				free(move);
				moveLeaks--;
			}
			if (x + 1 <= 7 && (isBlack(some_board[x + 1][y + 2]) || some_board[x + 1][y + 2] == EMPTY)){
				move = createMove(x, y, x + 1, y + 2, some_board, NULL);
				addMoveToMovesList(move, moves);
				free(move);
				moveLeaks--;
			}
		}
		if (y - 2 >=0){
			if (x - 1 >= 0 && (isBlack(some_board[x - 1][y - 2]) || some_board[x - 1][y - 2] == EMPTY)){
				move = createMove(x, y, x - 1, y - 2, some_board, NULL);
				addMoveToMovesList(move, moves);
				free(move);
				moveLeaks--;
			}
			if (x + 1 <= 7 && (isBlack(some_board[x + 1][y - 2]) || some_board[x + 1][y - 2] == EMPTY)){
				move = createMove(x, y, x + 1, y - 2, some_board, NULL);
				addMoveToMovesList(move, moves);
				free(move);
				moveLeaks--;
			}
		}
	}
	else{ // knight piece is black
		if (x - 2 >= 0){
			if (y - 1 >= 0 && (isWhite(some_board[x - 2][y - 1]) || some_board[x - 2][y - 1] == EMPTY)){
				move = createMove(x, y, x - 2, y - 1, some_board, NULL);
				addMoveToMovesList(move, moves);
			}
			if (y + 1 <= 7 && (isWhite(some_board[x - 2][y + 1]) || some_board[x - 2][y + 1] == EMPTY)){
				move = createMove(x, y, x - 2, y + 1, some_board, NULL);
				addMoveToMovesList(move, moves);
			}
		}
		if (x + 2 <= 7){
			if (y - 1 >= 0 && (isWhite(some_board[x + 2][y - 1]) || some_board[x - 2][y - 1] == EMPTY)){
				move = createMove(x, y, x + 2, y - 1, some_board, NULL);
				addMoveToMovesList(move, moves);
			}
			if (y + 1 <= 7 && (isWhite(some_board[x + 2][y + 1]) || some_board[x - 2][y + 1] == EMPTY)){
				move = createMove(x, y, x + 2, y + 1, some_board, NULL);
				addMoveToMovesList(move, moves);
			}
		}
		if (y + 2 <= 7){
			if (x - 1 >= 0 && (isWhite(some_board[x - 1][y + 2]) || some_board[x - 1][y + 2] == EMPTY)){
				move = createMove(x, y, x - 1, y + 2, some_board, NULL);
				addMoveToMovesList(move, moves);
			}
			if (x + 1 <= 7 && (isWhite(some_board[x + 1][y + 2]) || some_board[x + 1][y + 2] == EMPTY)){
				move = createMove(x, y, x + 1, y + 2, some_board, NULL);
				addMoveToMovesList(move, moves);
			}
		}
		if (y - 2 >= 0){
			if (x - 1 >= 0 && (isWhite(some_board[x - 1][y - 2]) || some_board[x - 1][y - 2] == EMPTY)){
				move = createMove(x, y, x - 1, y - 2, some_board, NULL);
				addMoveToMovesList(move, moves);
			}
			if (x + 1 <= 7 && (isWhite(some_board[x + 1][y - 2]) || some_board[x + 1][y - 2] == EMPTY)){
				move = createMove(x, y, x + 1, y - 2, some_board, NULL);
				addMoveToMovesList(move, moves);
			}
		}
	}
	return moves;
}
Exemple #8
0
struct Moves* RookMoves(int x, int y, char some_board[BOARD_SIZE][BOARD_SIZE]){
	struct Moves* moves = calloc(1, sizeof(struct Moves));
	movesLeaks++;
	struct Move* move;
	int i, j;
	// check if can eat up
	i = x;
	j = y + 1;
	while (j <= 7){
		if (some_board[i][j] != EMPTY)
			break;
		else{
			move = createMove(x, y, i, j, some_board, NULL);  // add step to an empty spot on board
			addMoveToMovesList(move, moves);
		}
		j++;
	}
	if (isWhite(some_board[x][y]) &&  j <= 7 && isBlack(some_board[i][j])){ // white rook eats black piece
		move = createMove(x, y, i, j, some_board, NULL);
		addMoveToMovesList(move, moves);
	}
	else{
		if (isBlack(some_board[x][y]) && j <= 7 && isWhite(some_board[i][j])){ // black rook eats white piece
			move = createMove(x, y, i, j, some_board, NULL);
			addMoveToMovesList(move, moves);
		}
	}
	// check if can eat right
	i = x +1;
	j = y;
	while (i<=7){
		if (some_board[i][j] != EMPTY)
			break;
		else{
			move = createMove(x, y, i, j, some_board, NULL);  // add step to an empty spot on board
			addMoveToMovesList(move, moves);
		}
		i++;
	}
	if (isWhite(some_board[x][y]) && i <= 7&& isBlack(some_board[i][j])){ // white rook eats black piece
		move = createMove(x, y, i, j, some_board, NULL);
		addMoveToMovesList(move, moves);
	}
	else{
		if (isBlack(some_board[x][y]) && i <= 7 && isWhite(some_board[i][j])){ // black rook eats white piece
			move = createMove(x, y, i, j, some_board, NULL);
			addMoveToMovesList(move, moves);
		}
	}

	//check if can eat down
	i = x;
	j = y - 1;
	while (j >= 0){
		if (some_board[i][j] != EMPTY)
			break;
		else{
			move = createMove(x, y, i, j, some_board, NULL);  // add step to an empty spot on board
			addMoveToMovesList(move, moves);
		}
		j--;
	}
	if (isWhite(some_board[x][y]) && j >= 0 && isBlack(some_board[i][j])){ // white rook eats black piece
		move = createMove(x, y, i, j, some_board, NULL);
		addMoveToMovesList(move, moves);
	}
	else{
		if (isBlack(some_board[x][y]) && j >= 0 && isWhite(some_board[i][j])){ // black rook eats white piece
			move = createMove(x, y, i, j, some_board, NULL);
			addMoveToMovesList(move, moves);
		}
	}

	// check if can eat left
	i = x - 1;
	j = y;
	while (i >=0 ){
		if (some_board[i][j] != EMPTY)
			break;
		else{
			move = createMove(x, y, i, j, some_board, NULL);  // add step to an empty spot on board
			addMoveToMovesList(move, moves);
		}
		i--;
	}
	if (isWhite(some_board[x][y]) && i >= 0 && isBlack(some_board[i][j])){ // white Bishop eats black piece
		move = createMove(x, y, i, j, some_board, NULL);
		addMoveToMovesList(move, moves);
	}
	else{
		if (isBlack(some_board[x][y]) && i >= 0 && isWhite(some_board[i][j])){ // black bishop eats white piece
			move = createMove(x, y, i, j, some_board, NULL);
			addMoveToMovesList(move, moves);
		}
	}
	return moves;
}
Exemple #9
0
struct Moves* PawnMoves(int x, int y, char some_board[BOARD_SIZE][BOARD_SIZE]){
	struct Moves* moves = calloc(1,sizeof(struct Moves));
	movesLeaks++;
	struct Move* move;
	int isPromoted = 0;
	if (isWhite(some_board[x][y])){
		if (y + 1 == 7) isPromoted = 1; // promote the pawn 
		if (y + 1 <= 7 && some_board[x][y + 1] == EMPTY) // if you can move to an empty spot that is in the board
			if (isPromoted){

				move = createMove(x, y, x, y + 1, some_board, W_ROOK);
				addMoveToMovesList(move, moves);
				move = createMove(x, y, x, y + 1, some_board, W_KNIGHT);
				addMoveToMovesList(move, moves);
				move = createMove(x, y, x, y + 1, some_board, W_QUEEN);
				addMoveToMovesList(move, moves);
				move = createMove(x, y, x, y + 1, some_board, W_BISHOP);
				addMoveToMovesList(move, moves);
			}
			else{
				move = createMove(x, y, x, y + 1, some_board, NULL); // Move with no promotion
				addMoveToMovesList(move, moves);
			}

		if (y + 1 <= 7 && x - 1 >= 0 && isBlack(some_board[x-1][y+1])){ // can move  diagonal only if can eat a black piece
			if (isPromoted){

				move = createMove(x, y, x - 1, y + 1, some_board, W_ROOK);
				addMoveToMovesList(move, moves);
				move = createMove(x, y, x - 1, y + 1, some_board, W_KNIGHT);
				addMoveToMovesList(move, moves);
				move = createMove(x, y, x - 1, y + 1, some_board, W_QUEEN);
				addMoveToMovesList(move, moves);
				move = createMove(x, y, x - 1, y + 1, some_board, W_BISHOP);
				addMoveToMovesList(move, moves);
			}
			else{
				move = createMove(x, y, x - 1, y + 1, some_board, NULL); // Move with no promotion
				addMoveToMovesList(move, moves);
			}
		}

		if (y + 1 <= 7 && x + 1 <= 7 && isBlack(some_board[x+1][y+1])){
			if (isPromoted){

				move = createMove(x, y, x + 1, y + 1, some_board, W_ROOK);
				addMoveToMovesList(move, moves);
				move = createMove(x, y, x + 1, y + 1, some_board, W_KNIGHT);
				addMoveToMovesList(move, moves);
				move = createMove(x, y, x + 1, y + 1, some_board, W_QUEEN);
				addMoveToMovesList(move, moves);
				move = createMove(x, y, x + 1, y + 1, some_board, W_BISHOP);
				addMoveToMovesList(move, moves);
			}
			else{
				move = createMove(x, y, x + 1, y + 1, some_board, NULL); // Move with no promotion
				addMoveToMovesList(move, moves);
			}
		}
	}
	else{ // color is black
		if (y - 1 == 0) isPromoted = 1; // promote the pawn 
		if (y - 1 >= 0 && some_board[x][y - 1] == EMPTY) // if you can move to an empty spot that is in the board
			if (isPromoted){

				move = createMove(x, y, x, y - 1, some_board, W_ROOK);
				addMoveToMovesList(move, moves);
				move = createMove(x, y, x, y - 1, some_board, W_KNIGHT);
				addMoveToMovesList(move, moves);
				move = createMove(x, y, x, y - 1, some_board, W_QUEEN);
				addMoveToMovesList(move, moves);
				move = createMove(x, y, x, y - 1, some_board, W_BISHOP);
				addMoveToMovesList(move, moves);
			}
			else{
				move = createMove(x, y, x, y - 1, some_board, NULL); // Move with no promotion
				addMoveToMovesList(move, moves);
			}

		if (y - 1 >=0 && x - 1 >= 0 && isWhite(some_board[x - 1][y - 1])){ // can move  diagonal only if can eat a black piece
			if (isPromoted){

				move = createMove(x, y, x - 1, y - 1, some_board, W_ROOK);
				addMoveToMovesList(move, moves);
				move = createMove(x, y, x - 1, y - 1, some_board, W_KNIGHT);
				addMoveToMovesList(move, moves);
				move = createMove(x, y, x - 1, y - 1, some_board, W_QUEEN);
				addMoveToMovesList(move, moves);
				move = createMove(x, y, x - 1, y - 1, some_board, W_BISHOP);
				addMoveToMovesList(move, moves);
			}
			else{
				move = createMove(x, y, x - 1, y - 1, some_board, NULL); // Move with no promotion
				addMoveToMovesList(move, moves);
			}
		}

		if (y - 1 >= 0 && x + 1 <= 7 && isWhite(some_board[x + 1][y - 1])){
			if (isPromoted){

				move = createMove(x, y, x + 1, y - 1, some_board, W_ROOK);
				addMoveToMovesList(move, moves);
				move = createMove(x, y, x + 1, y - 1, some_board, W_KNIGHT);
				addMoveToMovesList(move, moves);
				move = createMove(x, y, x + 1, y - 1, some_board, W_QUEEN);
				addMoveToMovesList(move, moves);
				move = createMove(x, y, x + 1, y - 1, some_board, W_BISHOP);
				addMoveToMovesList(move, moves);
			}
			else{
				move = createMove(x, y, x + 1, y - 1, some_board, NULL); // Move with no promotion
				addMoveToMovesList(move, moves);
			}
		}
	}
	return moves;
}
Exemple #10
0
Move* copyMove(Move* move) {
	return createMove(move->from, copyPositionList(move->to),
		copyPositionList(move->eatenAt), move->eatCount);
}