小姐姐学Python-class4

python推箱子

实现效果如下

《小姐姐学Python-class4》
p是人,* 是箱子,$是终点,#是围墙。
玩家通过 (wasd)来控制人行走,如果走的前方是箱子,则去尝试推动它,如果箱子的前面是空地,则可以推动,如果是墙则不行,如果是终点,则游戏结束胜利。
逻辑看似比较简单,但对初学者来说还是比较考验思维能力的或者说是否考虑全面。

首先画图

用数组存储地图,10×10数组代表地图,数组中存储数字,用数字0代表空地,数字1代表围墙,数字2代表箱子,数字3代表人,数字4代表终点

maze = [] # 10x10的二维数组

people_x , people_y = 5, 5 # 初始人的位置(x,y)

box_x ,box_y = 4,5 # 初始箱子的位置
target_x ,target_y = 1,1 # 初始终点的位置

def init():
    global maze # 使用全局变量maze
    maze = [[0 for i in range(10)] for i in range(10)]
    for i in range(10):
        for j in range(10):
            # 边界设置为1
            if i == 0 or j == 0 or i == 9 or j == 9:
                maze[i][j] = 1
            else:
                maze[i][j] = 0
    maze[box_x][box_y] = 2 # 箱子的位置置为2
    maze[people_x][people_y] = 3 # 人的位置置为3
    maze[target_x][target_y] = 4 # 目标的位置置为4

接着我们用约定好的符号打印出来这个数组,即将二维数组中的数字换成符号(# $p*)。
这里封装成了一个函数print_maze(),后面每次移动小人后,可以调用这个函数,实现地图的更新。

  1. 空地的数字-> 0 ,对应的符号是’ ‘(空格)
  2. 围墙的数字-> 1, 对应的符号是’#’
  3. 箱子的数字-> 2, 对应的符号是’*’
  4. 人的数字 -> 3,对应的符号是’p’
  5. 终点的数字-> 4,对应的符号是’$’
def print_maze():
    global maze
    for i in range(10):
        for j in range(10):
            #print(i,j)

            if maze[i][j] == 0:
                print(' ', end='')
            elif maze[i][j] == 1:
                print('#',end='')
            elif maze[i][j] == 2:
                print('*', end='')
            elif maze[i][j] == 3:
                print('p', end='')
            elif maze[i][j] == 4:
                print('$', end='')
        print()

如何让地图动起来?

我们有了数组里的数字代表地图的实体,因此我们只要根据推箱子游戏的逻辑更新数字,然后再调用print_maze()方法,就能让地图动起来了~

核心逻辑

推箱子一共有四个方向。我们只用把一个方向的逻辑写出来,剩余的三个稍加修改,就能搞定核心逻辑了。

我们以向上推举例。
当玩家按下w键,然后回车。
1. 首先判断小人上方的位置是不是在边界内,也就是在不在数组的范围内(参见下面in_border函数)。
2. 判断小人上面的位置是什么
* 如果是墙(1)不能移动
* 如果是空地(0),可以移动
* 如果是箱子(2),则看箱子前方是否为围墙,如果不是则可以移动
3. 移动,要更新小人的坐标,箱子的坐标。
将原来小人的二维数组(maze)中坐标位置的值置为空地(0),将新的坐标对应的值置为小人(2)。如果推动了箱子,则还要更新箱子的坐标。

# 判断位置x,y是否出界
def in_border(x,y):
    if x < 0 or x >=10 or y < 0 or y >=10:
        return False
    return True
x = input()
if x == 'w':
    # 向上, 判断 下一步是不是在界内。
    if in_border(people_x - 1,people_y):
        # 判断下一步的位置是什么:0.墙不能移动 1. 空,可以移动,2 箱子,看箱子前方是否为空,
        if maze[people_x - 1][people_y] == 0 : # 空地
            maze[people_x][people_y] = 0 # 原来位置置为空
            maze[people_x - 1][people_y] = 3 # 新位置置为小人
            people_x = people_x - 1 # 小人的坐标更新
            #前方为箱子,且箱子前方不是围墙
        elif maze[people_x - 1][people_y] == 2 and in_border(people_x - 2,people_y) and maze[people_x - 2][people_y] != 1:
            # 如果箱子前面是终点,则胜利结束游戏
            if maze[people_x - 2][people_y] == 4:
                print('\n\n*********  You Win !  *********\n\n')
                win = True
            maze[people_x][people_y] = 0
            maze[people_x - 1][people_y] = 3
            maze[people_x - 2][people_y] = 2
            # 更新箱子的坐标
            box_x = people_x - 2
            people_x = people_x - 1 # 更新人的坐标
        else:# 不能移动
            continue

好了,实现了向上的逻辑,向左,向右,向下的逻辑都可以用同样的方法复制出来了 :)

所有代码


