suzu-kの日記

メインはプログラミング

マインスイーパー その3

class化しました.

変数名つけるのって難しいデスネ...
次はState内を綺麗に?


State.h

#ifndef _STATE_H_
#define _STATE_H_

#define WIDTH 10
#define HEIGHT 10

class GameState{
public:
	GameState(){};
	~GameState(){};

	void initialize();
	void setBomb(int maxBomb);
	void showBombMap();
	void showMap();
	bool isGameClear(int selNum);
	void setAutoSelected(int x, int y);
	void input();

protected:
	typedef struct _state{
		bool bomb;
		bool selected;
		bool flag;
	}State;
	State mState[WIDTH][HEIGHT];
};

#endif

State.cpp

#include "State.h"
#include <iostream>

using namespace std;

void GameState::initialize(){
	    //initialize mState
	for(int y = 0; y < HEIGHT; y++){
		for (int x = 0; x < WIDTH; ++x)
		{
			State t = {false, false, false};
			mState[x][y] = t;
		}
	}
}

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

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

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

void GameState::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 << mState[x][y].bomb;
		}
		cout << endl;
	}

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

	cout << endl;
}

void GameState::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(mState[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( mState[xx][yy].bomb == true )
								++num;
						}
					}
				}
				cout << num << flush;
			}else{
				cout << "*" << flush;
			}
		}
		cout << endl;
	}
}

bool GameState::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 (mState[j][i].selected == true)
			{
				++s;
			}
		}
	}
	if (s == selNum)
	{
		return true;
	}
	return false;
}

void GameState::setAutoSelected(int x, int y){

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

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

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

		}
	}
}

void GameState::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(mState[x][y].bomb == true){
		cout << "Game Over" << endl;
		exit(1);
	}
	mState[x][y].selected = true;

}

main.cpp

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

#define DEBUG 1
#define BOMB 99

int main(){

	GameState gState;
	gState.initialize();

	gState.setBomb(BOMB);

	time_t firstTimer, currentTimer;
	time(&firstTimer);

	First:
	
	#if DEBUG
	gState.showBombMap();
	#endif

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

	gState.showMap();

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

	gState.input();

	goto First;

	return 0;
}

makefile

.cpp.o:
	c++ -o $@ -c $<

minesweeper: main.o State.o
	c++ -o $@ $^

main.cpp: State.h

State.cpp: State.h