Skip to content

Instantly share code, notes, and snippets.

@kazmura11
Last active August 29, 2015 14:13
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kazmura11/3d57b051ffe9eaf0125d to your computer and use it in GitHub Desktop.
Save kazmura11/3d57b051ffe9eaf0125d to your computer and use it in GitHub Desktop.
ぷよぷよの問題(人材募集企画 2011年版 問題2)
// 3.5h
#include <iostream>
#include <memory.h>
namespace Puyo
{
struct Check2D
{
int x;
int y;
};
const int SY = 13;
const int SX = 6;
// 右, 下, 左の順に定義
const Check2D Ofs[] = { {1, 0}, {0, 1}, {-1, 0} };
enum Dir
{
Right = 0,
Down = 1,
Left = 2,
None = 3
};
// グローバル
char gStage[SY][SX] =
{
' ',' ','G','Y','R','R',
'R','Y','Y','G','Y','G',
'G','Y','G','Y','R','R',
'R','Y','G','Y','R','G',
'Y','G','Y','R','Y','G',
'G','Y','R','Y','R','G',
'Y','G','Y','R','Y','R',
'Y','G','Y','R','Y','R',
'Y','R','R','G','R','G',
'R','Y','G','Y','G','G',
'G','R','Y','G','Y','R',
'G','R','Y','G','Y','R',
'G','R','Y','G','Y','R',
};
int gCombCnt = 0; // グローバル
int gCheckN = 0; // グローバル
Check2D gC2D[SY * SX] = { 0 }; // グローバル
// ↑こんなに要素いらないだろうけど念のため
void printAll();
bool checkAround(char target, int y, int x, Dir dir);
void del();
void fall();
void puyo();
bool isEnd();
/*
* 現状を出力
*/
void printAll()
{
std::cout << "+------+\n";
for (int y = 0; y < SY; y++)
{
std::cout << "|";
for (int x = 0; x < SX; x++)
{
std::cout << gStage[y][x];
}
std::cout << "|\n";
}
std::cout << "+------+\n";
}
/*
* 右, 下, 左 (この順がいいかはどうかは微妙)
* の順につながっている個数を数え、
* 結果をグローバルに保存する。
*/
bool checkAround(char target, int y, int x, Dir dir)
{
// 周りを調査
for (int i = 0; i < 3; i++)
{
int cx = x + Ofs[i].x;
int cy = y + Ofs[i].y;
// 境界チェック
if (cx < 0 || SX -1 < cx) { continue; }
if (cy < 0 || SY -1 < cy) { continue; }
// きた方向にもどるのはダメ Downは特別扱い
// 現在地点を基準にすると逆方向になるため2 - i
if (dir != Down && dir == 2 - i ) { continue; }
//
if (target == gStage[cy][cx])
{
gC2D[gCheckN].y = cy;
gC2D[gCheckN].x = cx;
gCheckN++;
// 再帰
checkAround(target, cy, cx, static_cast<Dir>(i));
}
}
}
/*
* checkした部分を消しに行く
*/
void del()
{
for (int i = 0; i < gCheckN; i++)
{
gStage[gC2D[i].y][gC2D[i].x] = ' ';
}
}
// この関数でハマった
/*
* 消去済み列を調べて下から上に順に落としていく
*/
void fall()
{
for (int i = gCheckN - 1; i >= 0; i--)
{
int ty = gC2D[i].y;
int tx = gC2D[i].x;
// 消えた列に既に何か移動済みであれば次へ
if (gStage[ty][tx] != ' ') { continue; }
int cnt = 0; // 上にずらした分のカウント
// 下から上へ
for (int y = ty; y >= 0; y--)
{
// 現在調べているところに何かあったら
if (gStage[y][tx] != ' ')
{
// 落とす
char swap = gStage[y][tx];
gStage[ty - cnt][tx] = swap;
gStage[y][tx] = ' ';
cnt++;
}
}
}
}
/*
* 1回のぷよぷよ処理
*/
void puyo()
{
// 左上→右下
//for (int y = 0; y < SY - 1; y++) // 一個手前まで
for (int y = 0; y < SY; y++) // 上は間違ってたので修正
{
for (int x = 0; x < SX; x++)
{
if (gStage[y][x] == ' ') { continue; }
// 現在位置をチェックに入れる!!
gC2D[gCheckN].y = y;
gC2D[gCheckN].x = x;
gCheckN++;
checkAround(gStage[y][x], y, x, None);
if (gCheckN >= 4)
{
del();
fall();
// DEBUG用 実際にはコンボかどうかチェックしていない
std::cout << ++gCombCnt << "コンボ!" << std::endl;
printAll();
}
// 元に戻す
memset(gC2D, 0, sizeof(gC2D));
gCheckN = 0;
}
}
}
/*
* 終了判定
*/
bool isEnd()
{
// 下から見てく
for (int y = SY - 1; y >= 0; y--)
{
for (int x = SX - 1; x >= 0; x--)
{
if (gStage[y][x] != ' ') { return false; }
}
}
return true;
}
} // end of namespace
int main()
{
std::cout << "--初期状態\n";
Puyo::printAll();
for (int i = 0;;i++)
{
std::cout << "--ループ" << i + 1 << "回目\n";
Puyo::puyo();
if (Puyo::isEnd()) { break; }
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment