python数组实现简单的推箱子

环境:Windows10 +Python3.7+Pycharm2017

目标:模拟用数组实现推箱子

一、基本思路

python新建数组,用数字来表示箱子,障碍物,目的地,到达目的地,以及人。
用键盘获取输入,每输入一个就进行一个动作,(由于这个只是简单写写,所以没有直接监听键码,一步一步的输入asdw(不区分大小写)进行),当然也没有写清屏的,有时间你们都可以去写一写。
判断情况 人遇到墙应该怎么做,到达目的地应该怎么做,人在目的地的情况等等

二、程序设计

1.初始化数组 Init()

用数字表示状态
墙:0 箱子:1 空:2 到达目的地:3 目的地: 4: 人:5

def Init():
    Interface = [
        [2,0,0,0,0,2],
        [0,0,2,2,0,2],
        [0,5,1,2,0,2],
        [0,0,1,2,0,0],
        [0,0,2,1,2,0],
        [0,4,1,2,2,0],
        [0,4,4,3,4,0],
        [0,0,0,0,0,0]
    ]   # 初始化界面
    return Interface

推箱子

2.显示数组 show(Interface)

打印数组,数字用字符代替,可以在拼音状态v1状态下查找特殊字符
一个字符占俩个空格
墙: ■ 箱子:☆ 空:’ ’ 到达目的地:● 目的地: ★: 人:♀

def show(Interface):
    global target_flag
    for i in range(len(Interface)):
        for j in range(len(Interface[i])):
            if ((j+1)%len(Interface[i]) != 0):  # 没有一行不换行
                end = ''
            else:
                end = '\n'
            if Interface[i][j] == 0:
                print('■',end=end)
            if Interface[i][j] == 1:
                print('☆',end=end)
            if Interface[i][j] == 2:
                print('  ',end=end)
            if Interface[i][j] == 3:
                print('●',end=end)
                if target_flag == 1:
                    target.append([i,j])
            if Interface[i][j] == 4:
                print('★',end=end)
                if target_flag == 1:
                    target.append([i,j])
            if Interface[i][j] == 5:
                print('♀',end=end)
    print('Show complete!')
    target_flag += 1    # 只添加第一次到target

打印出来的格式如下
在这里插入图片描述

3.获取输入并输出数组 get_input (Interface)

由于其他动作情况基本一样,这里只用向左作示范

def get_input(Interface):
    while True:
        break_flag = False      # 若指定运行完,则跳出双层循环
        input_key = input('请输入asdw(不区分大小写,分别对应左下右上):')
        for i in range(len(Interface)):
            for j in range(len(Interface[i])):
                if input_key == 'd' or input_key == 'D':    # 向右移动
                    # 如果数组为人且右边不为墙 那么俩种情况
                    if Interface[i][j] == 5 and Interface[i][j+1] != 0:
                        if Interface[i][j+1] != 1 and Interface[i][j+1] != 3:  # 右边不为箱子,到达目的地
                            Interface[i][j+1] = 5
                            Interface[i][j] = 2
                            break   # 如果不break且右边没有障碍物 它会一直右走 for自左向右 向左无影响
                        else:   # 右边为箱子或目的地到达
                            if Interface[i][j+2] != 0 : # 箱子右边不是墙
                                if Interface[i][j+2] != 4:  # 箱子右边不是目的地
                                    Interface[i][j] =  2
                                    Interface[i][j+1] = 5
                                    Interface[i][j+2] = 1
                                    break
                                else:            # 箱子到达目的地
                                    Interface[i][j] =  2
                                    Interface[i][j+1] = 5
                                    Interface[i][j+2] = 3
                                    break
                            else:
                                pass
                else:
                    print('您的输入有误,请重新输入')
                    break_flag = True
                    break
            if break_flag == True:  # 跳出第二层循环
            	break

        for i in range(len(target)):
            j = 0
            # 如果不是到达目的地的情况和人在目的地的情况   目的地还是为'★'
            if Interface[target[i][j]][target[i][j+1]] != 3 and Interface[target[i][j]][target[i][j+1]] != 5:
                Interface[target[i][j]][target[i][j+1]] = 4

        show(Interface)
        count = judge(Interface)

        if count == len(target):
            print('恭喜您,通关了')
            break

