int populate_tab(int **tab, int size, char **str) { int i; int j; i = 0; while (i < size - 1) { j = 0; while (str[i + 1][j]) { if (str[i + 1][j] == '.') tab[i][j] = 0; else if (str[i + 1][j] >= '0' && str[i + 1][j] <= '9') if (is_valid_move(tab, str[i + 1][j] - 48, i, j)) tab[i][j] = str[i + 1][j] - 48; else return (throw_error()); else return (throw_error()); j++; } if (j != 9) return (throw_error()); i++; } return (1); }
void test_invalid_move() { Board* board = new_board(3); make_move(board, 0, 'X'); bool check = is_valid_move(board, 0); assert(!check); destroy_board(board); }
int make_move(const GameState* state, int i, int d) { assert(d > 0); int player = ai_current_player(); MoveResult move = is_valid_move(state, player, i, d); DEBUG("make_move(): P%d moves %d -> %d (result %d)\n", player, i, i-d, move); int src = PT(player,i); int dest = PT(player,i-d); switch (move) { case MOVE_INVALID: return 0; case MOVE_BEAROFF: assert(src >= 0 && src < 24); SET(state->points[src], MAKEPOINT(player, state->points[src].count-1)); DEC(state->total[player]); ai_set_player_score(player, 15 - state->total[player]); DEBUG("make_move(): P%d beared off @ %d; %d left\n", player, i, state->total[player]); return 1; case MOVE_UNOCCUPIED: case MOVE_MERGE: assert(src >= 0 && src < 24); assert(dest >= 0 && dest < 24); SET(state->points[src], MAKEPOINT(player, state->points[src].count-1)); SET(state->points[dest], MAKEPOINT(player, state->points[dest].count+1)); return 1; case MOVE_HITBLOT: assert(src >= 0 && src < 24); assert(dest >= 0 && dest < 24); SET(state->points[src], MAKEPOINT(player, state->points[src].count-1)); SET(state->points[dest], MAKEPOINT(player, 1)); INC(state->bar[player^1]); return 1; } }
int try_move(int **tab, int row, int col, int is_reverse) { int i; i = 0; while (i < 9) { if (is_valid_move(tab, i + 1, row, col)) { tab[row][col] = i + 1; if ((col + 1) < 9) if (find_solution(tab, row, col + 1, is_reverse)) return (1); else tab[row][col] = 0; else if ((row + 1) < 9) if (find_solution(tab, row + 1, 0, is_reverse)) return (1); else tab[row][col] = 0; else return (1); } i++; } return (0); }
int make_move_0(const GameState* state) { int d1 = state->d1; int d2 = state->d2; int player = ai_current_player(); DEBUG("P%d dice %d %d\n", player, d1, d2); ChoiceMask mask = 0; // entering from bar has priority if (state->bar[player]) { if (reenter_from_bar(state, player, d1)) { SET(state->d1, 0); d1 = 0; } if (reenter_from_bar(state, player, d2)) { SET(state->d2, 0); d2 = 0; } } // player can move any of 24 points // TODO: bearing off rules for (int i=0; i<24; i++) { // does this point have a valid move? if (state->points[PT(player,i)].occupied == player+1 && (is_valid_move(state,player,i,d1) || is_valid_move(state,player,i,d2) || is_valid_move(state,player,i,d1+d2))) { mask |= (1<<i); } } if (mask != 0) { // try each of our pieces if (ai_choice(state, 0, make_move_1, 0, mask) == 0) mask = 0; } // none are valid, so player passes if (mask == 0) { DEBUG("P%d no moves\n", player); if (ai_next_player()) play_turn(state); // if in search mode } return 1; }
int get_valid_move_count(int x, int y, enum cell_contents board[][BOARD_WIDTH]) { int count = 0; struct move move; /* check all four directions */ move = create_move(x, y, x - 2, y); if (is_valid_move(move, board, NULL)) count++; move = create_move(x, y, x + 2, y); if (is_valid_move(move, board, NULL)) count++; move = create_move(x, y, x, y - 2); if (is_valid_move(move, board, NULL)) count++; move = create_move(x, y, x, y + 2); if (is_valid_move(move, board, NULL)) count++; return count; }
/* * returns an array of moves that can be made but don't exist in the nodes list */ Move *get_unimplemented_moves(linked_list *nodes_list, Board *board, int *new_length, int max, int (*is_valid_move)(Board* board, Move* new_move, int value)) { int i, j; Move *result; Move move = {.i = 0, .j = 0}; int result_index = 0; if ((result = (Move*)calloc(board->n*board->m, sizeof(Move))) == NULL) { printf("ERROR: unable to init moves list in get_unimplemented_moves.\n"); return NULL; } for (i=0; i < (board->n); i++) { for (j=0; j < board->m; j++) { move.i = i; move.j = j; // if this move doesn't exist in the linked list - add it to result if (!move_in_linked_list(move, nodes_list)) { // check that it is a valid move. // `is_valid_move` function can CHANGE the move coordinates, // and we only want moves that don't change their coordinates if (is_valid_move(board, &move, max ? FIRST_PL_TURN:SECOND_PL_TURN) && ((move.i == i) && (move.j == j)) ){ // add the move to the result result[result_index] = (Move){.i=move.i, .j=move.j}; result_index++; } } } } *new_length = result_index; if (result_index == 0) { free(result); return NULL; } // we now know how manu unimplemented moves we have - so we rellocate te memory to fit it. if ((result = (Move*)(realloc(result, sizeof(Move)*result_index))) == NULL) { printf("ERROR: can't allocate result in get_unimplemented_moves.\n"); exit(1); } return result; } /* * returns True if a move exists in the list of nodes, False o/w. */ int move_in_linked_list(Move move, linked_list *nodes_list) { element *iterator = nodes_list->head; while (iterator != NULL) { if ((iterator->node->current_move->i == move.i) && (iterator->node->current_move->j == move.j)) { return 1; } iterator = iterator->next; } return 0; }
bool Sudoku::is_valid() { for(int i = 0; i < 9; ++i){ for(int j = 0; j < 9; ++j){ if(grid[i][j] != 0 && !is_valid_move(i, j)) return false; } } return true; }
//Helper for solved bool Sudoku::is_solved() { for(int i = 0; i < 9; ++i){ for(int j = 0; j < 9; ++j){ if(!is_valid_move(i, j) || grid[i][j] == 0) return false; } } return true; }
int generate_valid_moves(GAME *game, MOVE *moves) { DECKP hand = game->players[game->current_player].hand; int i; int num = 0; MOVE all_moves[MAX_MOVES]; int num_moves; num_moves = generate_all_moves(hand, all_moves); /* Special case: put highest move first, just in case it helps pruning. */ if (num_moves >= 1 && is_valid_move(game, all_moves[num_moves-1])) moves[num++] = all_moves[num_moves-1]; for (i = 0; i < num_moves-1; i++) if (is_valid_move(game, all_moves[i])) moves[num++] = all_moves[i]; return num; }
// attempt to update board with players move // return 0 on success, 1 on failure. int update_board(tt_data * data, tt_move_coords * move) { int result = 0; if(is_valid_move(data, move)) { game_board_set_at_coord(data, move); } else { result = 1; } return result; }
// cgc_select a randomly generated valid move for the computer void computer_move(tt_data * data, tt_move_coords * move) { tt_move_coords tmp_move; tmp_move.row = prng_get_next() % 3; tmp_move.col = prng_get_next() % 3; while(!is_valid_move(data, &tmp_move)) { tmp_move.row = prng_get_next() % 3; tmp_move.col = prng_get_next() % 3; } move->row = tmp_move.row; move->col = tmp_move.col; }
void _play(int tid, int move) { if (!is_valid_move(move)) { reply(tid, INVALID_MOVE); } else if (players[tid] == -1) { reply(tid, NO_GAME_IN_PROGRESS); } else { int opponent = players[tid]; moves[tid] = move; if (moves[opponent] == -2) { reply(tid, PLAYER_QUIT); moves[tid] = -1; moves[opponent] = -1; players[tid] = -1; } else if (moves[opponent] != -1) { play_round(tid, opponent); } } }
void board_move(board_t b, int team, char* src_cn, char* dest_cn) { coordinate_t src_coord, dest_coord; cn_to_coord(src_cn, src_coord); cn_to_coord(dest_cn, dest_coord); char piece_type = b[src_coord[0]][src_coord[1]].type; if(b[src_coord[0]][src_coord[1]].team == team && is_valid_move(b, src_coord, dest_coord)) { b[dest_coord[0]][dest_coord[1]].type = b[src_coord[0]][src_coord[1]].type; b[dest_coord[0]][dest_coord[1]].team = b[src_coord[0]][src_coord[1]].team; b[src_coord[0]][src_coord[1]].type = 0; b[src_coord[0]][src_coord[1]].team = -1; } else printf("Invalid move.\n"); }
void board::find_starting_position(int * x, int * y, sprite * s) { int newx, newy; bool done = false; // SDL_Rect temp_dest; //temp_dest.w = s->get_width(); //temp_dest.h = s->get_height(); while ( ! done ) { newx = rand()%(_w - s->get_width()); newy = rand()%(_h - s->get_height()); done = is_valid_move(newx,newy, s); } *x = newx; *y = newy; }
/* tries to create a move from input, result returned in move_validity */ enum move_validity try_get_move(struct move *move, char *input, enum cell_contents board[][BOARD_WIDTH]) { enum move_validity move_validity; struct move tmp_move; char *start_coord; char *end_coord; char *delims = "- ,\t"; /* only accept input if there are exactly 2 delimeter separated values */ start_coord = strtok(input, delims); if (start_coord == NULL) return MALFORMED_INPUT; /* 0 values, thus invalid */ end_coord = strtok(NULL, delims); if (end_coord == NULL) return MALFORMED_INPUT; /* only 1 value, thus invalid */ if (strtok(NULL, delims) != NULL) return MALFORMED_INPUT; /* more than 2 values, thus invalid */ /* creates move if coords formatted correctly */ if (!try_create_move_from_coords(&tmp_move, start_coord, end_coord)) return MALFORMED_INPUT; /* check validity of move */ if (is_valid_move(tmp_move, board, &move_validity)) *move = tmp_move; return move_validity; }
int ai_controller_poll(controller *ctrl, ctrl_event **ev) { ai *a = ctrl->data; object *o = ctrl->har; if (!o) { return 1; } har *h = object_get_userdata(o); object *o_enemy = game_state_get_player(o->gs, h->player_id == 1 ? 0 : 1)->har; // Do not run AI while the game is paused if(game_state_is_paused(o->gs)) { return 0; } // Do not run AI while match is starting or ending // XXX this prevents the AI from doing scrap/destruction moves // XXX this could be fixed by providing a "scene changed" event if(is_arena(game_state_get_scene(o->gs)->id) && arena_get_state(game_state_get_scene(o->gs)) != ARENA_STATE_FIGHTING) { // null out selected move to fix the "AI not moving problem" a->selected_move = NULL; return 0; } // Grab all projectiles on screen vector_clear(&a->active_projectiles); game_state_get_projectiles(o->gs, &a->active_projectiles); // Try to block har if(ai_block_har(ctrl, ev)) { return 0; } // Try to block projectiles if(ai_block_projectile(ctrl, ev)) { return 0; } if(a->selected_move) { // finish doing the selected move first if(a->input_lag_timer > 0) { a->input_lag_timer--; } else { a->move_str_pos--; if(a->move_str_pos <= 0) { a->move_str_pos = 0; } a->input_lag_timer = a->input_lag; } int ch = str_at(&a->selected_move->move_string, a->move_str_pos); controller_cmd(ctrl, char_to_act(ch, o->direction), ev); } else if(rand_int(100) < a->difficulty) { af_move *selected_move = NULL; int top_value = 0; // Attack for(int i = 0; i < 70; i++) { af_move *move = NULL; if((move = af_get_move(h->af_data, i))) { move_stat *ms = &a->move_stats[i]; if(is_valid_move(move, h)) { int value = ms->value + rand_int(10); if (ms->min_hit_dist != -1){ if (ms->last_dist < ms->max_hit_dist+5 && ms->last_dist > ms->min_hit_dist+5){ value += 2; } else if (ms->last_dist > ms->max_hit_dist+10){ value -= 3; } } value -= ms->attempts/2; value -= ms->consecutive*2; if (is_special_move(move) && !maybe(a->difficulty)) { DEBUG("skipping special move %s because of difficulty", str_c(&move->move_string)); continue; } if (selected_move == NULL){ selected_move = move; top_value = value; } else if (value > top_value) { selected_move = move; top_value = value; } } } } for(int i = 0; i < 70; i++) { a->move_stats[i].consecutive /= 2; } if(selected_move) { a->move_stats[selected_move->id].attempts++; a->move_stats[selected_move->id].consecutive++; // do the move a->selected_move = selected_move; a->move_str_pos = str_size(&selected_move->move_string)-1; a->move_stats[a->selected_move->id].last_dist = fabsf(o->pos.x - o_enemy->pos.x); a->blocked = 0; DEBUG("AI selected move %s", str_c(&selected_move->move_string)); } } else { // Change action after 30 ticks if(a->act_timer <= 0 && rand_int(100) > 88){ int p = rand_int(100); if(p > 40){ // walk forward a->cur_act = (o->direction == OBJECT_FACE_RIGHT ? ACT_RIGHT : ACT_LEFT); } else if(p > 20){ // walk backward a->cur_act = (o->direction == OBJECT_FACE_RIGHT ? ACT_LEFT : ACT_RIGHT); } else if(p > 10){ // do nothing a->cur_act = ACT_STOP; } else { // crouch and block a->cur_act = (o->direction == OBJECT_FACE_RIGHT ? ACT_DOWN|ACT_LEFT : ACT_DOWN|ACT_RIGHT); } a->act_timer = 30; controller_cmd(ctrl, a->cur_act, ev); } else { a->act_timer--; } // Jump once in a while if(rand_int(100) == 88){ if(o->vel.x < 0) { controller_cmd(ctrl, ACT_UP|ACT_LEFT, ev); } else if(o->vel.x > 0) { controller_cmd(ctrl, ACT_UP|ACT_RIGHT, ev); } else { controller_cmd(ctrl, ACT_UP, ev); } } } return 0; }
/* * Comando per gestire il gioco degli scacchi */ void do_chess( CHAR_DATA *ch, char *argument ) { CHESSBOARD_DATA *board; char arg[MIL]; if ( !ch ) { send_log( NULL, LOG_BUG, "do_chess: ch è NULL" ); return; } if ( IS_MOB(ch) ) { send_to_char( ch, "I mob non possono giocare a scacchi.\r\n" ); return; } board = get_chessboard( ch ); if ( !VALID_STR(argument) || is_name(argument, "sintassi aiuto syntax help ?") ) { char *cmd; cmd = translate_command( ch, "chess" ); ch_printf( ch, "&YSintassi gioco&w: %s inizio|smetto|partecipo|forfeit\r\n", cmd ); ch_printf( ch, "&YSintassi info&w: %s pezzi\r\n", cmd ); ch_printf( ch, "&YSintassi mosse&w: %s muovo <sorgente> <destinazione> [comandi opzionali]\r\n", cmd ); ch_printf( ch, "&YSintassi extra&w: %s arrocco|promuovo\r\n", cmd ); if ( !VALID_STR(argument) && board ) { send_to_char( ch, "\r\n" ); show_status( ch, board ); send_to_char( ch, "\r\n" ); show_board( ch, board ); } return; } argument = one_argument( argument, arg ); if ( is_name_prefix(arg, "inizio inizia comincio comincia cominciare start") ) { CHESSBOARD_DATA *newboard; if ( board ) { send_to_char( ch, "Sto già partecipando ad una partita di scacchi.\r\n" ); return; } CREATE( newboard, CHESSBOARD_DATA, 1 ); init_board( newboard ); newboard->player1 = ch; newboard->turn = ch; LINK( newboard, first_chessboard, last_chessboard, next, prev ); top_chessboard++; send_to_char( ch, "Inizio una nuova partita di scacchi.\r\n" ); return; } if ( is_name_prefix(arg, "partecipa partecipo join") ) { CHESSBOARD_DATA *vboard = NULL; CHAR_DATA *vch; char arg2[MIL]; if ( board ) { send_to_char( ch, "Sto già partecipando ad una partita di scacchi.\r\n" ); return; } argument = one_argument( argument, arg2 ); if ( !VALID_STR(arg2) ) { send_to_char( ch, "Con chi devo partecipare ad una partita di scacchi?\r\n" ); return; } vch = get_player_room( ch, arg2, TRUE ); if ( !vch ) { ch_printf( ch, "Non vedo nessun %s nella stanza.\r\n", arg2 ); return; } vboard = get_chessboard( vch ); if ( !vboard ) { send_to_char( ch, "Non sta giocando a scacchi.\r\n" ); return; } if ( vboard->player2 ) { send_to_char( ch, "Questa scacchiera ha già due giocatori.\r\n" ); return; } vboard->player2 = ch; vboard->turn = vboard->player2; send_to_char( ch, "Mi unisco alla partita, è il mio turno.\r\n" ); ch_printf( vboard->player1, "%s si unisce alla tua partita.\r\n", ch->name ); return; } if ( is_name_prefix(arg, "pezzi pieces") ) { int x; /* contatore dei colori */ int y; /* contatore dei pezzi */ for ( x = 0; x < COLOR_NONE; x++ ) { if ( x == COLOR_BLACK ) send_to_char( ch, "\r\n\r\nPezzi neri:\r\n" ); else send_to_char( ch, "Pezzi bianchi:\r\n" ); for ( y = PIECE_PAWN; y < PIECE_NONE; y++ ) ch_printf( ch, "%-7s", table_pieces[y].name ); send_to_char( ch, "\r\n" ); for ( y = PIECE_PAWN; y < PIECE_NONE; y++ ) send_to_char( ch, (x == COLOR_WHITE) ? table_pieces[y].wgraph1 : table_pieces[y].bgraph1 ); send_to_char( ch, "\r\n" ); for ( y = PIECE_PAWN; y < PIECE_NONE; y++ ) send_to_char( ch, (x == COLOR_WHITE) ? table_pieces[y].wgraph2 : table_pieces[y].bgraph2 ); } send_to_char( ch, "\r\n" ); return; } if ( !board ) { send_to_char( ch, "Non ho iniziato o non sto partecipando a nessuna partita di scacchi.\r\n" ); return; } if ( is_name_prefix(arg, "smetto fermo stop") ) { free_chessboard( board ); return; } if ( is_name_prefix(arg, "forfeit") ) { send_to_char( ch, "Dò forfeit così perdendo.\r\n" ); free_chessboard( board ); return; } if ( !board->player1 || !board->player2 ) { send_to_char( ch, "C'è solo un giocatore.\r\n" ); return; } if ( board->moves < 0 ) { send_to_char( ch, "Il gioco non è ancora iniziato.\r\n" ); return; } if ( is_name_prefix(arg, "promuovo promuovi promote") ) { int piece = board->piece[board->lastx][board->lasty]; char extra[MIL]; if ( !((piece == PIECE_PAWN && board->player1 == ch) || (piece == PIECE_PAWN && board->player2 == ch)) ) { send_to_char( ch, "Non posso promuovere questo pezzo.\r\n" ); return; } if ( (piece == PIECE_PAWN && board->lastx != 0) || (piece == PIECE_PAWN && board->lastx != 7) ) { send_to_char( ch, "Puoi promuovere solamente i pedoni che hanno raggiunto l'altro lato della scacchiera.\r\n" ); return; } if ( !VALID_STR(argument) ) { send_to_char( ch, "Vorrei promuovere il pedone in che cosa?\r\n" ); return; } if ( is_name_prefix(argument, "regina queen" ) ) piece = PIECE_QUEEN; else if ( is_name_prefix(argument, "alfiere bishop") ) piece = PIECE_BISHOP; else if ( is_name_prefix(argument, "cavallo knight") ) piece = PIECE_KNIGHT; else if ( is_name_prefix(argument, "torre rook" ) ) piece = PIECE_ROOK; else { ch_printf( ch, "Non posso promuoverlo a %s.\r\n", argument ); return; } board->piece[board->lastx][board->lasty] = piece; sprintf( extra, "%s (%c%d)", table_pieces[piece].name, board->lastx+'a', board->lasty+1 ); board_move_messages( ch, MOVE_PROMOTE, extra ); return; } if ( board->turn != ch ) { send_to_char( ch, "Non è il mio turno.\r\n" ); return; } if ( is_name_prefix(arg, "arrocco") ) { int myx; int rooky; int kdy; int rdy; bool fRookShort; if ( king_in_check(board, PIECE_KING, (board->player1 == ch) ? COLOR_BLACK : COLOR_WHITE) > 0 ) { send_to_char( ch, "Non posso eseguire un arrocco mentre sono sotto scacco.\r\n" ); return; } if ( (board->player1 == ch && HAS_BIT(board->flags1, CHESSFLAG_MOVEDKING)) || (board->player2 == ch && HAS_BIT(board->flags2, CHESSFLAG_MOVEDKING)) ) { send_to_char( ch, "Non posso effettuare un arrocco quando ho già mosso il mio re.\r\n" ); return; } myx = (board->player1 == ch) ? 7 : 0; if ( !VALID_STR(argument) ) { ch_printf( ch, "Utilizzo: %s arrocco corto|lungo\r\n", translate_command(ch, "chess") ); return; } if ( is_name_prefix(argument, "corto short") ) fRookShort = TRUE; else if ( is_name_prefix(argument, "lungo long") ) fRookShort = FALSE; else { send_command( ch, "chess arrocco", CO ); return; } if ( (board->player1 == ch && HAS_BIT(board->flags1, fRookShort ? CHESSFLAG_MOVEDKROOK : CHESSFLAG_MOVEDQROOK)) || (board->player2 == ch && HAS_BIT(board->flags2, fRookShort ? CHESSFLAG_MOVEDKROOK : CHESSFLAG_MOVEDQROOK)) ) { ch_printf( ch, "Non posso effettuare l'arrocco %s perchè ho già mosso la torre prima.\r\n", fRookShort ? "corto" : "lungo" ); return; } rooky = fRookShort ? 7 : 0; if ( ( fRookShort && (board->piece[myx][6] != PIECE_NONE || board->piece[myx][5] != PIECE_NONE)) || (!fRookShort && (board->piece[myx][1] != PIECE_NONE || board->piece[myx][2] != PIECE_NONE || board->piece[myx][3] != PIECE_NONE)) ) { send_to_char( ch, "L'arrocco è bloccato dalla presenza di pezzi tra il re e la torre.\r\n" ); return; } /* castling succeeded */ if ( fRookShort ) { kdy = 6; rdy = 5; } else { kdy = 2; rdy = 3; } /* (FF) (TT) (RR) (bb) ricordo che una qualsiasi delle caselle, in cui avveniva l'arrocco * non dovevano essere sotto scacco, mi sa che qui non è così, o forse ricordo sbagliato */ /* check for 'move across check' rule */ board->piece[myx][rdy] = board->piece[myx][4]; board->piece[myx][4] = PIECE_NONE; if ( king_in_check(board, board->piece[myx][rdy], board->color[myx][rdy]) > 0 ) { send_to_char( ch, "Il mio re si troverebbe sotto scacco dopo l'arrocco.\r\n" ); board->piece[myx][4] = board->piece[myx][rdy]; board->piece[myx][rdy] = PIECE_NONE; return; } board->piece[myx][kdy] = board->piece[myx][rdy]; board->piece[myx][rdy] = board->piece[myx][rooky]; board->piece[myx][rooky] = PIECE_NONE; /* check for 'check' after castled */ if ( king_in_check(board, board->piece[myx][kdy], board->color[myx][kdy]) > 0 ) { send_to_char( ch, "Il mio re si troverebbe sotto scacco dopo l'arrocco.\r\n" ); board->piece[myx][4] = board->piece[myx][kdy]; board->piece[myx][kdy] = PIECE_NONE; board->piece[myx][rooky] = board->piece[myx][rdy]; board->piece[myx][rdy] = PIECE_NONE; return; } /* Basta indicare che è stato mosso il re per evitare un altro arrocco */ if ( board->player1 == ch ) SET_BIT( board->flags1, CHESSFLAG_MOVEDKING ); else SET_BIT( board->flags2, CHESSFLAG_MOVEDKING ); board_move_stuff( board ); board_move_messages( ch, MOVE_CASTLE, rooky == 7 ? "corto" : "lungo" ); } if ( is_name_prefix(arg, "muovo move") ) { char coord1[MIL]; char coord2[MIL]; char extra[MIL]; int x, y, dx, dy; int ret; if ( !VALID_STR(argument) ) { ch_printf( ch, "Utilizzo: %s muovo <sorgente> <destinazione>\r\n", translate_command(ch, "chess") ); return; } argument = one_argument( argument, coord1 ); argument = one_argument( argument, coord2 ); if ( !VALID_STR(coord1) || !VALID_STR(coord2) ) { ch_printf( ch, "Utilizzo: %s muovo <sorgente> <destinazione>\r\n", translate_command(ch, "chess") ); return; } get_coord( coord1, &x, &y ); get_coord( coord2, &dx, &dy ); if ( x < 0 || x >= 8 || dx < 0 || dx >= 8 || y < 0 || y >= 8 || dy < 0 || dy >= 8 ) { send_to_char( ch, "Mossa non valida, utilizza a-h e 1-8 (esempio: a4 b4).\r\n" ); return; } extra[0] = '\0'; ret = is_valid_move( ch, board, x, y, dx, dy ); if ( ret == MOVE_OK || ret == MOVE_TAKEN ) { int piece; int color; int destpiece; int destcolor; piece = board->piece[x][y]; color = board->color[x][y]; destpiece = board->piece[dx][dy]; destcolor = board->color[dx][dy]; board->piece[dx][dy] = piece; board->color[dx][dy] = color; board->piece[x][y] = PIECE_NONE; board->color[x][y] = COLOR_NONE; if ( king_in_check(board, PIECE_KING, board->color[dx][dy]) > 0 ) { board->piece[dx][dy] = destpiece; board->color[dx][dy] = destcolor; board->piece[x][y] = piece; board->color[x][y] = color; ret = MOVE_INCHECK; } else { if ( destpiece == PIECE_NONE ) sprintf( extra, "%c%d (%s) alle coordinate %c%d", x+'a', y+1, table_pieces[piece].name, y+'a', dy+1 ); else sprintf( extra, "%c%d (%s) alle coordinate %c%d (%s)", x+'a', y+1, table_pieces[piece].name, y+'a', dy+1, table_pieces[destpiece].name ); board_move_stuff( board ); board->lastx = dx; board->lasty = dy; /* Imposta le flag per evitare gli arrocchi */ if ( piece == PIECE_ROOK ) { if ( color == COLOR_WHITE ) { if ( y == 0 && x == 0 ) SET_BIT( board->flags1, CHESSFLAG_MOVEDKROOK ); else if ( y == 0 && x == 7 ) SET_BIT( board->flags1, CHESSFLAG_MOVEDQROOK ); } else { if ( y == 7 && x == 0 ) SET_BIT( board->flags2, CHESSFLAG_MOVEDKROOK ); else if ( y == 7 && x == 7 ) SET_BIT( board->flags2, CHESSFLAG_MOVEDQROOK ); } } else if ( piece == PIECE_KING ) { if ( color == COLOR_WHITE ) SET_BIT( board->flags1, CHESSFLAG_MOVEDKING ); else SET_BIT( board->flags2, CHESSFLAG_MOVEDKING ); } } board_move_messages( ch, ret, extra ); } /* Così qui gestisce i comandi opzionali, come il promote */ if ( VALID_STR(argument) ) { do_chess( ch, argument ); return; } return; } send_command( ch, "chess aiuto", CO ); }
void do_chess( CHAR_DATA * ch, const char *argument ) { char arg[MAX_INPUT_LENGTH]; argument = one_argument( argument, arg ); if ( IS_NPC( ch ) ) { send_to_char( "NPC's can't be in chess games.\r\n", ch ); return; } if ( !str_cmp( arg, "begin" ) ) { GAME_BOARD_DATA *board; if ( ch->pcdata->game_board ) { send_to_char( "You are already in a chess match.\r\n", ch ); return; } CREATE( board, GAME_BOARD_DATA, 1 ); init_board( board ); ch->pcdata->game_board = board; ch->pcdata->game_board->player1 = QUICKLINK( ch->name ); send_to_char( "You have started a game of chess.\r\n", ch ); return; } if ( !str_cmp( arg, "join" ) ) { GAME_BOARD_DATA *board = NULL; CHAR_DATA *vch; char arg2[MAX_INPUT_LENGTH]; if ( ch->pcdata->game_board ) { send_to_char( "You are already in a game of chess.\r\n", ch ); return; } argument = one_argument( argument, arg2 ); if ( arg2[0] == '\0' ) { send_to_char( "Join whom in a chess match?\r\n", ch ); return; } #ifdef IMC if ( strstr( arg2, "@" ) ) { if ( !str_cmp( imc_mudof( arg2 ), this_imcmud->localname ) ) { send_to_char( "You cannot join IMC chess on the local mud!\r\n", ch ); return; } if ( !str_cmp( imc_mudof( arg2 ), "*" ) ) { send_to_char( "* is not a valid mud name.\r\n", ch ); return; } if ( !str_cmp( imc_nameof( arg2 ), "*" ) ) { send_to_char( "* is not a valid player name.\r\n", ch ); return; } send_to_char( "Attempting to initiate IMC chess game...\r\n", ch ); CREATE( board, GAME_BOARD_DATA, 1 ); init_board( board ); board->type = TYPE_IMC; board->player1 = QUICKLINK( ch->name ); board->player2 = STRALLOC( arg2 ); board->turn = -1; ch->pcdata->game_board = board; imc_send_chess( ch->name, arg2, "start" ); return; } #endif if ( !( vch = get_char_world( ch, arg2 ) ) ) { send_to_char( "Cannot find that player.\r\n", ch ); return; } if ( IS_NPC( vch ) ) { send_to_char( "That player is an NPC, and cannot play games.\r\n", ch ); return; } board = vch->pcdata->game_board; if ( !board ) { send_to_char( "That player is not playing a game.\r\n", ch ); return; } if ( board->player2 ) { send_to_char( "That game already has two players.\r\n", ch ); return; } board->player2 = QUICKLINK( ch->name ); ch->pcdata->game_board = board; send_to_char( "You have joined a game of chess.\r\n", ch ); vch = get_char_world( ch, board->player1 ); ch_printf( vch, "%s has joined your game.\r\n", ch->name ); return; } if ( !ch->pcdata->game_board ) { send_to_char( "Usage: chess <begin|cease|status|board|move|join>\r\n", ch ); return; } if ( !str_cmp( arg, "cease" ) ) { free_game( ch->pcdata->game_board ); return; } if ( !str_cmp( arg, "status" ) ) { GAME_BOARD_DATA *board = ch->pcdata->game_board; if ( !board->player1 ) send_to_char( "There is no black player.\r\n", ch ); else if ( !str_cmp( board->player1, ch->name ) ) send_to_char( "You are black.\r\n", ch ); else ch_printf( ch, "%s is black.\r\n", board->player1 ); if ( king_in_checkmate( board, BLACK_KING ) ) send_to_char( "The black king is in checkmate!\r\n", ch ); else if ( king_in_check( board, BLACK_KING ) ) send_to_char( "The black king is in check.\r\n", ch ); if ( !board->player2 ) send_to_char( "There is no white player.\r\n", ch ); else if ( !str_cmp( board->player2, ch->name ) ) send_to_char( "You are white.\r\n", ch ); else ch_printf( ch, "%s is white.\r\n", board->player2 ); if ( king_in_checkmate( board, WHITE_KING ) ) send_to_char( "The white king is in checkmate!\r\n", ch ); else if ( king_in_check( board, WHITE_KING ) ) send_to_char( "The white king is in check.\r\n", ch ); if ( !board->player2 || !board->player1 ) return; ch_printf( ch, "%d turns.\r\n", board->turn ); if ( board->turn % 2 == 1 && !str_cmp( board->player1, ch->name ) ) { ch_printf( ch, "It is %s's turn.\r\n", board->player2 ); return; } else if ( board->turn % 2 == 0 && !str_cmp( board->player2, ch->name ) ) { ch_printf( ch, "It is %s's turn.\r\n", board->player1 ); return; } else { send_to_char( "It is your turn.\r\n", ch ); return; } return; } if ( !str_prefix( arg, "board" ) ) { send_to_char( print_big_board( ch, ch->pcdata->game_board ), ch ); return; } if ( !str_prefix( arg, "move" ) ) { CHAR_DATA *opp; char opp_name[MAX_INPUT_LENGTH]; char a, b; int x, y, dx, dy, ret; if ( !ch->pcdata->game_board->player1 || !ch->pcdata->game_board->player2 ) { send_to_char( "There is only 1 player.\r\n", ch ); return; } if ( ch->pcdata->game_board->turn < 0 ) { send_to_char( "The game hasn't started yet.\r\n", ch ); return; } if ( king_in_checkmate( ch->pcdata->game_board, BLACK_KING ) ) { send_to_char( "The black king has been checkmated, the game is over.\r\n", ch ); return; } if ( king_in_checkmate( ch->pcdata->game_board, WHITE_KING ) ) { send_to_char( "The white king has been checkmated, the game is over.\r\n", ch ); return; } if ( !*argument ) { send_to_char( "Usage: chess move [piece to move] [where to move]\r\n", ch ); return; } if ( ch->pcdata->game_board->turn % 2 == 1 && !str_cmp( ch->pcdata->game_board->player1, ch->name ) ) { send_to_char( "It is not your turn.\r\n", ch ); return; } if ( ch->pcdata->game_board->turn % 2 == 0 && !str_cmp( ch->pcdata->game_board->player2, ch->name ) ) { send_to_char( "It is not your turn.\r\n", ch ); return; } if ( sscanf( argument, "%c%d %c%d", &a, &y, &b, &dy ) != 4 ) { send_to_char( "Usage: chess move [dest] [source]\r\n", ch ); return; } if ( a < 'a' || a > 'h' || b < 'a' || b > 'h' || y < 1 || y > 8 || dy < 1 || dy > 8 ) { send_to_char( "Invalid move, use a-h, 1-8.\r\n", ch ); return; } x = a - 'a'; dx = b - 'a'; --y; --dy; ret = is_valid_move( ch, ch->pcdata->game_board, x, y, dx, dy ); if ( ret == MOVE_OK || ret == MOVE_TAKEN ) { GAME_BOARD_DATA *board; int piece, destpiece; board = ch->pcdata->game_board; piece = board->board[x][y]; destpiece = board->board[dx][dy]; board->board[dx][dy] = piece; board->board[x][y] = NO_PIECE; if ( king_in_check( board, IS_WHITE( board->board[dx][dy] ) ? WHITE_KING : BLACK_KING ) && ( board->board[dx][dy] != WHITE_KING && board->board[dx][dy] != BLACK_KING ) ) { board->board[dx][dy] = destpiece; board->board[x][y] = piece; ret = MOVE_INCHECK; } else { ++board->turn; #ifdef IMC if ( ch->pcdata->game_board->type == TYPE_IMC ) { snprintf( arg, LGST, "move %d%d %d%d", x, y, dx, dy ); imc_send_chess( ch->pcdata->game_board->player1, ch->pcdata->game_board->player2, arg ); } #endif } } if ( !str_cmp( ch->name, ch->pcdata->game_board->player1 ) ) { opp = get_char_world( ch, ch->pcdata->game_board->player2 ); if ( !opp ) mudstrlcpy( opp_name, ch->pcdata->game_board->player2, MAX_INPUT_LENGTH ); } else { opp = get_char_world( ch, ch->pcdata->game_board->player1 ); if ( !opp ) mudstrlcpy( opp_name, ch->pcdata->game_board->player1, MAX_INPUT_LENGTH ); } #ifdef IMC # define SEND_TO_OPP(arg,opp) \ if( opp ) \ { \ if( ch->pcdata->game_board->type == TYPE_LOCAL ) \ ch_printf( (opp), "%s\r\n", (arg) ); \ } \ else \ { \ if( ch->pcdata->game_board->type == TYPE_IMC ) \ imc_send_tell( ch->name, opp_name, (arg), 1 ); \ } #else # define SEND_TO_OPP(arg,opp) \ if( opp ) \ { \ if( ch->pcdata->game_board->type == TYPE_LOCAL ) \ ch_printf( (opp), "%s\r\n", (arg) ); \ } #endif switch ( ret ) { case MOVE_OK: send_to_char( "Ok.\r\n", ch ); snprintf( arg, MAX_INPUT_LENGTH, "%s has moved.\r\n", ch->name ); SEND_TO_OPP( arg, opp ); break; case MOVE_INVALID: send_to_char( "Invalid move.\r\n", ch ); break; case MOVE_BLOCKED: send_to_char( "You are blocked in that direction.\r\n", ch ); break; case MOVE_TAKEN: send_to_char( "You take the enemy's piece.\r\n", ch ); snprintf( arg, MAX_INPUT_LENGTH, "%s has taken one of your pieces!", ch->name ); SEND_TO_OPP( arg, opp ); break; case MOVE_CHECKMATE: send_to_char( "That move would result in a checkmate.\r\n", ch ); snprintf( arg, MAX_INPUT_LENGTH, "%s has attempted a move that would result in checkmate.", ch->name ); SEND_TO_OPP( arg, opp ); break; case MOVE_OFFBOARD: send_to_char( "That move would be off the board.\r\n", ch ); break; case MOVE_SAMECOLOR: send_to_char( "Your own piece blocks the way.\r\n", ch ); break; case MOVE_CHECK: send_to_char( "That move would result in a check.\r\n", ch ); snprintf( arg, MAX_INPUT_LENGTH, "%s has made a move that would result in a check.", ch->name ); SEND_TO_OPP( arg, opp ); break; case MOVE_WRONGCOLOR: send_to_char( "That is not your piece.\r\n", ch ); break; case MOVE_INCHECK: send_to_char( "You are in check, you must save your king.\r\n", ch ); break; default: bug( "%s: Unknown return value", __FUNCTION__ ); break; } #undef SEND_TO_OPP return; } send_to_char( "Usage: chess <begin|cease|status|board|move|join>\r\n", ch ); }
void test_valid_move() { Board* board = new_board(3); bool check = is_valid_move(board, 0); assert(check); destroy_board(board); }
// manages the users turn, game state user input loop int user_turn(char board[BOARD_SIZE][BOARD_SIZE], COLOR color){ get_all_moves(board, color); if (moves_head == NULL) return WIN_POS; char *word1; char *command = NULL; Move* new_move = NULL; int ret_val; while (1){ printf(ENTER_YOUR_MOVE); if (new_move != NULL) clear_old_moves(new_move); new_move = malloc(sizeof(Move)); new_move->dest = malloc(sizeof(Pos) * 2 * BOARD_SIZE); new_move->next = NULL; if (command != NULL) free(command); command = input2str(stdin); word1 = strtok(command, " "); if (strcmp(word1, "quit") == 0){ ret_val = QUIT; break; } else if (strcmp(word1, "get_moves") == 0){ print_moves(moves_head); continue; } else if (strcmp(word1, "move") == 0){ char * piece_coor1 = strtok(NULL, " <,>"); char * piece_coor2 = strtok(NULL, " <,>"); new_move->piece.col = piece_coor1[0] - 'a'; new_move->piece.row = atoi(piece_coor2) - 1; if (!is_valid_pos(new_move->piece)){ printf(WRONG_POSITION); continue; } int i = 0; char * dest_coor1 = strtok(NULL, " <,>to"); char * dest_coor2 = strtok(NULL, " <,>to"); while (dest_coor1 != NULL){ new_move->dest[i].col = dest_coor1[0] - 'a'; new_move->dest[i].row = atoi(dest_coor2) - 1; if (!is_valid_pos(new_move->dest[i])){ i = -1; break; } i++; dest_coor1 = strtok(NULL, " <,>[]"); if (dest_coor1 != NULL) dest_coor2 = strtok(NULL, " <,>[]"); } if (i == -1){ printf(WRONG_POSITION); continue; } if (!is_valid_piece(board, new_move, color)){ printf(NO_DISC); continue; } new_move->dest = realloc(new_move->dest, sizeof(Pos) * i); new_move->captures = i; Move * move2do = is_valid_move(moves_head, new_move); if (move2do == NULL){ printf(ILLEGAL_MOVE); continue; } else{ exc_move(board, move2do); print_board(board); ret_val = GAME_ON; break; } } else printf(ILLEGAL_COMMAND); } free(command); clear_old_moves(new_move); clear_old_moves(moves_head); return ret_val; }
int main(int argc, char *argv[]) { /* ------------------------- VARIABLE DEFINITIONS -------------------------- */ /* counters */ int i; /* arrays that stores game/board state */ int black_pieces[26]; int white_pieces[26]; /* variables for user interactions */ int location[2]; int new_location[2]; /* initialize pieces for once */ initialize_pieces(black_pieces, white_pieces); /* print hello */ printf("Hello! It is the solution of first question of midterm.\n"); printf("Press Ctrl + C to exit.\n"); /* main program loop */ while(1) { /* print board */ print_board(black_pieces, white_pieces); printf("\n"); /* get movements and move it */ for(i = 0; i < 2; i++) { do { /* get piece location from user */ printf("Enter piece-%d location: ", i+1); scanf("%d", &location[i]); /* get new location from user */ printf("Enter piece-%d new location: ", i+1); scanf("%d", &new_location[i]); /* if the move is not valid */ if(!is_valid_move(black_pieces, white_pieces, location[i], new_location[i])) printf("Invalid movement. Please try again.\n"); printf("\n"); /* repeat it until the move is valid */ } while(!is_valid_move(black_pieces, white_pieces, location[i], new_location[i])); /* move piece */ move(black_pieces, white_pieces, location[i], new_location[i]); } /* clear screen */ system("clear"); /* print movements */ for(i = 0; i < 2; i++) printf("movement-%d: from %d to %d.\n", i+1, location[i], new_location[i]); /* print information about exit */ printf("Press Ctrl + C to exit.\n"); } return 0; }