CandidateLane.cpp
//------------------------------------------------------------------------------
/// @file
/// @author ハル研究所プログラミングコンテスト実行委員会
///
/// @copyright Copyright (c) 2018 HAL Laboratory, Inc.
/// @attention このファイルの利用は、同梱のREADMEにある
/// 利用条件に従ってください。
//------------------------------------------------------------------------------
#pragma once
#include "CandidateLane.hpp"
//------------------------------------------------------------------------------
#include "Math.hpp"
#include "Print.hpp"
//------------------------------------------------------------------------------
namespace hpc {
//------------------------------------------------------------------------------
CandidateLane::CandidateLane()
: mRecipe()
, mCandidatePieces()
{
}
//------------------------------------------------------------------------------
CandidateLane::CandidateLane(const CandidateLaneRecipe& aRecipe)
: mRecipe(aRecipe)
, mCandidatePieces()
{
}
//------------------------------------------------------------------------------
CandidatePieces& CandidateLane::pieces()
{
return mCandidatePieces;
}
//------------------------------------------------------------------------------
const CandidatePieces& CandidateLane::pieces() const
{
return mCandidatePieces;
}
//------------------------------------------------------------------------------
const CandidateLaneRecipe& CandidateLane::recipe() const
{
return mRecipe;
}
//------------------------------------------------------------------------------
void CandidateLane::fill(Random* aRandom)
{
HPC_ASSERT(aRandom != nullptr);
while (mCandidatePieces.count() < mRecipe.visiblePieceCount()) {
// 外周の半分を決定して
const int hpm =
aRandom->randMinMax(
mRecipe.minSampleEdgeLength() * 2,
mRecipe.maxSampleEdgeLength() * 2
);
// 折る場所を決めて
const float foldPosRatio =
aRandom->randFloatMinTerm(
mRecipe.foldPosRatioMin(),
mRecipe.foldPosRatioTerm()
);
// w/h が確定
const int w = Math::LimitMinMax(static_cast<int>(hpm * foldPosRatio), 1, hpm - 1);
const int h = Math::LimitMinMax(hpm - w, 1, hpm - 1);
// 原始スコアを確定
const int primalScore =
aRandom->randMinMax(
mRecipe.minPrimalScore(),
mRecipe.maxPrimalScore()
);
// スコアを確定
const int score =
static_cast<int>(
primalScore *
aRandom->randFloatMinTerm(
mRecipe.scoreCoeffMin(),
mRecipe.scoreCoeffTerm()
)
);
// 必要加熱ターン数を確定
const int rhtc = primalScore / (w * h);
mCandidatePieces.add(Piece(Vector2i::Zero(), w, h, rhtc, score));
}
}
} // namespace
// EOF