static game_state *execute_move(game_state *from, char *move) { int w = from->par.w, a = w*w; game_state *ret; int x, y, i, n; if (move[0] == 'S') { ret = dup_game(from); ret->completed = ret->cheated = TRUE; for (i = 0; i < a; i++) { if (move[i+1] < '1' || move[i+1] > '0'+w) { free_game(ret); return NULL; } ret->grid[i] = move[i+1] - '0'; ret->pencil[i] = 0; } if (move[a+1] != '\0') { free_game(ret); return NULL; } return ret; } else if ((move[0] == 'P' || move[0] == 'R') && sscanf(move+1, "%d,%d,%d", &x, &y, &n) == 3 && x >= 0 && x < w && y >= 0 && y < w && n >= 0 && n <= w) { if (from->clues->immutable[y*w+x]) return NULL; ret = dup_game(from); if (move[0] == 'P' && n > 0) { ret->pencil[y*w+x] ^= 1L << n; } else { ret->grid[y*w+x] = n; ret->pencil[y*w+x] = 0; if (!ret->completed && !check_errors(ret, NULL)) ret->completed = TRUE; } return ret; } else if (move[0] == 'M') { /* * Fill in absolutely all pencil marks everywhere. (I * wouldn't use this for actual play, but it's a handy * starting point when following through a set of * diagnostics output by the standalone solver.) */ ret = dup_game(from); for (i = 0; i < a; i++) { if (!ret->grid[i]) ret->pencil[i] = (1L << (w+1)) - (1L << 1); } return ret; } else return NULL; /* couldn't parse move string */ }
/** * Handle button 'Quit'. * Closes window. */ int on_select_quit(Control* btn_quit) { if (game != NULL) { free_game(game); game = NULL; } return 1; }
int main(void) { TicTacToe game; int size; printf("This is the game of Tic Tac Toe.\n"); printf("You will be playing against the computer.\n"); printf("Enter the size of the board: "); scanf("%d", &size); printf("The game board is %d by %d.\n", size, size); init_game(&game, size); // initialise the board int done; do { print_game(game); do { done = player_move(&game); } while (!done); // loop until valid move if(check(&game) != FALSE) break; // was a winner or a draw computer_move(&game); if(check(&game) != FALSE) break; // was a winner or a draw } while (TRUE); print_result(game); print_game(game); // show final positions free_game(&game); return 0; }
/** * Returns to main menu without creating game. */ int on_cancel(Control* btn) { int (*handles[4])(Control*) = { empty_select, on_new_game, on_load_game, on_select_quit }; if (game != NULL) { free_game(game); game = NULL; } return !show_main_menu(get_root(btn), handles); }
static int proto_cli_leave_home_op(home_t* p_home, sprite_ol_t* p, void* data) { hero_cup_game_t* game = NULL; home_proto_t* p_proto = data; client_proto_t *cli = (client_proto_t*)p_proto->body; CHECK_BODY_LEN(p_proto->len, 20 + sizeof(home_proto_t) + sizeof(client_proto_t)); int i = 12; mapid_t newmap = 0; unpkg_mapid(cli->body,&newmap,&i); mapid_t gameid = (p_home->homeid & 0xFFFFFFFF00000000) | hero_cup_game_map; tranfer_to_home(p_home, data, p_proto->len); free_sprite_ol(p_home, p); if((gameid >> 56) != 0xFE) return 0; game = g_hash_table_lookup(all_games,&gameid); if(!game) { KDEBUG_LOG(p_proto->id,"LEAVE HOME: game(%x.%u) NOT EXSIT!",HI32(gameid),LO32(gameid)); return 0; } game->active--; if((newmap >> 56) != 0xFE) { if(game->active == 0) { free_game(NULL,game,NULL); return 0; } } attacker_t *atker = get_attacker(game,p_proto->id); if(!atker) { KDEBUG_LOG(p_proto->id,"LEAVE HOME: uid not in game(%x.%u)",HI32(gameid),LO32(gameid)); return 0; } if(atker->atkpos < 12) { position_t *weapon = &game->weapon[atker->atkpos]; if(weapon->uid == atker->userid) { weapon->state |= 1; weapon->card = 0; } else { weapon->state |= 2; weapon->atk_card = 0; } play_card_result(game,atker->atkpos); } if((newmap >> 56) != 0xFE) { del_attacker(game->group,atker->userid); } return 0; }
void free_all_chess_games( void ) { list < char_data * >::iterator ich; for( ich = pclist.begin( ); ich != pclist.end( ); ++ich ) { char_data *ch = *ich; free_game( ch->pcdata->game_board ); } }
int main(int argc, char *argv[]) { int CONTINUE,WINNER,HUMAN,COMPUTER; if(argc!=4) { fprintf(stderr,"Usage: mnkgame <row> <col> <k>\n"); return 1; } if(!read_parameters(argv)) return 1; if(!setup_game(M,N,K)) { fprintf(stderr,"Error: the board is too big!\n"); return 1; } COMPUTER=1; HUMAN=2; setup_player(M,N,K); printf("Computer Player ready\n"); mypause(); CONTINUE=N*M; WINNER=DRAW; while(CONTINUE>0) { if(read_move(PLAYER1,HUMAN)) { WINNER=PLAYER1; CONTINUE=0; } if(--CONTINUE>0) { if(read_move(PLAYER2,HUMAN)) { WINNER=PLAYER2; CONTINUE=0; } --CONTINUE; } } system("cls"); print_board(); end_game(WINNER,HUMAN); free_player(); free_game(); return 0; }
void game_done(void) { #ifdef CLEANUP_CODE /* Diese Routine enfernt allen allokierten Speicher wieder. Das ist nur * zum Debugging interessant, wenn man Leak Detection hat, und nach * nicht freigegebenem Speicher sucht, der nicht bis zum Ende benötigt * wird (temporäre Hilsstrukturen) */ free_game(); creport_cleanup(); #ifdef REPORT_FORMAT_NR report_cleanup(); #endif calendar_cleanup(); #endif free_functions(); curses_done(); kernel_done(); }
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 ); }
int main(int argc, const char *argv[]) { mt_seed(); unsigned int i,j; unsigned int total_games=100; double b; unsigned int **count; unsigned int **count_aux; count=malloc(total_games*sizeof(unsigned int *)); count_aux=malloc(total_games*sizeof(unsigned int *)); unsigned int **coop_cluster; coop_cluster=malloc(total_games*sizeof(unsigned int *)); for (i = 0; i < total_games; i++) coop_cluster[i]=NULL; double coop_mean; double coop_fixed_mean; double coop_isolated_mean; double coop_cluster_mean; double coop_effective_surface_mean; unsigned int **def_cluster; def_cluster=malloc(total_games*sizeof(unsigned int *)); for (i = 0; i < total_games; i++) def_cluster[i]=NULL; double def_mean; double def_fixed_mean; double def_isolated_mean; double def_cluster_mean; double def_effective_surface_mean; unsigned int *iter; unsigned int iter0=5000; unsigned int iter1; unsigned int iter_mean; iter=malloc(total_games*sizeof(unsigned int)); FILE *f; f=fopen("data_iter2.csv","w"); fprintf(f,"b\t"); fprintf(f,"coop_mean\tcoop_fixed_mean\tcoop_isolated_mean\tcoop_cluster_mean\tcoop_effective_surface_mean\t"); fprintf(f,"def_mean\tdef_fixed_mean\tdef_isolated_mean\tdef_cluster_mean\tdef_effective_surface_mean\t"); fprintf(f,"iter_mean\n"); fclose(f); struct game gam; struct game *g_aux; g_aux=&gam; for (b = 1.5; b < 2.0; b+=0.05) { for (j = 0; j < total_games;) { gam=create_prisioner_dilemma_game(b,4000,8000,1); for (i = 0; i < iter0; i++) evolve_game(g_aux,0); iter[j]=iter0; iter1=1000; do { count[j]=count_type(gam); for (i = 0; i < iter1; i++) evolve_game(g_aux,0); iter[j]+=iter1; count_aux[j]=count_type(gam); } while (abs(count[j][0]-count_aux[j][0])>10); iter1=10000; for (i = 0; i < iter1; i++) evolve_game(g_aux,0); iter1=1000; for (i = 0; i < iter1; i++) evolve_game(g_aux,1); free(count[j]); free(coop_cluster[j]); free(def_cluster[j]); count[j]=count_type(gam); coop_cluster[j]=cluster_analize(gam,0); def_cluster[j]=cluster_analize(gam,1); /* if(coop_cluster[j][2]==0) printf("b: %.3lf game: %u FAILED, COOPERATORS DESTROYED\n",b,j); else if(def_cluster[j][2]==0) printf("b: %.3lf game: %u FAILED, DEFECTORS DESTROYED\n",b,j); else {*/ printf("b: %.3lf game: %u DONE\n",b,j); j++; //} //graph_to_file("grafo.gdf",gam.g,1); free_game(g_aux); } coop_mean=0; coop_fixed_mean=0; coop_isolated_mean=0; coop_cluster_mean=0; coop_effective_surface_mean=0; def_mean=0; def_fixed_mean=0; def_isolated_mean=0; def_cluster_mean=0; def_effective_surface_mean=0; iter_mean=0; for (i = 0; i < total_games; i++) { coop_mean+=(double)count[i][0]/total_games; coop_fixed_mean+=(double)coop_cluster[i][2]/total_games; coop_isolated_mean+=(double)coop_cluster[i][4]/total_games; coop_cluster_mean+=(double)(coop_cluster[i][0]-coop_cluster[i][1])/total_games; coop_effective_surface_mean+=(double)coop_cluster[i][3]/(coop_cluster[i][2]-coop_cluster[i][4])/total_games; def_mean+=(double)count[i][1]/total_games; def_fixed_mean+=(double)def_cluster[i][2]/total_games; def_isolated_mean+=(double)def_cluster[i][4]/total_games; def_cluster_mean+=(double)(def_cluster[i][0]-def_cluster[i][1])/total_games; def_effective_surface_mean+=(double)def_cluster[i][3]/(def_cluster[i][2]-def_cluster[i][4])/total_games; iter_mean+=iter[i]/total_games; } coop_mean/=4000.; coop_fixed_mean/=4000.; coop_isolated_mean/=4000.; def_mean/=4000.; def_fixed_mean/=4000.; def_isolated_mean/=4000.; f=fopen("data_iter2.csv","a"); fprintf(f,"%lf\t",b); fprintf(f,"%lf\t%lf\t%lf\t%lf\t%lf\t",coop_mean,coop_fixed_mean,coop_isolated_mean,coop_cluster_mean,coop_effective_surface_mean); fprintf(f,"%lf\t%lf\t%lf\t%lf\t%lf\t",def_mean,def_fixed_mean,def_isolated_mean,def_cluster_mean,def_effective_surface_mean); fprintf(f,"%u\n",iter_mean); fclose(f); printf("\n"); } return 0; }
static game_state *execute_move(game_state *from, char *move) { game_state *ret = dup_game(from); int gx = -1, gy = -1, rangeno = -1; if (ret->justwrong) { int i; ret->justwrong = FALSE; for (i = 0; i < ret->nlasers; i++) if (ret->exits[i] != LASER_EMPTY) ret->exits[i] &= ~(LASER_OMITTED | LASER_WRONG); } if (!strcmp(move, "S")) { check_guesses(ret, FALSE); return ret; } if (from->reveal) goto badmove; if (!*move) goto badmove; switch (move[0]) { case 'T': sscanf(move+1, "%d,%d", &gx, &gy); if (gx < 1 || gy < 1 || gx > ret->w || gy > ret->h) goto badmove; if (GRID(ret, gx, gy) & BALL_GUESS) { ret->nguesses--; GRID(ret, gx, gy) &= ~BALL_GUESS; } else { ret->nguesses++; GRID(ret, gx, gy) |= BALL_GUESS; } break; case 'F': sscanf(move+1, "%d", &rangeno); if (ret->exits[rangeno] != LASER_EMPTY) goto badmove; if (!RANGECHECK(ret, rangeno)) goto badmove; fire_laser(ret, rangeno); break; case 'R': if (ret->nguesses < ret->minballs || ret->nguesses > ret->maxballs) goto badmove; check_guesses(ret, TRUE); break; case 'L': { int lcount = 0; if (strlen(move) < 2) goto badmove; switch (move[1]) { case 'B': sscanf(move+2, "%d,%d", &gx, &gy); if (gx < 1 || gy < 1 || gx > ret->w || gy > ret->h) goto badmove; GRID(ret, gx, gy) ^= BALL_LOCK; break; #define COUNTLOCK do { if (GRID(ret, gx, gy) & BALL_LOCK) lcount++; } while (0) #define SETLOCKIF(c) do { \ if (lcount > (c)) GRID(ret, gx, gy) &= ~BALL_LOCK; \ else GRID(ret, gx, gy) |= BALL_LOCK; \ } while(0) case 'C': sscanf(move+2, "%d", &gx); if (gx < 1 || gx > ret->w) goto badmove; for (gy = 1; gy <= ret->h; gy++) { COUNTLOCK; } for (gy = 1; gy <= ret->h; gy++) { SETLOCKIF(ret->h/2); } break; case 'R': sscanf(move+2, "%d", &gy); if (gy < 1 || gy > ret->h) goto badmove; for (gx = 1; gx <= ret->w; gx++) { COUNTLOCK; } for (gx = 1; gx <= ret->w; gx++) { SETLOCKIF(ret->w/2); } break; #undef COUNTLOCK #undef SETLOCKIF default: goto badmove; } } break; default: goto badmove; } return ret; badmove: free_game(ret); return NULL; }
/* Checks that the guessed balls in the state match up with the real balls * for all possible lasers (i.e. not just the ones that the player might * have already guessed). This is required because any layout with >4 balls * might have multiple valid solutions. Returns non-zero for a 'correct' * (i.e. consistent) layout. */ static int check_guesses(game_state *state, int cagey) { game_state *solution, *guesses; int i, x, y, n, unused, tmp; int ret = 0; if (cagey) { /* * First, check that each laser the player has already * fired is consistent with the layout. If not, show them * one error they've made and reveal no further * information. * * Failing that, check to see whether the player would have * been able to fire any laser which distinguished the real * solution from their guess. If so, show them one such * laser and reveal no further information. */ guesses = dup_game(state); /* clear out BALL_CORRECT on guess, make BALL_GUESS BALL_CORRECT. */ for (x = 1; x <= state->w; x++) { for (y = 1; y <= state->h; y++) { GRID(guesses, x, y) &= ~BALL_CORRECT; if (GRID(guesses, x, y) & BALL_GUESS) GRID(guesses, x, y) |= BALL_CORRECT; } } n = 0; for (i = 0; i < guesses->nlasers; i++) { if (guesses->exits[i] != LASER_EMPTY && guesses->exits[i] != laser_exit(guesses, i)) n++; } if (n) { /* * At least one of the player's existing lasers * contradicts their ball placement. Pick a random one, * highlight it, and return. * * A temporary random state is created from the current * grid, so that repeating the same marking will give * the same answer instead of a different one. */ random_state *rs = random_new((char *)guesses->grid, (state->w+2)*(state->h+2) * sizeof(unsigned int)); n = random_upto(rs, n); random_free(rs); for (i = 0; i < guesses->nlasers; i++) { if (guesses->exits[i] != LASER_EMPTY && guesses->exits[i] != laser_exit(guesses, i) && n-- == 0) { state->exits[i] |= LASER_WRONG; tmp = laser_exit(state, i); if (RANGECHECK(state, tmp)) state->exits[tmp] |= LASER_WRONG; state->justwrong = TRUE; free_game(guesses); return 0; } } } n = 0; for (i = 0; i < guesses->nlasers; i++) { if (guesses->exits[i] == LASER_EMPTY && laser_exit(state, i) != laser_exit(guesses, i)) n++; } if (n) { /* * At least one of the player's unfired lasers would * demonstrate their ball placement to be wrong. Pick a * random one, highlight it, and return. * * A temporary random state is created from the current * grid, so that repeating the same marking will give * the same answer instead of a different one. */ random_state *rs = random_new((char *)guesses->grid, (state->w+2)*(state->h+2) * sizeof(unsigned int)); n = random_upto(rs, n); random_free(rs); for (i = 0; i < guesses->nlasers; i++) { if (guesses->exits[i] == LASER_EMPTY && laser_exit(state, i) != laser_exit(guesses, i) && n-- == 0) { fire_laser(state, i); state->exits[i] |= LASER_OMITTED; tmp = laser_exit(state, i); if (RANGECHECK(state, tmp)) state->exits[tmp] |= LASER_OMITTED; state->justwrong = TRUE; free_game(guesses); return 0; } } } free_game(guesses); } /* duplicate the state (to solution) */ solution = dup_game(state); /* clear out the lasers of solution */ for (i = 0; i < solution->nlasers; i++) { tmp = range2grid(solution, i, &x, &y, &unused); assert(tmp); GRID(solution, x, y) = 0; solution->exits[i] = LASER_EMPTY; } /* duplicate solution to guess. */ guesses = dup_game(solution); /* clear out BALL_CORRECT on guess, make BALL_GUESS BALL_CORRECT. */ for (x = 1; x <= state->w; x++) { for (y = 1; y <= state->h; y++) { GRID(guesses, x, y) &= ~BALL_CORRECT; if (GRID(guesses, x, y) & BALL_GUESS) GRID(guesses, x, y) |= BALL_CORRECT; } } /* for each laser (on both game_states), fire it if it hasn't been fired. * If one has been fired (or received a hit) and another hasn't, we know * the ball layouts didn't match and can short-circuit return. */ for (i = 0; i < solution->nlasers; i++) { if (solution->exits[i] == LASER_EMPTY) fire_laser(solution, i); if (guesses->exits[i] == LASER_EMPTY) fire_laser(guesses, i); } /* check each game_state's laser against the other; if any differ, return 0 */ ret = 1; for (i = 0; i < solution->nlasers; i++) { tmp = range2grid(solution, i, &x, &y, &unused); assert(tmp); if (solution->exits[i] != guesses->exits[i]) { /* If the original state didn't have this shot fired, * and it would be wrong between the guess and the solution, * add it. */ if (state->exits[i] == LASER_EMPTY) { state->exits[i] = solution->exits[i]; if (state->exits[i] == LASER_REFLECT || state->exits[i] == LASER_HIT) GRID(state, x, y) = state->exits[i]; else { /* add a new shot, incrementing state's laser count. */ int ex, ey, newno = state->laserno++; tmp = range2grid(state, state->exits[i], &ex, &ey, &unused); assert(tmp); GRID(state, x, y) = newno; GRID(state, ex, ey) = newno; } state->exits[i] |= LASER_OMITTED; } else { state->exits[i] |= LASER_WRONG; } ret = 0; } } if (ret == 0 || state->nguesses < state->minballs || state->nguesses > state->maxballs) goto done; /* fix up original state so the 'correct' balls end up matching the guesses, * as we've just proved that they were equivalent. */ for (x = 1; x <= state->w; x++) { for (y = 1; y <= state->h; y++) { if (GRID(state, x, y) & BALL_GUESS) GRID(state, x, y) |= BALL_CORRECT; else GRID(state, x, y) &= ~BALL_CORRECT; } } done: /* fill in nright and nwrong. */ state->nright = state->nwrong = state->nmissed = 0; for (x = 1; x <= state->w; x++) { for (y = 1; y <= state->h; y++) { int bs = GRID(state, x, y) & (BALL_GUESS | BALL_CORRECT); if (bs == (BALL_GUESS | BALL_CORRECT)) state->nright++; else if (bs == BALL_GUESS) state->nwrong++; else if (bs == BALL_CORRECT) state->nmissed++; } } free_game(solution); free_game(guesses); state->reveal = 1; return ret; }
void __fastcall run_game_loop(int uMsg) { //int v3; // eax bool v5; // zf //int v6; // eax signed int v7; // [esp+8h] [ebp-24h] LRESULT (__stdcall *saveProc)(HWND, UINT, WPARAM, LPARAM); // [esp+Ch] [ebp-20h] struct tagMSG msg; // [esp+10h] [ebp-1Ch] nthread_ignore_mutex(1); start_game(uMsg); saveProc = SetWindowProc(GM_Game); control_update_life_mana(); msg_process_net_packets(); gbRunGame = 1; gbProcessPlayers = 1; gbRunGameResult = 1; drawpanflag = 255; DrawAndBlit(); PaletteFadeIn(8); drawpanflag = 255; gbGameLoopStartup = 1; nthread_ignore_mutex(0); while ( gbRunGame ) { diablo_color_cyc_logic(); if ( PeekMessageA(&msg, NULL, 0, 0, PM_NOREMOVE) ) { SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_ABOVE_NORMAL); while ( PeekMessageA(&msg, NULL, 0, 0, PM_REMOVE) ) { if ( msg.message == WM_QUIT ) { gbRunGameResult = 0; gbRunGame = 0; break; } TranslateMessage(&msg); DispatchMessageA(&msg); } if ( !gbRunGame || (v7 = 1, !nthread_has_500ms_passed()) ) v7 = 0; SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_NORMAL); v5 = v7 == 0; } else { //_LOBYTE(v6) = nthread_has_500ms_passed(); v5 = nthread_has_500ms_passed() == 0; } if ( !v5 ) { multi_process_network_packets(); game_loop(gbGameLoopStartup); msgcmd_send_chat(); gbGameLoopStartup = 0; DrawAndBlit(); } #ifdef SLEEP Sleep(1); #endif } if ( (unsigned char)gbMaxPlayers > 1u ) pfile_write_hero(); pfile_flush_W(); PaletteFadeOut(8); SetCursor(0); ClearScreenBuffer(); drawpanflag = 255; scrollrt_draw_game_screen(1); SetWindowProc(saveProc); free_game(); if ( cineflag ) { cineflag = 0; DoEnding(); } }
/////////////////////////////////// // MAIN (only for internal test) // /////////////////////////////////// int main () { // Valgrind run init_chess_library (); int i, from, to; for (i = 0; i < 1000; i++) { Game *g = init_game (); Board *board; char *fen; // 1. e4 a6 2. Bc4 a5 3. Qh5 a4 4. Qxf7# board = current_board (g); get_coord (board, 'P', "e", "e4", 0, &from, &to); pseudo_legal_move (board, from, to); apply_move (g, from, to, 0); fen = to_fen (board); free (fen); board = current_board (g); get_coord (board, 'P', "a", "a6", 0, &from, &to); pseudo_legal_move (board, from, to); apply_move (g, from, to, 0); fen = to_fen (current_board (g)); free (fen); board = current_board (g); get_coord (board, 'B', "", "c4", 0, &from, &to); pseudo_legal_move (board, from, to); apply_move (g, from, to, 0); fen = to_fen (current_board (g)); free (fen); board = current_board (g); get_coord (board, 'P', "a", "a5", 0, &from, &to); pseudo_legal_move (board, from, to); apply_move (g, from, to, 0); fen = to_fen (current_board (g)); free (fen); board = current_board (g); get_coord (board, 'Q', "", "h5", 0, &from, &to); pseudo_legal_move (board, from, to); apply_move (g, from, to, 0); fen = to_fen (current_board (g)); free (fen); board = current_board (g); get_coord (board, 'P', "a", "a4", 0, &from, &to); pseudo_legal_move (board, from, to); apply_move (g, from, to, 0); fen = to_fen (current_board (g)); free (fen); board = current_board (g); get_coord (board, 'Q', "", "f7", 0, &from, &to); pseudo_legal_move (board, from, to); apply_move (g, from, to, 0); fen = to_fen (current_board (g)); free (fen); free_game (g); } return 0; }