void actor_destroyed(int a, int source) { actor[a].in_play = 0; actor[a].spawn_delay = 50; // actor[a].lock = -1; // actor[a].turret_lock = -1; // actor[a].x = grand(arena.max_x - 100000) + 50000; // actor[a].y = grand(arena.max_y - 100000) + 50000; actor[a].next_spawn_x = grand(arena.max_x - 100000) + 50000; actor[a].next_spawn_y = grand(arena.max_y - 100000) + 50000; int e; for (e = 0; e < NO_ENEMIES; e ++) { if (enemy[e].type == ENEMY_NONE) continue; if (enemy[e].attacking == a) enemy[e].attacking = ATTACK_NONE; } if (game.type == GAME_DUEL) { score_duel_kill(a, source); return; } if (game.type == GAME_TIME_ATTACK || game.type == GAME_TIME_ATTACK_COOP) { arena.time_left -= 33.333 * 30; if (arena.time_left < 1) arena.time_left = 1; return; } if (game.ships_left == 0) { if (game.users == 1) game_is_over(); else { if (actor[0].in_play == 0 && actor[1].in_play == 0) game_is_over(); } } }
void GamePainter::gameOver() { hide(); m_IsPlay = false; m_gameTimer->stop(); emit game_is_over( m_score ); }
// ZZZ: split out from update_world()'s loop. static int update_world_elements_one_tick() { if (m1_solo_player_in_terminal()) { update_m1_solo_player_in_terminal(GameQueue); } else { L_Call_Idle(); update_lights(); update_medias(); update_platforms(); update_control_panels(); // don't put after update_players update_players(GameQueue, false); move_projectiles(); move_monsters(); update_effects(); recreate_objects(); handle_random_sound_image(); animate_scenery(); // LP additions: if (film_profile.animate_items) { animate_items(); } AnimTxtr_Update(); ChaseCam_Update(); motion_sensor_scan(); check_m1_exploration(); #if !defined(DISABLE_NETWORKING) update_net_game(); #endif // !defined(DISABLE_NETWORKING) } if(check_level_change()) { return kUpdateChangeLevel; } #if !defined(DISABLE_NETWORKING) if(game_is_over()) { return kUpdateGameOver; } #endif // !defined(DISABLE_NETWORKING) dynamic_world->tick_count+= 1; dynamic_world->game_information.game_time_remaining-= 1; return kUpdateNormalCompletion; }
/* brute-force search of the _entire game tree_. at completion, final_value will be the best value for 'maximizer'. returns a pointer to the best move. */ turn_t* minimax(board_t* board, int maximizer, int* final_value, long int* turn_count, int depth){ // only one base case: all the way to the end. careful with large boards! if(game_is_over(board)){ (*final_value) = board->scores[maximizer] - board->scores[1-maximizer]; return NULL; } turn_t* best_turn = board->sentinel; bool max = board->player_turn == maximizer; int score, best_score = max ? INT_MIN : INT_MAX; // loop over all possible turns for(turn_t* current_turn = board->sentinel->next; current_turn != board->sentinel; current_turn = current_turn->next){ #ifdef DEBUG printf("%d\t", board->player_turn); #endif // perform turn, remove it from DLLs execute_turn(current_turn, board); turn_t* memo = remove_turn_dll(current_turn); // we count all calls of execute_turn for stats on pruning factor (*turn_count)++; #ifdef DEBUG for(int i=0; i<depth; ++i) printf(" "); printf("%d %d %d : %d %d\n", current_turn->row, current_turn->col, current_turn->wall, board->scores[0], board->scores[1]); #endif // recurse to next level of the tree (without current_turn as an option anymore) minimax(board, maximizer, &score, turn_count, depth+1); // recursion done; undo move unexecute_turn(current_turn, board); add_turn_dll(memo, current_turn); if(max){ // MAX algorithm best_turn = score > best_score ? current_turn : best_turn; best_score = max(best_score, score); } else{ // MIN algorithm best_turn = score < best_score ? current_turn : best_turn; best_score = min(best_score, score); } } (*final_value) = best_score; return best_turn; }
MOVE search_tree(GAME *game, int *best_vector, int to_depth, int *window_vector, int window_player) { MOVE moves[MAX_MOVES]; int num_moves; int i; MOVE best_move = MOVE_INVALID; int player; unsigned int hash; if (to_depth <= 0 || game_is_over(game)) { evaluate_game_immediate(game, best_vector); return best_move; } #ifdef USE_TRANSPOSITION_TABLE_SEARCH hash = hash_game(game) % TRANSPOSITION_TABLE_SIZE; if (transposition_table[hash][0] != TABLE_UNUSED) { memcpy(best_vector, transposition_table[hash], sizeof(int)*MAX_PLAYERS); hit_count++; return best_move; } #endif num_moves = generate_valid_moves(game, moves); player = game->current_player; for (i = 0; i < num_moves; i++) { GAME *game2 = clone_game(game); int vector[MAX_PLAYERS]; MOVE move; apply_move(game2, moves[i]); node_count++; move = search_tree(game2, vector, to_depth - 1, best_vector, player); if (move == MOVE_INVALID) move = moves[i]; if (i == 0 || vector[player] > best_vector[player]) { memcpy(best_vector, vector, sizeof(vector)); best_move = moves[i]; } stack_pop(&game_stack, game2); /* Prune if this move is so good for the current player that the potential value for the window player is less than the window. */ if (vector[player] > parameters.total_score - window_vector[window_player]) { break; } } #ifdef USE_TRANSPOSITION_TABLE_SEARCH memcpy(transposition_table[hash], best_vector, sizeof(int)*MAX_PLAYERS); #endif return best_move; }
int IA(int player,int depth,int lx,int ly,int w1x,int w1y,int w2x,int w2y,int w3x,int w3y,int w4x,int w4y,int w5x,int w5y) { int count = 0,k; t_association pawn[6]={{NULL,{lx,ly}},{NULL,{w1x,w1y}},{NULL,{w2x,w2y}},{NULL,{w3x,w3y}},{NULL,{w4x,w4y}},{NULL,{w5x,w5y}}}; //printf("mouton %d:%d , loups : %d:%d %d:%d %d:%d %d:%d %d:%d\n",lx,ly,w1x,w1y,w2x,w2y,w3x,w3y,w4x,w4y,w5x,w5y); if(game_is_over(pawn)) { if(lamb_won(pawn)) { return importance(depth); } else { return (-1 * importance(depth)); } } if(depth == 0) return 0; if(player == LAMB) { if(possible_and_free(lx+1,ly+1,pawn) && isnt_too_far(lx+1,ly+1,pawn)) count += IA(WOLF,depth - 1,lx+1,ly+1,w1x,w1y,w2x,w2y,w3x,w3y,w4x,w4y,w5x,w5y); if(possible_and_free(lx+1,ly-1,pawn) && isnt_too_far(lx+1,ly-1,pawn)) count += IA(WOLF,depth - 1,lx+1,ly-1,w1x,w1y,w2x,w2y,w3x,w3y,w4x,w4y,w5x,w5y); if(possible_and_free(lx-1,ly+1,pawn) && isnt_too_far(lx-1,ly+1,pawn)) count += IA(WOLF,depth - 1,lx-1,ly+1,w1x,w1y,w2x,w2y,w3x,w3y,w4x,w4y,w5x,w5y); if(possible_and_free(lx-1,ly-1,pawn) && isnt_too_far(lx-1,ly-1,pawn)) count += IA(WOLF,depth - 1,lx-1,ly-1,w1x,w1y,w2x,w2y,w3x,w3y,w4x,w4y,w5x,w5y); } else { for(k=1;k<6;k++) { if(possible_and_free(pawn[k].position.x+1,pawn[k].position.y-1,pawn)) { switch(k) { case 1: count += IA(LAMB,depth - 1,lx,ly,w1x+1,w1y-1,w2x,w2y,w3x,w3y,w4x,w4y,w5x,w5y); break; case 2: count += IA(LAMB,depth - 1,lx,ly,w1x,w1y,w2x+1,w2y-1,w3x,w3y,w4x,w4y,w5x,w5y); break; case 3: count += IA(LAMB,depth - 1,lx,ly,w1x,w1y,w2x,w2y,w3x+1,w3y-1,w4x,w4y,w5x,w5y); break; case 4: count += IA(LAMB,depth - 1,lx,ly,w1x,w1y,w2x,w2y,w3x,w3y,w4x+1,w4y-1,w5x,w5y); break; case 5: count += IA(LAMB,depth - 1,lx,ly,w1x,w1y,w2x,w2y,w3x,w3y,w4x,w4y,w5x+1,w5y-1); break; } } if(possible_and_free(pawn[k].position.x-1,pawn[k].position.y-1,pawn)) { switch(k) { case 1: count += IA(LAMB,depth - 1,lx,ly,w1x-1,w1y-1,w2x,w2y,w3x,w3y,w4x,w4y,w5x,w5y); break; case 2: count += IA(LAMB,depth - 1,lx,ly,w1x,w1y,w2x-1,w2y-1,w3x,w3y,w4x,w4y,w5x,w5y); break; case 3: count += IA(LAMB,depth - 1,lx,ly,w1x,w1y,w2x,w2y,w3x-1,w3y-1,w4x,w4y,w5x,w5y); break; case 4: count += IA(LAMB,depth - 1,lx,ly,w1x,w1y,w2x,w2y,w3x,w3y,w4x-1,w4y-1,w5x,w5y); break; case 5: count += IA(LAMB,depth - 1,lx,ly,w1x,w1y,w2x,w2y,w3x,w3y,w4x,w4y,w5x-1,w5y-1); break; } } } } return count; }
/* Note - in capflag and porkball, sactor is a team number, not an actor. */ void score_event(int sactor, int event, int event2) { if (game_over != 0) return; if (serial[0].game_type == SERIAL_CLIENT) return; // only server is authorised to affect the score int i = 0; if (arena[0].teams == 0) { switch(event) { case SCORE_LFRUIT: user[actor[sactor].user].score += 2; // intentional fall-through... case SCORE_MFRUIT: user[actor[sactor].user].score += 2; // intentional fall-through... case SCORE_SFRUIT: user[actor[sactor].user].score ++; update_score(); score_message(SMESSAGE_FRUIT, actor[sactor].user, event2, 0); /* char fstring [50]; strcpy(fstring, user[actor[sactor].user].uname); strcat(fstring, " eats a"); switch(event2) { case FRUITS_FIG: strcat(fstring, " fig."); break; case FRUITS_CHERRY: strcat(fstring, " cherry."); break; case FRUITS_BLUEBERRY: strcat(fstring, " blueberry."); break; case FRUITS_STRAWBERRY: strcat(fstring, " strawberry."); break; case FRUITM_PEACH: strcat(fstring, " peach."); break; case FRUITM_RAPPLE: strcat(fstring, "n apple."); break; case FRUITM_PEAR: strcat(fstring, " pear."); break; case FRUITL_DURIAN: strcat(fstring, " durian."); break; case FRUITL_PINEAPPLE: strcat(fstring, " pineapple."); break; } teamed_message(-1, fstring, actor[sactor].team);*/ if (user[actor[sactor].user].score >= game[0].score_limit) { game_is_over(actor[sactor].user); // game_over = 200; // end_game(); } break; case SCORE_KILL: // last one standing gives you a score, though it's not used. if (game[0].game_type != GAME_KILL && game[0].game_type != GAME_LAST_ONE) break; case SCORE_FLAG: case SCORE_GRAIL: user[actor[sactor].user].score ++; update_score(); if (user[actor[sactor].user].score >= game[0].score_limit) { game_is_over(actor[sactor].user); // game_over = 200; // end_game(); } break; case SCORE_SUICIDE: if (game[0].game_type == GAME_KILL || game[0].game_type == GAME_LAST_ONE) { if (user[actor[sactor].user].score > 0) { user[actor[sactor].user].score --; update_score(); } } break; } } else { // Teams now: switch(event) { case SCORE_LFRUIT: team[user[actor[sactor].user].team].score += 2; // intentional fall-through... case SCORE_MFRUIT: team[user[actor[sactor].user].team].score += 2; // intentional fall-through... case SCORE_SFRUIT: team[user[actor[sactor].user].team].score ++; update_score(); score_message(SMESSAGE_FRUIT, actor[sactor].user, event2, 0); /* char fstring [50]; strcpy(fstring, user[actor[sactor].user].uname); strcat(fstring, " eats a"); switch(event2) { case FRUITS_FIG: strcat(fstring, " fig."); break; case FRUITS_CHERRY: strcat(fstring, " cherry."); break; case FRUITS_BLUEBERRY: strcat(fstring, " blueberry."); break; case FRUITS_STRAWBERRY: strcat(fstring, " strawberry."); break; case FRUITM_PEACH: strcat(fstring, " peach."); break; case FRUITM_RAPPLE: strcat(fstring, "n apple."); break; case FRUITM_PEAR: strcat(fstring, " pear."); break; case FRUITL_DURIAN: strcat(fstring, " durian."); break; case FRUITL_PINEAPPLE: strcat(fstring, " pineapple."); break; } teamed_message(-1, fstring, actor[sactor].team);*/ if (team[user[actor[sactor].user].team].score >= game[0].score_limit) { game_is_over(actor[sactor].team); // game_over = 200; // end_game(); } break; case SCORE_KILL: // last one standing gives you a score, though it's not used. if (game[0].game_type != GAME_KILL && game[0].game_type != GAME_LAST_ONE) break; if (user[actor[sactor].user].team == user[actor[event2].user].team) { if (team[user[actor[sactor].user].team].score > 0) { team[user[actor[sactor].user].team].score --; update_score(); } break; } team[user[actor[sactor].user].team].score ++; update_score(); if (team[user[actor[sactor].user].team].score >= game[0].score_limit) { game_is_over(actor[sactor].team); // game_over = 200; } break; case SCORE_GOAL: case SCORE_FLAG: team[sactor].score ++; for (i = 0; i < NO_TEAMS; i ++) { if (i != event2) team[i].score ++; if (team[i].score >= game[0].score_limit) { game_is_over(actor[sactor].team); // game_over = 200; } } update_score(); break; case SCORE_TH: team[sactor].score ++; update_score(); if (team[sactor].score >= game[0].score_limit) { game_is_over(actor[sactor].team); // game_over = 200; // end_game(); } break; case SCORE_GRAIL: team[user[actor[sactor].user].team].score ++; update_score(); if (team[user[actor[sactor].user].team].score >= game[0].score_limit) { game_is_over(actor[sactor].team); // game_over = 200; // end_game(); } break; case SCORE_SUICIDE: if (game[0].game_type != GAME_KILL && game[0].game_type != GAME_LAST_ONE) break; if (team[user[actor[sactor].user].team].score > 0) { team[user[actor[sactor].user].team].score --; update_score(); } break; } } //if (game_over == 200 && serial[0].game_type == SERIAL_SERVER) // async_end_game(0); }