public MazeGenerator() { this.start_pos = new Position(0, 0); this.current_pos = new Position(0, 0); this.end_pos = new Position(0, 0); this.rooms = new List<List<maze_room_internal>>(); this.CriticalPath = new List<maze_move>(); }
public DungeonFloorStructure(DungeonStructure dungeon_structure, SDungeonFloor floor_desc, bool isLastFloor, DungeonFloorStructure prev) { pos = new Position(0, 0); start_pos = new Position(0, 0); prev_floor_structure = prev; this.dungeon_structure = dungeon_structure; HasBossRoom = floor_desc.HasBossRoom; branchProbability = floor_desc.branchProbability; coverageFactor = floor_desc.coverageFactor; IsLastFloor = isLastFloor; _calculate_size(floor_desc); _init_roomtraits(); maze_generator = new MazeGenerator(); _generate_maze(floor_desc); }
List<maze_move> _create_critical_path(int crit_path_min, int crit_path_max) { while (true) { maze_generator.setSize(width, height); _set_random_path_position(); if (maze_generator.generateCriticalPath(dungeon_structure.MT_maze, crit_path_min, crit_path_max)) { start_pos = maze_generator.getStartPosition; if (_set_traits(start_pos, maze_generator.getStartDir, 3000)) break; } maze_generator = new MazeGenerator(); _init_roomtraits(); } return maze_generator.getCriticalPath; }
bool _make_move(int direction) { if (isRoomInDirectionFree(current_pos, direction)) { Position next_pos = current_pos.GetBiasedPosition(direction); maze_room_internal current_room = getRoom(current_pos); maze_room_internal next_room = getRoom(next_pos); maze_move move = new maze_move(current_pos, next_pos, direction); CriticalPath.Add(move); counter++; next_room.Visited(counter); next_room.isOnCriticalPath = true; current_room.directions[direction] = 1; next_room.directions[Direction.GetOppositeDirection(direction)] = 2; current_pos = next_pos; return true; } return false; }
bool _generateSubPath_sub_2(Position pos) { maze_room_internal room = getRoom(pos); if (room != null) { for (int i = 0; i < 4; i++) { if (room.GetPassageType(i) == 0) { if (this.isRoomInDirectionFree(pos, i)) return true; } } } return false; }
bool _generateCriticalPathRecursive(int CritPathPos, int CritPathMin, int CritPathMax, int direction, MTRandom MT) { int[] directions = new int[4]; _CritPathMaxResult += 1; if (_CritPathMaxResult <= 10 * CritPathMax) { if (CritPathMin <= CritPathPos && CritPathPos <= CritPathMax && this.isRoomInDirectionFree(this.current_pos, this.start_direction)) { start_pos = current_pos; foreach (maze_move move in CriticalPath) { int temp = move.pos_from.X; move.pos_from.X = move.pos_to.X; move.pos_to.X = temp; temp = move.pos_from.Y; move.pos_from.Y = move.pos_to.Y; move.pos_to.Y = temp; move.direction = Direction.GetOppositeDirection(move.direction); } CriticalPath.Reverse(); //print_maze(); return true; } else { CritPathPos += 1; int count = 0; if (CritPathPos <= CritPathMax) { if (direction != -1) direction = Direction.GetOppositeDirection(direction); for (int i = 0; i < 4; i++) { if (i == direction) directions[i] = 0; else { Position next_pos = current_pos.GetBiasedPosition(i); directions[i] = _sub(next_pos); count += directions[i]; } } while (count > 0) { var rnd = MT.GetUInt32() % count + 1; int cnt2 = 0; int i_dir = 0; while (i_dir < 4) { cnt2 += directions[i_dir]; if (cnt2 >= rnd) break; i_dir++; } count -= directions[i_dir]; directions[i_dir] = 0; //moves_count = len(self.CriticalPath) if (_make_move(i_dir)) { if (_generateCriticalPathRecursive(CritPathPos, CritPathMin, CritPathMax, i_dir, MT)) return true; _undo_move(); } } } } } return false; }
public void setSize(int width, int height) { this.width = width; this.height = height; this.rooms = new List<List<maze_room_internal>>(); this.CriticalPath = new List<maze_move>(); for (int h = 0; h < this.width; ++h) { var row = new List<maze_room_internal>(); for (int w = 0; w < this.height; ++w) row.Add(new maze_room_internal()); this.rooms.Add(row); } this.end_pos = new Position(width - 1, height - 1); }
void _init_roomtraits() { rooms = new List<List<RoomTrait>>(); for (int h = 0; h < width; h++) { List<RoomTrait> row = new List<RoomTrait>(); for (int w = 0; w < height; w++) row.Add(new RoomTrait()); rooms.Add(row); } for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { for (int direction = 0; direction < 4; direction++) { Position biased_pos = new Position(x, y).GetBiasedPosition(direction); if ((biased_pos.X >= 0) && (biased_pos.Y >= 0)) if ((biased_pos.X < width) && (biased_pos.Y < height)) rooms[x][y].setNeighbor(direction, rooms[biased_pos.X][biased_pos.Y]); } } } }
public maze_move(Position from, Position to, int direction) { this.pos_from = new Position(from); this.pos_to = new Position(to); this.direction = direction; }
public bool isRoomInDirectionFree(Position pos, int direction) { Position dir_pos = pos.GetBiasedPosition(direction); if ((0 <= dir_pos.X) && (dir_pos.X < width) && (0 <= dir_pos.Y) && (dir_pos.Y < height)) return !rooms[dir_pos.X][dir_pos.Y].isOccupied(); return false; }
public bool isFree(Position pos) { return rooms[pos.X][pos.Y].isOccupied() == false; // Possible exception...? }
public maze_room_internal getRoom(Position pos) { if ((0 <= pos.X) && (pos.X < width) && (0 <= pos.Y) && (pos.Y < height)) return rooms[pos.X][pos.Y]; return null; }
RoomTrait getRoom(Position pos) { if ((pos.X < 0) || (pos.Y < 0) || (pos.X >= width) || (pos.Y >= height)) throw new Exception(); return rooms[pos.X][pos.Y]; }
bool _set_traits(Position pos, int direction, int door_type) { Position biased_pos = pos.GetBiasedPosition(direction); if ((biased_pos.X >= 0) && (biased_pos.Y >= 0)) { if ((biased_pos.X < width) && (biased_pos.Y < height)) { if (!maze_generator.isFree(biased_pos)) return false; maze_generator.markReservedPosition(biased_pos); } } RoomTrait room = getRoom(pos); if (room.isLinked(direction)) throw new Exception(); if (room.getDoorType(direction) != 0) throw new Exception(); int link_type; if (door_type == 3100) link_type = 2; else if (door_type == 3000) link_type = 1; else throw new Exception(); room.Link(direction, link_type); room.setDoorType(direction, door_type); return true; }
int _sub(Position pos) { if (getRoom(pos) != null) { int cnt = 1; for (int i_dir = 0; i_dir < 4; i_dir++) { maze_room_internal room = getRoom(pos.GetBiasedPosition(i_dir)); if (room != null) if (!room.isOccupied()) cnt += 1; } return cnt; } return 0; }
public void markReservedPosition(Position pos) { maze_room_internal room = rooms[pos.X][pos.Y]; if (room.isVisited == 0) // I'm not really clear on this, since it's basically used as a boolean, but, is an integer.. for whatever reason. So, again, guesswork. room.isReserved = true; }
void _undo_move(int count = 1) { for (int i = 0; i < count; i++) { maze_move move = CriticalPath[CriticalPath.Count - 1]; CriticalPath.Remove(CriticalPath[CriticalPath.Count - 1]); maze_room_internal current_room = getRoom(move.pos_from); maze_room_internal next_room = getRoom(move.pos_to); int opposite_direction = Direction.GetOppositeDirection(move.direction); if (next_room.isVisited != 0) // Utter guesswork, but really the only thing that could make sense. { current_room.directions[move.direction] = 0; next_room.directions[opposite_direction] = 0; next_room.isVisited = 0; next_room.isOnCriticalPath = false; counter -= 1; } current_pos = current_pos.GetBiasedPosition(opposite_direction); } }
public void setPathPosition(Position pos) { if ((width > pos.X) && (height > pos.Y)) { maze_room_internal room; for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { room = rooms[x][y]; room.directions = new int[4]; room.isVisited = 0; } } CriticalPath = new List<maze_move>(); start_pos = new Position(0, 0); current_pos = new Position(0, 0); //var temp = end_pos.x; end_pos.X = pos.X; //pos.x = temp; //temp = end_pos.y; end_pos.Y = pos.Y; //pos.y = temp; //temp = current_pos.x; current_pos.X = pos.X; //pos.x = temp; //temp = current_pos.y; current_pos.Y = pos.Y; //pos.y = temp; counter = 1; room = rooms[pos.X][pos.Y]; room.isVisited = counter; room.isOnCriticalPath = true; } }
public Position(Position pos) : this(pos.X, pos.Y) { }
bool _create_sub_path_recursive(Position pos) { RoomTrait room = getRoom(pos); maze_room_internal maze_room = maze_generator.getRoom(pos); room.roomType = 1; for (int direction = 0; direction < 4; direction++) { if (maze_room.GetPassageType(direction) == 2) { Position biased_pos = pos.GetBiasedPosition(direction); if (room != null) room.Link(direction, 2); return _create_sub_path_recursive(biased_pos); } } return true; }