可视化约瑟夫生死环小游戏

news2025/2/28 15:43:19

这是一个基于Tkinter的图形界面应用程序,用于模拟约瑟夫环问题。约瑟夫环问题是一个经典的数学问题,描述的是N个人围成一圈,从第一个人开始报数,每数到第M个人就将其淘汰,然后从下一个人继续报数,直到剩下最后一个人。

实现可视化功能:

  • 环形排列的人物图标
  • 当前报数者高亮显示(橙色)
  • 实时显示淘汰信息
  • 动态更新剩余人数
  • 胜利者弹窗提示

程序说明:

       首先,在JosephusGame类的init_方法中,设置了主窗口的标题、大小,并创建了各种控件,如画布、标签、输入框和开始按钮。这些控件通过Frame进行布局,使得界面看起来整洁有序。这里需要注意的是,用户输入的人数和步长是通过Entry控件获取的,而开始按钮绑定了start_game方法。

       然后是draw_circle方法,负责在画布上绘制当前存活的人物。这里使用三角函数计算每个位置的角度,将人物均匀地排列成一个圆环。存活的人物用天蓝色表示,当前报数的人用橙色高亮显示。每个角色用一个圆形表示,中间显示其编号。

       接下来是start_game方法,处理游戏的初始化。这里会验证用户输入的人数和步长是否为正整数,如果无效则弹出错误提示。然后初始化存活列表、当前索引、步数等变量,并禁用开始按钮以防止重复点击。最后调用next_step方法开始淘汰过程。

       在next_step方法中,执行每一轮的淘汰逻辑。根据当前索引和步长计算下一个要淘汰的人,更新存活列表,并在界面上更新显示。如果还有多于一人存活,使用after方法在1.5秒后自动进行下一步,否则结束游戏,显示胜利者。

import tkinter as tk
from math import cos, sin, pi
from tkinter import messagebox

class JosephusGame:
    def __init__(self, master):
        self.master = master
        master.title("约瑟夫生死环小游戏")
        master.geometry("800x600")
        
        # 游戏控件
        self.canvas = tk.Canvas(master, width=600, height=500, bg='white')
        self.label = tk.Label(master, text="欢迎来到约瑟夫生死环游戏!", font=('微软雅黑', 12))
        self.people_num = tk.Entry(master, width=10)
        self.step_num = tk.Entry(master, width=10)
        self.start_btn = tk.Button(master, text="开始游戏", command=self.start_game)
        
        # 布局
        controls = tk.Frame(master)
        tk.Label(controls, text="人数:").pack(side=tk.LEFT)
        self.people_num.pack(side=tk.LEFT, padx=5)
        tk.Label(controls, text="步长:").pack(side=tk.LEFT)
        self.step_num.pack(side=tk.LEFT, padx=5)
        self.start_btn.pack(side=tk.LEFT, padx=10)
        
        controls.pack(pady=10)
        self.canvas.pack()
        self.label.pack(pady=10)
        
        # 游戏变量
        self.players = []
        self.current_index = 0
        self.alive_players = []
        self.step = 0
        self.running = False

    def draw_circle(self):
        """绘制环形排列的人物"""
        n = len(self.alive_players)
        radius = 200
        center_x, center_y = 300, 250
        
        self.canvas.delete("all")
        for i in range(n):
            angle = 2 * pi * i / n
            x = center_x + radius * cos(angle)
            y = center_y + radius * sin(angle)
            
            # 绘制人物图标
            color = 'skyblue' if i != self.current_index else 'orange'
            self.canvas.create_oval(x-20, y-20, x+20, y+20, fill=color, tags=f"player{i}")
            self.canvas.create_text(x, y, text=str(self.alive_players[i]+1), 
                                  font=('Arial', 12, 'bold'))

    def start_game(self):
        """初始化游戏"""
        try:
            n = int(self.people_num.get())
            m = int(self.step_num.get())
            if n < 1 or m < 1:
                raise ValueError
        except:
            messagebox.showerror("错误", "请输入有效的正整数")
            return
        
        self.alive_players = list(range(n))
        self.current_index = 0
        self.step = 0
        self.running = True
        self.start_btn.config(state=tk.DISABLED)
        self.next_step(m)
    
    def next_step(self, m):
        """执行下一步"""
        if not self.running or len(self.alive_players) == 1:
            return
            
        self.step += 1
        # 计算淘汰位置
        self.current_index = (self.current_index + m - 1) % len(self.alive_players)
        eliminated = self.alive_players.pop(self.current_index)
        
        # 更新显示
        self.label.config(text=f"第 {self.step} 轮:{eliminated+1}号被淘汰,剩余 {len(self.alive_players)} 人")
        self.draw_circle()
        
        # 继续游戏或结束
        if len(self.alive_players) > 1:
            self.master.after(1500, lambda: self.next_step(m))
        else:
            self.running = False
            self.start_btn.config(state=tk.NORMAL)
            winner = self.alive_players[0] + 1
            messagebox.showinfo("游戏结束", f"胜利者是 {winner} 号!")
            self.draw_circle()

