void stepping_thread()

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();
  }
}