/** 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); }
void deletePokemon(Pokemon* p){ free(p->name); free(p->nickname); int i; for(i = 0; i < 4; i++){ deleteMove(p->moves[i]); } free(p); p = NULL; }
/* * 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; }