プレイヤーがゴールに到達したら「Game Clear!!」を出力する。
main.py
import pygame
from pygame.locals import *
import sys
import maze
BLACK = (0, 0, 0)
WHITE = (255,255,255)
PLAY, CLEAR = (0, 1)
size = (640, 480)
width, height = size
board_w, board_h = 450, 450
space_w, space_h = (width-board_w)/2, (height-board_h)/2
cell_space = 5
maze1 = maze.Maze(5, 5)
maze1.set_maze_boutaoshi()
position = maze1.start
pygame.init()
screen = pygame.display.set_mode(size)
pygame.display.set_caption('Maze')
state = PLAY
font1 = pygame.font.SysFont(None, 100)
text1 = font1.render('GAME CLEAR!!', True, WHITE)
while True:
if state == PLAY:
screen.fill(BLACK)
pygame.draw.rect(screen,WHITE,(space_w,space_h,board_w,board_h),1)
for y in range(1, 3):
pygame.draw.line(screen,WHITE,(space_w,y*(board_h/3)+space_h),(width-space_w-1,y*(board_h/3)+space_h))
for x in range(1, 3):
pygame.draw.line(screen,WHITE,(x*(board_w/3)+space_w,space_h),(x*(board_w/3)+space_w,height-space_h-1))
pygame.draw.ellipse(screen,(255,255,255),((board_w/3)+space_w+cell_space,(board_h/3)+space_h+cell_space,(board_w/3)-(cell_space*2),(board_h/3)-(cell_space*2)))
for y in range(0, 3):
for x in range(0, 3):
if maze1.maze[y+position[1]-1][x+position[0]-1] == 1:
pygame.draw.rect(screen,(255,255,255),Rect(x*(board_w/3)+space_w+cell_space,y*(board_h/3)+space_h+cell_space,(board_w/3)-(cell_space*2),(board_h/3)-(cell_space*2)))
if position == maze1.goal:
state = CLEAR
if state == CLEAR:
screen.fill(BLACK)
screen.blit(text1, (65,height/2-50))
pygame.display.update()
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
sys.exit()
if event.type == KEYDOWN:
if event.key == K_LEFT:
if maze1.maze[position[1]][position[0]-1] == 0:
position[0] -= 1
if event.key == K_RIGHT:
if maze1.maze[position[1]][position[0]+1] == 0:
position[0] += 1
if event.key == K_UP:
if maze1.maze[position[1]-1][position[0]] == 0:
position[1] -= 1
if event.key == K_DOWN:
if maze1.maze[position[1]+1][position[0]] == 0:
position[1] += 1
if event.key == K_ESCAPE:
pygame.quit()
sys.exit()
maze.py
import sys
import random
from collections import deque
class Maze:
PATH = 0
WALL = 1
def __init__(self, width, height, seed=0):
self.width = width
self.height = height
if self.width < 5 or self.height < 5:
sys.exit()
if self.width % 2 == 0:
self.width += 1
if self.height % 2 == 0:
self.height += 1
self.maze = [[self.PATH for x in range(self.width)] for y in range(self.height)]
self.dist = [[-1 for i in range(self.width)] for j in range(self.height)]
self.start = [1, 1]
self.goal = [self.width-2, self.height-2]
random.seed(seed)
def set_outer_wall(self):
for y in range(0, self.height):
for x in range(0, self.width):
if x == 0 or y == 0 or x == self.width-1 or y == self.height-1:
self.maze[y][x] = self.WALL
return self.maze
def set_inner_wall(self):
for y in range(2, self.height-1, 2):
for x in range(2, self.width-1, 2):
self.maze[y][x] = self.WALL
return self.maze
def set_maze_boutaoshi(self):
self.set_outer_wall()
self.set_inner_wall()
for y in range(2, self.height-1, 2):
for x in range(2, self.width-1, 2):
while True:
wall_x = x
wall_y = y
if y == 2:
direction = random.randrange(0, 4)
else:
direction = random.randrange(0, 3)
if direction == 0:
wall_x += 1
elif direction == 1:
wall_y += 1
elif direction == 2:
wall_x -= 1
elif direction == 3:
wall_y -= 1
if self.maze[wall_y][wall_x] != self.WALL:
self.maze[wall_y][wall_x] = self.WALL
break
return self.maze
def set_start_goal(self, start, goal):
if self.maze[start[1]][start[0]] == self.PATH:
self.start = start
if self.maze[goal[1]][goal[0]] == self.PATH:
self.goal = goal
return self.maze
def set_dist_bfs(self,flag=False):
queue = deque()
self.dist[self.start[1]][self.start[0]] = 0
queue.append(self.start)
while len(queue) > 0:
point = queue.popleft()
for x in [[0,-1],[1,0],[0,1],[-1,0]]:
if self.maze[point[1]+x[1]][point[0]+x[0]] == 0 and self.dist[point[1]+x[1]][point[0]+x[0]] == -1:
self.dist[point[1]+x[1]][point[0]+x[0]] = self.dist[point[1]][point[0]] + 1
queue.append([point[0]+x[0],point[1]+x[1]])
if flag != True:
if point[0]+x[0] == self.goal[0] and point[1]+x[1] == self.goal[1]:
queue.clear()
break
return self.dist
def set_dist_dfs(self,flag=False):
stack = deque()
self.dist[self.start[1]][self.start[0]] = 0
stack.append(self.start)
while len(stack) > 0:
point = stack.pop()
for x in [[0,-1],[1,0],[0,1],[-1,0]]:
if self.maze[point[1]+x[1]][point[0]+x[0]] == 0 and self.dist[point[1]+x[1]][point[0]+x[0]] == -1:
self.dist[point[1]+x[1]][point[0]+x[0]] = self.dist[point[1]][point[0]] + 1
stack.append([point[0]+x[0],point[1]+x[1]])
if flag != True:
if point[0]+x[0] == self.goal[0] and point[1]+x[1] == self.goal[1]:
stack.clear()
break
return self.dist
def set_shortest_path(self):
point = self.goal
self.maze[point[1]][point[0]] = '*'
while self.dist[point[1]][point[0]] > 0:
for x in [[0,-1],[1,0],[0,1],[-1,0]]:
if self.dist[point[1]][point[0]]-self.dist[point[1]+x[1]][point[0]+x[0]] == 1:
if self.dist[point[1]][point[0]] > 0:
self.maze[point[1]+x[1]][point[0]+x[0]] = '*'
point = [point[0]+x[0],point[1]+x[1]]
return self.maze
def print_maze(self):
self.maze[self.start[1]][self.start[0]] = 'S'
self.maze[self.goal[1]][self.goal[0]] = 'G'
for col in self.maze:
for cell in col:
if cell == self.WALL:
print('#', end='')
elif cell == self.PATH:
print(' ', end='')
elif cell == 'S':
print('S', end='')
elif cell == 'G':
print('G', end='')
elif cell == '*':
print('*', end='')
print()
def print_dist(self):
for col in self.dist:
for cell in col:
if cell == -1:
if max(map(lambda x: max(x), self.dist)) == -1:
print('#', end='')
else:
for i in range(len(str(max(map(lambda x: max(x), self.dist))))):
print('#', end='')
else:
if len(str(cell)) == len(str(max(map(lambda x: max(x), self.dist)))):
print(cell, end='')
else:
for i in range(len(str(max(map(lambda x: max(x), self.dist))))-len(str(cell))):
print(' ', end='')
print(cell, end='')
print()
参考
font - Pygameドキュメント 日本語訳
font - Pygameドキュメント 日本語訳
surface - Pygameドキュメント 日本語訳