if __name__ == "__main__":
    root = tk.Tk()
    game = JosephusGame(root)
    root.mainloop() 

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

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

相关文章

【深入理解JWT】从认证授权到网关安全

最近的项目学习中&#xff0c;在进行登陆模块的用户信息验证这一部分又用到了JWT的一些概念和相关知识&#xff0c;特在此写了这篇文章、方便各位笔者理解JWT相关概念 目录 先来理解JWT是什么&#xff1f; 区分有状态认证和无状态认证 有状态认证 VS 无状态认证 JWT令牌的…

学习路之PHP --TP6异步执行功能 (无需安装任何框架)

学习路之PHP --异步执行功能 &#xff08;无需安装任何框架&#xff09; 简介一、工具类二、调用三、异步任务的操作四、效果&#xff1a; 简介 执行异步任务是一种很常见的需求&#xff0c;如批量发邮箱&#xff0c;短信等等执行耗时任务时&#xff0c;需要程序异步执行&…

九、数据治理架构流程

一、总体结构 《数据治理架构流程图》&#xff08;Data Governance Architecture Flowchart&#xff09; 水平结构&#xff1a;流程图采用水平组织&#xff0c;显示从数据源到数据应用的进程。 垂直结构&#xff1a;每个水平部分进一步划分为垂直列&#xff0c;代表数据治理的…

【数据结构】 最大最小堆实现优先队列 python

堆的定义 堆&#xff08;Heap&#xff09;是一种特殊的完全二叉树结构&#xff0c;通常分为最大堆和最小堆两种类型。 在最大堆中&#xff0c;父节点的值总是大于或等于其子节点的值&#xff1b; 而在最小堆中&#xff0c;父节点的值总是小于或等于其子节点的值。 堆常用于实…

51c自动驾驶~合集52

我自己的原文哦~ https://blog.51cto.com/whaosoft/13383340 #世界模型如何推演未来的千万种可能 驾驶世界模型&#xff08;DWM&#xff09;&#xff0c;专注于预测驾驶过程中的场景演变&#xff0c;已经成为追求自动驾驶的一种有前景的范式。这些方法使自动驾驶系统能够更…

【我的 PWN 学习手札】House of Husk

House of Husk House of Husk是利用格式化输出函数如printf、vprintf在打印输出时&#xff0c;会解析格式化字符如%x、%lld从而调用不同的格式化打印方法&#xff08;函数&#xff09;。同时C语言还提供了注册自定义格式化字符的方法。注册自定义格式化字符串输出方法&#xf…

Nmap使用指南

Nmap使用指南 Nmap (网络映射器) 是一款强大的应用网络扫描和安全核查工具&#xff0c;适合于网络管理和安全专家。本文将介绍Nmap的基本使用方法&#xff0c;包括基本命令和常用功能。 1. 基本使用方式 Nmap的基本命令格式如下&#xff1a; nmap [选项] 目标地址目标地址 可…

傅里叶分析

傅里叶分析之掐死教程&#xff08;完整版&#xff09;更新于2014.06.06 要让读者在不看任何数学公式的情况下理解傅里叶分析。 傅里叶分析不仅仅是一个数学工具&#xff0c;更是一种可以彻底颠覆一个人以前世界观的思维模式。但不幸的是&#xff0c;傅里叶分析的公式看起来太复…

