Guest User

Untitled

a guest
Jun 18th, 2018
92
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.37 KB | None | 0 0
  1. //Подключение заголовочных файлов и не конфликтующих пространств имен
  2. #include <iostream>
  3. #include <vector>
  4. #include <chrono>
  5. #include <thread>
  6. #include <ViZDoom.h>
  7. #include <opencv2/opencv.hpp>
  8.  
  9. using namespace vizdoom;
  10. using namespace cv;
  11. using namespace std;
  12.  
  13. // Boilerplate методы и переменные связанные с настройкой VizDoom
  14. DoomGame *game; // Здесь будем хранить игру - это указатель
  15. const int ButtonsCount = 42; // Введем 42 возможных действия (все доступные кнопки VizDoom)
  16. vector<double> actions[ButtonsCount]; // Массив векторов в которых мы предсохраним возможные действия
  17.  
  18. // Действия будем сохранять в форматaке 0,0,...,0,1,0,...,0 где расположеие 1 будет отвечать за нажимаемую кнопку
  19. void allowAllButtons() {
  20. vector<Button> n;
  21. game->setAvailableButtons(n);
  22. for(int i = 0; i < ButtonsCount; ++i ) {
  23. game->addAvailableButton((Button)i);
  24. actions[i] = vector<double>(42, 0);
  25. actions[i][i] = 1;
  26. }
  27. }
  28.  
  29. //вызов действия - нажать на кнопку!
  30. void PushButton(Button b) {
  31. game->makeAction(actions[b]);
  32. }
  33. //пропуск действия
  34. void SkeepFrame() {
  35. static vector<double> noAction(42, 0);
  36. game->makeAction(noAction);
  37. }
  38.  
  39. // Цифры которые в OpenCV соответствуют Клавишам
  40. enum KEYS {
  41. UP = 119,
  42. DOWN = 115 ,
  43. LEFT = 97,
  44. RIGHT = 100,
  45. SPACE = 32
  46. };
  47.  
  48. int main() {
  49. game = new DoomGame(); // Создаем инстанс игры
  50.  
  51. try{ // Попробуем настроить параметры игры
  52. game->setViZDoomPath("/headless/base/ViZDoom/bin/vizdoom"); // путь к тому где лежит "сервер игры" который мы запустим локально
  53. game->setDoomGamePath("/headless/base/ViZDoom/bin/freedoom2.wad"); // путь к тому где все текстуры, базовые карты и логика игры
  54. game->loadConfig("/headless/base/ViZDoom/scenarios/basic.cfg"); // путь к файлу настроек именно этой сессии
  55. allowAllButtons(); // Разрешим все кнопки (в не зависимости от того что было в конфигурации)
  56. game->init(); // запустим платформу VizDoom
  57. } catch(exception &e) { // Поймаем ошибку если что-то пошло не так
  58. cout << e.what() << endl; // Выведем ее на экран
  59. }
  60.  
  61. auto episodes = 10; // Система предпологает что игр будет проведено более одной
  62. auto sleepTime = 1000 / DEFAULT_TICRATE; // = 28 // Пока для простоты отладки мы заставляем сервер работать синхронно с нами
  63. // Другими словами пока мы не сказали - кадр кончился, новый не начнется. Эта переменная позволит нам создать аналог стабильного фреймрейта
  64. auto image = Mat(480, 640, CV_8UC3); // будем ранить здесь текущий кадр
  65. namedWindow( "Control Window", WINDOW_AUTOSIZE ); // Создадим OpenCV окно для приема управления от пользователя (клавиши WSAD)
  66. auto repeat_counter = 0; // Создадим переменную которая будет повторять последнее выполненное действие в течении некоторого времени
  67.  
  68. for (auto i = 0; i < episodes; ++i) {
  69. cout << "Episode #" << i + 1 << "\n";
  70. game->newEpisode(); // Раунд пошел
  71.  
  72. while (!game->isEpisodeFinished()) { // Пока эпизод не кончился
  73. auto state = game->getState(); // Получим текущее состояние игрока\доступного нам мира
  74.  
  75. //состоящего из:
  76. auto n = state->number;
  77. auto vars = state->gameVariables;
  78. auto screenBuf = state->screenBuffer;
  79. auto depthBuf = state->depthBuffer;
  80. auto labelsBuf = state->labelsBuffer;
  81. auto automapBuf = state->automapBuffer;
  82. // BufferPtr is shared_ptr<Buffer> where Buffer is vector<uint8_t>
  83. vector<Label> labels = state->labels;
  84. image.data= static_cast<uchar*>(screenBuf->data()); // здесь мы подменяем указатель на данные
  85. auto im = image.clone(); // ViZDoom моет писать в тот буфер асинронно - сделаем локальную копию
  86. imshow("Control Window", im);
  87. auto key = waitKey(sleepTime)%256; // Ждем момента нажатия клавиши несколько миллисекунд
  88.  
  89. if(key == 255 || key == -1 ) { // ненажали - продолжаем действие или спим
  90. if(repeat_counter-- > 0) {
  91. game->advanceAction(1);
  92. } else {
  93. SkeepFrame();
  94. }
  95. } else { // Нажали - смотрим что именно и либо выполняем либо ничего не делаем
  96. cout << "you pressed " << key << endl;
  97. repeat_counter = 5;
  98. switch(static_cast<KEYS>(key)) {
  99. case UP: {PushButton(MOVE_FORWARD); break;}
  100. case DOWN: { PushButton(MOVE_BACKWARD);break;}
  101. case LEFT: {PushButton(MOVE_LEFT); break;}
  102. case RIGHT: {PushButton(MOVE_RIGHT);break;}
  103. case SPACE: {PushButton(ATTACK);break;}
  104. default: { repeat_counter = 0; SkeepFrame(); break;}
  105. }
  106. }
  107. }
  108.  
  109. cout << "Episode finished.\n";
  110. cout << "Total reward: " << game->getTotalReward() << "\n"; // правила выставления успешности конца задаются в конфигурации мира
  111. }
  112. game->close();
  113. delete game;
  114. }
Add Comment
Please, Sign In to add comment