source: misc/maze.py @ 18:864e4e48dcf5

Revision 18:864e4e48dcf5, 4.1 KB checked in by Eriol, 5 years ago (diff)

Added maze.py

Line 
1#!/usr/bin/env python
2#
3# maze.py
4# Generating Maze using Python
5# http://mornie.org/blog/2007/08/02/Generating-Maze-using-Python/
6#
7# Copyright (C) 2007  Daniele Tricoli aka Eriol <eriol@mornie.org>
8#
9# This program is free software; you can redistribute it and/or
10# modify it under the terms of the GNU General Public License
11# as published by the Free Software Foundation; either version 2
12# of the License, or (at your option) any later version.
13#
14# This program is distributed in the hope that it will be useful,
15# but WITHOUT ANY WARRANTY; without even the implied warranty of
16# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17# GNU General Public License for more details.
18#
19# You should have received a copy of the GNU General Public License
20# along with this program; if not, write to the Free Software
21# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
22
23import random
24
25class Cell(object):
26    '''A square cell'''
27
28    def __init__(self, x, y):
29        self.walls = [1, 1, 1, 1]
30        self.x = x
31        self.y = y
32
33    def has_all_walls_intact(self):
34        if 0 in self.walls:
35            return False
36        else:
37            return True
38
39    def find_adjacent_wall(self, cell):
40        if cell.x == self.x:
41            if cell.y < self.y:
42                return 0 # left
43            else:
44                return 2 # right
45        else:
46            if cell.x < self.x:
47                return 1 # above
48            else:
49                return 3 # below
50
51    def destroy_wall(self, cell=None, wall=None):
52        if cell is not None:
53            wall_to_destroy = self.find_adjacent_wall(cell)
54            self.walls[wall_to_destroy] = 0
55            cell.walls[(wall_to_destroy + 2) % 4] = 0 # The opposite wall
56        elif wall is not None:
57            self.walls[wall] = 0
58
59    def neighbors_coords(self):
60        return ((self.x - 1, self.y),  # above
61                (self.x + 1, self.y),  # below
62                (self.x, self.y - 1),  # left
63                (self.x, self.y + 1))  # right
64
65
66class Maze(object):
67
68    def __init__(self, width, height):
69        self.width = width
70        self.height = height
71        self.cells = [[None for x in range(self.width)]
72                            for x in range(self.height)]
73        self.total_cells = self.width * self.height
74
75        for i in range(self.height):
76            for j in range(self.width):
77                self.cells[i][j] = Cell(i,j)
78
79        self.current_cell = self.cells[0][0]
80        self.visited_cells = 1
81
82    def find_neighbors_with_walls(self, cell):
83        coords = self.cells[cell.x][cell.y].neighbors_coords()
84        all_neighbors = [self.cells[i][j] for i, j in coords
85                                                 if self.isinside(i, j)]
86        return [neighbors for neighbors in all_neighbors
87                                         if neighbors.has_all_walls_intact()]
88
89    def isinside(self, x, y):
90        if (0 <= x < self.height) and (0 <= y < self.width):
91            return True
92
93    def create(self):
94        cell_stack = []
95        while self.visited_cells < self.total_cells:
96            neighbors = self.find_neighbors_with_walls(self.current_cell)
97            if neighbors:
98                new_cell = random.choice(neighbors)
99                self.current_cell.destroy_wall(cell=new_cell)
100                cell_stack.append(self.current_cell)
101                self.current_cell = new_cell
102                self.visited_cells += 1
103            else:
104                self.current_cell = cell_stack.pop()
105
106    def draw_ascii(self):
107        canvas = []
108        for x in range(self.height):
109            line = []
110            line2 = []
111            for y in range(self.width):
112                cell = self.cells[x][y]
113                line.append(' -'[cell.walls[1]] * 2)
114                line2.append(' |'[cell.walls[0]] + '  ')
115            canvas.append('+' + '+'.join(line) + '+\n')
116            canvas.append(''.join(line2) + '|\n')
117        canvas.append('+--' * self.width + '+\n')
118        return ''.join(canvas)
119
120if __name__ == '__main__':
121    x = Maze(10,6)
122    x.create()
123    print x.draw_ascii()
Note: See TracBrowser for help on using the repository browser.