尼姆游戏(人机对战)-Python

news2024/12/29 9:00:17

1.实验要求

编写程序设计和实现聪明的尼姆游戏(人机对战)。尼姆游戏是个著名的游戏,有很多变种玩法。两个玩家轮流从一堆物品中拿走一部分。在每一步中,玩家可以自由选择拿走多少物品,但是必须至少拿走一个并且最多只能拿走一半物品,然后轮到下一个玩家。拿走最后一个物品的玩家输掉游戏。

在聪明模式中,计算机每次拿走足够多的物品使得堆的大小是2 的幂次方减1——也就是3,7,15,31 或63。除了堆的大小已经是2 的幂次方减1,在其他情况下这样走都是符合游戏规则的。如果已是2的幂次方减1,计算机就按游戏规则随机拿走一些。

2.实验原理

2.1玩家回合

要确保玩家拿取的数要大于等于1,并且小于等于当前物品数的一半,可以使用while循环来完成。不过如果当前物品数为1时,会进入死循环,所以需要专门考虑:使用if语句来进行判断。拿取后,把更新的物品数返回即可。

其中用到的函数有player_turn。

def player_turn(heap_number):
    print(f'当前堆的大小为{heap_number},', end='')
    take_number = 0
    while take_number < 1 or take_number > heap_number // 2:
        take_number = eval(input('请输入你要拿取的数量(至少为1,至多为当前堆大小的一半):'))
        if heap_number == 1 and take_number == 1:  # 边界问题
            break
    return heap_number - take_number

2.2电脑回合

根据传入的参数,来判断当前的模式。

如果是傻瓜模式,就随机拿取[1,当前堆的大小的一半],不过要注意这个区间有可能是非法的,当堆大小为1时,当前堆大小的一半为0,所以非法区间为[1,0]。

如果是聪明模式,就先找到比此时物品数小的最大2的幂次方减1。如果这个2的幂次方减1恰好等于此时的物品数,就进行随机拿取;如果不等于,就拿取***此时物品数-2的幂次方减1***。

记得最后更新一下堆大小(返回当前的物品数)

其中用到的函数有computer_turn。

