python 基础系列篇:四、编写两个简单的小游戏(猜数字及2048)

这篇具有很好参考价值的文章主要介绍了python 基础系列篇:四、编写两个简单的小游戏(猜数字及2048)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

猜数字游戏

游戏规则:
产生一个随机的4位数,可能会有前置0,用户每输入一次4位数,记录次数加1,并返回猜测结果,位置正确数字正确的为一种,输出一个A,数字正确位置不正确的为另一种,输出一个B,限定12次(含)以内猜出数字为胜利,否则视为挑战失败。

游戏进程示例

挑战示例1:
请输入 4 位数字,可以前置 0 :0123
B
请输入 4 位数字,可以前置 0 :4567
AB
请输入 4 位数字,可以前置 0 :4689
BB
请输入 4 位数字,可以前置 0 :8967
B
请输入 4 位数字,可以前置 0 :3576
A
请输入 4 位数字,可以前置 0 :2589
AAB
请输入 4 位数字,可以前置 0 :2549
AABB
请输入 4 位数字,可以前置 0 :2594
AAAA
你用了 8 次才猜对哦。

挑战示例2:
请输入 4 位数字,可以前置 0 :0123
AA
请输入 4 位数字,可以前置 0 :0145
A
请输入 4 位数字,可以前置 0 :6127
AA
请输入 4 位数字,可以前置 0 :6183
AAA
请输入 4 位数字,可以前置 0 :6193
AAA
请输入 4 位数字,可以前置 0 :6113
AAA
请输入 4 位数字,可以前置 0 :6133
AAA
请输入 4 位数字,可以前置 0 :6163
AAAA
你用了 8 次才猜对哦。

相信小伙伴们看过描述,以及两个示例之后,应该明白游戏规则了吧?如果不明白游戏规则的小伙伴,请在评论区扣我哦。

好了,我们言归正传,开始分析一下,我们实现这个小游戏,需要做些什么工作。

需求分析并逐步实现

1、使用随机函数包 random

1、我们需要一个随机函数库,random 很适合你。

import random
s = '0123456789'
length = 4
num = ''.join([random.choice(s) for _ in range(length)])
print(num)
---
7431 # 第一次结果
6357 # 第二次结果
6421 # 第三次结果

很好,随机产生的数字完成了。通过 random.choice 随机从我们的 s 字符串里抽取一个数字的方式,并用 join 方式组成一个数字字符串。

2、记录用户输入

2、需要判断用户输入是否合法,如果不是四个数字,则不记录次数,否则记录

那么,我们需要定义一个变量,用来记录次数,还有一个变量,用来记录用户输入信息。并根据题意设置12次的时候跳出循环。

t = 0 # 计次
guess = ''
while guess != num:
	guess = input(f'请输入 {length} 位数字,可以前置 0 :')
    if len(guess) != length:
        continue
    if len(set(guess) - set(s)) > 0:
        continue
    t += 1
    if t == 12:
        break

3、提前做好的结果反馈

3、先实现结果反馈,如果猜中了,返回次数信息,未猜中,则反馈失败。

if guess == num:
    print('你用了 {} 次才猜对哦。'.format(t))
else:
    print('你已经使用完 12 次机会了,很遗憾你没能猜中。')

应该没有小伙伴觉得上边的代码难以理解吧,如果还是有小伙伴不理解,还是请在评论区扣我。

很好,我们现在开始进行数字正确与否的判定。先实现第一个判定 A。

4、判定A的实现

4、数字正确,位置正确的判定 A

我们把下边的代码插入到 t += 1 后边

    a,b = [],[] # 用来记录判定A及判定B的数据
    for i in range(length):
        if num[i] == guess[i]: # 如果数字和位置一致,则记录到判定A中
            a.append(i)

小伙伴们可以想一想,为什么我这里记录的是位置信息哦。

没错,这个位置的数字就不需要再进行判定了。所以我们在进行判定B的判断时,需要跳过这些位置的数字。

5、判定B的范围

5、进行判定B的判断,需要跳过判定A已记录的位置

    for i in range(length):
        if i not in a:
        	b += [] # 这里的判定B还没实现,小伙伴们先仔细想一想哦

在跳过判定A的位置后,我们剩余的位置的数字需要全部挑选出来,然后判断某个位置的数字是否存在于剩余数字中,如果存在,也记录这个数字的位置,注意,这里记录的是数字的位置,不是当前数字的位置哦,为什么呢?小伙伴们可以告诉我答案吗?

