suzu-kの日記

メインはプログラミング

マインスイーパー その1

コンソール版のマインスイーパー作りました.

まずは動くものをという方針でコンパイルが通ればコードを追加していきました.(製作期間は3−4時間くらい?初めて作るにしては早いのか?)

main関数内にほとんど放り込んだので関数化して見やすくした後に,機能を付け足すかもしくはGUIで遊べるようにしたいと思います.

#include <iostream>
#include <stdlib.h>
#include <time.h>
using namespace std;

#define DEBUG 1

#define WIDTH 10
#define HEIGHT 10
#define BOMB 50

typedef struct _state{
	bool bomb;
	bool selected;
	bool flag;
}State;

State gState[WIDTH][HEIGHT];

void setAutoSelected(int x, int y);

int main(){

    //initialize gState
	for(int y = 0; y < HEIGHT; y++){
		for (int x = 0; x < WIDTH; ++x)
		{
			State state = {false, false};
			gState[x][y] = state;
		}
	}

	srand(time(NULL));
	int bombNum = 0;

    //set bomb in gState
	while(bombNum < BOMB){
		int x = rand() % WIDTH;
		int y = rand() % HEIGHT;
		if(gState[x][y].bomb == true)
			continue;

		gState[x][y].bomb = true;
		++bombNum;
	}

	time_t firstTimer, currentTimer;
	time(&firstTimer);

	First:

#if DEBUG
	cout << "Bomb area" << endl;
	for(int i = 0; i < WIDTH; i++)
		cout << "-" <<flush;

	cout << endl;

	for(int y = WIDTH - 1; y >= 0 ; --y){
		for (int x = 0; x < WIDTH; ++x)
		{
			cout << gState[x][y].bomb;
		}
		cout << endl;
	}

	for(int i = 0; i < WIDTH; i++)
		cout << "-" <<flush;

	cout << endl;

#endif

	time(&currentTimer);
	cout << "経過時間:" << currentTimer - firstTimer << "秒" << endl;
	// selNum is judge GameClear
	int selNum = 0;
	//search bomb-area by gState.selected
	for(int y = HEIGHT - 1; y >= 0 ; y--){
		for (int x = 0; x < WIDTH; ++x)
		{
			int num = 0;
			if(gState[x][y].selected == true){
				selNum++;
				for(int dy = - 1; dy <= 1; dy++ ){
					for(int dx = -1; dx <= 1; dx++){
						int yy = y - dy;
						int xx = x - dx;
						if( yy >= 0 && yy < WIDTH && xx >= 0 && xx < HEIGHT ){
							if( gState[xx][yy].bomb == true )
								++num;
						}
					}
				}
				cout << num << flush;
			}else{
				cout << "*" << flush;
			}
		}
		cout << endl;
	}

	if (selNum == (WIDTH * HEIGHT - BOMB ))
	{
		cout << "!!!!Game Clear!!!!"<< endl;
		exit(1);
	}


	int x, y;
	cout << "Input x, y:" << flush;
	cin >> x >> y;
	x -= 1;
	y -= 1;

	while (x < 0 || x >= WIDTH || y < 0 || y >= HEIGHT)
	{
		cout << "Input x from 1 to " << WIDTH << endl;
		cout << "Input y from 1 to " << HEIGHT << endl;
		cin >> x >> y;
		x -= 1;
		y -= 1;
	}

	if(gState[x][y].bomb == true){
		cout << "Game Over" << endl;
		return 0;
	}
	gState[x][y].selected = true;

	setAutoSelected(x, y);

	goto First;

	return 0;
}

void setAutoSelected(int x, int y){

	for (int i = - 1; i <= 1; ++i)
	{
		int sx = x + i;
		if(sx >= 0 && sx < WIDTH && y >= 0){

			if (gState[sx][y].bomb == false && gState[sx][y].selected == false)
			{
				gState[sx][y].selected = true;
				setAutoSelected(sx, y);
			} 
		} 

		int sy = y + i;
		if (sy >= 0 && sy < HEIGHT)
		{
			if (gState[x][sy].bomb == false && gState[x][sy].selected == false)
			{
				gState[x][sy].selected = true;
				setAutoSelected(x, sy);
			}

		}
	}
}