1. 문제

 

Huma의 Food 먹기 게임

 

게임에는 Human, Monster, Food의 객체가 등장하며, 이들은 10x20 격저판에서 각각 정해진 규칙에 의해 움직인다. Human 객체는 사용자의 키에 의해 왼쪽(a 키), 아래(s 키), 위(d 키), 오른쪽(f 키)으로 한칸씩 움직이고, Monster는 한 번에 2칸씩, 왼쪽, 아래, 위, 오른쪽 방향으로 랜덤하게 움직인다. Food는 5번 중에 3번은 제자리에 있고, 나머지 2번은 4가지 방향 중 랜덤하게 한 칸씩 움직인다.

 

게임은 Hyman이 Monster를 피해 Food를 먹으면(Food의 위치로 이동) 성공으로 끝나고, Monster가 Food를 먹거나 Human이 Monster에게 잡히면 실패로 끝난다.

 

다음은 각 객체의 이동을 정의하는 move()와 각 객체의 모양을 정의하는 getShape() 함수를 순수 가상 함수로 가진 추상 클래스 GameObject이다. GameObject를 상속받아 Human, Monster, Food 클래스를 작성하라. 그리고 전체적인 게임을 진행하는 Game 클래스와 main() 함수를 작성하고 프로그램을 완성하라.

 

 

2. 결과

 

 

 

 

3. 코드

#include <iostream>
#include <cstdlib>
#include <ctime>
using namespace std;

class GameObject {
protected:
	int distance;
	int x, y;
public:
	GameObject(int startX, int startY, int distance) {
		this->x = startX; this->y = startY;
		this->distance = distance;
	}
	virtual ~GameObject() {};
	virtual void move() = 0;
	virtual char getShape() = 0;

	int getX() { return x; }
	int getY() { return y; }
	bool collide(GameObject *p) {
		if (this->x == p->getX() && this->y == p->getY())
			return true;
		else
			return false;
	}
};
class Human : public GameObject {
public:
	Human(int starX, int starY, int dis) : GameObject(starX, starY, dis) { ; }
	void move() {
		char key;
		cout << "왼쪽(a), 아래(s), 위(d), 오른쪽(f) >> ";
		cin >> key;
		cout << endl;
		if (key == 'a') {
			if (y - distance < 0) y = 20 + y - distance;
			else y -= distance;
		}
		else if (key == 's') {
			if (x + distance > 9) x = x + distance - 10;
			else x += distance;
		}
		else if (key == 'd') {
			if (x - distance < 0) x = 10 + x - distance;
			else x -= distance;
		}
		else if (key == 'f') {
			if (y + distance > 19) y = y + distance - 20;
			else y += distance;
		}
	}
	char getShape() {
		return 'H';
	}
};
class Monster : public GameObject {
public:
	Monster(int starX, int starY, int dis) : GameObject(starX, starY, dis) {
		srand((unsigned)time(0));
	}
	void move() {
		int num;
		num = rand() % 2;
		switch (num) {
		case 0:
			if (x - distance < 0) x = 10 + x - distance;
			else x -= distance;
			break;
		case 1:
			if (x + distance > 9) x = x + distance - 10;
			else x += distance;
			break;
		}
		num = rand() % 2;
		switch (num) {
		case 0:
			if (y - distance < 0) y = 20 + y - distance;
			else y -= distance;
			break;
		case 1:
			if (y + distance > 19) y = y + distance - 20;
			else y += distance;
			break;
		}
	}
	char getShape() {
		return 'M';
	}
};
class Food : public GameObject {
	int count;
public:
	Food(int starX, int starY, int dis) : GameObject(starX, starY, dis) {
		srand((unsigned)time(0));
		count = 0;
	}
	void move() {
		int n1, n2;		//n1 : 2/5 확률, n2 : 방향 선택
		n1 = rand() % 5;
		n2 = rand() % 4;
		if (n1 >= 1 && n1 <= 2) {
			switch (n2) {
			case 0:
				if (y - distance < 0) y = 20 + y - distance;
				else y -= distance;
				break;
			case 1:
				if (x + distance > 9) x = x + distance - 10;
				else x += distance;
				break;
			case 2:
				if (x - distance < 0) x = 10 + x - distance;
				else x -= distance;
				break;
			case 3:
				if (y + distance > 19) y = y + distance - 20;
				else y += distance;
				break;
			}
		}
	}
	char getShape() {
		return '@';
	}
};

class Game {
public:
	void game() {
		bool exit = true;
		Human* h = new Human(0, 0, 1);	Monster *m = new Monster(5, 5, 2);
		Food* f = new Food(8, 9, 1);

		cout << "** Human의 Food 먹기 게임을 시작합니다." << endl << endl;
		while (exit) {					// 10x20의 게임판을 출력
			for (int i = 0; i<10; i++) {
				for (int ii = 0; ii<20; ii++) {
					if (m->getX() == i && m->getY() == ii) cout << m->getShape();		// 순서 중요함 몬스터->헌터->음식 순으로 if문을
					else if (h->getX() == i && h->getY() == ii) cout << h->getShape();	// 만들어야 같은 위치가 되었을 때 출력할 문자의 순서가 됨
					else if (f->getX() == i && f->getY() == ii) cout << f->getShape();
					else cout << '-';
				}
				cout << endl;
			}

			if (m->collide(h)) {
				cout << "Human is Loser!!" << endl << "인간이 몬스터에게 잡혔습니다." << endl << endl;
				exit = false;
				break;
			}
			else if (m->collide(f)) {
				cout << "Human is Loser!!" << endl << "몬스터가 음식을 먹었습니다." << endl << endl;
				exit = false;
				break;
			}
			else if (h->collide(f)) {
				cout << "Human is Winner!!" << endl << "인간이 음식을 먹었습니다." << endl << endl;
				exit = false;
				break;
			}

			h->move();
			m->move();
			f->move();
		}

	}
};

int main() {
	Game* g = new Game;
	g->game();
	delete g;
}

 

4. 설명

 

GameObject를 상속받는 Human, Monster, Food 클래스와

 

전체적인 게임을 진행하는 Game 클래스를 작성하면 된다.

 

 

Game 클래스의 game메소드는 3개의 객체를 각각 하나씩 생성하며 시작한다.

 

GameObject 클래스에서 순수 가상 함수 선언한 move()와 getShape를 Human, Monster, Food 클래스의서 알맞게 구현한 후 호출하면 된다.

 

 

설명은 중간중간 주석으로 입력해놨습니다.

 

+ rand() % 4 = 랜덤 수를 구합니다. 왼쪽식의 결과로는 0~3 사이의 수를 얻을 수 있습니다. 

rand()로는 0~32000정도의 수를 얻어오는데 이 수 중 어느 수라도 4로 나눈 후 나머지는 0~3이기 때문입니다.

 

+ srand((unsigned)time(0)); = 보통 위 rand()와 연계하여 사용하는 것 입니다. 이를 입력해주어야 실행 때마다 다른 결과를 얻을 수 있습니다.

 

+ Recent posts