6、判定B的判定内容

6、判定B记录内容解析

假设数字为 1234,用户输入为0123。

那么第一次判定应该是 0 ,这个数字不存在于 1234 中。

第二次判断的数字是1,这个数字存在于1234中。记录到判定B的时候,我们需要把1这个数字所在的位置记录,即索引0,而不是用户输入的数字的索引1。

原因很简单,表示需要猜测的这个数字中索引1的位置已经被占用了。

那么,理解了这一点之后,后边的就简单了。把剩余的字符找出来,并同时记录剩余字符的索引位置。

            less = [v for v in range(length) if v not in a and v not in b] # 记录剩余数字的索引
            char = [num[v] for v in range(length) if v not in a and v not in b] # 记录剩余数字的内容

7、判定B的实现

7、最后实现判定B的记录

如果数字存在于剩余数字 char 中,我们要求出这个字符所在的索引,即对应于 less 中的数字,所以最后的代码也很简单。

            if guess[i] in char:
                b.append(less[char.index(guess[i])])

8、用户输入信息的反馈及完成

8、添加最终的反馈信息输出,完成游戏,并进行测试

最终完整代码已经拼接出来了,我们来看看完整代码是如何的吧:

import random
s = '0123456789'
length = 4
num = ''.join([random.choice(s) for _ in range(length)])
# print(num) 这里一定要注释掉或删除掉哦,否则就是作弊了呢
t = 0 # 计次
guess = ''
while guess != num:
    guess = input(f'请输入 {length} 位数字,可以前置 0 :')
    if len(guess) != length:
        continue
    if len(set(guess) - set(s)) > 0:
        continue
    t += 1
    a,b = [],[]
    for i in range(length):
        if num[i] == guess[i]:
            a.append(i)
    for i in range(length):
        if i not in a:
            less = [v for v in range(length) if v not in a and v not in b]
            char = [num[v] for v in range(length) if v not in a and v not in b]
            if guess[i] in char:
                b.append(less[char.index(guess[i])])
    print(len(a) * 'A' + len(b) * 'B') # 最终的反馈信息在这里哦,就一句话的事
    if t == 12:
        break
if guess == num:
    print('你用了 {} 次才猜对哦。'.format(t))
else:
    print('你已经使用完 12 次机会了,很遗憾你没能猜中。')

2048 游戏

相信大部分小伙伴应该都在手机上玩过这个游戏了,这次,我们也来自己实现一下 2048 游戏的内核。不过由于老顾还没开始学习 pygame,这次就用文字版代替了啊,游戏界面就在开发环境里,当然,你要是弄到命令行里也可以的。

游戏进程示例

截图如下
python 基础系列篇:四、编写两个简单的小游戏(猜数字及2048)
python 基础系列篇:四、编写两个简单的小游戏(猜数字及2048)

需求分析并逐步实现

1、使用随机函数包

我们知道,每次我们在移动数字以后,会随机出现一个1或者2的新数字,出现位置也是随机的,那么随机函数包还是需要引入的。

import random

2、使用二维列表

同样,我们也知道 2048 这个游戏,其实内容很少,就是一个 4 * 4 的矩形区域,然后数字在里面来回的倒腾。

row = 4
dp = [[0 for _ in range(row)] for _ in range(row)] # 初始化二维列表

3、定义每个数字显示的宽度

由于我们没有图形界面,所以,字符输出的时候,我们需要给每个数字定宽并右对齐。

wid = 7

4、使用变量记录当前分数

嗯,分数才是激励游戏进程的正反馈,没有分数的游戏是没有灵魂的。

score = 0

5、游戏初始,我们应该有一些数字

大部分游戏,初始就有一到三个数字已经在游戏中出现了,我们也来模拟实现

        for i in range(random.randint(1,3)):
            free = [(m,n) for m in range(row) for n in range(row) if dp[m][n] == 0]
            selected = random.choice(free)
            dp[selected[0]][selected[1]] = random.randint(1,2)
            score = sum([sum(r) for r in dp])

6、游戏界面呈现

前面做了这么多分析工作,结果我们还看不到自己做的东西,那就不太好了,我们来输出一下数据吧

    print('\n------------------------------')
    for r in dp:
        print('\n\n',''.join([str(n).rjust(wid) if n > 0 else '.'.rjust(wid) for n in r]))
    print('\n\nScore:',score)
    print('\n')

