BasicGames Python 源码解析 02 Amazing

简介: BasicGames Python 源码解析 02 Amazing

这个游戏会接收用户输入的长和宽,动态生成一个迷宫

改进自 Frank Palazzolo 的版本。



导入

import random
import os
from time import sleep



常量

# 定义移动方向常量
GO_LEFT, GO_UP, GO_RIGHT, GO_DOWN = [0, 1, 2, 3]
# 定义连通方向常量
CONN_DOWN = 1
CONN_RIGHT = 2



get_width_length()

# 从用户输入获取迷宫的长和宽
def get_width_length():
    while True:
        try:
            width, length = input('What are your width and length?').split(',')
            width = int(width)
            length = int(length)
            if width != 1 and length != 1:
                return (width, length)
            print('Meaningless dimensions. Try again.')
        except ValueError:
            print('Meaningless dimensions. Try again.')



get_possible_dirs()

# 返回从一个格子的可移动方向
def get_possible_dirs(row, col, width, length, used):
    possible_dirs = [GO_LEFT,GO_UP,GO_RIGHT,GO_DOWN]
    # 如果不是最左边,并且左面一格没有访问
    # 那左边就是可以访问的,以此类推
    if col==0 or used[row][col-1]!=0:
        possible_dirs.remove(GO_LEFT)
    if row==0 or used[row-1][col]!=0:
        possible_dirs.remove(GO_UP)
    if col==width-1 or used[row][col+1]!=0: 
        possible_dirs.remove(GO_RIGHT)
    if row==length-1 or used[row+1][col]!=0:
        possible_dirs.remove(GO_DOWN)   
    return possible_dirs



get_next_used()

# 获取某个位置的下一个已访问格子
def get_next_used(row, col, used):
    length, width  = len(used), len(used[0])
    while True:
        if col != width - 1:
            col += 1
        elif row != length - 1:
            row, col = row + 1, 0
        else:
            row, col = 0, 0
        if used[row][col] != 0:
            break
    return row, col


print_maze()

# 打印迷宫
def print_maze(walls, used, enter_col):
    # 每次打印之前先清屏
    os.system('cls')
    length, width = len(walls), len(walls[0])
    # 打印最上方的墙壁
    for col in range(width):
        # 如果是入口,就把它打开
        if col==enter_col:
            print('*  ',end='')
        else:
            print('*--',end='')
    print('*')
    for row in range(length):
        # 打印格子
        print('|',end='')
        for col in range(width):
            # 区分已访问和未访问
            cell_ch = '  ' if used[row][col] != 0 else '><'
            # 区分格子右边是否有墙壁
            if walls[row][col] | CONN_RIGHT == walls[row][col]:
                print(cell_ch + ' ',end='')
            else:
                print(cell_ch + '|',end='')
        print()
        # 打印格子下方的墙壁
        for col in range(width):
            # 区分格子下方是否有墙壁
            if walls[row][col] | CONN_DOWN == walls[row][col]:
                print('*  ',end='')
            else:
                print('*--',end='')
        print('*')
    # 短暂停留避免一闪而过
    sleep(0.1)



main()

# 程序的主要逻辑
def main():
    print(' '*28+'AMAZING PROGRAM')
    print(' '*15+'CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY')
    print()
    print()
    print()
    # 获取用户输入的长和宽
    width, length = get_width_length()
    # used 数组保存格子是否访问过
    # 0 表示未访问,其它数字表示该格子是第几个访问的
    used = [[0]*width for _ in range(length)]
    # wall 保存右边和下边是不是连通的
    # 0:不连通,1:下侧连通,2:右侧连通,3:右侧和下侧连通
    walls = [[0]*width for _ in range(length)]
    # 随机选取入口
    enter_col=random.randint(0,width-1)
    # 将起始位置定义为入口
    row,col=0,enter_col
    # 定义已访问格子数量
    count=1
    # 设置入口已访问
    used[row][col]=count
    # 每次格式发生变化都会打印迷宫,下同
    print_maze(walls, used, enter_col)
    # 在所有格子都已访问之前执行循环
    while count!=width*length:
        # 获取当然位置的可移动方向
        possible_dirs = get_possible_dirs(row, col, width, length, used)
        if len(possible_dirs)!=0:
            # 如果可以移动,那么随机选一个方向来移动
            # 并且把墙拆掉
            direction=random.choice(possible_dirs) 
            if direction==GO_LEFT:
                col=col-1
                walls[row][col] |= CONN_RIGHT
            elif direction==GO_UP:
                row=row-1 
                walls[row][col] |= CONN_DOWN
            elif direction==GO_RIGHT:
                walls[row][col] |= CONN_RIGHT    
                col=col+1
            elif direction==GO_DOWN:
                walls[row][col] |= CONN_DOWN
                row=row+1
            # 更新计数,设置已访问
            count=count+1
            used[row][col]=count
            print_maze(walls, used, enter_col)
        else:
            # 否则,选取下一个已访问的格子重复这个步骤
            # 因为外面已经检查了是否可移动,
            # 这里只检查已访问就可以了
            row, col = get_next_used(row, col, used)
    # 最后,随机选择出口
    col=random.randint(0,width-1)
    row=length-1
    walls[row][col]=walls[row][col]+1
    print_maze(walls, used, enter_col)
if __name__ == '__main__': main()
相关文章
|
2天前
|
Linux API Python
【python】如何通过python来发邮件,各种发邮件方式详细解析
【python】如何通过python来发邮件,各种发邮件方式详细解析
|
2天前
|
缓存 Java 开发者
10个点介绍SpringBoot3工作流程与核心组件源码解析
Spring Boot 是Java开发中100%会使用到的框架,开发者不仅要熟练使用,对其中的核心源码也要了解,正所谓知其然知其所以然,V 哥建议小伙伴们在学习的过程中,一定要去研读一下源码,这有助于你在开发中游刃有余。欢迎一起交流学习心得,一起成长。
|
3天前
|
Python
使用Python解析网页和正则表达式
使用Python解析网页涉及`requests`和`re`模块。首先导入这两个模块,然后用`requests.get()`发送HTTP请求获取URL内容。通过`.text`属性得到HTML文本。接着,利用正则表达式和`re.search()`匹配特定模式(如网页标题),并用`.group(1)`获取匹配数据。最后,对提取的信息进行处理,如打印标题。实际操作时,需根据需求调整正则表达式。
12 2
|
3天前
|
并行计算 数据处理 开发者
Python并发编程:解析异步IO与多线程
本文探讨了Python中的并发编程技术,着重比较了异步IO和多线程两种常见的并发模型。通过详细分析它们的特点、优劣势以及适用场景,帮助读者更好地理解并选择适合自己项目需求的并发编程方式。
|
4天前
|
安全 网络协议 Java
Netty核心NioEventLoop源码解析(下)
Netty核心NioEventLoop源码解析(下)
15 0
|
Linux C语言 开发者
源码安装Python学会有用还能装逼 | 解决各种坑
相信朋友们都看过这个零基础学习Python的开篇了
376 0
源码安装Python学会有用还能装逼 | 解决各种坑
|
7天前
|
存储 人工智能 数据处理
Python:编程的艺术与科学的完美交融
Python:编程的艺术与科学的完美交融
12 1
|
2天前
|
测试技术 调度 索引
python编程中常见的问题
【4月更文挑战第23天】
11 2

推荐镜像

更多