Recorder.cpp
//------------------------------------------------------------------------------
/// @file
/// @author ハル研究所プログラミングコンテスト実行委員会
///
/// @copyright Copyright (c) 2019 HAL Laboratory, Inc.
/// @attention このファイルの利用は、同梱のREADMEにある
/// 利用条件に従ってください。
//------------------------------------------------------------------------------
#pragma once
#include "Recorder.hpp"
//------------------------------------------------------------------------------
#include "Print.hpp"
//------------------------------------------------------------------------------
namespace hpc {
//------------------------------------------------------------------------------
Recorder::Recorder()
: mGameRecord()
, mCurrentStageNumber()
, mCurrentTurn()
{
}
//------------------------------------------------------------------------------
void Recorder::dumpJson() const
{
HPC_PRINTF("["); {
for (int i = 0; i < Parameter::GameStageCount; ++i) {
if (i != 0) {
HPC_PRINTF(",");
}
dumpJsonStage(mGameRecord.stageRecords[i]);
}
} HPC_PRINTF("]");
HPC_PRINTF("\n");
}
//------------------------------------------------------------------------------
void Recorder::dumpResult(bool aIsSilent) const
{
if (!aIsSilent) {
HPC_PRINTF("stage | turn\n");
for (int i = 0; i < Parameter::GameStageCount; ++i) {
HPC_PRINTF("% 5d | % 4d\n", i, mGameRecord.stageRecords[i].turn);
}
}
HPC_PRINTF("TotalTurn: %d\n", mGameRecord.totalTurn);
}
//------------------------------------------------------------------------------
void Recorder::afterInitializeStage(const Stage& aStage)
{
StageRecord& stageRecord = mGameRecord.stageRecords[mCurrentStageNumber];
mCurrentTurn = 0;
stageRecord.turtleCount = aStage.turtlePositions().count();
stageRecord.foodCount = aStage.foods().count();
for (int i = 0; i < aStage.foods().count(); ++i) {
stageRecord.foods[i].pos = aStage.foods()[i].pos();
stageRecord.foods[i].height = aStage.foods()[i].height();
stageRecord.foods[i].eatenTurn = Parameter::GameTurnLimit;
}
writeTurnRecord(mCurrentStageNumber, 0, aStage);
}
//------------------------------------------------------------------------------
void Recorder::afterAdvanceTurn(const Stage& aStage)
{
StageRecord& stageRecord = mGameRecord.stageRecords[mCurrentStageNumber];
++mCurrentTurn;
for (int i = 0; i < aStage.foods().count(); ++i) {
if (stageRecord.foods[i].eatenTurn == Parameter::GameTurnLimit && aStage.foods()[i].isEaten()) {
stageRecord.foods[i].eatenTurn = mCurrentTurn;
}
}
writeTurnRecord(mCurrentStageNumber, mCurrentTurn, aStage);
}
//------------------------------------------------------------------------------
void Recorder::afterFinishStage()
{
StageRecord& stageRecord = mGameRecord.stageRecords[mCurrentStageNumber];
stageRecord.turn = mCurrentTurn;
mGameRecord.totalTurn += mCurrentTurn;
++mCurrentStageNumber;
}
//------------------------------------------------------------------------------
void Recorder::afterFinishAllStages()
{
}
//------------------------------------------------------------------------------
int Recorder::totalTurn() const
{
return mGameRecord.totalTurn;
}
//------------------------------------------------------------------------------
void Recorder::dumpJsonStage(const StageRecord& aRecord) const
{
HPC_PRINTF("["); {
HPC_PRINTF("%d,", Parameter::GameTurnLimit);
HPC_PRINTF("%d,", Parameter::StageWidth);
HPC_PRINTF("%d,", Parameter::StageHeight);
HPC_PRINTF("%d,", aRecord.turtleCount);
HPC_PRINTF("%d,", aRecord.foodCount);
HPC_PRINTF("%d,", aRecord.turn);
// エサ情報
HPC_PRINTF("["); {
for (int i = 0; i < aRecord.foodCount; ++i) {
if (i != 0) {
HPC_PRINTF(",");
}
HPC_PRINTF("["); {
HPC_PRINTF("%d,", aRecord.foods[i].pos.x);
HPC_PRINTF("%d,", aRecord.foods[i].pos.y);
HPC_PRINTF("%d,", aRecord.foods[i].height);
HPC_PRINTF("%d", aRecord.foods[i].eatenTurn);
} HPC_PRINTF("]");
}
} HPC_PRINTF("],");
// ターンのログ
HPC_PRINTF("["); {
for (int i = 0; i <= aRecord.turn; ++i) {
if (i != 0) {
HPC_PRINTF(",");
}
dumpJsonTurn(aRecord.turnRecords[i]);
}
} HPC_PRINTF("]");
} HPC_PRINTF("]");
}
//------------------------------------------------------------------------------
void Recorder::dumpJsonTurn(const TurnRecord& aRecord) const
{
// カメ情報
HPC_PRINTF("["); {
for (int i = 0; i < aRecord.turtleRecordCount; ++i) {
if (i != 0) {
HPC_PRINTF(",");
}
HPC_PRINTF("["); {
HPC_PRINTF("%d,", aRecord.turtles[i].pos.x);
HPC_PRINTF("%d,", aRecord.turtles[i].pos.y);
HPC_PRINTF("["); {
for (int j = 0; j < aRecord.turtles[i].count; ++j) {
if (j != 0) {
HPC_PRINTF(",");
}
HPC_PRINTF("%d", aRecord.turtles[i].indices[j]);
}
} HPC_PRINTF("]");
} HPC_PRINTF("]");
}
} HPC_PRINTF("]");
}
//------------------------------------------------------------------------------
void Recorder::writeTurnRecord(int aStageNumber, int aTurn, const Stage& aStage)
{
TurnRecord& turnRecord = mGameRecord.stageRecords[aStageNumber].turnRecords[aTurn];
Array<int, Parameter::MaxTurtleCount> turtleIndices[Parameter::StageHeight][Parameter::StageWidth];
for (int i = 0; i < aStage.turtlePositions().count(); ++i) {
Point pos = aStage.turtlePositions()[i];
turtleIndices[pos.y][pos.x].add(i);
}
for (int y = 0; y < Parameter::StageHeight; ++y) {
for (int x = 0; x < Parameter::StageWidth; ++x) {
if (turtleIndices[y][x].count() > 0) {
TurtleRecord& turtleRecord = turnRecord.turtles[turnRecord.turtleRecordCount];
turtleRecord.pos = Point(x, y);
turtleRecord.count = turtleIndices[y][x].count();
for (int i = 0; i < turtleIndices[y][x].count(); ++i) {
turtleRecord.indices[i] = turtleIndices[y][x][i];
}
turnRecord.turtleRecordCount++;
}
}
}
}
} // namespace
// EOF