U E D R , A S I H C RSS

스터디/게임에 미친이들을 위한 히치하이킹 (rev. 1.13)

스터디/게임에 미친이들을 위한 히치하이킹



1. 게임에 미친이들을 위한 히치하이킹

  • 스터디 소개 : 게임을 만들기 위한 전반적인 공부를 하는 스터디
  • 스터디 완수 퀘스트 : 자기 자신만의 게임 엔진을 가지고, 원하는 게임을 만듭니다.
  • 스터디 참여 인원 : 김윤환, 조영준, 장혁재
  • 스터디에 사용하는 책 : 게임엔진아키텍쳐, 게임프로그래밍의 정석, game programming gems 시리즈
  • 스터디 일자 : 토요일 1시부터 ~ (?)시(default 4시간 - 이론 1~2시간 실습 2시간 이상)

1.1. 11월 2일 토요일





#include <stdio.h>
#include <stdlib.h>

enum FloorType {
	floor, goal, wall
};

enum ObjectType {
	box, player, empty
};

enum Direction {
	up, right, down, left
};

class Sokoban;
class Map;
class MapManager;

class Map {
public:
	int width;
	int height;
	FloorType **floorMatrix;
	ObjectType **objectMatrix;
};

class MapManager {
public :
	void printMap(Map *map) {
		int width = map->width;
		int height = map->height;

		for (int i = 0; i < height; i++) {
			for (int j = 0; j < width; j++) {
				char charToPrint;
				if (map->floorMatrix[i][j] == floor && map->objectMatrix[i][j] == empty) {
					charToPrint = ' ';
				} else if (map->floorMatrix[i][j] == floor && map->objectMatrix[i][j] == player) {
					charToPrint = 'p';
				} else if (map->floorMatrix[i][j] == floor && map->objectMatrix[i][j] == box) {
					charToPrint = 'o';
				} else if (map->floorMatrix[i][j] == goal && map->objectMatrix[i][j] == empty) {
					charToPrint = '.';
				} else if (map->floorMatrix[i][j] == goal && map->objectMatrix[i][j] == player) {
					charToPrint = 'P';
				} else if (map->floorMatrix[i][j] == goal && map->objectMatrix[i][j] == box) {
					charToPrint = 'O';
				} else if (map->floorMatrix[i][j] == wall) {
					charToPrint = '#';
				}
				printf("%c", charToPrint);
			}
			printf("\n");
		}
	}

	Map *phaseStringToMap(char *string[], int width, int height) {
		Map *map = new Map();

		map->width = width;
		map->height = height;

		map->floorMatrix = (FloorType**) (malloc(sizeof(FloorType*) * height));
		map->objectMatrix = (ObjectType**) (malloc(sizeof(ObjectType*) * height));

		for (int i = 0; i < height; i++) {
			map->floorMatrix[i] = (FloorType*) (malloc(sizeof(FloorType)* width));
			map->objectMatrix[i] = (ObjectType*)(malloc(sizeof(ObjectType)* width));
		}

		for (int i = 0; i < height; i++) {
			for (int j = 0; j < width; j++) {
				if (string[i][j] == ' ') {
					map->floorMatrix[i][j] = floor;
					map->objectMatrix[i][j] = empty;
				} else if (string[i][j] == '#') {
					map->floorMatrix[i][j] = wall;
					map->objectMatrix[i][j] = empty;
				} else if (string[i][j] == 'p') {
					map->floorMatrix[i][j] = floor;
					map->objectMatrix[i][j] = player;
				} else if (string[i][j] == 'P') {
					map->floorMatrix[i][j] = goal;
					map->objectMatrix[i][j] = player;
				} else if (string[i][j] == '.') {
					map->floorMatrix[i][j] = goal;
					map->objectMatrix[i][j] = empty;
				} else if (string[i][j] == 'o') {
					map->floorMatrix[i][j] = floor;
					map->objectMatrix[i][j] = box;
				} else if (string[i][j] == 'O') {
					map->floorMatrix[i][j] = goal;
					map->objectMatrix[i][j] = box;
				} else {
					map->floorMatrix[i][j] = floor;
					map->objectMatrix[i][j] = empty;
				}
			}
		}

		return map;
	}
};

