Labyrinth of the Minotaur A simple roguelike/RPG using a nokia 5110 screen

Dependencies:   N5110 PowerControl mbed

Committer:
ThomasBGill
Date:
Mon May 11 22:25:57 2015 +0000
Revision:
36:b64696135142
Parent:
35:2c290fa78f1d
Version 1.0 finished

Who changed what in which revision?

UserRevisionLine numberNew contents of line
ThomasBGill 20:e54792b89571 1 #include "WorldBuilder.h"
ThomasBGill 20:e54792b89571 2
ThomasBGill 22:dae750e4d749 3 int map[MAP_WIDTH][MAP_HEIGHT];
ThomasBGill 20:e54792b89571 4
ThomasBGill 20:e54792b89571 5 //Enterance coordinates
ThomasBGill 20:e54792b89571 6 int enx;
ThomasBGill 20:e54792b89571 7 int eny;
ThomasBGill 20:e54792b89571 8
ThomasBGill 20:e54792b89571 9 //Exit coordinates
ThomasBGill 20:e54792b89571 10 int exx;
ThomasBGill 20:e54792b89571 11 int exy;
ThomasBGill 20:e54792b89571 12
ThomasBGill 20:e54792b89571 13 int sx;
ThomasBGill 20:e54792b89571 14 int sy;
ThomasBGill 35:2c290fa78f1d 15
ThomasBGill 20:e54792b89571 16
ThomasBGill 20:e54792b89571 17 int level;
ThomasBGill 20:e54792b89571 18
ThomasBGill 21:aa4feee6aa39 19 //Player coordinates
ThomasBGill 21:aa4feee6aa39 20 int px;
ThomasBGill 21:aa4feee6aa39 21 int py;
ThomasBGill 21:aa4feee6aa39 22
ThomasBGill 20:e54792b89571 23 void Walls()
ThomasBGill 20:e54792b89571 24 {
ThomasBGill 20:e54792b89571 25 //Fill map with walls
ThomasBGill 22:dae750e4d749 26 for (int i = 0; i<MAP_WIDTH; i++) {
ThomasBGill 22:dae750e4d749 27 for (int j = 0; j<MAP_HEIGHT; j++) {
ThomasBGill 20:e54792b89571 28
ThomasBGill 20:e54792b89571 29 map[i][j] = WALL;
ThomasBGill 20:e54792b89571 30 }
ThomasBGill 20:e54792b89571 31 }
ThomasBGill 20:e54792b89571 32 }
ThomasBGill 20:e54792b89571 33
ThomasBGill 20:e54792b89571 34 void FirstRoom()
ThomasBGill 20:e54792b89571 35 {
ThomasBGill 20:e54792b89571 36 //Create initial room
ThomasBGill 36:b64696135142 37
ThomasBGill 36:b64696135142 38 //Generate starting coordinates
ThomasBGill 22:dae750e4d749 39 int si = rand()%25 + 1;
ThomasBGill 22:dae750e4d749 40 int sj = rand()%15 + 1;
ThomasBGill 20:e54792b89571 41
ThomasBGill 22:dae750e4d749 42 int sw = rand()%5 + 5;
ThomasBGill 22:dae750e4d749 43 int sh = rand()%5 + 5;
ThomasBGill 20:e54792b89571 44
ThomasBGill 22:dae750e4d749 45 for (int i = si; i < si + sw; i++) {
ThomasBGill 22:dae750e4d749 46 for (int j = sj; j < sj + sh; j++) {
ThomasBGill 20:e54792b89571 47 map[i][j] = FLOOR;
ThomasBGill 20:e54792b89571 48 }
ThomasBGill 20:e54792b89571 49 }
ThomasBGill 22:dae750e4d749 50
ThomasBGill 20:e54792b89571 51 //Create enterance in room
ThomasBGill 22:dae750e4d749 52 enx = rand()% sw + si;
ThomasBGill 22:dae750e4d749 53 eny = rand()% sh + sj;
ThomasBGill 20:e54792b89571 54 map[enx][eny] = ENTER;
ThomasBGill 22:dae750e4d749 55
ThomasBGill 20:e54792b89571 56 }
ThomasBGill 20:e54792b89571 57
ThomasBGill 20:e54792b89571 58 void ExitRoom()
ThomasBGill 20:e54792b89571 59 {
ThomasBGill 20:e54792b89571 60 //Create exit room
ThomasBGill 36:b64696135142 61
ThomasBGill 36:b64696135142 62 //Generate starting coordinates
ThomasBGill 22:dae750e4d749 63 int si = rand()%50 + 30;
ThomasBGill 22:dae750e4d749 64 int sj = rand()%25 + 20;
ThomasBGill 20:e54792b89571 65
ThomasBGill 22:dae750e4d749 66 int sw = rand()%5 + 5;
ThomasBGill 22:dae750e4d749 67 int sh = rand()%5 + 5;
ThomasBGill 20:e54792b89571 68
ThomasBGill 22:dae750e4d749 69 for (int i = si; i < si + sw; i++) {
ThomasBGill 22:dae750e4d749 70 for (int j = sj; j < sj + sh; j++) {
ThomasBGill 20:e54792b89571 71 map[i][j] = FLOOR;
ThomasBGill 20:e54792b89571 72 }
ThomasBGill 20:e54792b89571 73 }
ThomasBGill 22:dae750e4d749 74
ThomasBGill 20:e54792b89571 75 //Create exit in room
ThomasBGill 22:dae750e4d749 76 exx = rand()% sw + si;
ThomasBGill 22:dae750e4d749 77 exy = rand()% sh + sj;
ThomasBGill 20:e54792b89571 78 map[exx][exy] = EXIT;
ThomasBGill 20:e54792b89571 79 }
ThomasBGill 20:e54792b89571 80
ThomasBGill 20:e54792b89571 81 void DungeonRoomBuilder()
ThomasBGill 20:e54792b89571 82 {
ThomasBGill 36:b64696135142 83 //Generate starting coordinates
ThomasBGill 22:dae750e4d749 84 sx = rand() % (MAP_WIDTH - 1) + 1;
ThomasBGill 22:dae750e4d749 85 sy = rand() % (MAP_HEIGHT - 1) + 1;
ThomasBGill 20:e54792b89571 86
ThomasBGill 20:e54792b89571 87 //Get length
ThomasBGill 20:e54792b89571 88 int sw = rand() % 5 + 5;
ThomasBGill 20:e54792b89571 89 int sh = rand() % 5 + 5;
ThomasBGill 20:e54792b89571 90
ThomasBGill 20:e54792b89571 91 for (int i = sx; i < sx + sw; i++) {
ThomasBGill 20:e54792b89571 92 for (int j = sy; j < sy + sh; j++) {
ThomasBGill 22:dae750e4d749 93 if (i < MAP_WIDTH - 1 && j < MAP_HEIGHT - 1) {
ThomasBGill 20:e54792b89571 94 if (map[i][j] == WALL) {
ThomasBGill 20:e54792b89571 95 map[i][j] = FLOOR;
ThomasBGill 20:e54792b89571 96 }
ThomasBGill 20:e54792b89571 97 }
ThomasBGill 20:e54792b89571 98 }
ThomasBGill 20:e54792b89571 99 }
ThomasBGill 20:e54792b89571 100
ThomasBGill 30:4a03611a3d99 101 if (rand() % 3 == 0) {
ThomasBGill 36:b64696135142 102 //Build chest at random coordinate in room
ThomasBGill 20:e54792b89571 103 int i = rand() % sw + sx;
ThomasBGill 20:e54792b89571 104 int j = rand() % sh + sy;
ThomasBGill 20:e54792b89571 105 map[i][j] = CHEST;
ThomasBGill 20:e54792b89571 106 }
ThomasBGill 20:e54792b89571 107 }
ThomasBGill 20:e54792b89571 108
ThomasBGill 20:e54792b89571 109 int Neighbours(int i, int j)
ThomasBGill 20:e54792b89571 110 {
ThomasBGill 20:e54792b89571 111 //Check neighbours
ThomasBGill 20:e54792b89571 112 int n = 0;
ThomasBGill 20:e54792b89571 113
ThomasBGill 20:e54792b89571 114 if (map[i + 1][j] == FLOOR) {
ThomasBGill 20:e54792b89571 115 n++;
ThomasBGill 20:e54792b89571 116 }
ThomasBGill 20:e54792b89571 117 if (map[i - 1][j] == FLOOR) {
ThomasBGill 20:e54792b89571 118 n++;
ThomasBGill 20:e54792b89571 119 }
ThomasBGill 20:e54792b89571 120 if (map[i][j + 1] == FLOOR) {
ThomasBGill 20:e54792b89571 121 n++;
ThomasBGill 20:e54792b89571 122 }
ThomasBGill 20:e54792b89571 123 if (map[i][j - 1] == FLOOR) {
ThomasBGill 20:e54792b89571 124 n++;
ThomasBGill 20:e54792b89571 125 }
ThomasBGill 20:e54792b89571 126
ThomasBGill 20:e54792b89571 127 return n;
ThomasBGill 20:e54792b89571 128 }
ThomasBGill 20:e54792b89571 129
ThomasBGill 20:e54792b89571 130 void DeadEnds(int d)
ThomasBGill 20:e54792b89571 131 {
ThomasBGill 36:b64696135142 132 for (int del = d; del > 0; del--) { //Iterate the code d amount of times
ThomasBGill 36:b64696135142 133
ThomasBGill 20:e54792b89571 134 for (int i = 0; i < 84; i++) {
ThomasBGill 20:e54792b89571 135 for (int j = 0; j < 48; j++) {
ThomasBGill 20:e54792b89571 136
ThomasBGill 36:b64696135142 137 if (Neighbours(i, j) < 2) { //If an island or dead end then turn the floor into a wall
ThomasBGill 20:e54792b89571 138 map[i][j] = WALL;
ThomasBGill 20:e54792b89571 139 }
ThomasBGill 20:e54792b89571 140 }
ThomasBGill 20:e54792b89571 141 }
ThomasBGill 20:e54792b89571 142 }
ThomasBGill 20:e54792b89571 143 }
ThomasBGill 20:e54792b89571 144
ThomasBGill 20:e54792b89571 145 void Border()
ThomasBGill 20:e54792b89571 146 {
ThomasBGill 20:e54792b89571 147 for (int i = 0; i < 84; i++) {
ThomasBGill 20:e54792b89571 148 for (int j = 0; j < 48; j++) {
ThomasBGill 20:e54792b89571 149
ThomasBGill 20:e54792b89571 150 if (i == 0 || i == 83 || j == 0 || j == 47) {
ThomasBGill 20:e54792b89571 151
ThomasBGill 20:e54792b89571 152 map[i][j] = WALL;
ThomasBGill 20:e54792b89571 153
ThomasBGill 20:e54792b89571 154 }
ThomasBGill 20:e54792b89571 155 }
ThomasBGill 20:e54792b89571 156 }
ThomasBGill 20:e54792b89571 157 }
ThomasBGill 20:e54792b89571 158
ThomasBGill 20:e54792b89571 159 void RandFloor(int r)
ThomasBGill 20:e54792b89571 160 {
ThomasBGill 20:e54792b89571 161
ThomasBGill 36:b64696135142 162 for (int space = rand() % 50 + r; space > 0; space--) { //Iterate code r amount of times
ThomasBGill 20:e54792b89571 163
ThomasBGill 36:b64696135142 164 //Randomly generate coordinates
ThomasBGill 20:e54792b89571 165 int i = rand() % 84;
ThomasBGill 20:e54792b89571 166 int j = rand() % 48;
ThomasBGill 20:e54792b89571 167
ThomasBGill 20:e54792b89571 168 if (rand() % 2 == 0 && map[i][j] == WALL) {
ThomasBGill 20:e54792b89571 169 map[i][j] = FLOOR;
ThomasBGill 20:e54792b89571 170 }
ThomasBGill 20:e54792b89571 171 }
ThomasBGill 20:e54792b89571 172
ThomasBGill 20:e54792b89571 173 }
ThomasBGill 20:e54792b89571 174
ThomasBGill 20:e54792b89571 175 void MazeKill()
ThomasBGill 20:e54792b89571 176 {
ThomasBGill 36:b64696135142 177 //Array which stores the order in which directions whill be checked
ThomasBGill 20:e54792b89571 178 int move[4] = { UP, DOWN, LEFT, RIGHT };
ThomasBGill 20:e54792b89571 179
ThomasBGill 20:e54792b89571 180 bool moved = true;
ThomasBGill 20:e54792b89571 181
ThomasBGill 20:e54792b89571 182 while (moved == true) {
ThomasBGill 20:e54792b89571 183
ThomasBGill 20:e54792b89571 184 moved = false;
ThomasBGill 20:e54792b89571 185
ThomasBGill 20:e54792b89571 186 for (int s = 0; s < 3; s++) { //Shuffle array
ThomasBGill 20:e54792b89571 187
ThomasBGill 20:e54792b89571 188 int r = rand() % 4;
ThomasBGill 20:e54792b89571 189
ThomasBGill 20:e54792b89571 190 int temp = move[s];
ThomasBGill 20:e54792b89571 191
ThomasBGill 20:e54792b89571 192 move[s] = move[r];
ThomasBGill 20:e54792b89571 193
ThomasBGill 20:e54792b89571 194 move[r] = temp;
ThomasBGill 20:e54792b89571 195 }
ThomasBGill 20:e54792b89571 196
ThomasBGill 20:e54792b89571 197 for (int i = 0; i < 3; i++) {
ThomasBGill 36:b64696135142 198 //For (direction) check if there are walls 2 tiles in that directions
ThomasBGill 36:b64696135142 199 //and check that they do not interfere with any part of the maze that has already been built
ThomasBGill 36:b64696135142 200
ThomasBGill 20:e54792b89571 201 if (move[i] == UP) {
ThomasBGill 20:e54792b89571 202 if (map[sx][sy - 1] == WALL && Neighbours(sx, sy - 1) == 1 && map[sx][sy - 2] == WALL && Neighbours(sx, sy - 2) == 0 && sy > 3) {
ThomasBGill 20:e54792b89571 203 map[sx][sy - 1] = FLOOR;
ThomasBGill 20:e54792b89571 204 map[sx][sy - 2] = FLOOR;
ThomasBGill 20:e54792b89571 205 sy = sy - 2;
ThomasBGill 20:e54792b89571 206 moved = true;
ThomasBGill 20:e54792b89571 207 break;
ThomasBGill 20:e54792b89571 208 }
ThomasBGill 22:dae750e4d749 209 } else if (move[i] == DOWN) {
ThomasBGill 20:e54792b89571 210 if (map[sx][sy + 1] == WALL && Neighbours(sx, sy + 1) == 1 && map[sx][sy + 2] == WALL && Neighbours(sx, sy + 2) == 0 && sy < 45) {
ThomasBGill 20:e54792b89571 211 map[sx][sy + 1] = FLOOR;
ThomasBGill 20:e54792b89571 212 map[sx][sy + 2] = FLOOR;
ThomasBGill 20:e54792b89571 213 sy = sy + 2;
ThomasBGill 20:e54792b89571 214 moved = true;
ThomasBGill 20:e54792b89571 215 break;
ThomasBGill 20:e54792b89571 216 }
ThomasBGill 22:dae750e4d749 217 } else if (move[i] == LEFT) {
ThomasBGill 20:e54792b89571 218 if (map[sx - 1][sy] == WALL && Neighbours(sx - 1, sy) == 1 && map[sx - 2][sy] == WALL && Neighbours(sx - 2, sy) == 0 && sx > 3) {
ThomasBGill 20:e54792b89571 219 map[sx - 1][sy] = FLOOR;
ThomasBGill 20:e54792b89571 220 map[sx - 2][sy] = FLOOR;
ThomasBGill 20:e54792b89571 221 sx = sx - 2;
ThomasBGill 20:e54792b89571 222 moved = true;
ThomasBGill 20:e54792b89571 223 break;
ThomasBGill 20:e54792b89571 224 }
ThomasBGill 22:dae750e4d749 225 } else if (move[i] == RIGHT) {
ThomasBGill 20:e54792b89571 226 if (map[sx + 1][sy] == WALL && Neighbours(sx + 1, sy) == 1 && map[sx + 2][sy] == WALL && Neighbours(sx + 2, sy) == 0 && sx < 81) {
ThomasBGill 20:e54792b89571 227 map[sx + 1][sy] = FLOOR;
ThomasBGill 20:e54792b89571 228 map[sx + 2][sy] = FLOOR;
ThomasBGill 20:e54792b89571 229 sx = sx + 2;
ThomasBGill 20:e54792b89571 230 moved = true;
ThomasBGill 20:e54792b89571 231 break;
ThomasBGill 20:e54792b89571 232 }
ThomasBGill 20:e54792b89571 233 }
ThomasBGill 20:e54792b89571 234 }
ThomasBGill 20:e54792b89571 235 }
ThomasBGill 20:e54792b89571 236
ThomasBGill 20:e54792b89571 237 }
ThomasBGill 20:e54792b89571 238
ThomasBGill 20:e54792b89571 239 void Maze()
ThomasBGill 20:e54792b89571 240 {
ThomasBGill 36:b64696135142 241 //Start in top left corner
ThomasBGill 20:e54792b89571 242 sx = 1;
ThomasBGill 20:e54792b89571 243 sy = 1;
ThomasBGill 20:e54792b89571 244
ThomasBGill 20:e54792b89571 245 //Choose random direction
ThomasBGill 20:e54792b89571 246 //Check if 2 cells in direction have no neighbours (excluding current position)
ThomasBGill 20:e54792b89571 247 //If true then build and set new current position
ThomasBGill 20:e54792b89571 248 //If false chose next direction
ThomasBGill 20:e54792b89571 249
ThomasBGill 20:e54792b89571 250 //If cannot move in any direction scan through each cell until there is one which can be built on
ThomasBGill 20:e54792b89571 251 //If scan completes END
ThomasBGill 20:e54792b89571 252
ThomasBGill 20:e54792b89571 253 int end = false;
ThomasBGill 20:e54792b89571 254
ThomasBGill 20:e54792b89571 255 while (end == false) {
ThomasBGill 20:e54792b89571 256
ThomasBGill 20:e54792b89571 257 end = true;
ThomasBGill 20:e54792b89571 258
ThomasBGill 36:b64696135142 259 map[sx][sy] = FLOOR; //Set current tile to a floor
ThomasBGill 20:e54792b89571 260
ThomasBGill 20:e54792b89571 261 MazeKill();
ThomasBGill 20:e54792b89571 262
ThomasBGill 20:e54792b89571 263 //DrawMap();
ThomasBGill 20:e54792b89571 264
ThomasBGill 22:dae750e4d749 265 for (int i = 1; i < MAP_WIDTH - 1; i++) {
ThomasBGill 22:dae750e4d749 266 for (int j = 1; j < MAP_HEIGHT-1; j++) {
ThomasBGill 20:e54792b89571 267
ThomasBGill 20:e54792b89571 268 if (map[i][j] == WALL && Neighbours(i, j) == 1) {
ThomasBGill 20:e54792b89571 269 sx = i;
ThomasBGill 20:e54792b89571 270 sy = j;
ThomasBGill 20:e54792b89571 271
ThomasBGill 36:b64696135142 272 end = false; //If a wall tile in the array has only one neighbouring space that is a floor then more of the maze can be built so the generation has not yet finished
ThomasBGill 20:e54792b89571 273 }
ThomasBGill 20:e54792b89571 274
ThomasBGill 20:e54792b89571 275 }
ThomasBGill 20:e54792b89571 276 }
ThomasBGill 20:e54792b89571 277
ThomasBGill 20:e54792b89571 278 }
ThomasBGill 20:e54792b89571 279 }
ThomasBGill 20:e54792b89571 280
ThomasBGill 20:e54792b89571 281 void DungeonBuilder()
ThomasBGill 20:e54792b89571 282 {
ThomasBGill 20:e54792b89571 283
ThomasBGill 20:e54792b89571 284 Maze();
ThomasBGill 20:e54792b89571 285
ThomasBGill 20:e54792b89571 286 FirstRoom();
ThomasBGill 20:e54792b89571 287 ExitRoom();
ThomasBGill 20:e54792b89571 288
ThomasBGill 22:dae750e4d749 289 int rn = rand() % 15 + 6;
ThomasBGill 20:e54792b89571 290
ThomasBGill 20:e54792b89571 291 for (int i = rn; i>0; i--) {
ThomasBGill 20:e54792b89571 292 DungeonRoomBuilder();
ThomasBGill 20:e54792b89571 293 }
ThomasBGill 20:e54792b89571 294
ThomasBGill 22:dae750e4d749 295 RandFloor(31);
ThomasBGill 20:e54792b89571 296
ThomasBGill 20:e54792b89571 297 Border();
ThomasBGill 20:e54792b89571 298
ThomasBGill 36:b64696135142 299 DeadEnds(50); //Remove lots of dead ends to make the map less confusing
ThomasBGill 20:e54792b89571 300
ThomasBGill 20:e54792b89571 301 }
ThomasBGill 20:e54792b89571 302
ThomasBGill 20:e54792b89571 303 void LabyrinthBuilder()
ThomasBGill 20:e54792b89571 304 {
ThomasBGill 20:e54792b89571 305
ThomasBGill 20:e54792b89571 306 Maze();
ThomasBGill 20:e54792b89571 307
ThomasBGill 20:e54792b89571 308 FirstRoom();
ThomasBGill 20:e54792b89571 309 ExitRoom();
ThomasBGill 20:e54792b89571 310
ThomasBGill 20:e54792b89571 311 RandFloor(151);
ThomasBGill 20:e54792b89571 312
ThomasBGill 36:b64696135142 313 DeadEnds(1); //Only remove some of the dead ends so that the map is still a challenge
ThomasBGill 20:e54792b89571 314
ThomasBGill 20:e54792b89571 315 Border();
ThomasBGill 20:e54792b89571 316
ThomasBGill 21:aa4feee6aa39 317 }
ThomasBGill 21:aa4feee6aa39 318
ThomasBGill 21:aa4feee6aa39 319 void World()
ThomasBGill 21:aa4feee6aa39 320 {
ThomasBGill 21:aa4feee6aa39 321 Walls();
ThomasBGill 24:4c4467971c91 322 if(level%5 == 0) {
ThomasBGill 21:aa4feee6aa39 323 LabyrinthBuilder();
ThomasBGill 21:aa4feee6aa39 324 } else {
ThomasBGill 21:aa4feee6aa39 325 DungeonBuilder();
ThomasBGill 21:aa4feee6aa39 326 }
ThomasBGill 21:aa4feee6aa39 327
ThomasBGill 21:aa4feee6aa39 328 px = enx;
ThomasBGill 21:aa4feee6aa39 329 py = eny;
ThomasBGill 20:e54792b89571 330 }