python 基础系列篇:四、编写两个简单的小游戏(猜数字及2048)
很好,有个初始进程了。

7、接收用户输入,非法的内容跳过从新输入

我们值需要定义四个方向,以及跳出游戏的按键就好,这里老顾用 asdw来表示方向 a 为左,d为右,w为上,s为下,q为退出游戏。

    inp = input('请选择方向(ASDW)Q退出:').strip().lower()
    if len(inp) != 1:
        continue
    if inp == 'q':
        break
    if inp not in 'asdw':
        continue

8、貌似我们少了个循环控制?

额。。。。直接写完输入后才发现,我们好像少了个循环,游戏又不是只按一次键就完成,所以来个死循环吧。

while True:
    if score == 0:
        for i in range(random.randint(1,3)):
            free = [(m,n) for m in range(row) for n in range(row) if dp[m][n] == 0]
            selected = random.choice(free)
            dp[selected[0]][selected[1]] = random.randint(1,2)
            score = sum([sum(r) for r in dp])
    print('\n------------------------------')
    for r in dp:
        print('\n\n',''.join([str(n).rjust(wid) if n > 0 else '.'.rjust(wid) for n in r]))
    print('\n\nScore:',score)
    print('\n')
    inp = input('请选择方向(ASDW)Q退出:').strip().lower()
    if len(inp) != 1:
        continue
    if inp == 'q':
        break
    if inp not in 'asdw':
        continue

9、如何判断数字合并呢?

我们都知道合并规则,在输入的方向上,所有该方向的行或者列,相同的数字合并成一个更大的数,一共四个方向,每个方向都需要能合并数字。

小思考:我们需要写几次合并规则?小伙伴们可以仔细想一想哦。

其实,只需要写一次合并判定就可以了,我们只写行合并,且只实现方向向左的合并规则。

实现方法也很简单,把行中的所有的零都剔除,剩余的数字就挨住了,然后循环判断相邻的两个数字是否相同,相同就合并,被合并的位置改成零,避免与更后边的数发生多次合并。

    for i in range(row):
        while dp[i].count(0) > 0:
            dp[i].pop(dp[i].index(0)) # 剔除 0
        for j in range(len(dp[i]) - 1):
            if dp[i][j] == dp[i][j + 1]:
                dp[i][j] *= 2 # 合并
                dp[i][j + 1] = 0 # 被合并的位置改成 0
        while dp[i].count(0) > 0: # 剔除合并后产生的 0
            dp[i].pop(dp[i].index(0))
        while len(dp[i]) < 4: # 每行用零补足四个
            dp[i].append(0)

合并判定已经写好了,小伙伴们有没有想到,老顾为什么说,合并判定只需要写一次呢?想到的小伙伴们,在评论区秀下自己!

10、使用矩阵旋转

使用矩阵旋转,不管我们选择什么方向,都将矩阵旋转成左合并的规则就可以了

小伙伴们,有没有答对!答对的小伙伴在评论区打call哦。

    if inp == 'w':
        dp[:] = [[dp[m][n] for m in range(row)] for n in range(row)][::-1] # 左旋转 90 度
    if inp == 's':
        dp[:] = [[dp[m][n] for m in range(row)][::-1] for n in range(row)] # 右旋转 90 度
    if inp == 'd':
        dp[:] = [[dp[n][m] for m in range(row)][::-1] for n in range(row)][::-1] # 旋转 180 度

嗯,这里出现了一个骚操作,推导式且不去管他,dp[:] 是个什么鬼?

这里不得不说元组的强大了,如果等号前边是一个多元素变量,等号后的数据有同等数量的结果,那么就可以这么操作了!

嗯嗯。。。别听老顾说大话,老顾只见过列表这么用。

再回到主题,我们通过旋转,可以都用左合并的方式实现合并判定了,在合并后,再旋转回来就好。

    if inp == 'w':
        dp[:] = [[dp[m][n] for m in range(row)][::-1] for n in range(row)]
    if inp == 's':
        dp[:] = [[dp[m][n] for m in range(row)] for n in range(row)][::-1]
    if inp == 'd':
        dp[:] = [[dp[n][m] for m in range(row)][::-1] for n in range(row)][::-1]

11、追加未能合并判定

玩过2048的小伙伴都知道,假如一个方向上无法合并、移动,那么你选择这个方向,也不会出现新的数字,相当于无效的输入。

这个时候,我们就需要记录数字合并判定前的状态,以及合并后的状态是否一致了。

