C#使用随机数模拟器来模拟世界杯排名(三)

news2024/11/24 5:56:55

接上篇

C#使用随机数模拟器来模拟世界杯排名(二)_斯内科的博客-CSDN博客

上一篇我们使用随机数匹配比赛的世界杯国家,

这一篇我们使用随机数以及胜率模拟器 决赛出 世界杯冠军、亚军。

我们在主界面 新增按钮【开始比赛 直到 决出冠军】和【刷新重新随机分配】

面板Panel:pnlWorldCup

按钮:【开始比赛 直到 决出冠军】btnStart

按钮:【刷新重新随机分配】btnRefresh

富文本控件RichTextBox:rtxtDisplay

窗体FormWorldCupRanking设计如图:

 更新CountryUtil.cs,增加SoccerGame方法,用于获取两个参赛世界杯国家胜利的一方。

CountryUtil源程序如下:

using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace WorldCupRankingDemo
{
    internal class CountryUtil
    {
        /// <summary>
        /// 所有参赛的世界杯国家
        /// </summary>
        public static List<Country> ListWorldCup = new List<Country>();
        /// <summary>
        /// 初始化世界杯各个参赛国家
        /// </summary>
        public static void InitCountry() 
        {
            ListWorldCup.Clear();
            AddCountry(new Country()
            {
                CountryName = "法国",
                WinningRatio = 90,
                NationalFlag = Image.FromFile(AppDomain.CurrentDomain.BaseDirectory + "NationalFlagImage\\法国.png")
            });
            AddCountry(new Country()
            {
                CountryName = "阿根廷",
                WinningRatio = 95,
                NationalFlag = Image.FromFile(AppDomain.CurrentDomain.BaseDirectory + "NationalFlagImage\\阿根廷.png")
            });
            AddCountry(new Country()
            {
                CountryName = "巴西",
                WinningRatio = 98,
                NationalFlag = Image.FromFile(AppDomain.CurrentDomain.BaseDirectory + "NationalFlagImage\\巴西.png")
            });
            AddCountry(new Country()
            {
                CountryName = "荷兰",
                WinningRatio = 80,
                NationalFlag = Image.FromFile(AppDomain.CurrentDomain.BaseDirectory + "NationalFlagImage\\荷兰.png")
            });
            AddCountry(new Country()
            {
                CountryName = "克罗地亚",
                WinningRatio = 70,
                NationalFlag = Image.FromFile(AppDomain.CurrentDomain.BaseDirectory + "NationalFlagImage\\克罗地亚.png")
            });
            AddCountry(new Country()
            {
                CountryName = "葡萄牙",
                WinningRatio = 75,
                NationalFlag = Image.FromFile(AppDomain.CurrentDomain.BaseDirectory + "NationalFlagImage\\葡萄牙.png")
            });
            AddCountry(new Country()
            {
                CountryName = "摩洛哥",
                WinningRatio = 65,
                NationalFlag = Image.FromFile(AppDomain.CurrentDomain.BaseDirectory + "NationalFlagImage\\摩洛哥.png")
            });
            AddCountry(new Country()
            {
                CountryName = "英格兰",
                WinningRatio = 85,
                NationalFlag = Image.FromFile(AppDomain.CurrentDomain.BaseDirectory + "NationalFlagImage\\英格兰.png")
            });
        }

        /// <summary>
        /// 添加一个国家
        /// </summary>
        /// <param name="country"></param>
        public static void AddCountry(Country country) 
        {
            ListWorldCup.Add(country);
        }

        /// <summary>
        /// 两个匹配的世界杯国家进行比赛,根据胜率,进行随机,返回胜利的国家
        /// 胜利国家算法如下:先随机出一个胜率之和之间的随机数,
        /// 如果随机数小于【最小数的2倍】并且是奇数,则认为 胜率低的国家胜利,否则 胜率高的国家胜利
        /// </summary>
        /// <param name="tuple"></param>
        /// <returns></returns>
        public static Country SoccerGame(Tuple<Country, Country> tuple, out int randomNumber) 
        {
            randomNumber = -1;
            if (tuple == null || tuple.Item1 == null) 
            {
                throw new Exception("世界杯比赛无参赛的国家或者第一个参赛国家不存在");
            }
            if (tuple.Item2 == null) 
            {
                //无第二个世界杯参赛国家,直接躺赢【对奇数个参赛国家的特殊处理】
                return tuple.Item1;
            }
            decimal minWinningRatio = Math.Min(tuple.Item1.WinningRatio, tuple.Item2.WinningRatio);
            Country bigWin = null;//高胜率
            Country smallWin = null;//低胜率
            if (tuple.Item1.WinningRatio < tuple.Item2.WinningRatio)
            {
                bigWin = tuple.Item2;
                smallWin = tuple.Item1;
            }
            else
            {
                bigWin = tuple.Item1;
                smallWin = tuple.Item2;
            }

            int total = (int)(tuple.Item1.WinningRatio + tuple.Item2.WinningRatio);
            Random random = new Random(Guid.NewGuid().GetHashCode());
            //先随机出一个胜率之和之间的随机数
            randomNumber = random.Next(total);
            if (randomNumber < minWinningRatio * 2 && (randomNumber & 1) != 0) 
            {
                //如果随机数小于【最小数的2倍】并且是奇数,则认为 胜率低的国家胜利,否则 胜率高的国家胜利
                return smallWin;
            }
            return bigWin;
        }
    }
}