向右走

4.判断是否通关 judge (Interface)

def judge(Interface):
    count = 0 # 计数 如果都到达目的地 退出循环
    for i in range(len(Interface)):
        for j in range(len(Interface[i])):
            if Interface[i][j] == 3:
                count += 1
    return count

已通关

三、源代码

# -*- coding: utf-8 -*-

# 初始化                   墙:0    箱子:1   空:2    到达目的地:3   目的地: 4:   人:5
def Init():
    Interface = [
        [2,0,0,0,0,2],
        [0,0,2,2,0,2],
        [0,5,1,2,0,2],
        [0,0,1,2,0,0],
        [0,0,2,1,2,0],
        [0,4,1,2,2,0],
        [0,4,4,3,4,0],
        [0,0,0,0,0,0]
    ]   # 初始化界面
    return Interface

Interface = Init()

target = []     # 当人在目的地行走时,不会用空白将目的地覆盖
target_flag = 1

# 显示界面
def show(Interface):
    global target_flag
    for i in range(len(Interface)):
        for j in range(len(Interface[i])):
            if ((j+1)%len(Interface[i]) != 0):  # 没有一行不换行
                end = ''
            else:
                end = '\n'
            if Interface[i][j] == 0:
                print('■',end=end)
            if Interface[i][j] == 1:
                print('☆',end=end)
            if Interface[i][j] == 2:
                print('  ',end=end)
            if Interface[i][j] == 3:
                print('●',end=end)
                if target_flag == 1:
                    target.append([i,j])
            if Interface[i][j] == 4:
                print('★',end=end)
                if target_flag == 1:
                    target.append([i,j])
            if Interface[i][j] == 5:
                print('♀',end=end)
    print('Show complete!')
    target_flag += 1    # 只添加第一次到target