在 python 里,有个 copy 包,可以很方便的复制列表、词典等对象,我们称之为深拷贝。

import copy  # 引入 copy 包,以便使用深拷贝

    comp = copy.deepcopy(dp) # 合并前追加深拷贝

    isSame = True  # 合并后,判断状态是否一致
    for i in range(row):
        for j in range(row):
            if comp[i][j] != dp[i][j]:
                isSame = False  # 如果任意一个位置的数字不一样,则判定有合并或移动
                break
        if not isSame:
            break

    if isSame:
        continue  # 如果状态一致,则从新输入移动方向

12、合并或移动后,出现新的数字

这是应有之意,没有新的数字,进程就停顿在这里了。

    free = [(m,n) for m in range(row) for n in range(row) if dp[m][n] == 0]
    if len(free) == 0: # 如果所有的位置都已经有了数字,游戏结束
        break   
    selected = random.choice(free)
    dp[selected[0]][selected[1]] = random.randint(1,2)
    score = sum([sum(r) for r in dp])

这么看起来,2048游戏好像也不复杂啊。没有理解透彻的,还有疑问的小伙伴可以在评论区扣我哦。

13、完整的代码呈现

import random
import copy
import sys

row,wid = 4,7

dp = [[0 for _ in range(row)] for _ in range(row)]
score = 0

while True:
    if score == 0:
        for i in range(random.randint(1,3)):
            free = [(m,n) for m in range(row) for n in range(row) if dp[m][n] == 0]
            selected = random.choice(free)
            dp[selected[0]][selected[1]] = random.randint(1,2)
            score = sum([sum(r) for r in dp])
    print('\n------------------------------')
    for r in dp:
        print('\n\n',''.join([str(n).rjust(wid) if n > 0 else '.'.rjust(wid) for n in r]))
    print('\n\nScore:',score)
    print('\n')
    sys.stdout.flush() # 为了避免输入位置总是不在正确的位置,强制刷新输出缓存
    inp = input('请选择方向(ASDW)Q退出:').strip().lower()
    if len(inp) != 1:
        continue
    if inp == 'q':
        break
    if inp not in 'asdw':
        continue
    if inp == 'w':
        dp[:] = [[dp[m][n] for m in range(row)] for n in range(row)][::-1]
    if inp == 's':
        dp[:] = [[dp[m][n] for m in range(row)][::-1] for n in range(row)]
    if inp == 'd':
        dp[:] = [[dp[n][m] for m in range(row)][::-1] for n in range(row)][::-1]

    comp = copy.deepcopy(dp)
    for i in range(row):
        while dp[i].count(0) > 0:
            dp[i].pop(dp[i].index(0))
        for j in range(len(dp[i]) - 1):
            if dp[i][j] == dp[i][j + 1]:
                dp[i][j] *= 2
                dp[i][j + 1] = 0
        while dp[i].count(0) > 0:
            dp[i].pop(dp[i].index(0))
        while len(dp[i]) < row:
            dp[i].append(0)
    
    isSame = True
    for i in range(row):
        for j in range(row):
            if comp[i][j] != dp[i][j]:
                isSame = False
                break
        if not isSame:
            break
    
    if inp == 'w':
        dp[:] = [[dp[m][n] for m in range(row)][::-1] for n in range(row)]
    if inp == 's':
        dp[:] = [[dp[m][n] for m in range(row)] for n in range(row)][::-1]
    if inp == 'd':
        dp[:] = [[dp[n][m] for m in range(row)][::-1] for n in range(row)][::-1]

    free = [(m,n) for m in range(row) for n in range(row) if dp[m][n] == 0]
    if len(free) == 0: # 没有剩余空位,游戏失败
        break

    if isSame:  # 自己发现个小bug,这个判定要放到失败判定之后。
        continue

    selected = random.choice(free)
    dp[selected[0]][selected[1]] = random.randint(1,2)
    score = sum([sum(r) for r in dp])

小结

这次我们用了两个小游戏来熟悉并扩展了一些见世面,如果小伙伴还有什么想了解的,或者有什么好主意,老顾可以安排,一起创作一篇新的文章哦。文章来源地址https://www.toymoban.com/news/detail-400435.html