从零开始用react + tailwindcss + express + mongodb实现一个聊天程序(五) 实现登录功能

1.登录页面 完善登录页面 和注册差不多 直接copy signUpPage 内容 再稍微修改下 import { useState } from "react"; import { useAuthStore } from "../store/useAuthStore"; import { MessageSquare,Mail,Lock,Eye, EyeOff,Loader2} from "lucide…

【机器学习】Logistic回归#1基于Scikit-Learn的简单Logistic回归

主要参考学习资料&#xff1a; 《机器学习算法的数学解析与Python实现》莫凡 著 前置知识&#xff1a;线性代数-Python 目录 问题背景数学模型类别表示Logistic函数假设函数损失函数训练步骤 代码实现特点 问题背景 分类问题是一类预测非连续&#xff08;离散&#xff09;值的…

8.Dashboard的导入导出

分享自己的Dashboard 1. 在Dashboard settings中选择 JSON Model 2. 导入 后续请参考第三篇导入光放Dashboard&#xff0c;相近

next.js-学习2

next.js-学习2 1. https://nextjs.org/learn/dashboard-app/getting-started2. 模拟的数据3. 添加样式4. 字体&#xff0c;图片5. 创建布局和页面页面导航 1. https://nextjs.org/learn/dashboard-app/getting-started /app: Contains all the routes, components, and logic …

视频推拉流EasyDSS直播点播平台授权激活码无效,报错400的原因是什么?

在当今数字化浪潮中&#xff0c;视频推拉流 EasyDSS 视频直播点播平台宛如一颗璀璨的明珠&#xff0c;汇聚了视频直播、点播、转码、精细管理、录像、高效检索以及时移回看等一系列强大功能于一身&#xff0c;全方位构建起音视频服务生态。它既能助力音视频采集&#xff0c;精准…

【论文详解】Transformer 论文《Attention Is All You Need》能够并行计算的原因

文章目录 前言一、传统 RNN/CNN 存在的串行计算问题二、Transformer 如何实现并行计算&#xff1f;三、Transformer 的 Encoder 和 Decoder 如何并行四、结论 前言 亲爱的家人们&#xff0c;创作很不容易&#xff0c;若对您有帮助的话&#xff0c;请点赞收藏加关注哦&#xff…

Framework层JNI侧Binder

目录 一&#xff0c;Binder JNI在整个系统的位置 1.1 小结 二&#xff0c;代码分析 2.1 BBinder创建 2.2 Bpinder是在查找服务时候创建的 2.3 JNI实现 2.4 JNI层android_os_BinderProxy_transact 2.5 BPProxy实现 2&#xff09;调用IPCThreadState发送数据到Binder驱动…

Excel大文件拆分

import pandas as pddef split_excel_file(input_file, output_prefix, num_parts10):# 读取Excel文件df pd.read_excel(input_file)# 计算每部分的行数total_rows len(df)rows_per_part total_rows // num_partsremaining_rows total_rows % num_partsstart_row 0for i i…

OpenCV计算摄影学(7)HDR成像之多帧图像对齐的类cv::AlignMTB

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 该算法将图像转换为‌中值阈值位图‌&#xff08;Median Threshold Bitmap&#xff0c;MTB&#xff09;&#xff1a; 1.位图生成‌&#xff1a;…

Axure PR 9 中继器 03 翻页控制

大家好&#xff0c;我是大明同学。 接着上期的内容&#xff0c;这期内容&#xff0c;我们来了解一下Axure中继器图表翻页控制。 预览地址&#xff1a;https://pvie5g.axshare.com 翻页控制 1.打开上期RP 文件&#xff0c;在元件库中拖入一个矩形&#xff0c;宽值根据业务实际…

IO流(师从韩顺平)

文章目录 文件什么是文件文件流 常用的文件操作创建文件对象相关构造器和方法应用案例 获取文件的相关信息应用案例 目录的操作和文件删除应用案例 IO 流原理及流的分类Java IO 流原理IO流的分类 IO 流体系图-常用的类IO 流体系图&#xff08;重要&#xff01;&#xff01;&…