Game.cpp
//------------------------------------------------------------------------------
/// @file
/// @author ハル研究所プログラミングコンテスト実行委員会
///
/// @copyright Copyright (c) 2019 HAL Laboratory, Inc.
/// @attention このファイルの利用は、同梱のREADMEにある
/// 利用条件に従ってください。
//------------------------------------------------------------------------------
#pragma once
#include "Game.hpp"
//------------------------------------------------------------------------------
#include "Assert.hpp"
#include "Stage.hpp"
//------------------------------------------------------------------------------
namespace hpc {
//------------------------------------------------------------------------------
Game::Game()
: mIsRandomSeedSet(false)
, mGivenRandomSeed(RandomSeed::DefaultSeed())
, mRecorder()
, mTimer()
{
}
//------------------------------------------------------------------------------
void Game::changeSeed(RandomSeed aSeed)
{
mIsRandomSeedSet = true;
mGivenRandomSeed = aSeed;
}
//------------------------------------------------------------------------------
void Game::run(Answer* aAnswer)
{
HPC_ASSERT(aAnswer != nullptr);
// 乱数関連の定数定義。
// ここの randomSeed および randomSpin は
// サーバーの評価環境と配布パッケージとで異なります。
const uint randomSeedX = 0x81eacc80;
const uint randomSeedY = 0xcb9412ed;
const uint randomSeedZ = 0x1acb27dc;
const uint randomSeedW = 0x21a234f3;
const int randomSpinX = 0xFFF;
const int randomSpinY = 0xFF;
Random gameRandom =
Random(
mIsRandomSeedSet ?
mGivenRandomSeed :
RandomSeed(
randomSeedX,
randomSeedY,
randomSeedZ,
randomSeedW
)
);
// ゲーム開始
mTimer.start();
gameRandom.spin(randomSpinX);
for (int i = 0; i < Parameter::GameStageCount; ++i) {
// ステージ開始
gameRandom.spin(randomSpinY);
auto randomSeed = gameRandom.generateRandomSeed();
// ステージ生成
Stage stage;
int turtleCount = i / 3 % 20 + 6;
int foodCount = i / 60 % 4 * 20 + 40;
int distribution = 2 - i % 3;
stage.initialize(turtleCount, foodCount, distribution, randomSeed);
aAnswer->initialize(stage);
mRecorder.afterInitializeStage(stage);
while (!stage.isEnd() && stage.turn() < Parameter::GameTurnLimit) {
// ターン開始
Actions actions;
aAnswer->setActions(stage, actions);
stage.update(actions);
stage.advanceTurn();
mRecorder.afterAdvanceTurn(stage);
}
mRecorder.afterFinishStage();
aAnswer->finalize(stage);
}
mRecorder.afterFinishAllStages();
mTimer.stop();
}
//------------------------------------------------------------------------------
const Recorder& Game::recorder() const
{
return mRecorder;
}
//------------------------------------------------------------------------------
const Timer& Game::timer() const
{
return mTimer;
}
} // namespace
// EOF