到了这里,关于python 基础系列篇:四、编写两个简单的小游戏(猜数字及2048)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • python编写小游戏详细教程,python编写小游戏的代码

    大家好,小编来为大家解答以下问题,python编写小游戏详细教程,python编写小游戏的代码,现在让我们一起来看看吧! 今天给大家带来十五个Python小游戏,找回童年的同时学习编程还可以摸鱼, 源码附上结尾领取。 一、接金币(1分) 普通难度:❤ 玩法介绍: 吃金币,控制

    2024年01月17日
    浏览(62)
  • 利用python编写小游戏,用python编写的游戏

    大家好,小编为大家解答利用python编写小游戏的问题。很多人还不知道用python编写的游戏,现在让我们一起来看看吧! 小朋友们好,大朋友们好! 我是猫妹,一名爱上Python编程的小学生。 欢迎和猫妹一起,趣味学Pythonpython简单新年祝福代码。 今日主题 你玩过游戏吗? 你喜

    2024年01月15日
    浏览(45)
  • python做小游戏代码可复制,python编写小游戏的代码

    这篇文章主要介绍了python简单小游戏代码教程,具有一定借鉴价值,需要的朋友可以参考下。希望大家阅读完这篇文章后大有收获,下面让小编带着大家一起了解一下。 哈喽铁子们 表弟最近在学Python,总是跟我抱怨很枯燥无味,其实,他有没有认真想过,可能是自己学习姿

    2024年01月16日
    浏览(66)
  • unity期末作业-两个简单小游戏游戏-躲避障碍和跑酷(附下载链接和gif动态图演示)

    游戏角色为一个小人,天上不时会掉落障碍物,人物撞到了会掉生命值,人物可以左右移动跳跃来躲避,带游戏音效,比较简单!具体情况如下所示: 点我下载源文件和exe导出文件》》》》》》》 角色可以上下左右移动,J发射子弹k跳跃,只有在跳板上才可以跳跃,可以吃能

    2024年02月04日
    浏览(66)
  • 如何使用Python编写小游戏?

    大家好,我是沐尘而生,如果你是一个热爱编程的小伙伴,又想尝试游戏开发,那么这篇文章一定能满足你的好奇心。不废话,让我们马上进入Python游戏开发的精彩世界吧! Python游戏开发的魅力 编写小游戏不仅仅是锻炼编程技能的好方法,更是展现创意和享受成果的绝佳途

    2024年02月12日
    浏览(39)
  • python编写小游戏的代码,python游戏编程代码大全

    大家好,小编来为大家解答以下问题,python游戏编程入门游戏代码,python编写小游戏的代码,现在让我们一起来看看吧! 大家好,本文将围绕python小游戏编程100例运行成功截图展开说明,python小游戏编程100例1000行源码是一个很多人都想弄明白的事情,想搞清楚python编写的入

    2024年02月19日
    浏览(74)
  • Python编写简易猜数字小游戏

    下面是Python编写的简易猜数字小游戏: 运行该程序,即可开始游戏。程序会生成一个1~100之间的随机数字,然后逐渐提示你输入你的猜测。如果你猜错了,程序会提示你猜小了或猜大了,直到你猜中为止。游戏结束后,程序会告诉你你猜了多少次才猜中了。

    2024年03月28日
    浏览(49)
  • python编写小程序小游戏,python编写小程序的运行

    本篇文章给大家谈谈python编写小程序需要注意的地方,以及python编写小程序怎么看代码的,希望对各位有所帮助,不要忘了收藏本站喔。 Source code download: 本文相关源码 python可以开发小程序吗 谷歌人工智能写作项目:小发猫 用python可以做微信小程序吗? 其实微信小程序作为

    2024年03月12日
    浏览(48)
  • 用Python编写的小游戏:探索游戏世界的乐趣

    Python是一种简单易学的编程语言,它的灵活性和强大的功能使得它成为了许多开发者的首选。在本文中,我们将使用Python编写三个小游戏,展示Python的魅力和游戏开发的乐趣。这些小游戏将带领你进入一个奇妙的游戏世界,让你体验到编程的乐趣和创造力。 在这个游戏中,计

    2024年02月13日
    浏览(41)
  • python超简单小游戏代码,python简单小游戏代码

    大家好,小编来为大家解答以下问题,python超简单小游戏代码,python简单小游戏代码,今天让我们一起来看看吧! 大家好,我是辣条。 今天给大家带来30个py小游戏,一定要收藏! 目录 有手就行 1、吃金币 2、打乒乓 3、滑雪 4、并夕夕版飞机大战 5、打地鼠 简简单单 6、小恐

    2024年03月14日
    浏览(68)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包