some AI improvements

This commit is contained in:
uid68803 2004-01-08 14:47:53 +00:00
parent bf18668a1e
commit 688ad5a231
7 changed files with 88 additions and 17 deletions

View file

@ -203,8 +203,9 @@ void do_move(display& disp, const gamemap& map, const game_data& gameinfo,
for(paths::routes_map::const_iterator rt = new_paths.routes.begin();
rt != new_paths.routes.end(); ++rt) {
const std::pair<location,location> item(un_it->first,rt->first);
const std::pair<location,location> item_reverse(rt->first,un_it->first);
enemy_srcdst.insert(item);
enemy_dstsrc.insert(item);
enemy_dstsrc.insert(item_reverse);
}
}
@ -250,9 +251,32 @@ void do_move(display& disp, const gamemap& map, const game_data& gameinfo,
const unit_map::iterator leader = find_leader(units,team_num);
//no moves left, recruitment phase
//no moves left, recruitment phase and leader movement phase
//take stock of our current set of units
if(srcdst.empty()) {
if(srcdst.empty() || leader != units.end() && srcdst.count(leader->first) == srcdst.size()) {
if(leader == units.end()) {
recorder.end_turn();
return;
}
//find where the leader can move
const paths leader_paths(map,gameinfo,units,leader->first,teams,false,false);
const gamemap::location& start_pos = map.starting_position(leader->second.side());
possible_moves.insert(std::pair<gamemap::location,paths>(leader->first,leader_paths));
bool leader_moved = false;
//if the leader is not on his starting location, move him there.
if(leader->first != start_pos) {
leader_moved = true;
const paths::routes_map::const_iterator itor = leader_paths.routes.find(start_pos);
if(itor != leader_paths.routes.end()) {
move_unit(gameinfo,disp,map,units,leader->first,start_pos,
possible_moves,teams,team_num);
}
}
std::cout << "recruitment......\n";
//currently just spend all the gold we can!
@ -293,6 +317,52 @@ void do_move(display& disp, const gamemap& map, const game_data& gameinfo,
}
//see if the leader can capture a village safely
if(!leader_moved) {
//if the keep is accessible by an enemy unit, we don't want to leave it
gamemap::location adj[6];
get_adjacent_tiles(leader->first,adj);
for(size_t n = 0; n != 6; ++n) {
if(enemy_dstsrc.count(adj[n])) {
leader_moved = true;
break;
}
}
}
//search through villages finding one to capture
if(!leader_moved) {
const std::vector<gamemap::location>& villages = map.towers();
for(std::vector<gamemap::location>::const_iterator v = villages.begin();
v != villages.end(); ++v) {
const paths::routes_map::const_iterator itor = leader_paths.routes.find(*v);
if(itor == leader_paths.routes.end()) {
continue;
}
const int owner = tower_owner(*v,teams);
if(owner == -1 || current_team.is_enemy(owner+1) || leader->second.hitpoints() < leader->second.max_hitpoints()) {
//check that no enemies can reach the village
gamemap::location adj[6];
get_adjacent_tiles(*v,adj);
size_t n;
for(n = 0; n != 6; ++n) {
if(enemy_dstsrc.count(adj[n]))
break;
}
if(n != 6)
continue;
move_unit(gameinfo,disp,map,units,leader->first,*v,
possible_moves,teams,team_num);
break;
}
}
}
recorder.end_turn();
return;
}
@ -401,12 +471,6 @@ void do_move(display& disp, const gamemap& map, const game_data& gameinfo,
//mark the leader as having moved and attacked by now
for(std::vector<location>::const_iterator lead = leader_locations.begin();
lead != leader_locations.end(); ++lead) {
const std::map<location,unit>::iterator leader = units.find(*lead);
if(leader != units.end()) {
leader->second.set_movement(0);
leader->second.set_attacked();
}
//remove leader from further consideration
srcdst.erase(*lead);
dstsrc.erase(*lead);

View file

@ -70,7 +70,7 @@ struct move_cost_calculator
*/
double res = modifier*move_cost + enemies*2.0;
//if there is a unit (even a friendly one) on this tile, we increase the cost
//if there is a unit (even a friendly one) on this tile, we increase the cost to
//try discourage going through units, to thwart the 'single file effect'
if(units_.count(loc))
res *= 4.0;

View file

@ -296,8 +296,6 @@ SDL_Rect draw_text(display* gui, const SDL_Rect& area, int size,
bool is_format_char(char c)
{
switch(c) {
case '+':
case '-':
case '#':
case '@':
return true;

View file

@ -681,7 +681,7 @@ void event_handler::handle_event_command(const queued_event& event_info, const s
//if we're not replaying, or if there is no choice to be made, show
//the dialog.
if(recorder.at_end() == false || options.empty()) {
if(recorder.at_end() || options.empty()) {
option_chosen = gui::show_dialog(*screen,surface,caption,
lang_message.empty() ? cfg["message"] : lang_message,
options.empty() ? gui::MESSAGE : gui::OK_ONLY,
@ -693,7 +693,7 @@ void event_handler::handle_event_command(const queued_event& event_info, const s
}
//otherwise if a choice has to be made, get it from the replay data
else if(options.empty() == false) {
else {
const config* const action = recorder.get_next_action();
if(action == NULL || action->get_children("choose").empty()) {
std::cerr << "choice expected but none found\n";

View file

@ -79,6 +79,7 @@ LEVEL_RESULT play_level(game_data& gameinfo, config& game_config,
const bool modify_placing = (*level)["modify_placing"] == "true";
std::set<int> taken_places;
std::vector<gamemap::location> starting_locs;
const config::child_list& unit_cfg = level->get_children("side");
for(config::child_list::const_iterator ui = unit_cfg.begin(); ui != unit_cfg.end(); ++ui) {
@ -135,6 +136,7 @@ LEVEL_RESULT play_level(game_data& gameinfo, config& game_config,
assert(start != -1);
const gamemap::location& start_pos = map.starting_position(start);
starting_locs.push_back(start_pos);
if(!start_pos.valid() && new_unit.side() == 1) {
throw gamestatus::load_game_failed("No starting position for side 1");
@ -177,6 +179,10 @@ LEVEL_RESULT play_level(game_data& gameinfo, config& game_config,
}
}
for(size_t pos = 0; pos != starting_locs.size(); ++pos) {
map.set_starting_position(pos+1,starting_locs[pos]);
}
const teams_manager team_manager(teams);
const config* const theme_cfg = game_config.find_child("theme","name",preferences::theme());
@ -235,6 +241,7 @@ LEVEL_RESULT play_level(game_data& gameinfo, config& game_config,
const hotkey::basic_handler key_events_handler(gui);
clear_shroud(gui,map,gameinfo,units,teams,0);
std::cerr << "first_time..." << (recorder.skipping() ? "skipping" : "no skip") << "\n";
update_locker lock_display(gui,recorder.skipping());
game_events::fire("start");
gui.draw();
@ -474,6 +481,7 @@ redo_turn:
event_stream << "turn " << status.turn();
{
std::cerr << "turn event..." << (recorder.skipping() ? "skipping" : "no skip") << "\n";
update_locker lock_display(gui,recorder.skipping());
game_events::fire(event_stream.str());
}

View file

@ -102,7 +102,7 @@ void replay::next_skip()
bool replay::skipping() const
{
return skip_ != 0;
return at_end() == false && skip_ != 0;
}
void replay::save_game(game_data& data, const std::string& label, const config& start_pos,
@ -273,6 +273,7 @@ void replay::mark_current()
config* replay::add_command()
{
pos_ = ncommands()+1;
return current_ = &cfg_.add_child("command");
}

View file

@ -176,7 +176,7 @@ report generate_report(TYPE type, const gamemap& map, const unit_map& units,
str << status.turn() << "/" << status.number_of_turns() << "\n";
break;
case GOLD:
str << current_team.gold();
str << (current_team.gold() < 0 ? "#" : "") << current_team.gold();
break;
case VILLAGES: {
const team_data data = calculate_team_data(current_team,current_side,units);
@ -199,7 +199,7 @@ report generate_report(TYPE type, const gamemap& map, const unit_map& units,
}
case INCOME: {
const team_data data = calculate_team_data(current_team,current_side,units);
str << data.net_income;
str << (data.net_income < 0 ? "#" : "") << data.net_income;
break;
}
case TERRAIN: {