窗体FormWorldCupRanking,源程序如下:

(忽略设计器自动生成的代码)

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace WorldCupRankingDemo
{
    public partial class FormWorldCupRanking : Form
    {
        /// <summary>
        /// 比赛次数
        /// </summary>
        private static int matchCount = 0;
        /// <summary>
        /// 获胜世界杯国家列表,将进入下一轮
        /// </summary>
        private static List<Country> WinCountryList = new List<Country>();
        public FormWorldCupRanking()
        {
            InitializeComponent();
            rtxtDisplay.ReadOnly = true;
        }

        private void FormWorldCupRanking_Load(object sender, EventArgs e)
        {
            CountryUtil.InitCountry();
            LoadMatchCountry(CountryUtil.ListWorldCup);
        }

        /// <summary>
        /// 随机分配参赛国家列表
        /// </summary>
        /// <param name="countryList"></param>
        private void LoadMatchCountry(List<Country> countryList)
        {
            pnlWorldCup.Controls.Clear();
            DisplayMessage($"开始加载世界杯参赛国家.参赛国家[{countryList.Count}]个.参赛国:\n{string.Join(",", countryList.Select(c => c.CountryName))}");
            Application.DoEvents();
            //Thread.Sleep(500);
            int[] indexArray = new int[countryList.Count];
            for (int i = 0; i < indexArray.Length; i++)
            {
                indexArray[i] = i;
            }
            RandomUtil.Init(indexArray);
            int[] destArray = RandomUtil.Shuffle();
            int rowCount = (destArray.Length + 1) / 2;
            matchCount = rowCount;
            string[] matchNations = new string[rowCount];//比赛对战国家
            for (int i = 0; i < rowCount; i++)
            {
                UcCountry ucCountry1 = new UcCountry();
                ucCountry1.Name = $"ucCountry{i * 2 + 1}";
                Country country1 = countryList[destArray[i * 2]];
                ucCountry1.lblCountryName.Text = country1.CountryName;
                ucCountry1.lblWinningRatio.Text = $"胜率:{country1.WinningRatio}";
                ucCountry1.picNationalFlag.BackgroundImage = country1.NationalFlag;
                ucCountry1.Tag = country1;
                ucCountry1.Location = new Point(5, i * 200 + 5);
                pnlWorldCup.Controls.Add(ucCountry1);

                Button button = new Button();
                button.Name = $"button{i + 1}";
                button.Text = "VS";
                button.Font = new Font("宋体", 30, FontStyle.Bold);
                button.Size = new Size(100, 100);
                button.Location = new Point(310, i * 200 + 40);
                button.Enabled = false;//不允许界面交互
                pnlWorldCup.Controls.Add(button);

                Country item2 = null;
                if (i * 2 + 1 < destArray.Length)
                {
                    //对奇数个世界杯比赛国家特殊处理,最后一个国家直接胜利
                    UcCountry ucCountry2 = new UcCountry();
                    ucCountry2.Name = $"ucCountry{i * 2 + 2}";
                    Country country2 = countryList[destArray[i * 2 + 1]];
                    ucCountry2.lblCountryName.Text = country2.CountryName;
                    ucCountry2.lblWinningRatio.Text = $"胜率:{country2.WinningRatio}";
                    ucCountry2.picNationalFlag.BackgroundImage = country2.NationalFlag;
                    ucCountry2.Tag = country2;
                    ucCountry2.Location = new Point(455, i * 200 + 5);
                    pnlWorldCup.Controls.Add(ucCountry2);

                    item2 = country2;
                }
                //对按钮进行数据绑定 对应两个世界杯参赛国家
                button.Tag = Tuple.Create(country1, item2);
                button.Click += Button_Click;

                matchNations[i] = $"【{country1.CountryName} VS {(item2 == null ? "无" : item2.CountryName)}】";
            }
            DisplayMessage($"加载世界杯对战国家匹配完成.对战情况\n{string.Join(",\n", matchNations)}");
        }

        /// <summary>
        /// 淘汰赛,利用胜率获取随机数算法,获取世界杯比赛的胜利一方,并将获胜国家插入胜利列表,以便进行下一次的随机分配
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Button_Click(object sender, EventArgs e)
        {
            Button button = sender as Button;
            if (button == null) 
            {
                return;
            }
            Tuple<Country, Country> tuple = button.Tag as Tuple<Country, Country>;
            if (tuple == null) 
            {
                return;
            }
            int randomNumber;
            Country winCountry = CountryUtil.SoccerGame(tuple, out randomNumber);
            WinCountryList.Add(winCountry);//将获胜国家插入列表
            DisplayMessage($"世界杯参赛国家【{tuple.Item1.CountryName},胜率:{tuple.Item1.WinningRatio}】 VS 【{(tuple.Item2 == null ? "无" : $"{tuple.Item2.CountryName},胜率:{tuple.Item2.WinningRatio}")}】");
            DisplayMessage($"    胜利国家【{winCountry.CountryName}】,模拟随机数【{randomNumber}】");
            UcCountry ucCountry = FindWinCountry(button, winCountry);
            if (ucCountry == null) 
            {
                return;
            }

            Panel panel = new Panel();
            panel.Name = $"panel{button.Name.Substring(6)}";
            panel.Location = new Point(ucCountry.Location.X + 250, ucCountry.Location.Y + 10);
            panel.Size = new Size(100, 100);
            panel.BackgroundImage = null;
            Bitmap bitmap = new Bitmap(panel.Width, panel.Height);
            Graphics graphics = Graphics.FromImage(bitmap);
            graphics.DrawString("胜 利", new Font("华文楷体", 16), Brushes.Red, 10, 10);
            graphics.Dispose();
            panel.BackgroundImage = bitmap;
            pnlWorldCup.Controls.Add(panel);
        }

        /// <summary>
        /// 获取两个世界杯比赛国家胜利一方对应的控件
        /// </summary>
        /// <param name="button"></param>
        /// <param name="winCountry"></param>
        /// <returns></returns>
        private UcCountry FindWinCountry(Button button, Country winCountry) 
        {
            int index = int.Parse(button.Name.Substring(6)) - 1;
            Control[] controls = pnlWorldCup.Controls.Find($"ucCountry{index * 2 + 1}", true);
            Control[] controls2 = pnlWorldCup.Controls.Find($"ucCountry{index * 2 + 2}", true);
            if (controls != null && controls.Length > 0)
            {
                Country cTemp = ((UcCountry)controls[0]).Tag as Country;
                if (cTemp.CountryName == winCountry.CountryName)
                {
                    return (UcCountry)controls[0];
                }
                else
                {
                    if (controls2 != null && controls2.Length > 0)
                    {
                        cTemp = ((UcCountry)controls2[0]).Tag as Country;
                        if (cTemp.CountryName == winCountry.CountryName)
                        {
                            return (UcCountry)controls2[0];
                        }
                    }
                }
            }
            return null;
        }

        private void DisplayMessage(string message) 
        {
            this.BeginInvoke(new Action(() => 
            {
                if (rtxtDisplay.TextLength >= 40960) 
                {
                    rtxtDisplay.Clear();
                }
                rtxtDisplay.AppendText($"{DateTime.Now.ToString("HH:mm:ss")}-->{message}\n");
                rtxtDisplay.ScrollToCaret();
            }));
        }

        private void btnStart_Click(object sender, EventArgs e)
        {
            Country[] FinalTwoCountry = new Country[2];//最终决赛的两个国家,分出冠军、亚军
            do
            {
                WinCountryList.Clear();
                for (int i = 0; i < matchCount; i++)
                {
                    Button button = pnlWorldCup.Controls.Find($"button{i + 1}", true)[0] as Button;
                    Button_Click(button, null);
                    Application.DoEvents();
                    Thread.Sleep(2000);
                }
                if (WinCountryList.Count == 1) 
                {
                    //只有最后一个胜利国家,循环终止,找到亚军
                    Country secondPlace = Array.Find(FinalTwoCountry, c => c.CountryName != WinCountryList[0].CountryName);
                    DisplayMessage($"最终胜利国家,冠军【{WinCountryList[0].CountryName}】,亚军【{secondPlace.CountryName}】");
                    MessageBox.Show($"最终胜利国家,冠军【{WinCountryList[0].CountryName}】,亚军【{secondPlace.CountryName}】", "圆满结束");
                    break;
                }
                DisplayMessage($"当前胜利的世界杯国家为【{string.Join(",", WinCountryList.Select(country => country.CountryName))}】");
                Application.DoEvents();
                Thread.Sleep(3000);
                if (WinCountryList.Count == 2) 
                {
                    WinCountryList.CopyTo(FinalTwoCountry);
                    string worldCupBattle = $"世界杯决战即将开始,最终决赛双方:【{WinCountryList[0].CountryName} VS {WinCountryList[1].CountryName}】";
                    DisplayMessage(worldCupBattle);
                    Application.DoEvents();
                    Thread.Sleep(1000);
                    MessageBox.Show(worldCupBattle, "世界杯决战");
                }
                LoadMatchCountry(WinCountryList);
            } while (WinCountryList.Count >= 2);
        }

        private void btnRefresh_Click(object sender, EventArgs e)
        {
            WinCountryList.Clear();
            FormWorldCupRanking_Load(null, null);
        }
    }
}

