Describe 스터디/게임에 미친이들을 위한 히치하이킹/13-11-02 here

11월 2일 토요일


#include <iostream>
#include <conio.h>
using namespace std;
#define X 8
#define Y 5
//1=#(wall)
//0=""(space)
//2=p(player)
//3=.(wantedlocation)
//4=o(box)
//5=P(player_on_wanted_location)
//6=O(movedbox)
void printgame(int stage[][X]);
void makegame(int stage[][X]);
void input(int stage[][X]);
int collision(int stage[][X], char movement, int x, int y);
int main(){
	int stage[Y][X] = { 0 };
	makegame(stage);
	while (1){
		printgame(stage);
		input(stage);
	}
	getchar();
	return 0;
}
void printgame(int stage[][X]){
	int i = 0;
	int j = 0;
	for (i = 0; i < Y; i++){
		for (j = 0; j < X; j++){
			/*if (stage[i][j] == 1)
				printf("#");
			else if (stage[i][j] == 0)
				printf(" ");
			else if (stage[i][j] == 2)
				printf("p");
			else if (stage[i][j] == 3)
				printf(".");
			else if (stage[i][j] == 4)
				printf("o");
			else if (stage[i][j] == 5)
				printf("P");
			else if (stage[i][j] == 6)
				printf("O");*/
			printf("%d", stage[i][j]);

		}
			printf("\n");
		}
}
void makegame(int stage[][X]){
	int i = 0, j = 0;
		for (i = 0; i < Y; i++){
			for (j = 0; j < X; j++){
				if (i == 0 || i == 4)
					stage[i][j] = 1;
				else if (j == 0 || j == 7)
					stage[i][j] = 1;
				else
					stage[i][j] = 0;
			}
		}
	stage[1][5] = 2;
	stage[1][2] = 3;
	stage[1][3] = 3;
	stage[2][2] = 4;
	stage[2][3] = 4;
}
void input(int stage[][X]){
	char movement;
	int i = 0, j = 0;
	printf("a:left, w:up, s:down, d:right:");
	movement = getche();
	for (i = 0; i < Y; i++){
		for (j = 0; j < X; j++){
			if (stage[i][j] == 2 || stage[i][j]==5){
				switch (movement){
					case 'a':
						if (collision(stage, movement, j, i) == 1)
							break;
						else{
							stage[i][j--] += stage[i][j];
							stage[i][j] -= 2;
						}
						break;
					case 'w':
						if (collision(stage, movement, j, i) == 1)
							break;
						else{
							stage[i--][j] += stage[i][j];
							stage[i][j] -= 2;
						}
						break;
					case 's':
						if (collision(stage, movement, j, i) == 1)
							break;
						else{
							stage[i++][j] += stage[i][j];
							stage[i][j] - 2;
						}
						break;
					case 'd':
						if (collision(stage, movement, j, i) == 1)
							break;
						else{
							stage[i][j++] += stage[i][j];
							stage[i][j] -= 2;
						}
						break;
				}
			}
		}
	}
	printf("\n");
}
int collision(int stage[][X], char movement, int j, int i){
	switch (movement){
	case 'a':
		if (stage[i][j--] == 1)
			return 1;
		else if (stage[i][j--] == 4){
			if (stage[i][j - 2] == 4 || stage[i][j - 2] == 1)
				return 1;
			else
				return 0;
			//밑에 코드 모두 동일 조건
		}
		else
			return 0;
		break;
	case 'w'://i--, j
		if (stage[i--][j] == 1)
			return 1;
		else if (stage[i--][j] == 4){
			if (stage[i - 2][j] == 4 || stage[i - 2][j] == 1)
				return 1;
			else
				return 0;
		}
		else
			return 0;
		break;
	case 's'://i++, j
		if (stage[i++][j] == 1){
			return 1;
		}
		else if (stage[i++][j] == 4){
			if (stage[i + 2][j] == 4 || stage[i + 2][j] == 1)
				return 1;
			else
				return 0;
			
		}
		else
			return 0;

		break;
	case 'd'://i,j++
		if (stage[i][j++] == 1){
			return 1;
		}
		else if (stage[i][j++] == 4){
			if (stage[i][j + 2] == 4 || stage[i][j + 2] == 1)
				return 1;
			else
				return 0;
		}
		else
			return 0;
		break;
	}

}

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

 
Retrieved from http://wiki.zeropage.org/wiki.php/스터디/게임에 미친이들을 위한 히치하이킹/13-11-02
last modified 2021-02-07 05:30:17