Recorder.hpp
//------------------------------------------------------------------------------
/// @file
/// @author ハル研究所プログラミングコンテスト実行委員会
///
/// @copyright Copyright (c) 2018 HAL Laboratory, Inc.
/// @attention このファイルの利用は、同梱のREADMEにある
/// 利用条件に従ってください。
//------------------------------------------------------------------------------
#pragma once
//------------------------------------------------------------------------------
#include "FieldType.hpp"
#include "Stage.hpp"
//------------------------------------------------------------------------------
namespace hpc {
/// ゲーム進行を記録するクラス。
class Recorder
{
public:
/// @name コンストラクタ
//@{
Recorder();
//@}
/// @name ダンプ
//@{
/// 記録内容を JSON として出力する。
void dumpJson() const;
/// 最終結果を出力する。
void dumpResult(bool aIsSilent) const;
//@}
/// @name 記録
//@{
/// ステージの初期化後に実行される関数。
void afterInitStage(const Stage& aStage);
/// ターンを進めた後に実行される関数。
void afterAdvanceTurn(const Stage& aStage);
/// ステージが終了した後に実行される関数。
void afterFinishStage();
/// 全ステージが終了した後に実行される関数。
void afterFinishAllStages();
//@}
/// @name 問い合わせ
//@{
/// ゲーム全体での総ターン数。
int totalTurn() const;
/// ゲーム全体での総スコア。
int totalScore() const;
//@}
private:
/// @name 内部構造体
//@{
/// 生地情報。
struct PieceRecord
{
/// 置かれているフィールド。
char fieldType;
/// 置いた場所。
char posX;
char posY;
/// 横幅。
char width;
/// 縦幅。
char height;
/// 現在までに与えられた加熱ターン数。
short currentHeatTurnCount;
/// 完成に必要な加熱ターン数。
short requiredHeatTurnCount;
/// 完成で得られるスコア。
short score;
/// 情報を埋める。
PieceRecord& setup(const Oven* aOven, const Piece& aPiece);
/// Jsonで情報を出力する。
void dumpJson() const;
};
/// オーブン設定情報
struct OvenRecipeRecord
{
/// 横幅。
int width;
/// 縦幅。
int height;
};
/// オーブン情報。
struct OvenRecord
{
/// 1ターンで記録する最大生地数。
static const int MaxOvenedPieceCount = 60;
/// このターンに焼いている生地一覧。
PieceRecord prvBakingPieces[MaxOvenedPieceCount];
/// prvBakingPieces の有効な要素数。
int bakingPieceCount;
/// このターンに焼き上がった生地一覧。
PieceRecord prvBakedPieces[MaxOvenedPieceCount];
/// prvBakedPieces の有効な要素数。
int bakedPieceCount;
/// このターンにこのオーブンが計上したスコア。
int turnScore;
/// prvBakingPieces へのアクセサ。
PieceRecord& bakingPieces(int aIndex);
/// prvBakingPieces へのアクセサ。
const PieceRecord& bakingPieces(int aIndex) const;
/// prvBakedPieces へのアクセサ。
PieceRecord& bakedPieces(int aIndex);
/// prvBakedPieces へのアクセサ。
const PieceRecord& bakedPieces(int aIndex) const;
};
/// ターン情報。
struct TurnRecord
{
/// 生地置き場の記録。
PieceRecord candidateLane[CandidateLaneType_TERM][Parameter::CandidatePieceCount];
/// 生地置き場の生地数。
int candidatePieceCount[CandidateLaneType_TERM];
/// オーブン情報。
OvenRecord ovenRecord;
/// このターンで稼いだスコア。
int turnScore;
/// このターン終了時のステージスコア。
int turnEndScore;
};
/// ステージ情報。
struct StageRecord
{
/// スコア。
int score;
/// オーブン設定。
OvenRecipeRecord ovenRecipeRecord;
/// ターン情報。
TurnRecord turnRecords[Parameter::GameTurnLimit + 1];
/// 有効なターン情報の数。
int turnRecordCount;
/// ターン数。
/// @attention turnRecordCount != ターン数、です。
/// これは turnRecord[0] にステージ開始時の盤面が入っているためです。
int turn() const;
};
/// ゲーム情報。
struct GameRecord
{
/// ゲーム全体での総ターン数。
int totalTurn;
/// ゲーム全体での総スコア。
int totalScore;
/// ステージ情報。
StageRecord stageRecords[Parameter::GameStageCount];
};
//@}
/// @name 内部実装
//@{
/// ステージ情報を JSON として出力する。
void dumpJsonStage(const StageRecord& aRecord) const;
/// ターン情報を JSON として出力する。
void dumpJsonTurn(const TurnRecord& aRecord) const;
/// 現在のターン情報を記録する。
void writeTurnRecord(int aStageNumber, int aTurn, const Stage& aStage);
//@}
/// @name プライベートメンバ変数
//@{
/// ゲーム情報。
GameRecord mGameRecord;
/// 今記録中のステージ番号。
int mCurrentStageNumber;
/// 今記録中のターン番号。
/// @attention 初期盤面がターン番号 0 であることに注意が必要です。
/// つまりプレイヤーが初めて干渉したときの盤面は
/// ターン番号 1 で記録されます。
/// これはターン数を 0 オリジンで考えたときに
/// ターン番号と現在のターン数が一致しないことを意味します。
int mCurrentTurn;
/// 今記録中のスコア。
int mCurrentScore;
//@}
};
} // namespace
// EOF