Ich habe ein kleines Project gestartet und habe angefangen ein eigenes roguelike zu schreiben.
Leider habe ich Probleme mit dem Algorithmus zum generieren der map.
Hier der Code:
Code: Alles auswählen
import random
import curses
class Tile:  # a `class` with tiles of the map
    def __init__(self, char, blocked):
        self.char = char
        self.blocked = blocked
        self.color = None  #  would be defined in a `function` which will render the map
class Room:  # a `class` for the rooms
    def __init__(self, x, y, w, h):
        self.x_1 = x
        self.y_1 = y
        self.x_2 = x + w
        self.y_2 = y + h
        
        self.mid()
    def mid(self):
        self.mid_x = int((self.x_1 + self.x_2) / 2) if (self.x_1 + self.x_2) % 2 == 0 else int((self.x_1 + self.x_2 + 1) / 2)
        self.mid_y = int((self.y_1 + self.x_2) / 2) if (self.y_1 + self.y_2) % 2 == 0 else int((self.y_1 + self.y_2 + 1) / 2)
    def valid(self, room):  # looks if the place where the room comes is valid
        if self.x_1 <= room.x_2 and self.x_2 >= room.x_1:
            if self.y_1 <= room.y_2 and self.y_2 >= room.y_1:
                return False
            else:
                return True
        
        else:
            return True
class Dungeon:  # a `class` for generating the dungeon
    def __init__(self, size_x, size_y, max_rooms, min_size, max_size):
        '''
        This `function` will be executed when an object will be made later.
        This will generate the dungeon
        '''
        # set the size
        self._map_y = size_y
        self._map_x = size_x
        # sets the option for the rooms
        self._max_rooms = max_rooms
        self._room_size_min = min_size
        self._room_size_max = max_size
        # sets the map
        self._map = []
        
        # fills the dungeon with walls
        for i in range(0, self._map_x):
            self._map.append([i])
            for j in range(0, self._map_y):
                self._map[j].append(Tile('#', True))
#       self._map = [[Tile('#', True)
#               for j in range(0, self._map_y)]
#           for i in range(0, self._map_x)]
        room_num = 0
        self.rooms = []
        for i in range(self._max_rooms):
            # make random width, height, ...
            w = random.randint(self._room_size_min, self._room_size_max)
            h = random.randint(self._room_size_min, self._room_size_max)
            x = random.randint(0, self._map_x)
            y = random.randint(0, self._map_y)
            # make room as an `object` of Room
            new_room = Room(x, y, w, h)
            
            failed = False
            # look if it is valid
            for other in self.rooms:
                if new_room.valid(other) == False:
                    failed = True
                    break
                
                else:
                    failed = False
            # if it is valid go on 
            if failed == False:
                # take it into the map
                self._mk_room(new_room)
                if room_num == 0:  # it is the first room
                    # take the mid coordinates as the place for the player to begin
                    self.begin = (new_room.mid_x, new_room.mid_y)
                else:  # isn't the first room ^^
                    # connect this room with the previous
                    old_x = self.rooms[room_num - 1].mid_x
                    old_y = self.rooms[room_num - 1].mid_y
                    
                    # choose randomly if horizontal or vertical should be made at first
                    if random.choice('01') == '1':  # make horizontal at first
                        self._mk_h_cooridor(old_x, new_room.mid_x, old_y)
                        self._mk_v_cooridor(old_y, new_room.mid_y, new_room.mid_x)
                    else:  # make vertical at first
                        self._mk_v_cooridor(old_y, new_room.mid_y, old_x)
                        self._mk_h_cooridor(old_x, new_room.mid_x, new_room.mid_y)      
            # append it to the list
            self.rooms.append(new_room)
            room_num += 1
    
    def draw(self, stdscr):  # `function` to draw the dungeon
        for x in range(0, self._map_x):
            for y in range(0, self._map_y):
                stdscr.addstr(y, x, self._map[x][y].char, self._map[y][x].color)
    def _mk_h_cooridor(self, x_1, x_2, y):  # `function` for making horizontal cooridors
        for i in range(min(x_1, x_2), max(x_1, x_2) + 1):
            self._map[i][y].char = random.choice('.,')
            self._map[i][y].blocked = False
    def _mk_v_cooridor(self, y_1, y_2, x):  # `function` for making vertical cooridors
        for j in range(min(y_1, y_2), max(y_1, y_2) + 1):
            self._map[x][j].char = random.choice('.,')
            self._map[x][j].blocked = False
    def _mk_room(self, room):  # `function` for making a room
        for i in range(room.x_1 + 1, room.x_2):
            for j in range(room.y_1 + 1, room.y_2):
                self._map[i][j].char = random.choice('.,')
                self._map[i][j].blocked = False
Immer wenn ich ihn ausführe bekomme ich einen ``IndexError``
Hier nochmal die Fehlermeldung:
Code: Alles auswählen
Traceback (most recent call last):
  File "main.py", line 214, in <module>
    render()
  File "main.py", line 116, in render
    dungeon = Dungeon(MAP_X, MAP_Y, NUM_ROOMS, ROOM_MIN, ROOM_MAX)
  File "/home/lambda/git/dwarfs-roguelike/game/data/dungeon.py", line 62, in __init__
    self._map[j].append(Tile('#', True))
IndexError: list index out of range
PS: Ich habe erst in diesem Jahr mit programieren angefangen also würde ich mich auch um ein bischen Hilfe/Verbesserungsvorschläge freuen.
MfG
