Last active
August 29, 2015 14:13
-
-
Save kazmura11/3d57b051ffe9eaf0125d to your computer and use it in GitHub Desktop.
ぷよぷよの問題(人材募集企画 2011年版 問題2)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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