def get_input(Interface):
    while True:
        break_flag = False      # 若指定运行完,则break
        input_key = input('请输入asdw(不区分大小写,分别对应左下右上):')
        for i in range(len(Interface)):
            for j in range(len(Interface[i])):
                if input_key == 'a' or input_key == 'A':    # 向左移动
                # 如果数组为人且左边不为墙 那么俩种情况
                    if Interface[i][j] == 5 and Interface[i][j-1] != 0:
                        if Interface[i][j-1] != 1 and Interface[i][j-1] != 3:  # 左边不为箱子,到达目的地
                            Interface[i][j-1] = 5
                            Interface[i][j] = 2
                            break
                        else:   # 左边为箱子或目的地到达
                            if Interface[i][j-2] != 0 : # 箱子左边不是墙
                                if Interface[i][j-2] != 4:  # 箱子左边不是目的地
                                    Interface[i][j] =  2
                                    Interface[i][j-1] = 5
                                    Interface[i][j-2] = 1
                                else:            # 箱子到达目的地
                                    Interface[i][j] =  2
                                    Interface[i][j-1] = 5
                                    Interface[i][j-2] = 3

                            else:
                                pass
                elif input_key == 'd' or input_key == 'D':    # 向右移动
                    # 如果数组为人且右边不为墙 那么俩种情况
                    if Interface[i][j] == 5 and Interface[i][j+1] != 0:
                        if Interface[i][j+1] != 1 and Interface[i][j+1] != 3:  # 右边不为箱子,到达目的地
                            Interface[i][j+1] = 5
                            Interface[i][j] = 2
                            break   # 如果不break且右边没有障碍物 它会一直右走 for自左向右 向左无影响
                        else:   # 右边为箱子或目的地到达
                            if Interface[i][j+2] != 0 : # 箱子右边不是墙
                                if Interface[i][j+2] != 4:  # 箱子右边不是目的地
                                    Interface[i][j] =  2
                                    Interface[i][j+1] = 5
                                    Interface[i][j+2] = 1
                                    break
                                else:            # 箱子到达目的地
                                    Interface[i][j] =  2
                                    Interface[i][j+1] = 5
                                    Interface[i][j+2] = 3
                                    break
                            else:
                                pass
                elif input_key == 'w' or input_key == 'W':    # 向上移动
                    # 如果数组为人且上边不为墙 那么俩种情况
                    if Interface[i][j] == 5 and Interface[i-1][j] != 0:
                        if Interface[i-1][j] != 1 and Interface[i-1][j] != 3:  #上边不为箱子,到达目的地
                            Interface[i-1][j] = 5
                            Interface[i][j] = 2
                            break
                        else:   # 上边为箱子或目的地到达
                            if Interface[i-2][j] != 0 : # 箱子上边不是墙
                                if Interface[i-2][j] != 4:  # 箱子上边不是目的地
                                    Interface[i][j] =  2
                                    Interface[i-1][j] = 5
                                    Interface[i-2][j] = 1
                                else:            # 箱子到达目的地
                                    Interface[i][j] =  2
                                    Interface[i-1][j] = 5
                                    Interface[i-2][j] = 3
                            else:
                                pass

                elif input_key == 's' or input_key == 'S':    # 向下移动
                    # 如果数组为人且下边不为墙 那么俩种情况
                    if Interface[i][j] == 5 and Interface[i+1][j] != 0:
                        if Interface[i+1][j] != 1 and Interface[i+1][j] != 3:  #下边不为 箱子,到达目的地
                            Interface[i+1][j] = 5
                            Interface[i][j] = 2
                            break_flag = True

                        else:   # 下边为箱子或目的地到达
                            if Interface[i+2][j] != 0 : # 箱子下边不是墙
                                if Interface[i+2][j] != 4:  # 箱子下边不是目的地
                                    Interface[i][j] =  2
                                    Interface[i+1][j] = 5
                                    Interface[i+2][j] = 1
                                    break_flag = True
                                else:            # 箱子到达目的地
                                    Interface[i][j] =  2
                                    Interface[i+1][j] = 5
                                    Interface[i+2][j] = 3
                                    break_flag = True

                            else:
                                pass
                    if break_flag == True:  # 跳出第二层循环,否则会一直向下走 向上不会出现这种情况,因为for自上而下
                        break
                else:
                    print('您的输入有误,请重新输入')
                    break_flag = True
                    break
            if break_flag == True:  # 跳出第二层循环,否则会一直向下走 向上不会出现这种情况,因为for自上而下
                        break

        for i in range(len(target)):
            for j in range(1):
                # 如果不是到达目的地的情况和人在目的地的情况   目的地还是为'★'
                if Interface[target[i][j]][target[i][j+1]] != 3 and Interface[target[i][j]][target[i][j+1]] != 5:
                    Interface[target[i][j]][target[i][j+1]] = 4
                    
        show(Interface)
        count = judge(Interface)
        
        if count == len(target):
            print('恭喜您,通关了')
            break

# 判断是否通关
def judge(Interface):
    count = 0 # 计数 如果都到达目的地 退出循环
    for i in range(len(Interface)):
        for j in range(len(Interface[i])):
            if Interface[i][j] == 3:
                count += 1
    return count

def main():
    show(Interface)
    get_input(Interface)

if __name__ == '__main__':
    main()

四、碰到的问题

一开始主要没考虑到人离开目的地会变空白,后面加了一个target数组判断,
二是运行完要break出双层循环,不然向只要右边空白他就会向右走,还有向下(for从左到右,上到下)。小白第一次写文章,难免有所疏忽,有问题还请赐教

五、扩展与反思

一个数组可以扩展多个,通关之后可以继续下一关卡或者退出,还可以监听键盘直接获取按键值。

©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页