suzu-kの日記

メインはプログラミング

マインスイーパー その2

関数化しました.



最後の方にあるMain関数内がすっきり.
納得がいかない箇所がありますが,それは次回に回すことにします()

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

#define DEBUG 1

#define WIDTH 10
#define HEIGHT 10
#define BOMB 99

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

State gState[WIDTH][HEIGHT];

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

void setBomb(int maxBomb){
	srand(time(NULL));
	int bombNum = 0;

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

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

void showBombMap(){
	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;
}

void showMap(){
	//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){
				num++;
				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;
	}
}

bool isGameClear(int selNum){
    // s is judge GameClear
	int s = 0;

	for (int i = 0; i < HEIGHT; ++i)
	{
		for (int j = 0; j < WIDTH; ++j)
		{
			if (gState[j][i].selected == true)
			{
				++s;
			}
		}
	}
	if (s == selNum)
	{
		return true;
	}
	return false;
}

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);
			}

		}
	}
}

void input(){

	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;

}

int main(){

	initialize();

	setBomb(BOMB);

	time_t firstTimer, currentTimer;
	time(&firstTimer);


	First:
	
	#if DEBUG
	showBombMap();
	#endif

	time(&currentTimer);
	cout << "経過時間:" << currentTimer - firstTimer << "秒" << endl;

	showMap();

	if(isGameClear(WIDTH * HEIGHT - BOMB))
	{
		cout << "!!!!Game Clear!!!!"<< endl;
		return 1;
	}

	input();

	setAutoSelected(x, y);

	goto First;

	return 0;
}