// TODO: Track and display TPS in GUI. void GuiManager::runCurrentMatch() { interrupted_ = false; restarting_ = false; runnerConsole_->Hide(); destroyResultsDialog(); sf::RenderWindow *window = window_; try { while (window->isOpen() && !interrupted_ && !restarting_ && !quitting_) { while (!paused_ && !restarting_ && !engine_->isGameOver() && engine_->getGameTime() < nextDrawTime_) { engine_->processTick(); } while (!interrupted_ && !restarting_ && !quitting_ && (nextDrawTime_ <= engine_->getGameTime() || engine_->isGameOver())) { processMainWindowEvents(window, gfxManager_, viewWidth_, viewHeight_); clearTeamErroredForActiveConsoles(engine_); drawFrame(window); if (!paused_ && !engine_->isGameOver()) { nextDrawTime_ += tpsFactor_; } if (engine_->isGameOver() && !showedResults_) { ReplayBuilder *replayBuilder = engine_->getReplayBuilder(); Team **teams = engine_->getRankedTeams(); replayBuilder->setResults(teams, engine_->getNumTeams()); delete teams; showResults(replayBuilder); showedResults_ = true; } } } } catch (EngineException *e) { errorConsole_->println(e->what()); wxMessageDialog errorMessage(NULL, e->what(), "BerryBots encountered an error", wxOK | wxICON_EXCLAMATION); errorMessage.ShowModal(); newMatchDialog_->Show(); delete e; return; } if (!window->isOpen()) { listener_->onAllWindowsClosed(); } // TODO: Display CPU usage in GUI if (!interrupted_) { gfxManager_->destroyBbGfx(); delete engine_; engine_ = 0; delete gfxHandler_; gfxHandler_ = 0; } }
int main(int argc, char *argv[]) { Zipper *zipper = new GuiZipper(); FileManager *fileManager = new FileManager(zipper); CliPackageReporter *packageReporter = new CliPackageReporter(); fileManager->setListener(packageReporter); char *shipsBaseDir = fileManager->getAbsFilePath(SHIPS_SUBDIR); char *stagesBaseDir = fileManager->getAbsFilePath(STAGES_SUBDIR); if (flagExists(argc, argv, "packstage")) { char **stageInfo = parseFlag(argc, argv, "packstage", 2); if (stageInfo == 0) { printUsage(); } else { // TODO: add a new flag for obfuscating source code bool obfuscate = false; try { char *stageAbsName = fileManager->getAbsFilePath(stageInfo[0]); char *stageName = fileManager->parseRelativeFilePath(stagesBaseDir, stageAbsName); if (stageName == 0) { std::cout << "Stage must be located under " << STAGES_SUBDIR << "/ subdirectory: " << stageInfo[0] << std::endl; } else { fileManager->packageStage(stagesBaseDir, stageName, stageInfo[1], CACHE_SUBDIR, TMP_SUBDIR, obfuscate, true); delete stageName; } delete stageAbsName; } catch (std::exception *e) { std::cout << "BerryBots encountered an error:" << std::endl; std::cout << " " << e->what() << std::endl; delete e; } delete stageInfo; } return 0; } if (flagExists(argc, argv, "packbot")) { char **shipInfo = parseFlag(argc, argv, "packbot", 2); if (shipInfo == 0) { printUsage(); } else { // TODO: add a new flag for obfuscating source code bool obfuscate = false; try { char *shipAbsName = fileManager->getAbsFilePath(shipInfo[0]); char *shipName = fileManager->parseRelativeFilePath(shipsBaseDir, shipAbsName); if (shipName == 0) { std::cout << "Ship must be located under " << SHIPS_SUBDIR << "/ subdirectory: " << shipInfo[0] << std::endl; } else { fileManager->packageShip(shipsBaseDir, shipName, shipInfo[1], CACHE_SUBDIR, TMP_SUBDIR, obfuscate, true); delete shipName; } delete shipAbsName; } catch (std::exception *e) { std::cout << "BerryBots encountered an error:" << std::endl; std::cout << " " << e->what() << std::endl; delete e; } delete shipInfo; } return 0; } bool nodisplay = flagExists(argc, argv, "nodisplay"); bool saveReplay = flagExists(argc, argv, "savereplay"); int optArgsOffset = (nodisplay ? 1 : 0) + (saveReplay ? 1 : 0); if (argc < 3 + optArgsOffset) { printUsage(); } srand(time(NULL)); CliPrintHandler *printHandler = new CliPrintHandler(); BerryBotsEngine *engine = new BerryBotsEngine(printHandler, fileManager, resourcePath().c_str()); Stage *stage = engine->getStage(); char *stageAbsName = fileManager->getAbsFilePath(argv[1 + optArgsOffset]); char *stageName = fileManager->parseRelativeFilePath(stagesBaseDir, stageAbsName); if (stageName == 0) { std::cout << "Stage must be located under " << STAGES_SUBDIR << "/ subdirectory: " << argv[1 + optArgsOffset] << std::endl; return 0; } try { engine->initStage(stagesBaseDir, stageName, CACHE_SUBDIR); } catch (EngineException *e) { delete stageAbsName; delete stageName; std::cout << "BerryBots initialization failed:" << std::endl; std::cout << " " << e->what() << std::endl; delete e; return 0; } delete stageAbsName; delete stageName; int firstTeam = (2 + optArgsOffset); int numTeams = argc - firstTeam; char **teams = new char*[numTeams]; for (int x = 0; x < numTeams; x++) { char *teamAbsName = fileManager->getAbsFilePath(argv[x + firstTeam]); char *teamName = fileManager->parseRelativeFilePath(shipsBaseDir, teamAbsName); if (teamName == 0) { std::cout << "Ship must be located under " << SHIPS_SUBDIR << "/ subdirectory: " << argv[x + firstTeam] << std::endl; return 0; } teams[x] = teamName; delete teamAbsName; } printHandler->setNumTeams(numTeams); try { engine->initShips(shipsBaseDir, teams, numTeams, CACHE_SUBDIR); } catch (EngineException *e) { std::cout << "BerryBots initialization failed:" << std::endl; std::cout << " " << e->what() << std::endl; delete e; return 0; } printHandler->updateTeams(engine->getTeams()); GfxManager *gfxManager; sf::RenderWindow *window = 0; GfxEventHandler *gfxHandler = 0; unsigned int viewWidth = stage->getWidth() + (STAGE_MARGIN * 2); unsigned int viewHeight = stage->getHeight() + (STAGE_MARGIN * 2); if (!nodisplay) { gfxHandler = new GfxEventHandler(); stage->addEventHandler((EventHandler*) gfxHandler); unsigned int screenWidth = sf::VideoMode::getDesktopMode().width; unsigned int screenHeight = sf::VideoMode::getDesktopMode().height; double windowScale = std::min(1.0, std::min(((double) screenWidth) / viewWidth, ((double) screenHeight) / viewHeight)); unsigned int targetWidth = round(windowScale * viewWidth); unsigned int targetHeight = round(windowScale * viewHeight); gfxManager = new GfxManager(false); window = new sf::RenderWindow(sf::VideoMode(targetWidth, targetHeight), "BerryBots", sf::Style::Default, sf::ContextSettings(0, 0, 16, 2, 0)); gfxManager->initViews(window, viewWidth, viewHeight); gfxManager->initBbGfx(window, viewHeight, stage, engine->getTeams(), engine->getNumTeams(), engine->getShips(), engine->getNumShips(), resourcePath()); window->clear(); gfxManager->drawGame(window, stage, engine->getShips(), engine->getNumShips(), engine->getGameTime(), gfxHandler, false, false, 0); window->display(); } time_t realTime1; time_t realTime2; time(&realTime1); int realSeconds = 0; try { while ((nodisplay || window->isOpen()) && !engine->isGameOver()) { engine->processTick(); if (!nodisplay) { sf::Event event; bool resized = false; while (window->pollEvent(event)) { if (event.type == sf::Event::Closed) { window->close(); } if (event.type == sf::Event::KeyPressed && event.key.code == sf::Keyboard::Escape) { window->close(); } if (event.type == sf::Event::Resized && !resized) { resized = true; gfxManager->onResize(window, viewWidth, viewHeight); } } window->clear(); gfxManager->drawGame(window, stage, engine->getShips(), engine->getNumShips(), engine->getGameTime(), gfxHandler, false, false, 0); window->display(); } time(&realTime2); if (realTime2 - realTime1 > 0) { realSeconds++; if (realSeconds % 10 == 0) { std::cout << "TPS: " << (((double) engine->getGameTime()) / realSeconds) << std::endl; } } realTime1 = realTime2; } } catch (EngineException *e) { std::cout << "BerryBots encountered an error:" << std::endl; std::cout << " " << e->what() << std::endl; delete e; return 0; } if (!nodisplay) { gfxManager->destroyBbGfx(); delete window; } const char* winnerName = engine->getWinnerName(); if (winnerName != 0) { std::cout << std::endl<< winnerName << " wins! Congratulations!" << std::endl; } std::cout << std::endl << "Results:" << std::endl; Team **rankedTeams = engine->getRankedTeams(); bool hasScores = false; for (int x = 0; x < numTeams; x++) { if (rankedTeams[x]->result.score != 0) { hasScores = true; break; } } TeamResult *firstResult = &(rankedTeams[0]->result); int numStats = firstResult->numStats; char **statKeys = 0; if (numStats > 0) { statKeys = new char*[firstResult->numStats]; for (int x = 0; x < numStats; x++) { statKeys[x] = new char[strlen(firstResult->stats[x]->key) + 1]; strcpy(statKeys[x], firstResult->stats[x]->key); } } for (int x = 0; x < engine->getNumTeams(); x++) { TeamResult *result = &(rankedTeams[x]->result); if (result->showResult) { std::cout << " " << rankedTeams[x]->name << ":" << std::endl; std::cout << " Rank: "; if (result->rank == 0) { std::cout << "-"; } else { std::cout << result->rank; } std::cout << std::endl; if (hasScores) { std::cout << " Score: " << round(result->score, 2) << std::endl; } for (int y = 0; y < numStats; y++) { char *key = statKeys[y]; bool found = false; for (int z = 0; z < result->numStats; z++) { char *resultKey = result->stats[z]->key; if (strcmp(key, resultKey) == 0) { std::cout << " " << key << ": " << round(result->stats[z]->value, 2) << std::endl; found = true; break; } } if (!found) { std::cout << " " << key << ": -" << std::endl; } } } } std::cout << std::endl << "CPU time used per tick (microseconds):" << std::endl; for (int x = 0; x < engine->getNumTeams(); x++) { Team *team = engine->getTeam(x); if (!team->stageShip && !team->disabled) { std::cout << " " << team->name << ": " << (team->totalCpuTime / team->totalCpuTicks) << std::endl; } } if (realSeconds > 0) { std::cout << std::endl << "TPS: " << (((double) engine->getGameTime()) / realSeconds) << std::endl; } if (saveReplay) { ReplayBuilder *replayBuilder = engine->getReplayBuilder(); // TODO: move this into a function in the engine Team **rankedTeams = engine->getRankedTeams(); replayBuilder->setResults(rankedTeams, engine->getNumTeams()); char *filename = 0; char *absFilename = 0; do { if (filename != 0) { delete filename; } if (absFilename != 0) { delete absFilename; } filename = replayFilename(stage->getName()); char *filePath = fileManager->getFilePath(REPLAYS_SUBDIR, filename); absFilename = fileManager->getAbsFilePath(filePath); delete filePath; } while (fileManager->fileExists(absFilename)); replayBuilder->saveReplay(filename); std::cout << std::endl << "Saved replay to: " << REPLAYS_SUBDIR << "/" << filename << std::endl; delete filename; delete absFilename; } std::cout << std::endl; delete engine; for (int x = 0; x < numTeams; x++) { delete teams[x]; } delete teams; delete rankedTeams; for (int x = 0; x < numStats; x++) { delete statKeys[x]; } delete statKeys; delete printHandler; if (!nodisplay) { delete gfxManager; } delete packageReporter; delete fileManager; delete zipper; delete shipsBaseDir; delete stagesBaseDir; return 0; }