Пример #1
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;
}
Пример #2
0
void StagePreview::showPreview(sf::RenderWindow *window, const char *stageName,
                               int x, int y) {
  if (stageName_ != 0) {
    delete stageName_;
  }
  stageName_ = new char[strlen(stageName) + 1];
  strcpy(stageName_, stageName);

  SetPosition(wxPoint(x, y));
  infoSizer_->Clear(true);
  descSizer_->Clear(true);
  
  BerryBotsEngine *engine = new BerryBotsEngine(0, fileManager_, 0);
  Stage *stage = engine->getStage();
  try {
    engine->initStage(getStagesDir().c_str(), stageName, getCacheDir().c_str());
  } catch (EngineException *e) {
    wxMessageDialog errorMessage(NULL, e->what(), "Preview failure",
                                 wxOK | wxICON_EXCLAMATION);
    errorMessage.ShowModal();
    delete engine;
    delete e;
    return;
  }
  SetTitle(wxString::Format(wxT("%s"), stage->getName()));

  unsigned int targetWidth;
  unsigned int targetHeight;
  char *previewFilename =
      savePreviewImage(window, engine, targetWidth, targetHeight);
  wxImage previewImage(previewFilename);
  delete previewFilename;

  double backingScale = getBackingScaleFactor();
  if (backingScale > 1) {
    targetWidth /= backingScale;
    targetHeight /= backingScale;
  }
  visualPreview_->SetMinSize(wxSize(targetWidth, targetHeight));
  visualPreview_->SetMaxSize(wxSize(targetWidth, targetHeight));

#ifdef __WXOSX__
  int padding = 4;
#else
  int padding = 8;
#endif

  wxSizer *infoGrid = new wxFlexGridSizer(2, 0, padding);
  addInfo(infoGrid, "Name:", stage->getName());
  addInfo(infoGrid, "Size:",
      wxString::Format(wxT("%i x %i"), stage->getWidth(), stage->getHeight()));
  if (engine->getTeamSize() > 1) {
    addInfo(infoGrid, "Team size:", engine->getTeamSize());
  }
  addInfo(infoGrid, "Walls:", (stage->getWallCount() - 4));
  addInfo(infoGrid, "Zones:", stage->getZoneCount());
  addInfo(infoGrid, "Starts:", stage->getStartCount());
  int numStageShips = stage->getStageShipCount();
  if (numStageShips > 0) {
    char **stageShips = stage->getStageShips();
    for (int x = 0; x < numStageShips; x++) {
      const char *shipName = stageShips[x];
      if (shipName != 0) {
        int count = 1;
        for (int y = x + 1; y < numStageShips; y++) {
          const char *shipName2 = stageShips[y];
          if (shipName2 != 0 && strcmp(shipName, shipName2) == 0) {
            count++;
            stageShips[y] = 0;
          }
        }
        wxString wxShipName = (count == 1) ? wxString(stageShips[x])
            : wxString::Format(wxT("%s x%i"), shipName, count);
        addInfo(infoGrid, (x == 0 ? "Ships:" : ""), wxShipName);
      }
    }
  }
  infoSizer_->Add(infoGrid);

  char *description = fileManager_->getStageDescription(
      getStagesDir().c_str(), stageName, getCacheDir().c_str());
  if (description == 0) {
    std::string descstr("<No description>");
    description = new char[descstr.length() + 1];
    strcpy(description, descstr.c_str());
  }
  wxStaticText *descCtrl = new wxStaticText(mainPanel_, wxID_ANY, description);
  descSizer_->Add(descCtrl);
  delete description;

  mainPanel_->GetSizer()->SetSizeHints(mainPanel_);
  mainPanel_->Layout();
  Fit();
  mainPanel_->SetFocus();

  wxBitmap bitmap;
#ifdef __WINDOWS__
  bitmap = wxBitmap(previewImage);
#else
  bitmap.CreateScaled(targetWidth, targetHeight, wxBITMAP_SCREEN_DEPTH,
                      backingScale);
  wxMemoryDC dc(bitmap);
  double logicalScale = (backingScale > 1) ? (1.0 / backingScale) : 1;
  dc.SetLogicalScale(logicalScale, logicalScale);
  dc.DrawBitmap(wxBitmap(previewImage), 0, 0);
#endif

  // On Windows, if we set the bitmap before the Layout/Fit stuff, we get visual
  // artifacts when paging through the stages with up/down keys.
  visualPreview_->SetBitmap(bitmap);

  delete engine;
}