取火柴小游戏python turtle库

本文介绍了一个利用python turtle库制作的取火柴小游戏。玩家与电脑交替取火柴,谁使得剩下的火柴数为1或0就输掉游戏。游戏通过图形界面展示,增强视觉效果。代码讲解包括初始化画布、绘制火柴、主程序逻辑以及奖励环节的设定。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录

一、代码展示

二、代码讲解

1.海龟画布初始化和检测用户输入

2.绘制火柴的函数draw_line()

3.主程序

4.奖励环节。


游戏介绍

这是一场电脑和人类的博弈。游戏规则是:一共有21个火柴(默认),人类选手先开始取火柴,一次可以取1-3根火柴。接下来就是电脑取。谁取完火柴后,总火柴数只剩下1或0,那位选手就输掉了游戏,而赢家会有奖励。这款小游戏的游戏页面不限于枯燥无味的python黑色文本页面,拓展使用了turtle库进行图形展示,让这款游戏的可视性更强。

f5720079c9eb4c486e2d8118eba1842e.png

488d229f63b2f107a7483d1f33a85bae.png

海龟画布已经擦掉4根火柴的效果

 

一、代码展示

from turtle import*
import time
import random

speed(0)
sticks = int(numinput("enter number of sticks: ", "21"))

while sticks < 15 or sticks > 30:  # 检测火柴总数是否符合规范
    print("invalid, have to be 15-30")
    sticks = int(numinput("enter number of sticks: ", "21"))

#海龟画布的一些初始化设置
w, h = [1000, 500]
setup(w, h)
dis = 50  # 屏幕边缘离火柴的距离
step = (w-dis*2)/(sticks-1)  # 火柴之间间隔
cnt = 0  # 记录取走火柴的累加情况
coor_x=[(-w/2+dis)+i*step for i in range(sticks)]  # 每个火柴开始画的x坐标
coor_y = (-h+dis)/2
colors, white = [["red", "darkblue", "orange", "darkgreen",
                  "darkgoldenrod", "black", "purple"], ["white"]]  # 序列解包


def draw_line(nums, colors):  # 绘制火柴的函数,nums是要绘制的火柴数量
    setheading(90)  # 火柴垂直于屏幕
    pensize(3)
    nums = min(nums, len(coor_x))  # 取较小值,避免
    for i in range(0, nums):
        pu()  # 抬笔
        pencolor(colors[i % len(colors)])
        goto(coor_x[i], coor_y)
        pd()  # 落笔
        fd(h-dis*2)


is_win=False
draw_line(sticks, colors)  # 绘制总火柴数
gift = ["薯片", "谢谢参与", "饮料", "王者皮肤"]

with open("input.txt", "r") as file:
    txt = file.read()
print(txt.format(sticks), "\n")  # 打印一段存储在txt文件中的游戏介绍

while sticks >= 2:  # 主程序
    num = int(input("enter sticks to take:"))
    if num > 3 or num < 1:
        print("take 1-3 sticks once!")
        continue

    # 人机互战的代码
    cnt = cnt+num  # 累计拿去的火柴
    draw_line(cnt, white)  # 在海龟屏幕里抹去拿掉的火柴
    sticks = sticks-num  # 剩余的火柴
    if sticks <= 1:  # 人类选手输的情况
        print("you lost! you can try again")
        is_win=False
        break

    else:  # 若人类未输,电脑取火柴
        print("there are {}sticks left".format(sticks))
        ro = random.randint(1, 3)
        sticks = sticks-ro
        time.sleep(1)
        print(f"i am going to take away... {ro} sticks\n")
        cnt = cnt+ro
        draw_line(cnt, white)  # 用白线条覆盖原来的彩色线条,实现擦除效果

if is_win:
    time.sleep(1)  # 人类选手赢的情况
    print("oh no, i lose!", "\n")
    time.sleep(1)
    done()  # 关闭海龟画布页面
    print("great, you beat the computer...you are worth being rewarded! ",
          "\nyou get:", gift[random.randint(0, len(gift)-1)])