窗体运行如图:

 四强比赛:

 世界杯决赛:

 

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

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

相关文章

Python语言程序设计实验报告

第二章&#xff1a;Python变量与数据类型 一、实验目的&#xff1a; 1.了解Python变量的概念与相关含义&#xff1b; 2.学习Python中的数据类型&#xff1b; 二、实验环境&#xff1a; 1.笔记本电脑 2.PyCharm Community Edition 2022.2.3工具 三、实验内容&#xff1a; 1.将字…

ZABBIX6.0LTS安装笔记

一、准备好干净的操作系统 推荐使用&#xff1a;Rocky Linux 8.6 二、安装ZABBIX 官网&#xff1a;https://www.zabbix.com/cn/download 【1】选择您Zabbix服务器的平台 【2】 安装Zabbix包 下载安装包源 # rpm -Uvh https://repo.zabbix.com/zabbix/6.0/rhel/8/x86_64/zabb…

Spring的动态AOP源码解析

一… 引入 1.1 概念 1.2 注解方式使用AOP @Aspect public class LogAspects {/*** 1. 本类引用,只需要写方法名* 2. 其他类引用,需要写路径*/@Pointcut("execution(public int com.floweryu.aop.MathCalculator.*(..))")public void pointCut

Linux--进程间通信

目录1. 进程间通信目的2. 管道2.1 管道特性&#xff08;匿名管道&#xff09;2.1.1 单向通信2.1.2 面向字节流2.2 管道的大小2.3 命名管道3. system V进程间通信3.1 shmget函数3.1.1 key VS shmid3.2 shmctl函数3.3 shmat函数 VS shmdt函数&#xff1a;3.4 测试4. 感性认识4.1 …

R语言中的多类别问题的绩效衡量:F1-score 和广义AUC

最近我们被客户要求撰写关于分类的研究报告&#xff0c;包括一些图形和统计输出。对于分类问题&#xff0c;通常根据与分类器关联的混淆矩阵来定义分类器性能。根据混淆矩阵 &#xff0c;可以计算灵敏度&#xff08;召回率&#xff09;&#xff0c;特异性和精度。 对于二进制…

基于javaweb物业管理系统的设计与实现/小区物业管理系统

摘 要 随着世界经济快速的发展&#xff0c;全国各地的城市规模不断扩大&#xff0c;住进城市的人口日益增多&#xff0c;房地产行业在现代社会的发展中有着重要的作用&#xff0c;有越来越多的人居住在小区里。 因此&#xff0c;一套高效并且无差错的物业管理系统软件在现代社会…

基于Android的校园一卡通App平台

演示视频信息&#xff1a; A6604基于Android的校园一卡通一、研究背景、目的及意义 &#xff08;一&#xff09;研究背景 二十一世纪是信息化的时代&#xff0c;信息化建设成为我们的首要任务。当前我国大力发展信息产业&#xff0c;在全国范围内各行各业开始实施信息化…

为什么要上机械制造业ERP系统?对企业有什么帮助?

在日益竞争激烈的市场背景下&#xff0c;机械制造企业提供的产品需要具有更短的交货期、更高的质量、更好的服务。而机械行业由于其工艺复杂的生产特点&#xff0c;工艺及在制品管理困难&#xff0c;单纯的靠手工记账处理&#xff0c;已经难以满足现代企业科学管理的需要。只有…

艾美捷IFN-gamma体内抗体参数及应用

艾美捷IFN-gamma体内抗体背景&#xff1a; 干扰素γ&#xff08;IFN-γ&#xff09;或II型干扰素是一种二聚可溶性细胞因子&#xff0c;是II型干扰素的唯1成员。它是一种细胞因子&#xff0c;对抵抗病毒和细胞内细菌感染的先天性和适应性免疫以及肿瘤控制至关重要。IFNG主要由…

TensorFlow平台应用

目录 一&#xff1a;TensorFlow简介 二&#xff1a;TensorFlow工作形式 三&#xff1a;图/Session 四&#xff1a;安装tensorflow 五&#xff1a;张量 六&#xff1a;变量/常量 七&#xff1a;创建数据流图、会话 八&#xff1a;张量经典创建方法 九&#xff1a;变量赋…

[Java EE初阶]Thread 类的基本用法

本就无大事,庸人觅闲愁. 文章目录1. 线程创建2. 线程中断2.1 通知终止后立即终止2.2 通知终止,通知之后线程继续执行2.3 通知终止后,添加操作后终止3. 线程等待4. 线程休眠5. 获取线程实例1. 线程创建 创建线程有五个方法 详情见我的另一个文章 https://editor.csdn.net/md/?…

【K8S系列】第十二讲:Service进阶

目录 ​编辑 序言 1.Service介绍 1.1 什么是Service 1.2 Service 类型 1.2.1 NodePort 1.2.2 LoadBalancer 1.2.3 ExternalName 1.2.4 ClusterIP 2.yaml名词解释 3.投票 序言 当发现自己的才华撑不起野心时&#xff0c;就安静下来学习吧 三言两语&#xff0c;不如细…

Unity 灯光

初始化时&#xff0c;系统默认会给一个灯光&#xff0c;类型为定向光。 定向光意为&#xff0c;从无穷远处照射过来的平行光&#xff0c;因此每个图形的阴影的方向一致 灯光的系统参数 阴影类型&#xff1a;①无阴影 ②硬阴影 ③软阴影 &#xff08;注意&#xff09;阴影类型最…

力扣(LeetCode)164. 最大间距(C++)

桶排序(划分区间) 一次遍历找到区间内最大值 MaxMaxMax &#xff0c;最小值 MinMinMin 。区间 (Min,Max](Min,Max](Min,Max] 左开右闭&#xff0c;划分为 n−1n-1n−1 个长度为 lenlenlen 的区间 &#xff0c;划分的区间左开右闭&#xff0c;所以每个子区间有 len−1len-1len−…

SpringCloud学习笔记

SpringCloud学习笔记成熟分布式微服务架构包含技术模块SpringCloud与SpringBoot版本选择SpringCloud各技术模块的技术选择SpringCloud实现订单-支付微服务创建父工程(管理子工程即各个微服务)父工程的build.gradle配置父工程的settings.gradle配置创建支付子工程(payment_nativ…

物联网开发笔记(64)- 使用Micropython开发ESP32开发板之控制ILI9341 3.2寸TFT-LCD触摸屏进行LVGL图形化编程:控件显示

一、目的 这一节我们学习如何使用我们的ESP32开发板来控制ILI9341 3.2寸TFT-LCD触摸屏进行LVGL图形化编程&#xff1a;控件显示。 二、环境 ESP32 ILI9341 3.2寸TFT-LCD触摸屏 Thonny IDE 几根杜邦线 接线方法&#xff1a;见前面文章。 三、滑杆代码 import lvgl as lv i…

北京理工大学汇编语言复习重点

汇编是半开卷&#xff0c;可以带纸质资料。理论上&#xff0c;学好了以后&#xff0c;带本书进去就ok了&#xff0c;但是这次是线上&#xff0c;我还没书&#xff0c;就对着考试重点整理一点资料用于打印吧。 因为是线上&#xff0c;所以第4章基本不考框架了&#xff0c;浮点操…

工业4.0,科技引发产业革命,MES系统是数字化工厂的核心

当前&#xff0c;把握工业4.0时代信息技术引发的产业革命风口期&#xff0c;促进产业数字化转型升级&#xff0c;构建产业竞争新格局&#xff0c;实现弯道超车是难得一遇的大好时机&#xff0c;是局势所趋。在这样的大环境下&#xff0c;顺应全世界产业革命趋势&#xff0c;将数…

python的安装

python可以在所有操作系统上运行&#xff0c;但不同操作系统的安装方法有所不同 以&#xff1a;Mac OS X 和 Windows为例 为了安装 Python 并能正常使用&#xff0c;请根据你的操作系统安装提示&#xff0c;按照相应的步骤来操作。 我们还将进行一系列的测试&#xff0c;确保一…

SpringBoot实战(十)集成多数据源dynamic-datasource

目录1.Maven依赖2. DS注解3.普通Hihari连接池3.1 yml配置4.Druid连接池4.1 Druid依赖4.2 yml配置4.3 排除原生的Druid配置5. UserController6. UserServiceImpl7.测试7.1 新增数据7.2 查询数据7.3 测试结果8.源码地址&#xff1a;dynamic-datasource-spring-boot-starter 是一个…