class Sokoban {
public:
	Sokoban() {
		mapManager = new MapManager();

		map = NULL;
		playerX = -1;
		playerY = -1;
		numberOfGoals = 0;
		numberOfFilledGoals = 0;
		numberOfMoves = 0;
	}

	void setGame(Map *newMap) {
		map = newMap;

		for (int i = 0; i < map->height; i++) {
			for (int j = 0; j < map->width; j++) {
				if (map->floorMatrix[i][j] == wall) {
					map->objectMatrix[i][j] = empty;
				} else if (map->floorMatrix[i][j] == goal) {
					numberOfGoals++;
				}
				if (map->objectMatrix[i][j] == player) {
					if (playerX >= 0) {
						map->objectMatrix[playerY][playerX] = empty;
					}
					playerX = j;
					playerY = i;
				}
			}
		}

		update();
	}

	void movePlayer(Direction direction) {
		if (moveObject(playerX, playerY, direction) == true) {
			numberOfMoves++;
			update();
		}
	}

	void print() {
		mapManager->printMap(map);
		printf("%d, %d, %d\n", numberOfGoals, numberOfFilledGoals, numberOfMoves);
	}
private:
	MapManager *mapManager;
	Map *map;
	int playerX;
	int playerY;
	int numberOfGoals;
	int numberOfFilledGoals;
	int numberOfMoves;

	bool moveObject(int x, int y, Direction direction) {
		int frontX = x;
		int frontY = y;

		if (direction == up) {
			frontY -= 1;
		}
		else if (direction == right) {
			frontX += 1;
		}
		else if (direction == down) {
			frontY += 1;
		}
		else if (direction == left) {
			frontX -= 1;
		}

		if (frontX < 0 || frontX >= map->width || frontY < 0 || frontY >= map->height) {
			return false;
		}

		ObjectType thisObject = map->objectMatrix[y][x];
		FloorType thisFloor = map->floorMatrix[y][x];
		ObjectType frontObject = map->objectMatrix[frontY][frontX];
		FloorType frontFloor = map->floorMatrix[frontY][frontX];

		if (thisFloor == wall) {
			return false;
		}
		else if (thisObject == empty) {
			return true;
		}
		else if (thisObject == box && (frontObject == box || frontFloor == wall)) {
			return false;
		}
		else if (moveObject(frontX, frontY, direction) == true) {
			map->objectMatrix[frontY][frontX] = map->objectMatrix[y][x];
			map->objectMatrix[y][x] = empty;
			return true;
		}
		else {
			return false;
		}
	}

	void update() {
		numberOfFilledGoals = 0;
		for (int i = 0; i < map->height; i++) {
			for (int j = 0; j < map->width; j++) {
				if (map->objectMatrix[i][j] == box) {
					if (map->floorMatrix[i][j] == goal) {
						numberOfFilledGoals++;
					}
				}
				else if (map->objectMatrix[i][j] == player) {
					playerY = i;
					playerX = j;
				}
			}
		}
	}
};

int main() {
	char *string[] = {
		"########",
		"# .. p #",
		"# o o  #",
		"# p    #",
		"########"
	};

	char input;

	MapManager *mapManager = new MapManager();
	Map *map = mapManager->phaseStringToMap(string, 8, sizeof(string) / sizeof(string[0]));
	Sokoban *sokoban = new Sokoban();

	sokoban->setGame(map);

	while (true) {
		sokoban->print();
		printf(":");
		scanf_s("%c%*c", &input);
		if (input == 'w') {
			sokoban->movePlayer(up);
		} else if (input == 'd') {
			sokoban->movePlayer(right);
		} else if (input == 's') {
			sokoban->movePlayer(down);
		} else if (input == 'a') {
			sokoban->movePlayer(left);
		}
	}
}

 

Valid XHTML 1.0! Valid CSS! powered by MoniWiki
last modified 2021-02-07 05:30:17
Processing time 0.0417 sec