diff --git a/tuixiangzi.py b/tuixiangzi.py deleted file mode 100644 index 0c1b68a..0000000 --- a/tuixiangzi.py +++ /dev/null @@ -1,351 +0,0 @@ -import pygame, sys, os -from pygame.locals import * - -from collections import deque - - -def to_box(level, index): - if level[index] == '-' or level[index] == '@': - level[index] = '$' - else: - level[index] = '*' - - -def to_man(level, i): - if level[i] == '-' or level[i] == '$': - level[i] = '@' - else: - level[i] = '+' - - -def to_floor(level, i): - if level[i] == '@' or level[i] == '$': - level[i] = '-' - else: - level[i] = '.' - - -def to_offset(d, width): - d4 = [-1, -width, 1, width] - m4 = ['l', 'u', 'r', 'd'] - return d4[m4.index(d.lower())] - - -def b_manto(level, width, b, m, t): - maze = list(level) - maze[b] = '#' - if m == t: - return 1 - queue = deque([]) - queue.append(m) - d4 = [-1, -width, 1, width] - m4 = ['l', 'u', 'r', 'd'] - while len(queue) > 0: - pos = queue.popleft() - for i in range(4): - newpos = pos + d4[i] - if maze[newpos] in ['-', '.']: - if newpos == t: - return 1 - maze[newpos] = i - queue.append(newpos) - return 0 - - -def b_manto_2(level, width, b, m, t): - maze = list(level) - maze[b] = '#' - maze[m] = '@' - if m == t: - return [] - queue = deque([]) - queue.append(m) - d4 = [-1, -width, 1, width] - m4 = ['l', 'u', 'r', 'd'] - while len(queue) > 0: - pos = queue.popleft() - for i in range(4): - newpos = pos + d4[i] - if maze[newpos] in ['-', '.']: - maze[newpos] = i - queue.append(newpos) - if newpos == t: - path = [] - while maze[t] != '@': - path.append(m4[maze[t]]) - t = t - d4[maze[t]] - return path - - return [] - - -class Sokoban: - def __init__(self): - self.level = list( - '----#####--------------#---#--------------#$--#------------###--$##-----------#--$-$-#---------###-#-##-#---#######---#-##-#####--..##-$--$----------..######-###-#@##--..#----#-----#########----#######--------') - self.w = 19 - self.h = 11 - self.man = 163 - self.hint = list(self.level) - self.solution = [] - self.push = 0 - self.todo = [] - self.auto = 0 - self.sbox = 0 - self.queue = [] - - def draw(self, screen, skin): - w = skin.get_width() / 4 - offset = (w - 4) / 2 - for i in range(0, self.w): - for j in range(0, self.h): - if self.level[j * self.w + i] == '#': - screen.blit(skin, (i * w, j * w), (0, 2 * w, w, w)) - elif self.level[j * self.w + i] == '-': - screen.blit(skin, (i * w, j * w), (0, 0, w, w)) - elif self.level[j * self.w + i] == '@': - screen.blit(skin, (i * w, j * w), (w, 0, w, w)) - elif self.level[j * self.w + i] == '$': - screen.blit(skin, (i * w, j * w), (2 * w, 0, w, w)) - elif self.level[j * self.w + i] == '.': - screen.blit(skin, (i * w, j * w), (0, w, w, w)) - elif self.level[j * self.w + i] == '+': - screen.blit(skin, (i * w, j * w), (w, w, w, w)) - elif self.level[j * self.w + i] == '*': - screen.blit(skin, (i * w, j * w), (2 * w, w, w, w)) - if self.sbox != 0 and self.hint[j * self.w + i] == '1': - screen.blit(skin, (i * w + offset, j * w + offset), (3 * w, 3 * w, 4, 4)) - - def move(self, d): - self._move(d) - self.todo = [] - - def _move(self, d): - self.sbox = 0 - h = to_offset(d, self.w) - h2 = 2 * h - if self.level[self.man + h] == '-' or self.level[self.man + h] == '.': - # move - to_man(self.level, self.man + h) - to_floor(self.level, self.man) - self.man += h - self.solution += d - elif self.level[self.man + h] == '*' or self.level[self.man + h] == '$': - if self.level[self.man + h2] == '-' or self.level[self.man + h2] == '.': - # push - to_box(self.level, self.man + h2) - to_man(self.level, self.man + h) - to_floor(self.level, self.man) - self.man += h - self.solution += d.upper() - self.push += 1 - - def undo(self): - if self.solution.__len__() > 0: - self.todo.append(self.solution[-1]) - self.solution.pop() - - h = to_offset(self.todo[-1], self.w) * -1 - if self.todo[-1].islower(): - # undo a move - to_man(self.level, self.man + h) - to_floor(self.level, self.man) - self.man += h - else: - # undo a push - to_floor(self.level, self.man - h) - to_box(self.level, self.man) - to_man(self.level, self.man + h) - self.man += h - self.push -= 1 - - def redo(self): - if self.todo.__len__() > 0: - self._move(self.todo[-1].lower()) - self.todo.pop() - - def manto(self, x, y): - maze = list(self.level) - maze[self.man] = '@' - queue = deque([]) - queue.append(self.man) - d4 = [-1, -self.w, 1, self.w] - m4 = ['l', 'u', 'r', 'd'] - while len(queue) > 0: - pos = queue.popleft() - for i in range(4): - newpos = pos + d4[i] - if maze[newpos] in ['-', '.']: - maze[newpos] = i - queue.append(newpos) - # print str(maze) - t = y * self.w + x - if maze[t] in range(4): - self.todo = [] - while maze[t] != '@': - self.todo.append(m4[maze[t]]) - t = t - d4[maze[t]] - # print self.todo - self.auto = 1 - - def automove(self): - if self.auto == 1 and self.todo.__len__() > 0: - self._move(self.todo[-1].lower()) - self.todo.pop() - else: - self.auto = 0 - - def boxhint(self, x, y): - d4 = [-1, -self.w, 1, self.w] - m4 = ['l', 'u', 'r', 'd'] - b = y * self.w + x - maze = list(self.level) - to_floor(maze, b) - to_floor(maze, self.man) - mark = maze * 4 - size = self.w * self.h - self.queue = [] - head = 0 - for i in range(4): - if b_manto(maze, self.w, b, self.man, b + d4[i]): - if len(self.queue) == 0: - self.queue.append((b, i, -1)) - mark[i * size + b] = '1' - # print self.queue - while head < len(self.queue): - pos = self.queue[head] - head += 1 - # print pos - for i in range(4): - if mark[pos[0] + i * size] == '1' and maze[pos[0] - d4[i]] in ['-', '.']: - # print i - if mark[pos[0] - d4[i] + i * size] != '1': - self.queue.append((pos[0] - d4[i], i, head - 1)) - for j in range(4): - if b_manto(maze, self.w, pos[0] - d4[i], pos[0], pos[0] - d4[i] + d4[j]): - mark[j * size + pos[0] - d4[i]] = '1' - for i in range(size): - self.hint[i] = '0' - for j in range(4): - if mark[j * size + i] == '1': - self.hint[i] = '1' - # print self.hint - - def boxto(self, x, y): - d4 = [-1, -self.w, 1, self.w] - m4 = ['l', 'u', 'r', 'd'] - om4 = ['r', 'd', 'l', 'u'] - b = y * self.w + x - maze = list(self.level) - to_floor(maze, self.sbox) - to_floor(maze, self.man) # make a copy of working maze by removing the selected box and the man - for i in range(len(self.queue)): - if self.queue[i][0] == b: - self.todo = [] - j = i - while self.queue[j][2] != -1: - self.todo.append(om4[self.queue[j][1]].upper()) - k = self.queue[j][2] - if self.queue[k][2] != -1: - self.todo += b_manto_2(maze, self.w, self.queue[k][0], self.queue[k][0] + d4[self.queue[k][1]], - self.queue[k][0] + d4[self.queue[j][1]]) - else: - self.todo += b_manto_2(maze, self.w, self.queue[k][0], self.man, - self.queue[k][0] + d4[self.queue[j][1]]) - j = k - # print self.todo - self.auto = 1 - return - print('not found!') - - def mouse(self, x, y): - if x >= self.w or y >= self.h: - return - m = y * self.w + x - if self.level[m] in ['-', '.']: - if self.sbox == 0: - self.manto(x, y) - else: - self.boxto(x, y) - elif self.level[m] in ['$', '*']: - if self.sbox == m: - self.sbox = 0 - else: - self.sbox = m - self.boxhint(x, y) - elif self.level[m] in ['-', '.', '@', '+']: - self.boxto(x, y) - - -def main(): - # start pygame - pygame.init() - screen = pygame.display.set_mode((400, 300)) - - # load skin - skinfilename = os.path.join('borgar.png') - try: - skin = pygame.image.load(skinfilename) - except pygame.error as msg: - print('cannot load skin') - raise SystemExit(msg) - skin = skin.convert() - - # print skin.get_at((0,0)) - # screen.fill((255,255,255)) - screen.fill(skin.get_at((0, 0))) - pygame.display.set_caption('sokoban.py') - - # create Sokoban object - skb = Sokoban() - skb.draw(screen, skin) - - # - clock = pygame.time.Clock() - pygame.key.set_repeat(200, 50) - - # main game loop - while True: - clock.tick(60) - - if skb.auto == 0: - for event in pygame.event.get(): - if event.type == QUIT: - # print skb.solution - pygame.quit() - sys.exit() - elif event.type == KEYDOWN: - if event.key == K_LEFT: - skb.move('l') - skb.draw(screen, skin) - elif event.key == K_UP: - skb.move('u') - skb.draw(screen, skin) - elif event.key == K_RIGHT: - skb.move('r') - skb.draw(screen, skin) - elif event.key == K_DOWN: - skb.move('d') - skb.draw(screen, skin) - elif event.key == K_BACKSPACE: - skb.undo() - skb.draw(screen, skin) - elif event.key == K_SPACE: - skb.redo() - skb.draw(screen, skin) - elif event.type == MOUSEBUTTONUP and event.button == 1: - mousex, mousey = event.pos - mousex /= (skin.get_width() / 4) - mousey /= (skin.get_width() / 4) - skb.mouse(mousex, mousey) - skb.draw(screen, skin) - else: - skb.automove() - skb.draw(screen, skin) - - pygame.display.update() - pygame.display.set_caption(skb.solution.__len__().__str__() + '/' + skb.push.__str__() + ' - sokoban.py') - - -if __name__ == '__main__': - main() \ No newline at end of file