maze = [] people_x , people_y = 5, 5 box_x ,box_y = 4,5 target_x ,target_y = 1,1 def init(): global maze maze = [[0 for i in range(10)] for i in range(10)] for i in range(10): for j in range(10): if i == 0 or j == 0 or i == 9 or j == 9: maze[i][j] = 1 else: maze[i][j] = 0 maze[box_x][box_y] = 2 maze[people_x][people_y] = 3 maze[target_x][target_y] = 4 def print_maze(): global maze for i in range(10): for j in range(10): #print(i,j) if maze[i][j] == 0: print(' ', end='') elif maze[i][j] == 1: print('#',end='') elif maze[i][j] == 2: print('*', end='') elif maze[i][j] == 3: print('p', end='') elif maze[i][j] == 4: print('$', end='') print() def in_border(x,y): if x < 0 or x >=10 or y < 0 or y >=10: return False return True def main(): import os i = os.system("clear") init() print_maze() # 声明全局变量。 global people_x, people_y,box_x,box_y win = False while True: x = input() if x == 'w': # 向上, 判断 下一步是不是在界内。 if in_border(people_x - 1,people_y): # 判断下一步的位置是什么0.墙不能移动 1. 空,可以移动,2 箱子,看箱子前方是否为空, if maze[people_x - 1][people_y] == 0 : # 空地 maze[people_x][people_y] = 0 maze[people_x - 1][people_y] = 3 people_x = people_x - 1 #前方为箱子,且箱子前方为空 elif maze[people_x - 1][people_y] == 2 and in_border(people_x - 2,people_y) and maze[people_x - 2][people_y] != 1: if maze[people_x - 2][people_y] == 4: print('\n\n********* You Win ! *********\n\n') win = True maze[people_x][people_y] = 0 maze[people_x - 1][people_y] = 3 maze[people_x - 2][people_y] = 2 # 注意这里,先赋值了 box_x,倒过来就错了 box_x = people_x - 2 people_x = people_x - 1 else:# 不能移动 continue if x == 's': # 向上, 判断 下一步是不是在界内。 if in_border(people_x + 1,people_y): # 判断下一步的位置是什么0.墙不能移动 1. 空,可以移动,2 箱子,看箱子前方是否为空, if maze[people_x + 1][people_y] == 0 : # 空地 maze[people_x][people_y] = 0 maze[people_x + 1][people_y] = 3 people_x = people_x + 1 #前方为箱子,且箱子前方为空 elif maze[people_x + 1][people_y] == 2 and in_border(people_x + 2,people_y) and maze[people_x + 2][people_y] != 1: if maze[people_x + 2][people_y] == 4: print('\n\n********* You Win ! *********\n\n') win = True maze[people_x][people_y] = 0 maze[people_x + 1][people_y] = 3 maze[people_x + 2][people_y] = 2 # 注意这里,先赋值了 box_x,倒过来就错了 box_x = people_x + 2 people_x = people_x + 1 else:# 不能移动 continue if x == 'a': # 向上, 判断 下一步是不是在界内。 if in_border(people_x ,people_y - 1): # 判断下一步的位置是什么0.墙不能移动 1. 空,可以移动,2 箱子,看箱子前方是否为空, if maze[people_x][people_y - 1] == 0 : # 空地 maze[people_x][people_y] = 0 maze[people_x][people_y - 1] = 3 people_y = people_y - 1 #前方为箱子,且箱子前方为空 elif maze[people_x ][people_y -1 ] == 2 and in_border(people_x,people_y -2) and maze[people_x][people_y - 2] != 1: if maze[people_x][people_y - 2] == 4: print('\n\n********* You Win ! *********\n\n') win = True maze[people_x][people_y] = 0 maze[people_x][people_y - 1] = 3 maze[people_x][people_y - 2] = 2 # 注意这里,先赋值了 box_x,倒过来就错了 box_y = people_y - 2 people_y = people_y - 1 else:# 不能移动 continue if x == 'd': # 向上, 判断 下一步是不是在界内。 if in_border(people_x ,people_y + 1): # 判断下一步的位置是什么0.墙不能移动 1. 空,可以移动,2 箱子,看箱子前方是否为空, if maze[people_x][people_y + 1] == 0 : # 空地 maze[people_x][people_y] = 0 maze[people_x][people_y + 1] = 3 people_y = people_y + 1 #前方为箱子,且箱子前方为空 elif maze[people_x ][people_y + 1] == 2 and in_border(people_x,people_y + 2) and maze[people_x][people_y + 2] != 1: if maze[people_x][people_y + 2] == 4: print('\n\n********* You Win ! *********\n\n') win = True maze[people_x][people_y] = 0 maze[people_x][people_y + 1] = 3 maze[people_x][people_y + 2] = 2 # 注意这里,先赋值了 box_x,倒过来就错了 box_y = people_y + 2 people_y = people_y + 1 else:# 不能移动 continue if win: break import os i = os.system("clear") print_maze() if __name__ == '__main__': main()
点赞
  1. 图图说道:

    :mrgreen: :mrgreen: 好帖子,顶一顶顶一顶

    1. chaiwenjun000说道:

      :biggrin: 谢谢捧场