in coinrun/coinrun.cpp [1727:1791]
void stepping_thread(int n)
{
while (1) {
std::shared_ptr<State> todo_state;
std::list<std::shared_ptr<State>> my_todo;
while (1) {
if (shutdown_flag)
return;
QMutexLocker sleeplock(&h2s_mutex);
if (workers_todo.empty()) {
wait_for_actions.wait(&h2s_mutex, 1000); // milliseconds
continue;
}
my_todo.splice(my_todo.begin(), workers_todo, workers_todo.begin());
break;
}
todo_state = my_todo.front();
{
QMutexLocker lock(&todo_state->step_mutex);
assert(todo_state->agent_ready);
todo_state->step_in_progress = true;
}
{
QMutexLocker lock(&todo_state->state_mutex);
std::shared_ptr<VectorOfStates> belongs_to = todo_state->belongs_to.lock();
if (!belongs_to)
continue;
todo_state->time += 1;
bool game_over = todo_state->maze->is_terminated;
for (const std::shared_ptr<Monster>& m: todo_state->maze->monsters) {
m->step(todo_state->maze);
Agent& a = todo_state->agent;
if (fabs(m->x - a.x) + fabs(m->y - a.y) < 1.0)
todo_state->maze->is_terminated = true; // no effect on agent score
}
Agent& a = todo_state->agent;
if (game_over)
a.monitor_csv_episode_over();
a.game_over = game_over;
a.step(belongs_to->game_type);
if (game_over) {
state_reset(todo_state, belongs_to->game_type);
}
paint_render_buf(a.render_buf, RES_W, RES_H, todo_state, &a, false, false);
if (a.render_hires_buf)
paint_render_buf(a.render_hires_buf, VIDEORES, VIDEORES, todo_state, &a, false, false);
}
{
QMutexLocker lock(&todo_state->step_mutex);
assert(todo_state->agent_ready);
assert(todo_state->step_in_progress);
todo_state->agent_ready = false;
todo_state->step_in_progress = false;
}
wait_for_step_completed.wakeAll();
}
}