Skip to content

Instantly share code, notes, and snippets.

@yashihei
Created January 17, 2014 16:46
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 yashihei/8476749 to your computer and use it in GitHub Desktop.
Save yashihei/8476749 to your computer and use it in GitHub Desktop.
#include <Siv3D.hpp>
//色々だるいしシーケンスグローバル
enum class State {
TITLE,
IN_GAME,
GAMEOVER,
CLEAR,
};
State state = State::IN_GAME;
//TODO: セルのクラス化?
//反省:[y][x]の記述多すぎ、ミスの原因にもなるので
class Board {
struct Cell {
bool bom;
bool open;
bool flag;
int num;//周りのボム数
};
static const int HEIGHT = 9, WIDTH = 9;
static const int SIZE = 30;
std::array<std::array<Cell, HEIGHT>, WIDTH> cellState;
std::array<std::array<Rect, HEIGHT>, WIDTH> cellRect;
Texture bomTexure { L"bom.png" };
Texture flagTexure { L"flag.png" };
Font font {SIZE/2};
const int BOM_NUM = 10;
public:
Board() {
for (int y = 0; y < HEIGHT; y++) {
for (int x = 0; x < WIDTH; x++) {
cellRect[y][x].setPos({ x * SIZE, y * SIZE });
cellRect[y][x].setSize({ SIZE, SIZE });//イニシャライザリスト素敵
}
}
Init();
}
void Init() {
//初期化ー
for (int y = 0; y < HEIGHT; y++) {
for (int x = 0; x < WIDTH; x++) {
cellState[y][x].open = false;
cellState[y][x].bom = false;
cellState[y][x].flag = false;
cellState[y][x].num = 0;
}
}
//ボム混ぜるー
for (int i = 0; i < BOM_NUM; i++) {
int x = Random(0, HEIGHT - 1);
int y = Random(0, WIDTH - 1);
if (!cellState[y][x].bom) cellState[y][x].bom = true;
else i--;
}
//各マスの周りのボム数カウント
for (int y = 0; y < HEIGHT; y++) {
for (int x = 0; x < WIDTH; x++) {
cellState[y][x].num = searchBomCnt(x, y);
}
}
}
void Move() {
int openCnt = 0;
for (int y = 0; y < HEIGHT; y++) {
for (int x = 0; x < WIDTH; x++) {
if (cellRect[y][x].leftClicked && !cellState[y][x].open && !cellState[y][x].flag) {
cellState[y][x].open = true;
if (cellState[y][x].num == 0 && !cellState[y][x].bom) autoOpen(x, y);
if (cellState[y][x].bom) {
state = State::GAMEOVER;//ゲームオーバー
//TODO:全てのボム表示
for (int i = 0; i < HEIGHT; i++) for (int j = 0; j < WIDTH; j++) if (cellState[i][j].bom) cellState[i][j].open = true;
}
}
if (cellRect[y][x].rightClicked && !cellState[y][x].open) {
if (!cellState[y][x].flag) cellState[y][x].flag = true;
else cellState[y][x].flag = false;
}
if (cellState[y][x].open) openCnt++;
}
}
if (openCnt >= WIDTH * HEIGHT - BOM_NUM) state = State::CLEAR;//クリア
}
void Draw() {
for (int y = 0; y < HEIGHT; y++) {
for (int x = 0; x < WIDTH; x++) {
if (cellState[y][x].open) {
cellRect[y][x].draw(Palette::Black);
if (cellState[y][x].bom) {
bomTexure.draw(x * SIZE, y * SIZE);
}
if (cellState[y][x].num > 0) {
font.draw(Format(cellState[y][x].num), SIZE * x + 10, SIZE * y);
//font.draw(Format(cellState[y][x].bom));
}
} else {
cellRect[y][x].draw(Palette::Darkgray);
cellRect[y][x].drawFrame(1, 0, Palette::Black);
if (cellState[y][x].flag) flagTexure.draw(x * SIZE, y * SIZE);
}
}
}
}
bool onBoard(int x, int y) {
if (x < 0 || x >= WIDTH || y < 0 || y >= HEIGHT) return false;
return true;
}
int searchBomCnt(int x, int y) {
int cnt = 0;
for (int dy = -1; dy < 2; dy++) {
for (int dx = -1; dx < 2; dx++) {
if (!onBoard(x + dx, y + dy)) continue;
if (dy == 0 && dx == 0) continue;
if (cellState[y][x].bom) continue;
if (cellState[y + dy][x + dx].bom) cnt++;
}
}
return cnt;
}
void autoOpen(int x, int y) {
for (int dy = -1; dy < 2; dy++) {
for (int dx = -1; dx < 2; dx++) {
if (dy == 0 && dx == 0) continue;
int tx = x + dx, ty = y + dy;
if (!onBoard(tx, ty)) continue;
if (cellState[ty][tx].bom) continue;
if (!cellState[ty][tx].open) {
cellState[ty][tx].open = true;
} else {
continue;
}
if (cellState[ty][tx].num == 0) autoOpen(tx, ty);//再帰的に
}
}
}
};
void Main()
{
Window::Resize(270, 270);
Window::SetTitle(L"てくにゃんすいーぱー");
auto board = std::make_shared<Board>();
Font mes(30);
while (System::Update()) {
switch (state) {
case State::IN_GAME:
board->Move();
board->Draw();
break;
case State::GAMEOVER:
board->Draw();
mes.draw(L"GAMEOVER", { 0, 0 }, Palette::Red);
break;
case State::CLEAR:
board->Draw();
mes.draw(L"CLEAR!", { 0, 0 }, Palette::Green);
break;
}
if (Input::KeyR.clicked) {
board->Init();
state = State::IN_GAME;
}
}
}

#てくにゃんすいーぱー

siv3d触ってすげえ思ったので、思っただけでは悲しいので、マインスイーパー作りました。
ダウンロードはこちら()
てくにゃん要素はボムだけなんです!こめんなさい。

##操作方法 Rキーでリスタート出来ます。あとは普通のマインスイーパーと同じです。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment