前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >BasicGames Python 源码解析 02 Amazing

BasicGames Python 源码解析 02 Amazing

作者头像
ApacheCN_飞龙
发布2022-04-02 08:59:36
2940
发布2022-04-02 08:59:36
举报
文章被收录于专栏:信数据得永生

阅读更多:apachecn/python-code-anal

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

改进自 Frank Palazzolo 的版本。

导入

代码语言:javascript
复制
import random
import os
from time import sleep

常量

代码语言:javascript
复制
# 定义移动方向常量
GO_LEFT, GO_UP, GO_RIGHT, GO_DOWN = [0, 1, 2, 3]
# 定义连通方向常量
CONN_DOWN = 1
CONN_RIGHT = 2

get_width_length()

代码语言:javascript
复制
# 从用户输入获取迷宫的长和宽
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()

代码语言:javascript
复制
# 返回从一个格子的可移动方向
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()

代码语言:javascript
复制
# 获取某个位置的下一个已访问格子
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()

代码语言:javascript
复制
# 打印迷宫
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()

代码语言:javascript
复制
# 程序的主要逻辑
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()
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 导入
  • 常量
  • get_width_length()
  • get_possible_dirs()
  • get_next_used()
  • print_maze()
  • main()
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档