txt文本文档内容如下:

a competition between human and AI is taking place...
remember, the rule is: whoever left the last stick or no sticks lost the game.
game begins! there are {} sticks in total
you can only take 1-3sticks once, good luck! 

e87e67c2d3608693d43b285f0a6d383d.png

txt文本文档的写入

二、代码讲解

这个代码看起来好像很长,其实他就是由很多个简单的小部分衔接在一起的组成的,我们来介绍这几个部分:1.海龟画布初始化和检测用户输入 2.海龟画五彩火柴部分 3.主程序:人类输入和机器人输入 4.奖励环节

1.海龟画布初始化和检测用户输入

首先第一行我们写from turtle import* 而不是直接import turtle,主要是因为使用前者可以直接使用海龟库内一定义项目名称,而且使用的是函数的绝对路径,不需要确定引用,所以就比较方便。注意到这里没有写turtle.xxx,直接写xxx就是这个原因。

变量sticks是用户输入的总火柴数,默认是21,我们这里使用while条件循环检测sticks是否太大或太小。然后就是序列解包,把1000,500分别赋值给宽w和高h,然后setup(w,h)设置海龟屏幕大小。

dis是火柴离屏幕边缘的距离。step是火柴之间的间隔,等于火柴排序总长/间隔数量。但我们没有间隔数量,所以我们想用火柴数量代替。火柴数量=间隔数量+1,稍微变换一下,我们得到step=火柴总长/(火柴数量-1)。另外火柴排序总长就是屏幕宽w减火柴离两边屏幕边缘的距离dis*2。所以就有了step=(w-dis*2)/(sticks-1)。

2.绘制火柴的函数draw_line()

怎么绘制火柴呢?其实和之前我做的绘制坐标轴刻度很像:火柴垂直于x轴,之间有固定的间隔,且都是靠x坐标轴的自增来实现绘制的。其中nums是循环次数,代码每循环一次,就画一根火柴。大家可能有些不太理解 nums=min(nums,len(coor_x))是要干什么。他其实就是一行规避程序报错的代码(处理边界问题)。因为有时候如果只剩下2根火柴,而此时又到了电脑,他有随机生成3的概率,这样剩下的火柴数就可能会变成-1,而cnt (记录取走火柴的累加情况)就会超过coor_x索引。因此我们要把cnt控制在len(coor_x),也就是列表长度内。至于为什么cnt会有这个影响,等我们看到主程序部分大家也许就会更清楚了。

剩下的代码都不难,就是反复执行抬笔,找到火柴的x,y坐标和落笔画火柴的代码。

3.主程序

主程序分为人类输入和电脑输入。我们想实现的功能是:人类或电脑输入一个数后,火柴剩余数量减去这个数,并显示出剩余sticks,同时海龟屏幕中抹去取走的火柴。对于实现让终端显示剩下火柴数这个功能,我们很容易就想到,就是让sticks每次在num和ro输入后自减num和ro,并在终端显示自减后的sticks。对于实现让海龟屏幕抹去取走的火柴的功能也不难,用draw_line()绘制白色线条来覆盖原来的彩色线条就好了嘛!我们这里要稍微注意,对于绘制白色线条的位置,我们要用累加位置,因为draw_line()中开始抹的火柴位置永远是第一个火柴的摆放位置。所以如果我们用num或ro的数量当draw_line()的循环数量nums,画笔永远会在前三个火柴的位置重复画白线。

4.奖励环节。

奖励环节就简单了,他在循环之外。因为如果人类输了,os._exit()就会停止执行程序内的所有代码,所以只有人类赢了才有机会到循环外面来获得奖励。存储礼物的列表的索引是 random.randint(0,len(gift)-1),即随机索引(范围是从0到该列表的最大索引)。

f70f654ba5daf1490ac681dc4aefa2d6.png

呵呵,我输了

 抱歉各位,本人智商有限,可能暂时演示不了奖励环节的代码了,留给大家自行探索

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值