MakeProblemは、ほかの関数を変更したので若干の変更が必要である。
ただし処理内容はコンソール版と変わらない
なんか効率の悪い生成法だが、工夫できそうな人は効率の良い方法を考えてほしい。
何回シャッフルしたかで、難しさが変わってくるので、レベル設定的なのはここでできる。
void MakeProblem(Board& _board) { Point p; for (適当な回数繰り返す(繰り返しが多いほうが難しくなるはず)) { while (true) { int num = 1~16の乱数を生成; p = numのあるタイルのインデックス{i,j}をPoint型に代入 if (pは動かせるか?) { //動かせるならループを抜ける break; }//動かせないならもう一回乱数を生成 } //タイルを動かす SwapTile(p, _board); } }
InitGameでMakeProblemよんじゃえばいいよね。
void InitGame(Board& _board) { Window::Resize(WSIZE); state = GAME_STATE::TITLE; InitBoard(_board); 問題作成関数を呼ぼう }
ゲームクリアの判定は、MakeProblemでひっかきまわす前のタイルの状態が整列状態=クリア状態なので、InitBoardでタイルを初期化した時と同じ配置にタイルが並んでいるかどうかを確認すればよい。
bool CheckClear(Board& _board) { //よほどの確率じゃなきゃMakeProblemした後に、間違って揃っちゃったってことはないはず for (int j = 0; j < BOARD_HEIGHT; j++) { for (int i = 0; i < BOARD_WIDTH; i++) { //順番があってないのを発見した時点でfalse返して関数を抜ける<codeblock code_label> if (_board.tile[j][i] != j * BOARD_WIDTH + i + 1) return(false); } } //最後までたどり着いたら整列されてるってことでtrueを返す return(true); }
void PlayUpdate(Board& _board)
{
if (MouseL.down()) {
省略
}
if (クリアチェックの呼び出し)
{
state = GAME_STATE::CLEAR;
}
}
これで、MakeProblemの繰り返し回数を1か2ぐらいにして、クリアしたときにおめでとう画面が描画されれば正常に動作している。