/** * Find possible actions down on a column * * @param state a game state * @param col the column to check * @return a list of actions */ static struct List * actions_down( const struct State * state, int col ) { int idx = 0; struct List * actions = new_list(); for(idx = 0; (idx < SIZE) && ((idx + 2) < SIZE); idx++){ if( (state->board[ idx ][col] == state->player ) && (state->board[ idx + 1 ][ col ] == opposite_player( state->player )) && (state->board[ idx + 2 ][ col ] == 'O')){ /* check for moves - increment to optimize move*/ int end_row = idx + 2; /* add move to action list for single jump */ add_front( &actions, new_move( idx, col, end_row, col) ); while( ((end_row + 2) < SIZE ) && (state->board[ end_row ][ col ] == 'O' ) && (state->board[ end_row + 1 ][ col ] == opposite_player( state->player )) && (state->board[ end_row + 2 ][ col ] == 'O') ){ end_row += 2; /* add optimized moves to action list */ add_front( &actions, new_move( idx, col, end_row, col) ); } } } return actions; }
/** * Find possible actions left on a row * * @param state a game state * @param row the row to check * @return a list of actions */ static struct List * actions_left( const struct State * state, int row ) { int idx = SIZE-1; struct List * actions = new_list(); for(idx = SIZE - 1; (idx > 0) && ((idx - 2) >= 0); idx--){ if( (state->board[ row ][idx] == state->player ) && (state->board[ row ][ idx - 1 ] == opposite_player( state->player )) && (state->board[ row ][ idx - 2 ] == 'O')){ /* check for moves - increment to optimize move*/ int end_col = idx - 2; /* add move to action list for single jump */ add_front( &actions, new_move( row, idx, row, end_col) ); while( ((end_col - 2) > 0 ) && (state->board[ row ][ end_col ] == 'O' ) && (state->board[ row ][ end_col - 1 ] == opposite_player( state->player )) && (state->board[ row ][ end_col - 2 ] == 'O') ){ end_col -= 2; /* add optimized moves to action list */ add_front( &actions, new_move( row, idx, row, end_col) ); } } } return actions; }
/** * Translate an input move * * @param move a move input by the user * @return a move */ struct Move * translate_in_move( const char * move ) { int length = strnlen( move, 20 ); int i; int valid = 0; char start_row[2]; char start_col[2]; char end_row[2]; char end_col[2]; /* find first letter */ for( i = 0; i < length; i++ ) if( isalpha( move[ i ] ) ) { start_row[0] = move[ i ]; start_row[1] = '\0'; valid++; break; } /* find next number */ for( ; i< length; i++ ) if( isdigit( move[i] ) ) { start_col[0] = move[ i ]; start_col[1] = '\0'; valid++; break; } /* find next letter */ for( ; i < length; i++ ) if( isalpha( move[ i ] ) ) { end_row[0] = move[ i ]; end_row[1] = '\0'; valid++; break; } /* find next number */ for( ; i < length; i++ ) if( isdigit( move[ i ] ) ) { end_col[0] = move[ i ]; end_col[1] = '\0'; valid++; break; } if( valid != 4 ) return NULL; struct Move * translated_move = new_move( letter2row( start_row ), atoi( start_col ) - 1, letter2row( end_row ), atoi( end_col ) - 1 ); return translated_move; }
event_node_ptr fake_event_source::move_mouse(const size_t time, const int x, const int y) { SDL_Event event; event.type = SDL_MOUSEMOTION; event.motion.x = static_cast<Uint16>(x); event.motion.y = static_cast<Uint16>(y); event_node_ptr new_move(new event_node_mouse_motion(time, event)); add_event(new_move); return new_move; }
/** * Find possible actions left on a row * * @param state a game state * @param row the row to check * @return a list of actions */ static struct List * actions_left( const struct State * state, int row ) { int idx = SIZE-1; struct List * actions = new_list(); /*for( idx = SIZE - 1; idx >= 0; idx-- ) { // find next piece on board for( ; state->board[ row ][ idx ] != state->player && idx > 0; idx-- ); if( idx < 0 ) continue; // check for moves for( int i = idx - 1; i >= 0; i-- ) { if( state->board[ row ][ i ] == opposite_player( state->player ) ) { if( state->board[ row ][ i - 1 ] == 'O' || state->board[ row ][ i - 1 ] == '0' ) { //printf( "(%d,%d), (%d, %d)\n", row, idx, row, i - 1 ); add_front( &actions, new_move( row, idx, row, i - 1 ) ); // check for more moves continue; } break; } } }*/ for(idx = SIZE - 1; (idx > 0) && ((idx - 2) >= 0); idx--){ if( (state->board[ row ][idx] == state->player ) && (state->board[ row ][ idx - 1 ] == opposite_player( state->player )) && (state->board[ row ][ idx - 2 ] == 'O')){ /* check for moves - increment to optimize move*/ int end_col = idx - 2; while( ((end_col - 2) > 0 ) && (state->board[ row ][ end_col ] == 'O' ) && (state->board[ row ][ end_col - 1 ] == opposite_player( state->player )) && (state->board[ row ][ end_col - 2 ] == 'O') ){ end_col -= 2; } /* add move to action list */ add_front( &actions, new_move( row, idx, row, end_col) ); } } return actions; }
/** * Find possible actions down on a column * * @param state a game state * @param col the column to check * @return a list of actions */ static struct List * actions_down( const struct State * state, int col ) { int idx = 0; struct List * actions = new_list(); /*for( idx = 0; idx < SIZE; idx++ ) { // find next piece on board for( ; state->board[ idx ][ col ] != state->player && idx < SIZE - 1; ++idx ); if( idx > SIZE - 1 ) continue; // check for moves for( int i = 1; i + idx < SIZE; i++ ) { if( state->board[ idx + i ][ col ] == opposite_player( state->player ) ) { if( state->board[ idx + i + 1 ][ col ] == 'O' || state->board[ idx + i + 1 ][ col ] == '0' ) { // has move //printf( "(%d,%d), (%d, %d)\n", row, idx, row, idx + i + 1 ); add_front( &actions, new_move( idx, col, idx + i + 1, col )); // check for more moves continue; } break; } } }*/ for(idx = 0; (idx < SIZE) && ((idx + 2) < SIZE); idx++){ if( (state->board[ idx ][col] == state->player ) && (state->board[ idx + 1 ][ col ] == opposite_player( state->player )) && (state->board[ idx + 2 ][ col ] == 'O')){ /* check for moves - increment to optimize move*/ int end_row = idx + 2; while( ((end_row + 2) < SIZE ) && (state->board[ end_row ][ col ] == 'O' ) && (state->board[ end_row + 1 ][ col ] == opposite_player( state->player )) && (state->board[ end_row + 2 ][ col ] == 'O') ){ end_row += 2; } /* add move to action list */ add_front( &actions, new_move( idx, col, end_row, col) ); } } return actions; }
/** * Find possible actions up on a column * * @param state a game state * @param col the column to check * @return a list of actions */ static struct List * actions_up( const struct State * state, int col ) { int idx = SIZE - 1; struct List * actions = new_list(); /*for( idx = SIZE; idx >= 0; idx-- ) { // find next piece on board for( ; state->board[ idx ][ col ] != state->player && idx > 0; --idx ); if( idx < 0 ) continue; // check for moves for( int i = 1; idx - i >= 0; i++ ) { if( state->board[ idx - i ][ col ] == opposite_player( state->player ) ) { if( state->board[ idx - (i+1) ][ col ] == 'O' || state->board[ idx - (i+1) ][ col ] == '0' ) { // has move add_front( &actions, new_move( idx, col, idx - (i+1), col ) ); // check for more moves continue; } break; } } }*/ for(idx = SIZE - 1; (idx > 0) && ((idx - 2) >= 0); idx--){ if( (state->board[ idx ][col] == state->player ) && (state->board[ idx - 1 ][ col ] == opposite_player( state->player )) && (state->board[ idx - 2 ][ col ] == 'O')){ /* check for moves - increment to optimize move*/ int end_row = idx - 2; while( ((end_row - 2) > 0 ) && (state->board[ end_row ][ col ] == 'O' ) && (state->board[ end_row - 1 ][ col ] == opposite_player( state->player )) && (state->board[ end_row - 2 ][ col ] == 'O') ){ end_row -= 2; } /* add move to action list */ add_front( &actions, new_move( idx, col, end_row, col) ); } } return actions; }
/** * Find possible actions right on a row * * @param state a game state * @param row the row to check * @return a list of actions */ static struct List * actions_right( const struct State * state, int row ) { int idx = 0; struct List * actions = new_list(); /*while( idx < SIZE - 1 ) { // find next piece for( ; ( state->board[ row ][ idx ] != state->player ) && ( idx < SIZE - 1 ); idx++ ); //check if overbounds if( idx < SIZE - 1 ) { //find all moves for( int i = idx; i + 2 < SIZE; i++ ) if( state->board[ row ][ i + 1 ] == opposite_player( state->player ) ) if( state->board[ row ][ i + 2 ] == 'O' ) { add_front( &actions, new_move( row, idx, row, i + 2 ) ); } else { break; } } idx++; }*/ for(idx = 0; (idx < SIZE) && ((idx + 2) < SIZE); idx++){ if( (state->board[ row ][idx] == state->player ) && (state->board[ row ][ idx + 1 ] == opposite_player( state->player )) && (state->board[ row ][ idx + 2 ] == 'O')){ /* check for moves - increment to optimize move*/ int end_col = idx + 2; while( ((end_col + 2) < SIZE ) && (state->board[ row ][ end_col ] == 'O' ) && (state->board[ row ][ end_col + 1 ] == opposite_player( state->player )) && (state->board[ row ][ end_col + 2 ] == 'O') ){ end_col += 2; } /* add move to action list */ add_front( &actions, new_move( row, idx, row, end_col) ); } } return actions; }
void add_mob(int npc, int x, int y, enum e_dir direc) { static GLfloat dir[3] = {0.0, 0.0, 0.0}; static GLfloat vec[3] = {0.0, 0.0, 1.0}; GLfloat pos[3]; t_move *move; t_rot *rot; t_anim *anim; t_square *sq; t_mob *mob; set_vecf(pos, (float)x * 2, 0.0, (float)y * 2); anim = new_anim(rand() % 360, 360, anim_mob); move = new_move(0, 0, pos, dir); rot = new_rot(0, vec, 90 * direc, 0); mob = new_mob(anim, move, rot, npc); sq = g_env->sq + x + y * g_env->mapw; g_env->npc[npc].sq = sq; sq->mobs = new_link(sq->mobs, mob); }
/** * Translate a beginning move to coordinates * * @param move a string consisting of the human input (will only read one piece) * @return a move consisting of one piece */ struct Move * translate_first_in_move( const char * move ) { int length = strnlen( move, 20 ); int i; int valid = 0; char start_row[2]; char start_col[2]; /* find first letter */ for( i = 0; i < length; i++ ) if( isalpha( move[ i ] ) ) { start_col[0] = move[ i ]; start_col[1] = '\0'; valid++; break; } /* find next number */ for( ; i< length; i++ ) if( isdigit( move[i] ) ) { start_row[0] = move[ i ]; start_row[1] = '\0'; valid++; break; } /* check input parameters */ if( valid != 2 ) return NULL; struct Move * translated_move = new_move( atoi( start_row ) - 1, letter2row( start_col ), 0, 0 ); return translated_move; }
Move Move::add(const Move & m) const { Move new_move(m.x, m.y); return new_move; }
/** * Clone a move * * @param move a move to clone * @return a duplicate move */ struct Move * clone_move( const struct Move * move ) { return new_move( move->start_row, move->start_col, move->end_row, move->end_col ); }
// Non-capturing checks. //------------------------------------------------------------------------------ MoveGen *generate_checks(MoveGen *self) { Position *p = self->p; int color = p->color, enemy = p->color ^ 1; int square = (int)p->king[enemy]; // Non-capturing Knight checks. Bitmask prohibit = maskNone; Bitmask checks = knightMoves[square]; Bitmask outposts = p->outposts[knight(color)]; while (any(outposts)) { int from = pop(&outposts); add_piece_move(self, from, knightMoves[from] & checks & ~p->board); } // Non-capturing Bishop or Queen checks. checks = targets_for(p, square, bishop(enemy)); outposts = p->outposts[bishop(color)] | p->outposts[queen(color)]; while (any(outposts)) { int from = pop(&outposts); Bitmask squares = targets_for(p, from, bishop(enemy)) & checks & ~p->outposts[enemy]; while (any(squares)) { int to = pop(&squares); Piece piece = p->pieces[to]; if (!piece) { // Empty square: simply move a bishop to check. append(self, new_move(p, from, to)); } else if (color(piece) == color && any(maskDiagonal[from][square])) { // Non-empty square occupied by friendly piece on the same // diagonal: moving the piece away causes discovered check. switch (kind(piece)) { case Pawn: // Block pawn promotions (since they are treated as // captures) and en-passant captures. prohibit = maskRank[0] | maskRank[7]; if (p->enpassant) { prohibit |= bit[p->enpassant]; } add_pawn_move(self, to, targets(p, to) & ~p->board & ~prohibit); break; case King: // Make sure the king steps out of attack diaginal. add_king_move(self, to, targets(p, to) & ~p->board & ~maskBlock[from][square]); break; default: add_piece_move(self, to, targets(p, to) & ~p->board); } } } if (is_queen(p->pieces[from])) { // Queen could move straight as a rook and check diagonally as a bishop // or move diagonally as a bishop and check straight as a rook. Bitmask squares = (targets_for(p, from, rook(color)) & checks) | (targets_for(p, from, bishop(color)) & targets_for(p, square, rook(color))); add_piece_move(self, from, squares & ~p->board); } } // Non-capturing Rook or Queen checks. checks = targets_for(p, square, rook(enemy)); outposts = p->outposts[rook(color)] | p->outposts[queen(color)]; while (any(outposts)) { int from = pop(&outposts); Bitmask squares = targets_for(p, from, rook(enemy)) & checks & ~p->outposts[enemy]; while (any(squares)) { int to = pop(&squares); Piece piece = p->pieces[to]; if (!piece) { // Empty square: simply move a rook to check. append(self, new_move(p, from, to)); } else if (color(piece) == color) { if (any(maskStraight[from][square])) { // Non-empty square occupied by friendly piece on the same // file or rank: moving the piece away causes discovered check. switch (kind(piece)) { case Pawn: // If pawn and rook share the same file then non-capturing // discovered check is not possible since the pawn is going // to stay on the same file no matter what. if (col(from) == col(to)) { continue; } // Block pawn promotions (since they are treated as captures) // and en-passant captures. prohibit = maskRank[0] | maskRank[7]; if (p->enpassant) { prohibit |= bit[p->enpassant]; } add_pawn_move(self, to, targets(p, to) & ~p->board & ~prohibit); break; case King: // Make sure the king steps out of attack file or rank. prohibit = maskNone; if (row(from) == row(square)) { prohibit = maskRank[row(from)]; } else { prohibit = maskFile[col(square)]; } add_king_move(self, to, targets(p, to) & ~p->board & ~prohibit); break; default: add_piece_move(self, to, targets(p, to) & ~p->board); } } } } } // Non-capturing Pawn checks. outposts = p->outposts[pawn(color)] & maskIsolated[col(square)]; while (any(outposts)) { int from = pop(&outposts); Bitmask target = maskPawn[color][square] & targets(p, from); if (any(target)) { append(self, new_pawn_move(p, from, pop(&target))); } } return self; }
int swmain(int argc, char *argv[]) { int nexttic; nobjects = (OBJECTS *) malloc(100 * sizeof(OBJECTS)); swinit(argc, argv); setjmp(envrestart); // sdh 28/10/2001: playmode is called from here now // makes for a more coherent progression through the setup process if (!playmode) getgamemode(); swinitlevel(); nexttic = Timer_GetMS(); skip_time = 0; for (;;) { int nowtime; /* generate a new move command periodically * and send to other players if neccessary */ nowtime = Timer_GetMS(); if (nowtime > nexttic && latest_player_time[player] - countmove < MAX_NET_LAG) { new_move(); /* Be accurate (exact amount between tics); * However, if a large spike occurs between tics, * catch up immediately. */ if (nowtime - nexttic > 1000) nexttic = nowtime + (1000/FPS); else nexttic += (1000 / FPS); // wait a bit longer to compensate for lag nexttic += skip_time; skip_time = 0; } asynupdate(); swsndupdate(); /* if we have all the tic commands we need, we can move */ if (can_move()) { calculate_lag(); //dump_cmds(); swmove(); swdisp(); swcollsn(); swsound(); } // sdh 15/11/2001: dont thrash the // processor while waiting Timer_Sleep(10); } return 0; }
/** * Computer player goes second * * @param game_state the current game state * @return a new state */ struct State * computer_player_second( struct State * game_state ) { struct State * state; struct Move * move; int random_move = 0; int row, col, i, j; /* find blank spot */ for( row = 0; row < SIZE; row++ ) for( col = 0; col < SIZE; col++ ) if( game_state->board[row][col] == 'O' ) { i = row; j = col; break; } srand( time( NULL ) ); /* select piece */ /* valid moves are on either side of empty space */ if( i == 0 && j == 0 ) { if( ( game_state->board[ i ][ j + 1 ] == 'W' ) || ( game_state->board[ i + 1][ j ] == 'W' ) ) { random_move = rand() % 2; switch( random_move ) { case 0: move = new_move( i, j+1, 0, 0 ); break; case 1: move = new_move( i+1, j, 0, 0 ); break; } } } else if( i == 0 && j == 7 ) { if( (game_state->board[ i ][ j - 1 ] == 'W' ) || (game_state->board[ i + 1 ][ j ] == 'W' ) ) { random_move = rand() % 2; switch( random_move ) { case 0: move = new_move( i, j-1, 0, 0 ); break; case 1: move = new_move( i+1, j, 0, 0 ); break; } } } else if( i == 7 && j == 0 ) { if( (game_state->board[ i ][ j + 1 ] == 'W' ) || (game_state->board[ i - 1 ][ j ] == 'W' ) ) { random_move = rand() % 2; switch( random_move ) { case 0: move = new_move( i, j+1, 0, 0 ); break; case 1: move = new_move( i-1, j, 0, 0 ); break; } } } else if( i == 7 && j == 7 ) { if( (game_state->board[ i ][ j - 1 ] == 'W' ) || (game_state->board[ i - 1 ][ j ] == 'W' ) ) { random_move = rand() % 2; switch( random_move ) { case 0: move = new_move( i, j-1, 0, 0 ); break; case 1: move = new_move( i-1, j, 0, 0 ); break; } } } else { if( (game_state->board[ i + 1 ][ j ] == 'W' ) || (game_state->board[ i - 1 ][ j ] == 'W' ) || (game_state->board[ i ][ j + 1 ] == 'W' ) || (game_state->board[ i ][ j - 1 ] == 'W' ) ) { random_move = rand() % 4; switch( random_move ) { case 0: move = new_move( i+1, j, 0, 0 ); break; case 1: move = new_move( i-1, j, 0, 0 ); break; case 2: move = new_move( i, j+1, 0, 0 ); break; case 3: move = new_move( i, j-1, 0, 0 ); break; } } } /* print move */ printf( "Move chosen: " ); print_single_move( move ); /* create new state */ state = new_state( game_state->board, opposite_player( game_state->player ) ); /* apply move */ state->board[ move->start_row ][ move->start_col ] = 'O'; Free( move, sizeof( struct Move ) ); return state; }
/** * Computer player goes first * * @param game_state the current state of the game * @return a new game state */ struct State * computer_player_first( struct State * game_state ) { struct State * state; struct Move * move; srand( time( NULL ) ); do { /* determine a move randomly */ int random_move = rand() % 8; switch( random_move ) { case 0: /* center top left */ move = new_move( 3, 3, 0, 0 ); break; case 1: /* center top right */ move = new_move( 3, 4, 0, 0 ); break; case 2: /* center botom left */ move = new_move( 4, 3, 0, 0 ); break; case 3: /* center bottom right */ move = new_move( 4, 4, 0, 0 ); break; #if 1 case 4: /* corner top left */ move = new_move( 0, 0, 0, 0 ); break; case 5: /* corner top right */ move = new_move( 0, 7, 0, 0 ); break; case 6: /* corner bottom left */ move = new_move( 7, 0, 0, 0 ); break; case 7: /* corner bottom right */ move = new_move( 7, 7, 0, 0 ); break; #endif } /* check if move is valid */ if( game_state->board[ move->start_row ][ move->start_col ] == 'B' ) { break; } else { Free( move, sizeof( struct Move ) ); } } while( 1 ); /* print move */ printf( "Move chosen: " ); print_single_move( move ); /* create new state */ state = new_state( game_state->board, opposite_player( game_state->player ) ); /* apply move */ state->board[ move->start_row ][ move->start_col ] = 'O'; Free( move, sizeof( struct Move ) ); return state; }
void test_game_suite__000(void) { new_game(); Position *p = start(); Move m0 = new_move(p, E2, E4); Move m1 = new_move(p, E7, E5); Move m2 = new_move(p, G1, F3); Move m3 = new_move(p, B8, C6); Move m4 = new_move(p, F1, B5); save_best(0, m0); save_best(1, m1); save_best(2, m2); save_best(3, m3); save_best(4, m4); cl_check(game.pv[0].size == 1); cl_check(game.pv[0].moves[0] == m0); cl_check(game.pv[1].size == 2); cl_check(game.pv[1].moves[0] == (Move)0); cl_check(game.pv[1].moves[1] == m1); cl_check(game.pv[2].size == 3); cl_check(game.pv[2].moves[0] == (Move)0); cl_check(game.pv[2].moves[1] == (Move)0); cl_check(game.pv[2].moves[2] == m2); cl_check(game.pv[3].size == 4); cl_check(game.pv[3].moves[0] == (Move)0); cl_check(game.pv[3].moves[1] == (Move)0); cl_check(game.pv[3].moves[2] == (Move)0); cl_check(game.pv[3].moves[3] == m3); cl_check(game.pv[4].size == 5); cl_check(game.pv[4].moves[0] == (Move)0); cl_check(game.pv[4].moves[1] == (Move)0); cl_check(game.pv[4].moves[2] == (Move)0); cl_check(game.pv[4].moves[3] == (Move)0); cl_check(game.pv[4].moves[4] == m4); Move m5 = new_move(p, A7, A6); save_best(1, m5); cl_check(game.pv[0].size == 1); cl_check(game.pv[0].moves[0] == m0); cl_check(game.pv[1].size == 3); // <-- cl_check(game.pv[1].moves[0] == (Move)0); cl_check(game.pv[1].moves[1] == m5); // <-- cl_check(game.pv[1].moves[2] == game.pv[2].moves[2]); // <-- cl_check(game.pv[2].size == 3); cl_check(game.pv[2].moves[0] == (Move)0); cl_check(game.pv[2].moves[1] == (Move)0); cl_check(game.pv[2].moves[2] == m2); cl_check(game.pv[3].size == 4); cl_check(game.pv[3].moves[0] == (Move)0); cl_check(game.pv[3].moves[1] == (Move)0); cl_check(game.pv[3].moves[2] == (Move)0); cl_check(game.pv[3].moves[3] == m3); cl_check(game.pv[4].size == 5); cl_check(game.pv[4].moves[0] == (Move)0); cl_check(game.pv[4].moves[1] == (Move)0); cl_check(game.pv[4].moves[2] == (Move)0); cl_check(game.pv[4].moves[3] == (Move)0); cl_check(game.pv[4].moves[4] == m4); }