widelands-dev team mailing list archive
-
widelands-dev team
-
Mailing list archive
-
Message #10864
[Merge] lp:~widelands-dev/widelands/ai_training_switch into lp:widelands
TiborB has proposed merging lp:~widelands-dev/widelands/ai_training_switch into lp:widelands.
Requested reviews:
Widelands Developers (widelands-dev)
For more details, see:
https://code.launchpad.net/~widelands-dev/widelands/ai_training_switch/+merge/329008
ai training mode is triggered now from command line, it has three effects:
- dumps new AI files in home folder
- activate auto-speed
- uses higher mutation ratios
There is one NOCOM/question left in the code
--
Your team Widelands Developers is requested to review the proposed merge of lp:~widelands-dev/widelands/ai_training_switch into lp:widelands.
=== modified file 'src/ai/ai_help_structs.cc'
--- src/ai/ai_help_structs.cc 2017-07-25 20:56:04 +0000
+++ src/ai/ai_help_structs.cc 2017-08-14 20:03:03 +0000
@@ -31,9 +31,9 @@
constexpr int kRoadNotFound = -1000;
constexpr int kShortcutWithinSameEconomy = 1000;
constexpr int kRoadToDifferentEconomy = 10000;
+constexpr int kNoAiTrainingMutation = 200;
constexpr int kUpperDefaultMutationLimit = 150;
constexpr int kLowerDefaultMutationLimit = 75;
-constexpr int16_t kPrefNumberProbability = kAITrainingMode ? 5 : 100;
// CheckStepRoadAI
CheckStepRoadAI::CheckStepRoadAI(Player* const pl, uint8_t const mc, bool const oe)
@@ -347,6 +347,8 @@
next_neuron_id = 0;
performance_change = 0;
AiDnaHandler ai_dna_handler();
+ ai_training_mode_ = false;
+ pref_number_probability = 100;
}
// Initialization of neuron. Neuron is defined by curve (type) and weight [-kWeightRange,
@@ -620,11 +622,18 @@
int16_t probability =
shift_weight_value(get_military_number_at(kMutationRatePosition), false) + 101;
- if (probability > kUpperDefaultMutationLimit) {
- probability = kUpperDefaultMutationLimit;
- }
- if (probability < kLowerDefaultMutationLimit) {
- probability = kLowerDefaultMutationLimit;
+
+
+ // When doing training mutation probability is to be bigger than not in training mode
+ if (ai_training_mode_) {
+ if (probability > kUpperDefaultMutationLimit) {
+ probability = kUpperDefaultMutationLimit;
+ }
+ if (probability < kLowerDefaultMutationLimit) {
+ probability = kLowerDefaultMutationLimit;
+ }
+ } else {
+ probability = kNoAiTrainingMutation;
}
set_military_number_at(kMutationRatePosition, probability - 101);
@@ -639,7 +648,7 @@
}
// Wildcard for ai trainingmode
- if (kAITrainingMode && std::rand() % 8 == 0) {
+ if (ai_training_mode_ && std::rand() % 8 == 0) {
probability /= 3;
}
@@ -654,7 +663,7 @@
// Preferred numbers are ones that will be mutated agressively in full range
// [-kWeightRange, kWeightRange]
std::set<int32_t> preferred_numbers = {std::rand() % kMagicNumbersSize *
- kPrefNumberProbability};
+ pref_number_probability};
for (uint16_t i = 0; i < kMagicNumbersSize; i += 1) {
if (i == kMutationRatePosition) { // mutated above
@@ -680,7 +689,7 @@
{
// Neurons to be mutated more agressively
std::set<int32_t> preferred_neurons = {std::rand() % kNeuronPoolSize *
- kPrefNumberProbability};
+ pref_number_probability};
for (auto& item : neuron_pool) {
const MutatingIntensity mutating_intensity =
@@ -711,7 +720,7 @@
{
// FNeurons to be mutated more agressively
std::set<int32_t> preferred_f_neurons = {std::rand() % kFNeuronPoolSize *
- kPrefNumberProbability};
+ pref_number_probability};
for (auto& item : f_neuron_pool) {
uint8_t changed_bits = 0;
// is this a preferred neuron
=== modified file 'src/ai/ai_help_structs.h'
--- src/ai/ai_help_structs.h 2017-08-12 06:51:08 +0000
+++ src/ai/ai_help_structs.h 2017-08-14 20:03:03 +0000
@@ -119,12 +119,13 @@
};
// TODO(tiborb): this should be replaced by command line switch
-constexpr bool kAITrainingMode = false;
constexpr int kMagicNumbersSize = 150;
constexpr int kNeuronPoolSize = 80;
constexpr int kFNeuronPoolSize = 60;
constexpr int kFNeuronBitSize = 32;
constexpr int kMutationRatePosition = 42;
+constexpr int16_t AiPrefNumberProbability = 5;
+
constexpr uint32_t kNever = std::numeric_limits<uint32_t>::max();
@@ -665,6 +666,11 @@
void reset_bi_neuron_id() {
next_bi_neuron_id = 0;
}
+ void set_ai_training_mode() {
+ ai_training_mode_ = true;
+ pref_number_probability = AiPrefNumberProbability;
+ }
+
int16_t get_military_number_at(uint8_t);
void set_military_number_at(uint8_t, int16_t);
MutatingIntensity do_mutate(uint8_t, int16_t);
@@ -672,6 +678,7 @@
void test_consistency(bool = false);
AiDnaHandler ai_dna_handler;
+
private:
int32_t score;
uint8_t primary_parent;
@@ -680,6 +687,8 @@
uint16_t performance_change;
Widelands::AiType ai_type;
void dump_output(Widelands::Player::AiPersistentState, PlayerNumber);
+ bool ai_training_mode_;
+ uint16_t pref_number_probability;
};
// this is used to count militarysites by their size
=== modified file 'src/ai/defaultai.cc'
--- src/ai/defaultai.cc 2017-08-01 12:03:03 +0000
+++ src/ai/defaultai.cc 2017-08-14 20:03:03 +0000
@@ -482,10 +482,14 @@
void DefaultAI::late_initialization() {
player_ = game().get_player(player_number());
tribe_ = &player_->tribe();
+ if (game().is_ai_training_mode()) {
+ ai_training_mode_ = true;
+ management_data.set_ai_training_mode();
+ }
const uint32_t gametime = game().get_gametime();
- log("ComputerPlayer(%d): initializing as type %u\n", player_number(),
- static_cast<unsigned int>(type_));
+ log("ComputerPlayer(%d): initializing as type %u%s\n", player_number(),
+ static_cast<unsigned int>(type_), (ai_training_mode_)?", in ai training mode":"");
if (player_->team_number() > 0) {
log(" ... member of team %d\n", player_->team_number());
}
@@ -530,7 +534,7 @@
management_data.new_dna_for_persistent(player_number(), type_);
management_data.copy_persistent_to_local();
management_data.mutate(player_number());
- if (kAITrainingMode) {
+ if (ai_training_mode_) {
management_data.dump_data(player_number());
}
@@ -553,7 +557,7 @@
persistent_data->least_military_score = persistent_data->target_military_score;
}
- if (kAITrainingMode) {
+ if (ai_training_mode_) {
log("%2d: reinitializing dna (kAITrainingMode set true)", player_number());
management_data.new_dna_for_persistent(player_number(), type_);
management_data.copy_persistent_to_local();
@@ -912,7 +916,7 @@
"count military vacant"));
taskPool.push_back(SchedulerTask(std::max<uint32_t>(gametime, 10 * 60 * 1000),
SchedulerTaskId::kCheckEnemySites, 6, "check enemy sites"));
- if (kAITrainingMode) {
+ if (ai_training_mode_) {
taskPool.push_back(SchedulerTask(std::max<uint32_t>(gametime, 10 * 1000),
SchedulerTaskId::kManagementUpdate, 8, "reviewing"));
}
@@ -1782,7 +1786,7 @@
field.military_score_ += score_parts[i];
}
- if (kAITrainingMode) {
+ if (ai_training_mode_) {
if (field.military_score_ < -5000 || field.military_score_ > 2000) {
log("Warning field.military_score_ %5d, compounds: ", field.military_score_);
for (uint16_t i = 0; i < score_parts_size; i++) {
@@ -2351,7 +2355,7 @@
bo.primary_priority = 0;
}
- if (kAITrainingMode && bo.type == BuildingObserver::Type::kProductionsite) {
+ if (ai_training_mode_ && bo.type == BuildingObserver::Type::kProductionsite) {
log("%2d: %-35s(%2d now) %-11s: max prec: %2d/%2d, primary priority: %4d, overdue: %3d\n",
player_number(), bo.name, bo.total_count(),
(bo.new_building == BuildingNecessity::kAllowed ||
=== modified file 'src/ai/defaultai.h'
--- src/ai/defaultai.h 2017-07-19 20:40:32 +0000
+++ src/ai/defaultai.h 2017-08-14 20:03:03 +0000
@@ -395,6 +395,8 @@
bool has_critical_mines = false;
uint16_t buil_material_mines_count = 0;
+ bool ai_training_mode_ = false;
+
// Notification subscribers
std::unique_ptr<Notifications::Subscriber<Widelands::NoteFieldPossession>>
field_possession_subscriber_;
=== modified file 'src/logic/game.cc'
--- src/logic/game.cc 2017-07-02 19:11:13 +0000
+++ src/logic/game.cc 2017-08-14 20:03:03 +0000
@@ -122,6 +122,7 @@
ctrl_(nullptr),
writereplay_(true),
writesyncstream_(false),
+ ai_training_mode_(false),
state_(gs_notrunning),
cmdqueue_(*this),
/** TRANSLATORS: Win condition for this game has not been set. */
@@ -151,6 +152,10 @@
ctrl_ = ctrl;
}
+void Game::set_ai_training_mode(const bool mode) {
+ ai_training_mode_ = mode;
+}
+
GameController* Game::game_controller() {
return ctrl_;
}
=== modified file 'src/logic/game.h'
--- src/logic/game.h 2017-06-23 17:23:04 +0000
+++ src/logic/game.h 2017-08-14 20:03:03 +0000
@@ -126,7 +126,8 @@
// Run a single player loaded game directly via --loadgame on the cmdline. Will
// run the 'script_to_run' directly after the game was loaded.
// Returns the result of run().
- bool run_load_game(const std::string& filename, const std::string& script_to_run);
+ bool run_load_game(const std::string& filename,
+ const std::string& script_to_run);
void postload() override;
@@ -231,6 +232,12 @@
return replay_;
}
+ bool is_ai_training_mode() const {
+ return ai_training_mode_;
+ }
+
+ void set_ai_training_mode(bool);
+
private:
void sync_reset();
@@ -281,6 +288,8 @@
/// is written only if \ref writereplay_ is true too.
bool writesyncstream_;
+ bool ai_training_mode_;
+
int32_t state_;
RNG rng_;
=== modified file 'src/network/gamehost.cc'
--- src/network/gamehost.cc 2017-07-02 21:09:23 +0000
+++ src/network/gamehost.cc 2017-08-14 20:03:03 +0000
@@ -664,6 +664,7 @@
broadcast(s);
Widelands::Game game;
+ game.set_ai_training_mode(g_options.pull_section("global").get_bool("ai_training", false));
game.set_write_syncstream(g_options.pull_section("global").get_bool("write_syncstreams", true));
try {
=== modified file 'src/wlapplication.cc'
--- src/wlapplication.cc 2017-07-25 20:56:04 +0000
+++ src/wlapplication.cc 2017-08-14 20:03:03 +0000
@@ -413,6 +413,7 @@
replay();
} else if (game_type_ == LOADGAME) {
Widelands::Game game;
+ game.set_ai_training_mode(g_options.pull_section("global").get_bool("ai_training", false));
try {
game.run_load_game(filename_, script_to_run_);
} catch (const Widelands::GameDataError& e) {
@@ -955,6 +956,15 @@
commandline_.erase("script");
}
+ // NOCOM why non-existing section returns 'true' by default? It does not make sense to me....
+ // to be sure I set value in both alternatives
+ if (commandline_.count("ai_training")) {
+ g_options.pull_section("global").create_val("ai_training", "true");
+ commandline_.erase("ai_training");
+ } else {
+ g_options.pull_section("global").create_val("ai_training", "false");
+ }
+
// If it hasn't been handled yet it's probably an attempt to
// override a conffile setting
// With typos, this will create invalid config settings. They
@@ -1211,6 +1221,8 @@
Widelands::Game game;
+ game.set_ai_training_mode(g_options.pull_section("global").get_bool("ai_training", false));
+
if (code == FullscreenMenuBase::MenuTarget::kScenarioGame) { // scenario
try {
game.run_splayer_scenario_direct(sp.get_map().c_str(), "");
@@ -1261,6 +1273,7 @@
Widelands::Game game;
std::string filename;
+ game.set_ai_training_mode(g_options.pull_section("global").get_bool("ai_training", false));
SinglePlayerGameSettingsProvider sp;
FullscreenMenuLoadGame ssg(game, &sp, nullptr);
@@ -1411,14 +1424,11 @@
* Delete old ai dna files generated during AI initialization
*/
void WLApplication::cleanup_ai_files() {
- for (const std::string& filename :
- filter(g_fs->list_directory(
- Widelands::AiDnaHandler::get_ai_dir()), // NOCOM repace with common defineds
- // used by both locations (here and ai_dna_handler)
- [](const std::string& fn) {
- return boost::ends_with(fn, Widelands::AiDnaHandler::get_ai_suffix()) ||
- boost::contains(fn, "ai_player");
- })) {
+ for (const std::string& filename : filter(
+ g_fs->list_directory(Widelands::AiDnaHandler::get_ai_dir()), [](const std::string& fn) {
+ return boost::ends_with(fn, Widelands::AiDnaHandler::get_ai_suffix()) ||
+ boost::contains(fn, "ai_player");
+ })) {
if (is_autogenerated_and_expired(filename, kAIFilesKeepAroundTime)) {
log("Deleting generated ai file: %s\n", filename.c_str());
g_fs->fs_unlink(filename);
=== modified file 'src/wlapplication_messages.cc'
--- src/wlapplication_messages.cc 2017-01-25 18:55:59 +0000
+++ src/wlapplication_messages.cc 2017-08-14 20:03:03 +0000
@@ -90,6 +90,10 @@
" You can add a =FILENAME to directly load\n"
" the map FILENAME in editor.")
<< endl
+ << _(" --ai_training Starts in AI training mode: wai files are generated,\n"
+ " autospeed is activated, and higher mutation rates are\n"
+ " used.")
+ << endl
<< _(" --scenario=FILENAME Directly starts the map FILENAME as scenario\n"
" map.")
<< endl
=== modified file 'src/wui/interactive_base.cc'
--- src/wui/interactive_base.cc 2017-08-12 20:13:24 +0000
+++ src/wui/interactive_base.cc 2017-08-14 20:03:03 +0000
@@ -55,9 +55,6 @@
#include "wui/minimap.h"
#include "wui/unique_window_handler.h"
-// TODO(tiborb): This constant is temporary and should be replaced by command line switch
-constexpr bool AItrainingMode = false;
-
using Widelands::Area;
using Widelands::CoordPath;
using Widelands::Coords;
@@ -348,33 +345,37 @@
avg_usframetime_ = ((avg_usframetime_ * 15) + (frametime_ * 1000)) / 16;
lastframe_ = curframe;
+ const Map& map = egbase().map();
+ const bool is_game = dynamic_cast<const Game*>(&egbase());
+
// This portion of code keeps the speed of game so that FPS are kept within
// range 13 - 15, this is used for training of AI
- if (AItrainingMode) {
+ if (is_game) {
if (upcast(Game, game, &egbase())) {
- uint32_t cur_fps = 1000000 / avg_usframetime_;
- int32_t speed_diff = 0;
- if (cur_fps < 13) {
- speed_diff = -100;
- }
- if (cur_fps > 15) {
- speed_diff = +100;
- }
- if (speed_diff != 0) {
+ if (game->is_ai_training_mode()) {
+ uint32_t cur_fps = 1000000 / avg_usframetime_;
+ int32_t speed_diff = 0;
+ if (cur_fps < 13) {
+ speed_diff = -100;
+ }
+ if (cur_fps > 15) {
+ speed_diff = +100;
+ }
+ if (speed_diff != 0) {
- if (GameController* const ctrl = game->game_controller()) {
- if ((ctrl->desired_speed() > 950 && ctrl->desired_speed() < 30000) ||
- (ctrl->desired_speed() < 1000 && speed_diff > 0) ||
- (ctrl->desired_speed() > 29999 && speed_diff < 0)) {
- ctrl->set_desired_speed(ctrl->desired_speed() + speed_diff);
+ if (GameController* const ctrl = game->game_controller()) {
+ if ((ctrl->desired_speed() > 950 && ctrl->desired_speed() < 30000) ||
+ (ctrl->desired_speed() < 1000 && speed_diff > 0) ||
+ (ctrl->desired_speed() > 29999 && speed_diff < 0)) {
+ ctrl->set_desired_speed(ctrl->desired_speed() + speed_diff);
+ }
}
}
}
}
}
- const Map& map = egbase().map();
- const bool is_game = dynamic_cast<const Game*>(&egbase());
+
// Blit node information when in debug mode.
if (get_display_flag(dfDebug) || !is_game) {
Follow ups
-
[Merge] lp:~widelands-dev/widelands/ai_training_switch into lp:widelands
From: noreply, 2017-08-18
-
[Merge] lp:~widelands-dev/widelands/ai_training_switch into lp:widelands
From: bunnybot, 2017-08-18
-
Re: [Merge] lp:~widelands-dev/widelands/ai_training_switch into lp:widelands
From: GunChleoc, 2017-08-17
-
Re: [Merge] lp:~widelands-dev/widelands/ai_training_switch into lp:widelands
From: TiborB, 2017-08-17
-
Re: [Merge] lp:~widelands-dev/widelands/ai_training_switch into lp:widelands
From: kaputtnik, 2017-08-17
-
Re: [Merge] lp:~widelands-dev/widelands/ai_training_switch into lp:widelands
From: GunChleoc, 2017-08-17
-
[Merge] lp:~widelands-dev/widelands/ai_training_switch into lp:widelands
From: GunChleoc, 2017-08-17
-
Re: [Merge] lp:~widelands-dev/widelands/ai_training_switch into lp:widelands
From: TiborB, 2017-08-16
-
Re: [Merge] lp:~widelands-dev/widelands/ai_training_switch into lp:widelands
From: kaputtnik, 2017-08-16
-
Re: [Merge] lp:~widelands-dev/widelands/ai_training_switch into lp:widelands
From: TiborB, 2017-08-16
-
Re: [Merge] lp:~widelands-dev/widelands/ai_training_switch into lp:widelands
From: kaputtnik, 2017-08-16
-
Re: [Merge] lp:~widelands-dev/widelands/ai_training_switch into lp:widelands
From: GunChleoc, 2017-08-16
-
Re: [Merge] lp:~widelands-dev/widelands/ai_training_switch into lp:widelands
From: TiborB, 2017-08-16
-
Re: [Merge] lp:~widelands-dev/widelands/ai_training_switch into lp:widelands
From: kaputtnik, 2017-08-16
-
Re: [Merge] lp:~widelands-dev/widelands/ai_training_switch into lp:widelands
From: TiborB, 2017-08-16
-
Re: [Merge] lp:~widelands-dev/widelands/ai_training_switch into lp:widelands
From: kaputtnik, 2017-08-16
-
Re: [Merge] lp:~widelands-dev/widelands/ai_training_switch into lp:widelands
From: TiborB, 2017-08-16
-
Re: [Merge] lp:~widelands-dev/widelands/ai_training_switch into lp:widelands
From: TiborB, 2017-08-16
-
Re: [Merge] lp:~widelands-dev/widelands/ai_training_switch into lp:widelands
From: GunChleoc, 2017-08-16
-
Re: [Merge] lp:~widelands-dev/widelands/ai_training_switch into lp:widelands
From: TiborB, 2017-08-16
-
Re: [Merge] lp:~widelands-dev/widelands/ai_training_switch into lp:widelands
From: GunChleoc, 2017-08-16
-
Re: [Merge] lp:~widelands-dev/widelands/ai_training_switch into lp:widelands
From: TiborB, 2017-08-16
-
Re: [Merge] lp:~widelands-dev/widelands/ai_training_switch into lp:widelands
From: Klaus Halfmann, 2017-08-16
-
Re: [Merge] lp:~widelands-dev/widelands/ai_training_switch into lp:widelands
From: TiborB, 2017-08-16
-
Re: [Merge] lp:~widelands-dev/widelands/ai_training_switch into lp:widelands
From: Klaus Halfmann, 2017-08-16
-
Re: [Merge] lp:~widelands-dev/widelands/ai_training_switch into lp:widelands
From: GunChleoc, 2017-08-16
-
Re: [Merge] lp:~widelands-dev/widelands/ai_training_switch into lp:widelands
From: TiborB, 2017-08-15
-
Re: [Merge] lp:~widelands-dev/widelands/ai_training_switch into lp:widelands
From: TiborB, 2017-08-15
-
Re: [Merge] lp:~widelands-dev/widelands/ai_training_switch into lp:widelands
From: kaputtnik, 2017-08-15
-
Re: [Merge] lp:~widelands-dev/widelands/ai_training_switch into lp:widelands
From: TiborB, 2017-08-15
-
Re: [Merge] lp:~widelands-dev/widelands/ai_training_switch into lp:widelands
From: kaputtnik, 2017-08-15
-
Re: [Merge] lp:~widelands-dev/widelands/ai_training_switch into lp:widelands
From: TiborB, 2017-08-15
-
Re: [Merge] lp:~widelands-dev/widelands/ai_training_switch into lp:widelands
From: Klaus Halfmann, 2017-08-15
-
Re: [Merge] lp:~widelands-dev/widelands/ai_training_switch into lp:widelands
From: TiborB, 2017-08-15
-
Re: [Merge] lp:~widelands-dev/widelands/ai_training_switch into lp:widelands
From: GunChleoc, 2017-08-15
-
Re: [Merge] lp:~widelands-dev/widelands/ai_training_switch into lp:widelands
From: TiborB, 2017-08-15
-
Re: [Merge] lp:~widelands-dev/widelands/ai_training_switch into lp:widelands
From: GunChleoc, 2017-08-15
-
Re: [Merge] lp:~widelands-dev/widelands/ai_training_switch into lp:widelands
From: TiborB, 2017-08-15
-
Re: [Merge] lp:~widelands-dev/widelands/ai_training_switch into lp:widelands
From: GunChleoc, 2017-08-15
-
[Merge] lp:~widelands-dev/widelands/ai_training_switch into lp:widelands
From: bunnybot, 2017-08-15