“顺手牵羊”:用Python制作小游戏的简单实践

(试玩链接:https://onlinegdb.com/5kZgTJgM1


一、玩法介绍

  • 有一块9*9的草地,上面有一只随机跑动的羊,每次朝上下左右中的一个随机方向跑动一格
  • 玩家需要扮演一位猎人抓住羊,每次可朝上下左右中的一个方向移动1到3格
  • (查百度汉语,“顺手”通常指右手,因此猎人需要出现在羊的左边才能抓到羊)

二、程序设计

1.介绍游戏规则,并开始游戏

# 介绍游戏规则
print('''欢迎试玩Python小游戏"顺手牵羊"(v.beta)!
在游戏中,你将扮演一位猎人捕捉草地上的一只羊,
·规则很简单,移动"我"到达"羊"的左边,即可成功抓住淘气的小羊!
·移动时,你可以从"上下左右"中选择一个方向,在1~3中选择一个速度,
 ·比如"向左移动2格"可表示为"左2"。''')

start_game = str(input("\r有兴趣玩这个游戏吗?(输入start开始)"))
if start_game == "start":
    start = True # while循环的标志
else:
    print("不好玩吗?感谢反馈。")
    exit(0)
  • 2-6行,使用print()输出多行字符串,介绍游戏规则和玩法
  • 第8行,使用input()询问玩家是否准备就绪
  • 9-10行,如果玩家就绪,定义start的值为True,为主循环做准备
  • 11-13行,否则使用exit(0)告诉程序直接停止运行

2.绘制地图,初始化猎人和羊的位置

#准备地图,初始化猎人和羊的位置
game_map = [["口","口","口","口","口","口","口","口","口"],
            ["口","口","口","口","口","口","口","口","口"],
            ["口","口","口","口","口","口","口","口","口"],
            ["口","口","口","口","口","口","口","口","口"],
            ["口","口","口","口","口","口","口","口","口"],
            ["口","口","口","口","口","口","口","口","口"],
            ["口","口","口","口","口","口","口","口","口"],
            ["口","口","口","口","口","口","口","口","口"],
            ["口","口","口","口","口","口","口","口","口"],]
import math
import random
n = 0
hunter = {"x":4,"y":4}
sheep = {}
sheep["x"] = random.randint(0,8)
sheep["y"] = random.randint(0,8)
# 防止猎人和羊的初始位置相同
while sheep["x"] == 4 and sheep["y"] == 4:
    sheep["x"] = random.randint(0,8)
    sheep["y"] = random.randint(0,8)
game_map[sheep["x"]][sheep["y"]] = "羊"
game_map[4][4] = "我"
  • 2-10行,使用一个二维列表模拟地图,分别用“口”、“羊”和“我”代表空地、羊和猎人
  • 11-12行,导入math和random模块,用于计算距离(需要开根号)和随机改变羊的位置
  • 第13行,n为计数器,在后面游戏主循环中负责记录玩家的步数,用以计算总分
  • 14-15行,定义两个字典hunter和sheep,用于记录各自的位置等信息
  • 第14行,猎人的初始位置固定在第五行第五列,即索引为4,4的点
  • 16-17行,随机生成羊的位置
  • 22-23行,替换地图中的"口",显示羊和猎人的位置

3.定义函数

① 绘制地图

def print_map():
    """绘制地图"""
    print("地图如下:")
    for x in game_map:
        pos_y = 0
        for y in x:
            pos_y += 1
            if pos_y == 9:
                print(y)
            else:
                print(y,end="")
  • 第4行,遍历game_map列表中的元素,得到地图中每一行的列表x
  • 第5行,pos_y用于记录列表x中每个元素y的值,即这个元素在第几列,初始值为0
  • 第6行,遍历列表x中的每一个元素y,得到地图中的每一个字符,相当于一个格子
  • 8-9行,如果遍历到第九列元素(此时pos_y的值是8,因为初始值是0),即最右侧的一列,则正常输出y的内容,输出后默认换行
  • 10-11行,如果遍历到的元素是前面几列,通过指定输出时以空字符""结尾来防止输出后换行,也就是说能保证地图中每一行的内容都输出在同一行里
  • 运行结果如下:
口口口口口口口口口
口口口口口口口口口
口口口口口羊口口口
口口口口口口口口口
口口口口我口口口口
口口口口口口口口口
口口口口口口口口口
口口口口口口口口口
口口口口口口口口口

② 移动羊

def move_sheep():
    """移动羊"""
    direction = random.randint(1,4)
    game_map[sheep["x"]][sheep["y"]] = "口"
    if direction == 1:
        direction = "左边"
        sheep["y2"] = sheep["y"] - 1
        sheep["x2"] = sheep["x"]
    if direction == 2:
        direction = "右边"
        sheep["y2"] = sheep["y"] + 1
        sheep["x2"] = sheep["x"]
    if direction == 3:
        direction = "上面"
        sheep["y2"] = sheep["y"]
        sheep["x2"] = sheep["x"] - 1
    if direction == 4:
        direction = "下面"
        sheep["y2"] = sheep["y"]
        sheep["x2"] = sheep["x"] + 1
    sheep["direction"] = direction
  • 第3行,随机生成1~4中的一个数,用于确定移动的方向
  • 第4行,由于羊的位置发生变化,以前的位置变成空地("口")
  • 5-20行,判断移动方向并确定新的位置,这里之所以用了新键"x2"和"y2",是因为原有的键"x"和"y"储存的值(移动前的的位置)要用于在下一个函数sheep_position_judge()中与"x2"和"y2"(移动后的位置)相比较,所以不能直接把新的位置赋给键"x"和"y"
  • 第21行,添加新键"direction",用于存储移动方向,便于在下一个函数sheep_position_judg()中使用

③ 检查羊的位置

def sheep_position_judge():
    """检查羊的位置是否正确"""
    # 防止羊跑出地图
    while sheep["x2"] == hunter["x"] and sheep["y2"] == hunter["y"]:
        move_sheep()
    if sheep["x"] == 8 and sheep["direction"] == "下面":
        sheep["x2"] = 0
    if sheep["y"] == 8 and sheep["direction"] == "右边":
        sheep["y2"] = 0
    # 检查完毕,更新羊的位置
    sheep["x"] = sheep["x2"]
    sheep["y"] = sheep["y2"]
    game_map[sheep["x2"]][sheep["y2"]] = "羊"
    print("羊向%s处移动一格,坐标为(%s,%s)。" %(sheep["direction"],sheep["y"]+1,sheep["x"]+1))
  • 4-5行,当羊和猎人紧邻时,可能移动的新位置和猎人的位置相同,因此要用while进行排除
  • 6-9行,当羊在左边界和上边界时,如果继续向上或者向左移动,得到的列表索引为-1,即会出现在右边界或下边界,这种情况不用管;但是如果羊在右边界和下边界的时候继续向右或者向下移动,得到的列表索引为9,显然会跑出地图,所以这里用if语句判断了一下,如果跑出地图就把相应的索引改成0,使其出现在相应的左边界或者上边界
  • 11-12行,检查结束,表明羊的位置现在是符合游戏要求的,可以赋给键x和y来更新羊的位置
  • 第13行,将地图中相应位置从空地"口"改成"羊"
  • 第14行,输出相关信息告知玩家羊移动的方向和移动后的坐标

④ 移动猎人

def move_hunter():
    """移动猎人"""
    next_step = str(input("\n下一步怎么走?"))
    next_step_list = list(next_step)
    direction = next_step_list[0]
    speed = int(next_step_list[1])
    if direction == "左":
        hunter["x2"] = hunter["x"]
        hunter["y2"] = hunter["y"] - speed
    if direction == "右":
        hunter["x2"] = hunter["x"]
        hunter["y2"] = hunter["y"] + speed
    if direction == "上":
        hunter["x2"] = hunter["x"] - speed
        hunter["y2"] = hunter["y"]
    if direction == "下":
        hunter["x2"] = hunter["x"] + speed
        hunter["y2"] = hunter["y"]
    hunter["speed"] = speed
    game_map[hunter["x"]][hunter["y"]] = "口"   
  • 第3行,使用input()函数询问玩家移动的方向和格数,此时对输入信息有严格的格式要求,为“方向+速度”,如,“左2”
  • 4-6行,把玩家输入的信息转换成字符串列表,其中第一、二个元素即为猎人移动的方向和速度
  • 7-18行,结构与函数move_sheep(l相似,此处不做赘述
  • 第19行,添加新键"speed",记录猎人的速度以供下面的函数进行检查
  • 第20行,因为猎人离开之前的位置,索引为hunter["x"]][hunter["y"]的元素变成空地"口"

⑤ 检查猎人的位置

def hunter_position_judge():
    """检查猎人的位置是否正确"""
    # 检查速度
    while hunter["speed"] < 0:
        print("还带挂倒档的?不可以这么走!")
        move_hunter()
    while hunter["speed"] == 0:
        print("一动不动是王八?不可以这么走!")
        move_hunter()
    while hunter["speed"] > 3:
        print("超速是要罚款的!不可以这么走!")
        move_hunter()
    # 检查位置
    while hunter["x2"] == sheep["x"] and hunter["y2"] == sheep["y"]:
        print("你踩到羊了!不可以这么走!")
        move_hunter()
    while hunter["x2"] < 0 or hunter["x2"] > 8:
        print("你出图啦!不可以这么走!")
        move_hunter()
    while hunter["y2"] < 0 or hunter["y2"] > 8:
        print("你出图啦!不可以这么走!")
        move_hunter()
        # 检查完毕,更新猎人的位置
    hunter["x"] = hunter["x2"]
    hunter["y"] = hunter["y2"]
    game_map[hunter["x2"]][hunter["y2"]] = "我"
  • 4-12行,检查猎人的速度
  • 14-22行,分别检查猎人移动的新位置和羊的位是否置重合或猎人是否跑出地图
  • 24-26行的作用和检查羊的位置的函数里面最后几行相同,此处不做赘述

4.游戏主循环

# 游戏循环部分
# 开场
print_map()
distance = math.sqrt((sheep["x"]-4)**2 + (sheep["y"]-4)**2)
print("羊在(%s,%s)处,距离你%.2f格" %(sheep["y"]+1,sheep["x"]+1,distance))
# 循环
while start:
    move_hunter()
    n += 1
    hunter_position_judge()
    if game_map[sheep["x"]][sheep["y"]-1] == "我":
        start = False
        print_map()
        print('成功“顺手牵羊”!得分:%s' %(100 - n))
    else:
        move_sheep()
        sheep_position_judge()
        print_map()
  • 3-5行,输出地图并计算羊与猎人的距离(勾股定理),输出初始消息给玩家
  • 第七行以下是游戏的循环部分,每次都移动猎人并检查位置,如果不符合获胜条件就继续移动羊的位置并进行检查,然后一直如此循环,直到游戏获胜

三、总结

整个程序的代码如下:

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

# 介绍游戏规则
print('''欢迎试玩Python小游戏"顺手牵羊"(v.beta)!
在游戏中,你将扮演一位猎人捕捉草地上的一只羊,
·规则很简单,移动"我"到达"羊"的左边,即可成功抓住淘气的小羊!
·移动时,你可以从"上下左右"中选择一个方向,在1~3中选择一个速度,
 ·比如"向左移动2格"可表示为"左2"。''')

start_game = str(input("\r有兴趣玩这个游戏吗?(输入start开始)"))
if start_game == "start":
    start = True # while循环的标志
else:
    print("不好玩吗?感谢反馈。")
    exit(0)

#准备地图,初始化猎人和羊的位置
game_map = [["口","口","口","口","口","口","口","口","口"],
            ["口","口","口","口","口","口","口","口","口"],
            ["口","口","口","口","口","口","口","口","口"],
            ["口","口","口","口","口","口","口","口","口"],
            ["口","口","口","口","口","口","口","口","口"],
            ["口","口","口","口","口","口","口","口","口"],
            ["口","口","口","口","口","口","口","口","口"],
            ["口","口","口","口","口","口","口","口","口"],
            ["口","口","口","口","口","口","口","口","口"],]
import math
import random
n = 0
hunter = {"x":4,"y":4}
sheep = {}
sheep["x"] = random.randint(0,8)
sheep["y"] = random.randint(0,8)
# 防止猎人和羊的初始位置相同
while sheep["x"] == 4 and sheep["y"] == 4:
    sheep["x"] = random.randint(0,8)
    sheep["y"] = random.randint(0,8)
game_map[sheep["x"]][sheep["y"]] = "羊"
game_map[4][4] = "我"

#函数部分
def print_map():
    """绘制地图"""
    print("地图如下:")
    for x in game_map:
        pos_y = 0
        for y in x:
            pos_y += 1
            if pos_y == 9:
                print(y)
            else:
                print(y,end="")

def move_sheep():
    """移动羊"""
    direction = random.randint(1,4)
    game_map[sheep["x"]][sheep["y"]] = "口"
    if direction == 1:
        direction = "左边"
        sheep["y2"] = sheep["y"] - 1
        sheep["x2"] = sheep["x"]
    if direction == 2:
        direction = "右边"
        sheep["y2"] = sheep["y"] + 1
        sheep["x2"] = sheep["x"]
    if direction == 3:
        direction = "上面"
        sheep["y2"] = sheep["y"]
        sheep["x2"] = sheep["x"] - 1
    if direction == 4:
        direction = "下面"
        sheep["y2"] = sheep["y"]
        sheep["x2"] = sheep["x"] + 1
    sheep["direction"] = direction

def sheep_position_judge():
    """检查羊的位置是否正确"""
    # 防止羊跑出地图
    while sheep["x2"] == hunter["x"] and sheep["y2"] == hunter["y"]:
        move_sheep()
    if sheep["x"] == 8 and sheep["direction"] == "下面":
        sheep["x2"] = 0
    if sheep["y"] == 8 and sheep["direction"] == "右边":
        sheep["y2"] = 0
    # 检查完毕,更新羊的位置
    sheep["x"] = sheep["x2"]
    sheep["y"] = sheep["y2"]
    game_map[sheep["x2"]][sheep["y2"]] = "羊"
    print("羊向%s处移动一格,坐标为(%s,%s)。" %(sheep["direction"],sheep["y"]+1,sheep["x"]+1))

def move_hunter():
    """移动猎人"""
    next_step = str(input("\n下一步怎么走?"))
    next_step_list = list(next_step)
    direction = next_step_list[0]
    speed = int(next_step_list[1])
    if direction == "左":
        hunter["x2"] = hunter["x"]
        hunter["y2"] = hunter["y"] - speed
    if direction == "右":
        hunter["x2"] = hunter["x"]
        hunter["y2"] = hunter["y"] + speed
    if direction == "上":
        hunter["x2"] = hunter["x"] - speed
        hunter["y2"] = hunter["y"]
    if direction == "下":
        hunter["x2"] = hunter["x"] + speed
        hunter["y2"] = hunter["y"]
    hunter["speed"] = speed
    game_map[hunter["x"]][hunter["y"]] = "口"   
    
def hunter_position_judge():
    """检查猎人的位置是否正确"""
    # 检查速度
    while hunter["speed"] < 0:
        print("还带挂倒档的?不可以这么走!")
        move_hunter()
    while hunter["speed"] == 0:
        print("一动不动是王八?不可以这么走!")
        move_hunter()
    while hunter["speed"] > 3:
        print("超速是要罚款的!不可以这么走!")
        move_hunter()
    # 检查位置
    while hunter["x2"] == sheep["x"] and hunter["y2"] == sheep["y"]:
        print("你踩到羊了!不可以这么走!")
        move_hunter()
    while hunter["x2"] < 0 or hunter["x2"] > 8:
        print("你出图啦!不可以这么走!")
        move_hunter()
    while hunter["y2"] < 0 or hunter["y2"] > 8:
        print("你出图啦!不可以这么走!")
        move_hunter()
        # 检查完毕,更新猎人的位置
    hunter["x"] = hunter["x2"]
    hunter["y"] = hunter["y2"]
    game_map[hunter["x2"]][hunter["y2"]] = "我"


# 游戏循环部分
# 开场
print_map()
distance = math.sqrt((sheep["x"]-4)**2 + (sheep["y"]-4)**2)
print("羊在(%s,%s)处,距离你%.2f格" %(sheep["y"]+1,sheep["x"]+1,distance))
# 循环
while start:
    move_hunter()
    n += 1
    hunter_position_judge()
    if game_map[sheep["x"]][sheep["y"]-1] == "我":
        start = False
        print_map()
        print('成功“顺手牵羊”!得分:%s' %(100 - n))
    else:
        move_sheep()
        sheep_position_judge()
        print_map()

尝试运行了一次,结果如下:

欢迎试玩Python小游戏"顺手牵羊"(v.beta)!
在游戏中,你将扮演一位猎人捕捉草地上的一只羊,
·规则很简单,移动"我"到达"羊"的左边,即可成功抓住淘气的小羊!
·移动时,你可以从"上下左右"中选择一个方向,在1~3中选择一个速度,
 ·比如"向左移动2格"可表示为"左2"。

有兴趣玩这个游戏吗?(输入start开始)start
地图如下:
口口口口口口口口口
口口口口口口口口口
口口口口口口口口口
口口口口口口口口口
口口口口我口口口口
口口口口口口口口口
口口口口口口羊口口
口口口口口口口口口
口口口口口口口口口
羊在(7,7)处,距离你2.83格

下一步怎么走?下2
羊向右边处移动一格,坐标为(8,7)。
地图如下:
口口口口口口口口口
口口口口口口口口口
口口口口口口口口口
口口口口口口口口口
口口口口口口口口口
口口口口口口口口口
口口口口我口口羊口
口口口口口口口口口
口口口口口口口口口

下一步怎么走?右2
地图如下:
口口口口口口口口口
口口口口口口口口口
口口口口口口口口口
口口口口口口口口口
口口口口口口口口口
口口口口口口口口口
口口口口口口我羊口
口口口口口口口口口
口口口口口口口口口
成功“顺手牵羊”!得分:98

四、结束语

感谢每一个坚持看到这里的小伙伴!

把自己的思路说出来并让人明白并不容易,而我也正在努力做到这一点。

本人正在读高二,用来学python的时间不多,难免有错误和偏颇之处,还请各位多多包涵,不吝指教。

如果觉得这篇文章有用的话,请点一个小小的赞吧~

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值