def computer_turn(heap_number, game_mode):
    print(f'堆的大小为{heap_number},', end='')
    if game_mode == 1: # 傻瓜模式:随机拿取
        if heap_number > 1:
            take_number = random.randint(1, heap_number // 2) # 如果heap_number <= 1,那么随机区间非法
        else:
            take_number = 1
        print(f'对手拿取了{take_number}个物品,还剩下{heap_number - take_number}个物品。')
        return heap_number - take_number
    else:
        x = 0
        while True:  # 找到此时比物品数小的 最大的2的幂次方减1
            if pow(2, x) <= heap_number:
                x = x + 1
            else:
                break
        x = x - 1
        if pow(2, x) == heap_number:  # 恰好等于物品数
            if heap_number > 1: # 如果heap_number <= 1,那么随机区间非法
                take_number = random.randint(1, heap_number // 2)
            else:
                take_number = 1
            print(f'对手拿取了{take_number}个物品,还剩下{heap_number - take_number}个物品。')
            return heap_number - take_number
        else:
            take_number = heap_number - (pow(2, x) - 1)
            print(f'对手拿取了{take_number}个物品,还剩下{heap_number - take_number}个物品。')
            return heap_number - take_number

2.3实现交替拿取

仅需定义一个变量now_play,用它来表示当前拿取的是谁,0代表电脑,1代表玩家,然后每有人拿取后,把now_play更新为表示对手的值就行了,这样就可以进行轮流进行拿取物品。

其中用到的函数有change_play。

def change_play(now_play):  # 改变玩家回合
    if now_play == 0:
        return 1
    return 0

2.4判断游戏结束

仅需判断当前物品数是否为0即可,一个玩家拿取后,如果此时物品数为0,那么游戏就可以结束了,这个玩家输了。

用到的函数有is_over。

def is_over(heap_number):  # 判断游戏是否结束
    if heap_number == 0:
        return True
    else:
        return False

3.全部代码

import random


def game():
    heap_number = eval(input('请输入堆的初始大小:'))
    game_mode = eval(input("请选择游戏模式:1.傻瓜模式 2.聪明模式"))
    now_play = eval(input('请输入谁先进行拿取:1.自己 0.对手'))  # 此时轮到谁进行游戏
    while True:
        if now_play == 0:
            heap_number = computer_turn(heap_number, game_mode)
            now_play = change_play(now_play)
            if is_over(heap_number):
                print('恭喜你,赢得了比赛!')
                break
        else:
            heap_number = player_turn(heap_number)
            now_play = change_play(now_play)
            if is_over(heap_number):
                print('很可惜呢,希望下一次能胜利!')
                break


def player_turn(heap_number):
    print(f'当前堆的大小为{heap_number},', end='')
    take_number = 0
    while take_number < 1 or take_number > heap_number // 2:
        take_number = eval(input('请输入你要拿取的数量(至少为1,至多为当前堆大小的一半):'))
        if heap_number == 1 and take_number == 1:  # 边界问题
            break
    return heap_number - take_number


def computer_turn(heap_number, game_mode):
    print(f'堆的大小为{heap_number},', end='')
    if game_mode == 1: # 傻瓜模式:随机拿取
        if heap_number > 1: 
            take_number = random.randint(1, heap_number // 2) # 如果heap_number <= 1,那么随机区间非法
        else:
            take_number = 1
        print(f'对手拿取了{take_number}个物品,还剩下{heap_number - take_number}个物品。')
        return heap_number - take_number
    else:
        x = 0
        while True:  # 找到此时比物品数小的 最大的2的幂次方减1
            if pow(2, x) <= heap_number:
                x = x + 1
            else:
                break
        x = x - 1
        if pow(2, x) == heap_number:
            if heap_number > 1: # 如果heap_number <= 1,那么随机区间非法
                take_number = random.randint(1, heap_number // 2)
            else:
                take_number = 1
            print(f'对手拿取了{take_number}个物品,还剩下{heap_number - take_number}个物品。')
            return heap_number - take_number
        else:
            take_number = heap_number - (pow(2, x) - 1)
            print(f'对手拿取了{take_number}个物品,还剩下{heap_number - take_number}个物品。')
            return heap_number - take_number


def change_play(now_play):  # 改变玩家回合
    if now_play == 0:
        return 1
    return 0


def is_over(heap_number):  # 判断游戏是否结束
    if heap_number == 0:
        return True
    else:
        return False


if __name__ == '__main__':
    game()

4.运行结果

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1700225.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

保险业务管理系统的设计与实现(论文 + 源码)

保险业务管理系统.zip资源-CSDN文库https://download.csdn.net/download/JW_559/89361419 保险业务管理系统的设计与实现 摘要 历经二十余年的高速发展&#xff0c;我国保险行业的市场竞争已经达到白热化的程度&#xff0c;在同一个城市往往有数十家主体参与保险业务的竞争。保…

一款颜值颇高的虚拟列表!差点就被埋没了,终于还是被我挖出来了

大家好&#xff0c;我是晓衡&#xff01; 今天&#xff0c;推荐一款颇有颜值的虚拟列表组件&#xff0c;不然真的被埋没就可惜了&#xff01; 我们先来看下效果&#xff1a; 感觉怎么样&#xff1f;还不错吧&#xff01; 为什么说这个资源差点被埋没呢&#xff1f;因为个朋友找…

echarts饼图图例右侧纵向排列

如图所示&#xff0c;一开始&#xff0c;我设置了图例的right和top值&#xff0c;还有orient&#xff0c;但图例始终不能纵向排成一排&#xff0c;要么上面两个一行&#xff0c;要么最后两个一行&#xff0c;最后我发现同时设置一下left的值就可以了&#xff0c;如下所示&#…

Lookin高效调试iOS App的UI

Lookin是一款iOS开发时常用的调试软件&#xff0c;由腾讯微信读书团队QMUI开发。 它可以查看和修改iOS App里的UI对象的软件&#xff0c;展示App UI图层&#xff0c;类似于Xcode自带的UI Inspector工具&#xff0c;或另一款叫做Reveal的软件。 此外&#xff0c;虽然Lookin主体…

【有效的数独】python

目录 很好&#xff0c;超级暴力做法&#xff0c;能过就行&#xff0c;优雅个锤子啊 优雅的做法 &#xff0c;绅士&#xff0c;噢听说叫模拟 很好&#xff0c;超级暴力做法&#xff0c;能过就行&#xff0c;优雅个锤子啊 我直接11个2层for循环暴力秒杀 class Solution:def is…

Oracle实践|内置函数之日期与时间函数

&#x1f4eb; 作者简介&#xff1a;「六月暴雪飞梨花」&#xff0c;专注于研究Java&#xff0c;就职于科技型公司后端工程师 &#x1f3c6; 近期荣誉&#xff1a;华为云云享专家、阿里云专家博主、腾讯云优秀创作者、ACDU成员 &#x1f525; 三连支持&#xff1a;欢迎 ❤️关注…

识别鼠标绘制的数学公式网站

https://webdemo.myscript.com/views/math/index.html x n m x n x m x^{nm}x^{n}\times x^{m} xnmxnxm 使用"$$"进行包裹

【C语言项目实战】使用单链表实现通讯录

&#x1f493; 博客主页&#xff1a;倔强的石头的CSDN主页 &#x1f4dd;Gitee主页&#xff1a;倔强的石头的gitee主页 期待您的关注 ​ 目录 一、引言 二、单链表的基本概念 三、通讯录项目的需求分析 四、通讯录的数据结构 五、通讯录的接口 1.通讯录初始化 / 导入外部…

Python 机器学习 基础 之 数据表示与特征工程 【分类变量】的简单说明

Python 机器学习 基础 之 数据表示与特征工程 【分类变量】的简单说明 目录 Python 机器学习 基础 之 数据表示与特征工程 【分类变量】的简单说明 一、简单介绍 二、数据表示与特征工程 数据表示 特征工程 三、分类变量 1、One-Hot编码&#xff08;虚拟变量&#xff09…

rk3568_spinlock

文章目录 前言1、spinlock是什么?2、自旋锁实验2.1源码2.2 结果图总结前言 本文记录在rk3568开发板做的自旋锁实验。通过自旋锁控制state变量来限制只有一个应用程序来打开驱动设备。 1、spinlock是什么? spinlock称为自旋锁,如果获取不到资源,就只能一直傻傻地等待资源被…

提高Java编程效率:ArrayList类的使用技巧

哈喽&#xff0c;各位小伙伴们&#xff0c;你们好呀&#xff0c;我是喵手。运营社区&#xff1a;C站/掘金/腾讯云&#xff1b;欢迎大家常来逛逛 今天我要给大家分享一些自己日常学习到的一些知识点&#xff0c;并以文字的形式跟大家一起交流&#xff0c;互相学习&#xff0c;一…

乐理学习-音及音名

1. 我觉得练习题很重要。我要得到一个反馈 所以我想没学习完书中的一节就要把练习题做下来&#xff0c;虽然慢点也可以。 2. 做个小计划。 今天计算了一下学完《基本乐理-李重光》如果每天3张。也要80天干完&#xff0c;希望能有一天可以学习7张的速度的时候。 3. 练习记录…

如何利用已有数据对模型进行微调

1.langchain整合llm做知识问答 利用LangChain的能力来结合检索和生成&#xff0c;形成一个知识增强的问答系统&#xff08;不涉及对模型的微调&#xff09;&#xff0c;而是利用llm从文档检索到问题解答。 langchain整合llm做知识检索 2.微调llm模型 1、首先是我们的数据集&…

从0开始学统计-秩和检验

1.什么是秩和检验&#xff1f; 秩和检验&#xff0c;也称为Wilcoxon 秩和检验&#xff0c;是一种非参数统计检验方法&#xff0c;用于比较两个独立样本的中位数是否有显著差异。它不要求数据满足正态分布假设&#xff0c;因此适用于小样本或者数据不满足正态分布假设的情况。 …

Android 快速调试网络 复制curl 到postMan

搜索这个插件 官网地址&#xff1a;https://github.com/itkacher/OkHttpProfiler 集成教程也在里面集成完毕后右下角有一个入口点进去可以复制curl| 插件名称&#xff1a;Okhttp Profiler 真的很好用&#xff01;

Ubuntu server 24 源码安装Quagga 支持动态路由协议ospf bgp

1 下载:GitHub - Quagga/quagga: Quagga Tracking repository - Master is at http://git.savannah.gnu.org/cgit/quagga.git 2 安装 #安装依赖包 sudo apt install gcc make libreadline-dev pkg-config #解压 tar zxvf quagga-1.2.4.tar.gz cd quagga-1.2.4/sudo ./co…

Linux(五)

Linux&#xff08;五&#xff09; 结构体如何定义一个结构体如何定义一个结构体变量结构体变量如何访问成员如何定义一个指向结构体的指针 动态分配空间 malloc,free在堆区分配5个存Stu的空间 #include <stdio.h> //编写一子函数,对pstr中的值进行输出 /*void output(int…

【开源】租房管理系统 JAVA+Vue+SpringBoot+MySQL

目录 一、系统介绍 租客屋主模块 房源信息模块 租客评价模块 房源订单模块 留言板模块 二、系统截图 三、核心代码 一、系统介绍 基于Vue.js和SpringBoot的租房管理系统&#xff0c;分为管理后台和用户网页端&#xff0c;可以给管理员、租客和屋主角色使用&#xff0c…

Layui设置table表格中时间的显示格式

1、问题概述? 【数据库中的时间格式】 【Layui中table表格默认的显示格式】 默认的格式中会显示时间的毫秒单位,但是这个毫秒有时候是不需要的。 总结:这个时候我们就需要定义table表格中的时间显示格式。 2、解决办法? 【解决后时间的显示格式】 【解决办法1:通过字符…

AI图书推荐:ChatGPT解码—人工智能增强生活指南

《ChatGPT解码—人工智能增强生活指南》&#xff08;ChatGPT Decoded. A Beginners Guide to AI-Enhanced Living &#xff09;是一本由 大卫维恩斯&#xff08;David Wiens &#xff09;所著的书籍&#xff0c;旨在帮助读者了解并有效利用GPT-4语言模型这一强大工具来提升日常…