/** * @brief Creates a list of pseudo valid moves for a given color. * * Returns a list of pseudo valid moves for a given color. Pseudo valid moves * include those moves which leave the setting stone without liberties. Ko * moves are not included in this list. * * @param[in] color Current color to move * @param[out] valid_moves List of pseudo valid moves (Ko moves excluded) * @return Number of pseudo valid moves * @note This list does not contain invalid ko moves, those are dropped * from this list. But moves that leave the stone or group * without a liberty are still contained in this list. Therefore * the term "pseudo valid". */ int get_pseudo_valid_move_list( int color, int valid_moves[][4] ) { int count; int i, j; int board_size = get_board_size(); count = 0; for ( i = 0; i < board_size; i++ ) { for ( j = 0; j < board_size; j++ ) { if ( get_vertex( i, j ) == EMPTY && ! is_move_ko( color, i, j ) ) { valid_moves[count][0] = i; valid_moves[count][1] = j; valid_moves[count][2] = 0; valid_moves[count][3] = 0; count++; } } } valid_moves[count][0] = INVALID; valid_moves[count][1] = INVALID; valid_moves[count][2] = 0; valid_moves[count][3] = 0; return count; }
/** * Handles a request to print out current state of the board. * @param[in] client_fd File descriptor of a client that is currently served. * @param[in] game Pointer to a game structure that is currently played. * \sa game_s */ void thread_handle_print_board_request(int client_fd, game_s *game) { int i, j, size, index = 0; char temp[NROWS * NCOLS]; response_s response; response.type = MSG_PRINT_BOARD_RSP; size = get_board_size(game->board); if (size == -1) { response.error = MSG_RSP_INTERNAL_SERVER_ERROR; send_response_message(client_fd, &response); return; } for (i = 0; i < NROWS; i++) { for (j = 0; j < NCOLS; j++) { temp[index] = game->board[i][j]; index++; } } snprintf(response.payload, MAX_RSP_SIZE, "%d%s%s%s", size, PAYLOAD_DELIM, temp, PAYLOAD_DELIM); response.error = MSG_RSP_ERROR_NONE; send_response_message(client_fd, &response); }
/** * Sends a message with current state of the board to all connected spectators. */ void send_broadcast_message(void) { int i, j, k, size, index = 0; char temp[NROWS * NCOLS]; response_s response; response.type = MSG_PRINT_BOARD_SPC_RSP; size = get_board_size(tdata.game->board); if (size == -1) { response.error = MSG_RSP_INTERNAL_SERVER_ERROR; for (k = 0; k < SPECTATORS_NO; k++) { if (tdata.spectators_fd[k] == -1) { continue; } send_response_message(tdata.spectators_fd[k], &response); } return; } for (i = 0; i < NROWS; i++) { for (j = 0; j < NCOLS; j++) { temp[index] = tdata.game->board[i][j]; index++; } } snprintf(response.payload, MAX_RSP_SIZE, "%d%s%s%s", size, PAYLOAD_DELIM, temp, PAYLOAD_DELIM); response.error = MSG_RSP_ERROR_NONE; for (k = 0; k < SPECTATORS_NO; k++) { if (tdata.spectators_fd[k] == -1) { continue; } send_response_message(tdata.spectators_fd[k], &response); } }
int main(int argc, char *argv[]) { // Decide what configure file and game file to use. // Either from the defaults or from command line. std::string conf_name, game_name; std::pair<std::string, std::string> names; names = parse_arguments(argc, argv); conf_name = names.first; game_name = names.second; // Feedback to the user. std::cout << "Verifying computed reversi game with:" << std::endl; std::cout << " Configure file: " << conf_name << std::endl; std::cout << " Game file: " << game_name << std::endl << std::endl; // Read configure file and generate the board. int board_size = get_board_size(conf_name); Board board(board_size); std::vector<Move> moves = read_moves(game_name); Cell_state last_player = white; // Last player to verify skipping. std::vector<Move>::size_type i; try { for (i = 0; i < moves.size(); i++) { // If a player was skipped, verify validity. if (last_player == moves[i].player()) { Cell_state other_player = last_player == black ? white : black; // Look all cells for a valid move of other_player for (int r = 0; r < board_size; r++) { for (int c = 0; c < board_size; c++) { Cell current_cell(r, c); Move other_move(other_player, current_cell); if (board.is_valid(other_move)) { // Found a valid move: error! move_error("A player with valid move was skipped", other_move, i, board); } } } } // Player is ok. Verify move validity and update board. board.play(moves[i]); last_player = moves[i].player(); } } catch (Invalid_move_exception e) { // An invalid move was tried. move_error("You tried an invalid move.", e.move(), i, e.board()); } catch (std::out_of_range) { // Cell out of the board accessed. move_error("Illegal cell.", moves[i], i, board); } // File ended. Verify if there are any valid moves left. for (int r = 0; r < board_size; r++) { for (int c = 0; c < board_size; c++) { Cell current_cell = Cell(r, c); Move possible_move_black(black, current_cell); Move possible_move_white(white, current_cell); if (board.is_valid(possible_move_black)) { move_error("Your game file ended prematurely (valid moves left)", possible_move_black, i, board); } if (board.is_valid(possible_move_white)) { move_error("Your game file ended prematurely (valid moves left)", possible_move_white, i, board); } } } std::cout << "Your moves are all legal. Congratulations!\n"; return 0; }