[WinForm开源]概率计算器 - Genshin Impact(V1.0)

创作目的:为方便旅行者估算自己拥有的纠缠之缘能否达到自己的目的,作者使用C#开发了一款小型软件供旅行者参考使用。

创作说明:此软件所涉及到的一切概率与规则完全按照游戏《原神》(V4.4.0)内公示的概率与规则(包括保底机制)进行编写,仅用于计模拟已知纠缠之缘数量对已知抽取五星目标的成功频率(可看作成功率),无任何暗箱操作。


目录

一、软件介绍

1.软件主页面展示

2.软件适用范围

3.软件使用方法

二、获取途径

1.软件获取

2.项目获取

三、项目开源

1.MainForm页面(软件主页面)

2.Form_Poster页面(祈愿海报页面)

3.README页面(说明页面)

4. 应用程序清单文件

四、其他说明


一、软件介绍

1.软件主页面展示

2.软件适用范围

该软件适用范围为:2位UP角色不同卡池但一同保底计数、2把专武在同一卡池且只能定轨一把武器。[说通俗点就是目前能够支持到4.4下半版本,后期如开启混池,作者将会对软件进行更新]

3.软件使用方法

点击顶部卡池选择」下拉框可切换当前的卡池信息,目前支持4.3与4.4上下半卡池总计4期卡池。

点击顶部点击查看卡池海报」按钮可以查看选择的当期卡池的海报。

左侧计划抽取」一栏可以选择旅行者计划抽取的角色、武器的数量,默认为0,角色最大为7,武器最大为5 。当旅行者四栏全部选择为0时,将不被允许进行模拟。

左侧「当前资源」一栏填写旅行者计划投入的纠缠之缘与原石的数量,当填入的资源不足1抽时将不被允许进行模拟,最大支持999抽。

左侧「其他情况」一栏旅行者可以勾选自己对应的情况,若不清楚对于情况,可进入游戏进行查看;旅行者勾选的选项将影响到模拟结果。

中间「用户须知」一栏为简要的用户须知,如页面过小可点击放大到新窗口。旅行者阅读完毕请勾选其下方的“我已认真阅读上述内容”。

点击中间「仅将原石转化为纠缠之缘」按钮,软件将根据用户填入的原石数量,转化为纠缠之缘并将合计的纠缠之缘数量、剩余的原石数量展现给旅行者。

点击中间「开始模拟」按钮,软件将进行10,000次模拟,每次模拟到抽取到目标为止,若有纠缠之缘剩余,则计入剩余总数,最终计算平均剩余数。软件最终将给出「达成预期频率」「超越预期频率」「综合成功频率」(后面介绍)。模拟的计算速度取决于旅行者的纠缠之缘数量与计算机的运算速度。

右侧「达成预期频率」一栏将展示软件对旅行者给出的资源数量与目标进行1W次模拟后得到的恰好达到目标的情况的数量与模拟总量的比值。“达成预期”判定标准:在达成所有抽取目标后,纠缠之缘剩余量不小于0时,所获得的所有5星物品(含常驻)与填写的抽取目标完全一致。

右侧「超出预期频率」一栏将展示软件对旅行者给出的资源数量与目标进行1W次模拟后得到的超出预期目标的情况的数量与模拟总量的比值。“超出预期”判定标准:在达成所有抽取目标后,纠缠之缘剩余量不小于0时,所获得的所有5星物品(含常驻)超出填写的抽取目标(常驻默认为0)。

右侧「综合成功频率」一栏将展示软件对旅行者给出的资源数量与目标进行1W次模拟后得到的能够完成给定的抽取目标的情况的数量与模拟总量的比值。该栏为上述两栏之和。

点击右侧「保存为图片」按钮,软件将会把当前页面保存为PNG图片。

二、获取途径

1.软件获取

(1)CSDN站内下载:https://download.csdn.net/download/qq_64516527/88817489

(2)百度网盘下载:https://pan.baidu.com/s/1Uw1mMIONUh9-heMUHRgOOQ?pwd=SLLH 提取码:SLLH

(3)123云盘下载:https://www.123pan.com/s/Il2bVv-CwvQh.html

2.项目获取

(1)CSDN站内下载:https://download.csdn.net/download/qq_64516527/88817874

(2)123云盘下载:https://www.123pan.com/s/Il2bVv-NwvQh.html

三、项目开源

注:接下来的代码主要按页面进行分栏,代码中注释比较全,可直接阅读。

1.MainForm页面(软件主页面)

设计器:

页面代码:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Threading;
using System.Diagnostics;
using System.Security.Cryptography;
using System.IO;namespace 概率计算器___Genshin_Impact
{public partial class MainForm : Form{public MainForm(){InitializeComponent();}#region 变量的声明public bool Avaluable = true;Thread Thread_Load = null;//淡入淡出的线程Thread Thread_DataDetection = null;//用于检测数据并调控Enable属性的线程Thread T_Imitate = null;//用于进行模拟的线程public int NUM_Ball = 0, NUM_Stone = 0;//纠缠之缘与原石的数量public int[] Success = new int[2] { 0, 0 };//分别表示恰好达到预期与超出预期的次数public int Success_Sum = 0;//表示综合成功次数public bool NextRoleIsBig = false;//表示下次角色池是否为大保底public bool NextWeaponIsUp = false;//表示下次武器池是否为UP武器public int Num_Weapon_Base = 0;//表示武器池定轨数string[,] RoleName = new string[4, 2] {{"娜维娅", "神里绫华" },//4.3上半卡池,卡池编码为0{"雷电将军", "宵宫" },//4.3下半卡池,卡池编码为1{ "闲云", "纳西妲" }, //4.4上半卡池,卡池编码为2{ "魈", "八重神子" }//4.4下半卡池,卡池编码为3};//第一维度为版本编号,第二维度为卡池序号//比如4.4上半对应第一维度,而角色祈愿-2对应第二维度//角色头像图片名称为RoleName[m,n] + "·头像.png"//专武图片名称为RoleName[m,n] + "专武.png"#endregionprivate void MainForm_Load(object sender, EventArgs e){panelMain.BackColor = Color.FromArgb(191, 0, 0, 0);panelMain.Height = 0;Thread_Load = new Thread(() => LoadThread());Thread_Load.Start();Thread_DataDetection = new Thread(() => T_DataDetection());Thread_DataDetection.Start();foreach (Control control in panelMain.Controls)//遍历panel中的所有控件if (!((control is ComboBox) || (control is TextBox) || (control is RichTextBox)))control.BackColor = Color.FromArgb(0, 0, 0, 0);else if (control is ComboBox){ComboBox CB = (ComboBox)control;CB.SelectedIndex = 0;}pictureBox_README.BackColor = Color.FromArgb(64, 0, 0, 0);comboBox_VersionChoose.SelectedIndex = 0;//设置初始选择值#region 关于SelectedIndex的说明/* 0为4.4上半(闲云 纳西妲)* 1为4.4下半(魈 八重神子)*/#endregionlabel1.Text = "还未进行过模拟";}private void T_DataDetection(){bool B = false;//用于判断能否抽卡while(true){if (NUM_Stone >= 160)Invoke(new Action(() => { button_Transport.Enabled = true; }));//跨线程操作else Invoke(new Action(() => { button_Transport.Enabled = false; }));//跨线程操作B = ((NUM_Ball > 0) && (NUM_Stone >= 0)) || ((NUM_Ball == 0) && (NUM_Stone >= 160));if (B && Avaluable)Invoke(new Action(() => { button_Start.Enabled = true; }));//跨线程操作else Invoke(new Action(() => { button_Start.Enabled = false; }));//跨线程操作Thread.Sleep(50);}}//用于检测数据并调控Enable属性的线程private void LoadThread(){do{Invoke(new Action(() =>{panelMain.Height += 20;}));//跨线程操作Thread.Sleep(2);} while (panelMain.Height <= 750);}//黑色半透明下降的动画的线程#region 为获取comboBox控件的SelectedIndex属性而定义的内容// 定义一个委托来执行操作  delegate int GetSelectedIndexDelegate();// 在主线程中执行操作的方法  private int GetCBWNSelectedIndex(){if (comboBox_WeaponN.InvokeRequired){// 如果需要跨线程调用,则使用Invoke  return (int)comboBox_WeaponN.Invoke(new GetSelectedIndexDelegate(GetCBWNSelectedIndex));}else{// 直接返回SelectedIndex  return comboBox_WeaponN.SelectedIndex;}}#endregionprivate void imitate(int N,int[] Target,CheckBox[] CB, ComboBox comboBox_WN){//Target储存四者的抽取目标double Average_Residue = 0;//平均剩余的粉球for (int i=1;i<=10000;i++){NextRoleIsBig = CB[2].Checked;#region 获取并储存comboBox_WN的SelectedIndex属性值的代码段int CB_WN_SI;//储存comboBox_WN的SelectedIndex属性值CB_WN_SI = GetCBWNSelectedIndex();#endregionif (CB[3].Checked)//定轨不为0/2的情况Num_Weapon_Base = CB_WN_SI + 1;if (CB[3].Checked && CB_WN_SI == 0 && CB[4].Checked)NextWeaponIsUp = true;//定轨0/2歪常驻变成1/2的情况,下次必定是UP武器int N_Ball;if (CB[0].Checked) N_Ball = (int)(N / 0.9);else N_Ball = N;bool[] Process_Role_Weapon = new bool[4] { false, false, false, false };//记录四者的抽取目标达成情况int[] Reality = new int[5] { 0, 0, 0, 0, 0};//记录实际抽取到的数量,第五个表示歪的常驻(包括角色与武器)for (int j = 0; j < 4; j++)if (Target[j] == 0)Process_Role_Weapon[j] = true;//抽取目标为0的直接标记为已达成目标//然后调用方法进行模拟并通过返回值得到消耗的纠缠之缘数量if (!CB[1].Checked){for (int j = 0; j <= 1; j++)if (!Process_Role_Weapon[j])N_Ball -= RolePrayer(Target[j], Reality, Process_Role_Weapon, j);for (int j = 2; j <= 3; j++)if (!Process_Role_Weapon[j])N_Ball -= WeaponPrayer(Target[j], Reality, Process_Role_Weapon, j);}else{//如果勾选了checkBox2,那么优先抽取武器for (int j = 2; j <= 3; j++)if (!Process_Role_Weapon[j])N_Ball -= WeaponPrayer(Target[j], Reality, Process_Role_Weapon, j);for (int j = 0; j <= 1; j++)if (!Process_Role_Weapon[j])N_Ball -= RolePrayer(Target[j], Reality, Process_Role_Weapon, j);}//然后对该次模拟结果进行统计if (i == 1 && N_Ball >= 0) Average_Residue = N_Ball;else if (N_Ball >= 0) Average_Residue = (double)(Average_Residue * (i - 1) + N_Ball) / i;else Average_Residue = (double)(Average_Residue * (i - 1)) / i;//统计平均剩余粉球if (Process_Role_Weapon[0] && Process_Role_Weapon[1] && Process_Role_Weapon[2] && Process_Role_Weapon[3] &&N_Ball>=0){//说明达成目标bool NotOver = true;for (int j = 0; j < 4; j++)NotOver = NotOver && (Reality[j] == Target[j]);NotOver = NotOver && (Reality[4] == 0);if (NotOver) Success[0]++;//这里是恰好达成目标else Success[1]++;//这里是超出预期Success_Sum++;}Invoke(new Action(() =>{if (i != 10000)label1.Text = "已进行" + i.ToString() + "次模拟……";else label1.Text = "已进行10000次模拟,每次模拟投入" + N.ToString() + "纠缠。";label_Succ_1_3.Text = "共计" + Success[0].ToString() + "次出现";label_Succ_2_3.Text = "共计" + Success[1].ToString() + "次出现";label_Succ_3_3.Text = "共计" + Success_Sum.ToString() + "次出现";}));}Avaluable = true;double[] Rate = new double[3] { (double)Success[0] / 10000,(double)Success[1] / 10000,(double)Success_Sum / 10000 };Invoke(new Action(() =>{button_Start.Text = "开始模拟";label_Succ_1_3.Text = "共计" + Success[0].ToString() + "次出现";label_Succ_2_3.Text = "共计" + Success[1].ToString() + "次出现";label_Succ_3_3.Text = "共计" + Success_Sum.ToString() + "次出现";label_Succ_1_2.Text = (Rate[0]*100).ToString() + "%";label_Succ_2_2.Text = (Rate[1]*100).ToString() + "%";label_Succ_3_2.Text = (Rate[2]*100).ToString() + "%";label_Remain.Text = "平均剩余纠缠之缘" + Average_Residue.ToString("F2") + "个";if (Rate[2] >= 0 && Rate[2] <= 0.2)label_Label.Text = "白日做梦";else if (Rate[2] > 0.2 && Rate[2] <= 0.4)label_Label.Text = "考验人品";else if (Rate[2] > 0.4 && Rate[2] <= 0.6)label_Label.Text = "成败参半";else if (Rate[2] > 0.6 && Rate[2] <= 0.8)label_Label.Text = "值得一试";else if (Rate[2] > 0.8 && Rate[2] < 1)label_Label.Text = "十拿九稳";else label_Label.Text = "板上钉钉";label_Remain.Visible = label2.Visible = label_Label.Visible = true;}));//跨线程操作Success[0] = Success[1] = Success_Sum = 0;}//进行抽卡模拟的线程private int RolePrayer(int N,int[] Re, bool[] PRW, int Code){   /* N表示目标抽取数量* Re[5]是储存实际抽到数量的数组* PRW[4]是记录目标达成情况的bool型数组*/int N_Used = 0;//使用的纠缠之缘数量int RandomNumber = 0;int BaoDi = 0;//保底计数器while(Re[Code] < N){RandomNumber = randomNum(1000);BaoDi++;N_Used++;if ((RandomNumber>=1 && RandomNumber<=6)||(BaoDi == 90)){//抽到了5星的情况if (NextRoleIsBig)//如果是大保底{Re[Code]++;NextRoleIsBig = false;}else//小保底但是不确定会不会歪常驻{RandomNumber = randomNum(1000);if (RandomNumber >= 1 && RandomNumber <= 500)//没歪Re[Code]++;else//歪了{Re[4]++;//R[4]表示歪的常驻的数量NextRoleIsBig = true;//下次就是大保底了}}BaoDi = 0;}}PRW[Code] = true;return N_Used;}//角色池祈愿的方法private int WeaponPrayer(int N, int[] Re, bool[] PRW, int Code){   /* N表示目标抽取数量* Re[5]是储存实际抽到数量的数组* PRW[4]是记录目标达成情况的bool型数组*/int N_Used = 0;//使用的纠缠之缘数量int RandomNumber = 0;int BaoDi = 0;//保底计数器if (Code == 3 && Num_Weapon_Base != 0)Num_Weapon_Base = 0;//抽第二把武器的时候更换定轨,归零while (Re[Code] < N){RandomNumber = randomNum(1000);BaoDi++;N_Used++;if ((RandomNumber >= 1 && RandomNumber <= 7) || (BaoDi == 80)){//出金的情况if (Num_Weapon_Base==2)//满定轨的情况{Re[Code]++;//必定出定轨武器Num_Weapon_Base = 0;//定轨归零}else//非满定轨{if (NextWeaponIsUp)//上一次出金歪的常驻{RandomNumber = randomNum(10);//两个UP武器中随机一个出if (RandomNumber>=1 && RandomNumber<=5){//出了定轨武器Re[Code]++;Num_Weapon_Base = 0;}else{//歪了另一把UP武器Num_Weapon_Base++;if (Code == 2) Re[3]++;else Re[2]++;}NextWeaponIsUp = false;}else//上一次没歪常驻,包括定轨0/2时的情况{RandomNumber = randomNum(20);if (RandomNumber >= 1 && RandomNumber <= 15)//75%的概率出UP武器{RandomNumber = randomNum(10);if (RandomNumber >= 1 && RandomNumber <= 5){//没歪Re[Code]++;Num_Weapon_Base = 0;}else{//歪了另一把UP武器Num_Weapon_Base++;if (Code == 2) Re[3]++;else Re[2]++;}}else//25%概率歪常驻了!{NextWeaponIsUp = true;Re[4]++;//获得的常驻数量+1}}}BaoDi = 0;}}PRW[Code] = true;NextWeaponIsUp = false;return N_Used;}//武器池祈愿的方法private int randomNum(int N)//使用RNGCryptoServiceProvider类生成随机数{Random r = new Random();int randomNumber;using (var rng = new RNGCryptoServiceProvider()){// 生成一个随机字节数组  byte[] randomBytes = new byte[4]; // 4 bytes for a uint32  rng.GetBytes(randomBytes);// 将字节数组转换为整数  randomNumber = BitConverter.ToInt32(randomBytes, 0);randomNumber += r.Next();randomNumber = Math.Abs(randomNumber) % N + 1;return randomNumber;}}//生成一个范围在[1,N]的随机数的方法private void comboBox_VersionChoose_SelectedIndexChanged(object sender, EventArgs e){ReTry://如果用户丢失了文件并选择了重试,就跳回这里//label_VersionChoose.Text = comboBox_VersionChoose.SelectedIndex.ToString();//调试用string path;bool FileLose = false;//没有文件丢失就是falsepath = "bins\\" + RoleName[comboBox_VersionChoose.SelectedIndex, 0] + "·头像.png";if (File.Exists(path))PB_Role_1.Image = Image.FromFile(path);else MessageBox.Show("文件丢失:" + path, "文件丢失", MessageBoxButtons.OK, MessageBoxIcon.Error);FileLose = FileLose || (!File.Exists(path));path = "bins\\" + RoleName[comboBox_VersionChoose.SelectedIndex, 1] + "·头像.png";if (File.Exists(path))PB_Role_2.Image = Image.FromFile(path);else MessageBox.Show("文件丢失:" + path, "文件丢失", MessageBoxButtons.OK, MessageBoxIcon.Error);FileLose = FileLose || (!File.Exists(path));path = "bins\\" + RoleName[comboBox_VersionChoose.SelectedIndex, 0] + "专武.png";if (File.Exists(path))PB_Weapon_1.Image = Image.FromFile(path);else MessageBox.Show("文件丢失:" + path, "文件丢失", MessageBoxButtons.OK, MessageBoxIcon.Error);FileLose = FileLose || (!File.Exists(path));path = "bins\\" + RoleName[comboBox_VersionChoose.SelectedIndex, 1] + "专武.png";if (File.Exists(path))PB_Weapon_2.Image = Image.FromFile(path);else MessageBox.Show("文件丢失:" + path, "文件丢失", MessageBoxButtons.OK, MessageBoxIcon.Error);FileLose = FileLose || (!File.Exists(path));if (FileLose){DialogResult DR=MessageBox.Show("文件已丢失,建议旅行者找回丢失资源或尝试卸载并重新安装。", "温馨提示", MessageBoxButtons.RetryCancel, MessageBoxIcon.Information);if (DR == DialogResult.Retry)goto ReTry;else{if (Thread_Load != null)Thread_Load.Abort();if (T_Imitate != null)T_Imitate.Abort();Thread_DataDetection.Abort();Application.Exit();}}foreach (Control C in panelMain.Controls)if ((C is ComboBox) && (C!=comboBox_VersionChoose)){ComboBox CB = (ComboBox)C;CB.SelectedIndex = 0;}}//卡池选择改变时触发private void button_More_Click(object sender, EventArgs e){Form_Poster FP = new Form_Poster(comboBox_VersionChoose.SelectedIndex);FP.Show();}private void panelMain_Paint(object sender, PaintEventArgs e){}private void pictureBox_Exit_Click(object sender, EventArgs e){DialogResult DR = MessageBox.Show("确认退出软件?", "询问", MessageBoxButtons.OKCancel);if (DR == DialogResult.OK){DialogResult Dr = MessageBox.Show("祝屏幕前的旅行者十连多金、小保底不歪!", "诚挚的祝福", MessageBoxButtons.OK);if (Dr==DialogResult.OK){if (Thread_Load != null)Thread_Load.Abort();if (T_Imitate != null)T_Imitate.Abort();Thread_DataDetection.Abort();Application.Exit();}}}private void textBox_Ball_TextChanged(object sender, EventArgs e){if (textBox_Ball.Text == "") textBox_Ball.Text = "0";else if ((textBox_Ball.Text[0]=='0') && (textBox_Ball.Text.Length == 2))//去掉多余的0,包括光标在0右侧时输入的情况textBox_Ball.Text = textBox_Ball.Text[1].ToString();//接下来将Text属性转化为数据并存储入NUM_Balltry{NUM_Ball = int.Parse(textBox_Ball.Text);}catch (FormatException){// 转换失败,用户可能输入了非数字字符  MessageBox.Show("包含非法字符,该输入框已清空,请输入有效的数字以表示拥有的纠缠之缘的数量!", "数据无效",MessageBoxButtons.OK,MessageBoxIcon.Warning);textBox_Ball.Text = "0";NUM_Ball = 0;return;}textBox_Ball.SelectionStart = textBox_Ball.Text.Length;//每次将光标移动到末尾}private void textBox_Stone_TextChanged(object sender, EventArgs e){if (textBox_Stone.Text == "") textBox_Stone.Text = "0";else if ((textBox_Stone.Text[0] == '0') && (textBox_Stone.Text.Length == 2))//去掉多余的0,包括光标在0右侧时输入的情况textBox_Stone.Text = textBox_Stone.Text[1].ToString();//接下来将Text属性转化为数据并存储入NUM_Stonetry{NUM_Stone = int.Parse(textBox_Stone.Text);}catch (FormatException){// 转换失败,用户可能输入了非数字字符  MessageBox.Show("包含非法字符,该输入框已清空,请输入有效的数字以表示拥有的原石的数量!", "数据无效", MessageBoxButtons.OK, MessageBoxIcon.Warning);textBox_Stone.Text = "0";NUM_Stone = 0;return;}textBox_Stone.SelectionStart = textBox_Stone.Text.Length;//每次将光标移动到末尾}private void checkBox4_CheckedChanged(object sender, EventArgs e){if (checkBox4.Checked)comboBox_WeaponN.Enabled = true;else comboBox_WeaponN.Enabled = false;if (checkBox4.Checked && comboBox_WeaponN.SelectedIndex == 0)checkBox5.Enabled = true;else checkBox5.Enabled = false;}private void comboBox_Weapon_1_SelectedIndexChanged(object sender, EventArgs e){if (comboBox_Weapon_1.SelectedIndex + comboBox_Weapon_2.SelectedIndex == 0)checkBox5.Enabled = checkBox4.Enabled = false;else checkBox5.Enabled = checkBox4.Enabled = true;//不计划抽取武器,则无法选取武器池定轨选项if ((comboBox_Weapon_1.SelectedIndex + comboBox_Weapon_2.SelectedIndex == 0) ||(comboBox_Role_1.SelectedIndex + comboBox_Role_2.SelectedIndex == 0))checkBox2.Enabled = false;else checkBox2.Enabled = true;//武器角色二种只抽取一种则无法选取“优先抽取武器”}private void comboBox_Weapon_2_SelectedIndexChanged(object sender, EventArgs e){if (comboBox_Weapon_1.SelectedIndex + comboBox_Weapon_2.SelectedIndex == 0)checkBox5.Enabled = checkBox4.Enabled = false;else checkBox5.Enabled = checkBox4.Enabled = true;//不计划抽取武器,则无法选取武器池定轨选项if ((comboBox_Weapon_1.SelectedIndex + comboBox_Weapon_2.SelectedIndex == 0) ||(comboBox_Role_1.SelectedIndex + comboBox_Role_2.SelectedIndex == 0))checkBox2.Enabled = false;else checkBox2.Enabled = true;//武器角色二种只抽取一种则无法选取“优先抽取武器”}private void comboBox_Role_1_SelectedIndexChanged(object sender, EventArgs e){if ((comboBox_Weapon_1.SelectedIndex + comboBox_Weapon_2.SelectedIndex == 0) ||(comboBox_Role_1.SelectedIndex + comboBox_Role_2.SelectedIndex == 0))checkBox2.Enabled = false;else checkBox2.Enabled = true;//武器角色二种只抽取一种则无法选取“优先抽取武器”if (comboBox_Role_1.SelectedIndex + comboBox_Role_2.SelectedIndex == 0)checkBox1.Enabled = checkBox3.Enabled = false;else checkBox1.Enabled = checkBox3.Enabled = true;//不抽取角色则无法选择“角色卡池为9折”}private void comboBox_Role_2_SelectedIndexChanged(object sender, EventArgs e){if ((comboBox_Weapon_1.SelectedIndex + comboBox_Weapon_2.SelectedIndex == 0) ||(comboBox_Role_1.SelectedIndex + comboBox_Role_2.SelectedIndex == 0))checkBox2.Enabled = false;else checkBox2.Enabled = true;//武器角色二种只抽取一种则无法选取“优先抽取武器”if (comboBox_Role_1.SelectedIndex + comboBox_Role_2.SelectedIndex == 0)checkBox1.Enabled = checkBox3.Enabled = false;else checkBox1.Enabled = checkBox3.Enabled = true;//不抽取角色则无法选择“角色卡池为9折”}private void button_Transport_Click(object sender, EventArgs e){if (NUM_Stone>=160){NUM_Ball += NUM_Stone / 160;NUM_Stone = NUM_Stone - NUM_Stone / 160 * 160;textBox_Ball.Text = NUM_Ball.ToString();textBox_Stone.Text = NUM_Stone.ToString();}}private void button_Start_Click(object sender, EventArgs e){int Ball = NUM_Ball + NUM_Stone / 160;//抽取的次数bool NotSelectedTarget = (comboBox_Role_1.SelectedIndex == 0) && (comboBox_Role_2.SelectedIndex == 0) && (comboBox_Weapon_1.SelectedIndex == 0) && (comboBox_Weapon_2.SelectedIndex == 0);//如果全部为0,就说明没有选择,那么值为trueif ((Ball>0 && Ball<=999)&&(checkBox_Ensure.Checked)&&(!NotSelectedTarget)){//先将数据清空表示所有给出的资源全部用于抽卡NUM_Ball = 0;NUM_Stone -= NUM_Stone / 160 * 160;textBox_Ball.Text = NUM_Ball.ToString();textBox_Stone.Text = NUM_Stone.ToString();label_Succ_1_3.Visible = label_Succ_2_3.Visible = label_Succ_3_3.Visible = true;//接下来调用线程进行模拟int[] Temp = new int[4] {comboBox_Role_1.SelectedIndex,comboBox_Role_2.SelectedIndex,comboBox_Weapon_1.SelectedIndex,comboBox_Weapon_2.SelectedIndex};//简单粗暴地避免跨线程访问问题NextRoleIsBig = checkBox3.Checked;if (checkBox4.Checked)//定轨不为0/2的情况Num_Weapon_Base = comboBox_WeaponN.SelectedIndex + 1;if (checkBox4.Checked && comboBox_WeaponN.SelectedIndex == 0 && checkBox5.Checked)NextWeaponIsUp = true;//定轨0/2歪常驻变成1/2的情况,下次必定是UP武器CheckBox[] CB = new CheckBox[5] { checkBox1, checkBox2, checkBox3, checkBox4, checkBox5 };T_Imitate = new Thread(() => imitate(Ball,Temp, CB, comboBox_WeaponN));T_Imitate.Start();Avaluable = false;button_Start.Text = "正在模拟,请稍等……";}else if (!(checkBox_Ensure.Checked))MessageBox.Show("请仔细阅读用户须知并勾选下方选项!");else{if (NotSelectedTarget)MessageBox.Show("请选择你的抽取目标!", "错误", MessageBoxButtons.OK, MessageBoxIcon.Information);else{MessageBox.Show("填入的已有资源超过允许模拟的最大限度!", "错误提示", MessageBoxButtons.OK, MessageBoxIcon.Error);NUM_Ball = NUM_Stone = 0;textBox_Ball.Text = textBox_Stone.Text = "0";}}textBox_Ball.SelectionStart = textBox_Ball.Text.Length;}private void linkLabel_ScreenShot_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e){try{linkLabel_ScreenShot.Visible = false;//接下来开始截图与保存操作Bitmap BM = new Bitmap(this.ClientSize.Width, this.ClientSize.Height);using (Graphics G = Graphics.FromImage(BM)){G.CopyFromScreen(this.PointToScreen(new Point(0, 0)), Point.Empty, this.ClientSize);}DateTime CurruntTime = DateTime.Now;string FileName = "ScreenShot_" + CurruntTime.ToString("yyyyMMddHHmmss") + ".png";BM.Save("bins\\ScreenShot\\" + FileName, System.Drawing.Imaging.ImageFormat.Png);//到此linkLabel_ScreenShot.Visible = true;MessageBox.Show("截图已保存至 安装目录/bins/ScreenShot/" + FileName);}catch(Exception Ex){MessageBox.Show("发生错误:" + Ex.Message);}}private void label_Succ_2_2_Click(object sender, EventArgs e){}private void label_Succ_2_3_Click(object sender, EventArgs e){}private void label_Succ_2_1_Click(object sender, EventArgs e){}private void comboBox_WeaponN_SelectedIndexChanged(object sender, EventArgs e){if (checkBox4.Checked && comboBox_WeaponN.SelectedIndex == 0)checkBox5.Enabled = true;else checkBox5.Enabled = false;}private void checkBox1_CheckedChanged(object sender, EventArgs e){}private void pictureBox_README_Click(object sender, EventArgs e){README RM = new README();RM.Show();}}
}

2.Form_Poster页面(祈愿海报页面)

设计器:

页面代码:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Threading;
using System.IO;namespace 概率计算器___Genshin_Impact
{public partial class Form_Poster : Form{public Form_Poster(int N_Mode){InitializeComponent();Mode = N_Mode;pictureBox_Down.DoubleClick += pictureBox_Down_Click;pictureBox_Up.DoubleClick += pictureBox_Up_Click;}#region 变量的声明public int Mode = 0;Thread TTF = null;public int CurruntPage = 1;string[,] RoleName = new string[4, 2] {{"娜维娅", "神里绫华" },//4.3上半卡池,卡池编码为0{"雷电将军", "宵宫" },//4.3下半卡池,卡池编码为1{ "闲云", "纳西妲" }, //4.4上半卡池,卡池编码为2{ "魈", "八重神子" }//4.4下半卡池,卡池编码为3};//第一维度为版本编号,第二维度为卡池序号//比如4.4上半对应第一维度,而角色祈愿-2对应第二维度//角色池图片名称为RoleName[m,n] + ".png"//武器池图片名称为RoleName[m,0] + "-" + RoleName[m,1] + "-专武.png"#endregionprivate void Form_Poster_Load(object sender, EventArgs e){this.Opacity = 0;TTF = new Thread(() => Thread_TransparencyFade());TTF.Start();foreach (Control Con in this.Controls)Con.BackColor = Color.FromArgb(0, 0, 0, 0);ReTrySearchFile://如果选择ReTry就跳回这里string path;bool FileLose = false;//文件没丢失就是falsepath = "bins\\" + RoleName[Mode, 0] + ".png";if (File.Exists(path))pictureBox_Role_1.Image = Image.FromFile(path);else MessageBox.Show("文件丢失:" + path, "文件丢失", MessageBoxButtons.OK, MessageBoxIcon.Error);FileLose = FileLose || (!File.Exists(path));path = "bins\\" + RoleName[Mode, 1] + ".png";if (File.Exists(path))pictureBox_Role_2.Image = Image.FromFile(path);else MessageBox.Show("文件丢失:" + path, "文件丢失", MessageBoxButtons.OK, MessageBoxIcon.Error);FileLose = FileLose || (!File.Exists(path));path = "bins\\" + RoleName[Mode, 0] + "-" + RoleName[Mode, 1] + "-专武.png";if (File.Exists(path))pictureBox_Weapon.Image = Image.FromFile(path);else MessageBox.Show("文件丢失:" + path, "文件丢失", MessageBoxButtons.OK, MessageBoxIcon.Error);FileLose = FileLose || (!File.Exists(path));if (FileLose){//文件已丢失DialogResult DR = MessageBox.Show("文件已丢失,建议旅行者找回丢失资源或尝试卸载并重新安装。", "温馨提示", MessageBoxButtons.RetryCancel, MessageBoxIcon.Information);if (DR == DialogResult.Retry)goto ReTrySearchFile;else{if (TTF != null)TTF.Abort();Application.Exit();}}pictureBox_Role_2.Location = pictureBox_Weapon.Location = pictureBox_Role_1.Location;pictureBox_Role_2.Visible = pictureBox_Weapon.Visible = false;}private void Thread_TransparencyFade(){int transparency = -5;do{transparency += 5;Invoke(new Action(() =>{this.Opacity = (double)transparency / 100;}));//跨线程操作Thread.Sleep(5);} while (transparency < 100);}//透明淡入的线程private void Thread_Out(){int transparency = 105;do{transparency -= 5;Invoke(new Action(() =>{this.Opacity = (double)transparency / 100;}));//跨线程操作Thread.Sleep(5);} while (transparency > 0);Invoke(new Action(() =>{this.Close();}));//跨线程操作}//透明淡出的线程private void pictureBox_Out_Click(object sender, EventArgs e){if (TTF != null){TTF.Abort();TTF = new Thread(() => Thread_Out());TTF.Start();}}private void pictureBox_Up_Click(object sender, EventArgs e){if (CurruntPage >= 2) CurruntPage--;else CurruntPage = 3;switch(CurruntPage){case 1:pictureBox_Role_2.Visible = false;pictureBox_Role_1.Visible = true;break;case 2:pictureBox_Weapon.Visible = false;pictureBox_Role_2.Visible = true;break;case 3:pictureBox_Role_1.Visible = false;pictureBox_Weapon.Visible = true;break;}}private void pictureBox_Down_Click(object sender, EventArgs e){if (CurruntPage <= 3) CurruntPage++;else CurruntPage = 1;switch (CurruntPage){case 1:pictureBox_Weapon.Visible = false;pictureBox_Role_1.Visible = true;break;case 2:pictureBox_Role_1.Visible = false;pictureBox_Role_2.Visible = true;break;case 3:pictureBox_Role_2.Visible = false;pictureBox_Weapon.Visible = true;break;}}}
}

3.README页面(说明页面)

设计器:

页面代码:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Diagnostics;namespace 概率计算器___Genshin_Impact
{public partial class README : Form{public README(){InitializeComponent();}private void README_Load(object sender, EventArgs e){}private void label_Link_Click(object sender, EventArgs e){try{Process.Start("http://sherrychou.blog.csdn.net");}catch (Exception E){MessageBox.Show("出现错误:" + E.Message, "出错啦", MessageBoxButtons.OK, MessageBoxIcon.Error);}this.Close();}private void pictureBox1_Click(object sender, EventArgs e){}}
}

4. 应用程序清单文件

将以下代码取消注释。

  <application xmlns="urn:schemas-microsoft-com:asm.v3"><windowsSettings><dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">true</dpiAware></windowsSettings></application>

四、其他说明

1.本软件不用于盈利,也不允许被用于盈利,如发现用该软件盈利的行为,欢迎举报!

2.本软件内的一切图片素材版权仍归 上海米哈游网络科技股份有限公司 与 上海米哈游天命科技有限公司 所有。

3.使用过程中如发现任何不应该出现的技术问题,欢迎联系作者反馈!

文章字数统计君:22565字

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

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

相关文章

猫头虎分享已解决Bug || DNS解析问题(DNS Resolution Issue):DNSLookupFailure, DNSResolveError

博主猫头虎的技术世界 &#x1f31f; 欢迎来到猫头虎的博客 — 探索技术的无限可能&#xff01; 专栏链接&#xff1a; &#x1f517; 精选专栏&#xff1a; 《面试题大全》 — 面试准备的宝典&#xff01;《IDEA开发秘籍》 — 提升你的IDEA技能&#xff01;《100天精通鸿蒙》 …

大学生必备搜题软件推荐?找题不再难!好用的大学搜题工具推荐 #媒体#职场发展

在快节奏的大学生活中&#xff0c;合理利用这些日常学习工具&#xff0c;能够让你事半功倍&#xff0c;提高学习效率。 1.茱莉亚公开课 茱莉亚公开课APP不是一款针对所有人的应用&#xff0c;是针对对艺术有特殊爱好和艺术领域的人 茱莉亚音乐学院里面都是世界著名的茱莉亚音…

Vulhub kali 环境安装教程

进入 root 权限 sudo su 更新软件 apt-get update 安装 HTTPS 协议和 CA 证书 apt-get install -y apt-transport-https ca-certificates 安装 docker apt install docker.io 查看 docker 是否安装完成 docker -v 安装 pip apt-get install python3-pip 安装 docker-compose do…

Linux第57步_“linux系统镜像”和“根文件系统”重新打包小结

实时总结是很重要的&#xff0c;时间久了&#xff0c;可能会遗忘。下面是“linux系统镜像”和“根文件系统”重新打包小结。 1、linux系统镜像重新打包 在第1次完成linux系统镜像打包后&#xff0c;再重新打包就很容易了 将“bootfs”重新打包 准备打包文件: 输入“cd /ho…

(10)Hive的相关概念——文件格式和数据压缩

目录 一、文件格式 1.1 列式存储和行式存储 1.1.1 行存储的特点 1.1.2 列存储的特点 1.2 TextFile 1.3 SequenceFile 1.4 Parquet 1.5 ORC 二、数据压缩 2.1 数据压缩-概述 2.1.1 压缩的优点 2.1.2 压缩的缺点 2.2 Hive中压缩配置 2.2.1 开启Map输出阶段压缩&…

MySQL篇之回表查询

一、聚集索引 将数据存储与索引放到了一块&#xff0c;索引结构的叶子节点保存了行数据。特点&#xff1a;必须有,而且只有一个。 聚集索引选取规则: 1. 如果存在主键&#xff0c;主键索引就是聚集索引。 2. 如果不存在主键&#xff0c;将使用第一个唯一&#xff08;UNIQUE&am…

Linux环境中的git

目录 1.要使用git&#xff0c;首先要安装git 2.首次使用git需要做的操作 3.git操作 1.要使用git&#xff0c;首先要安装git 指令&#xff1a;sudo yum install -y git 2.首次使用git需要做的操作 在gitee网页&#xff0c;在你的仓库中找到&#xff1a; 先将下面两行代码分别…

高中生护眼台灯怎么选?教育部认可护眼灯品牌

随着孩子步入更高的年级&#xff0c;学业压力也会越来越繁重&#xff0c;随之带来的也是更长时间的用眼和高近视率。众所周知&#xff0c;高中是孩子学业最繁忙的一段时期&#xff0c;同时也是青少年近视的重灾区&#xff0c;不少学生因为每天过度用眼&#xff0c;再加上缺少户…

【Cocos入门】物理系统(物理碰撞)

物理碰撞 物理引擎默认是关闭状态以节省资源开销。开启方法和之前的普通碰撞类似&#xff1a;cc.director.getPhysicsManager().enabled true但有一个区别&#xff0c;物理引擎的开启必须放在onLoad函数内运行&#xff0c;否则不生效。 物理碰撞组件也同样具有碰撞回调函数。…

day14笔记(多态)

多态 自己写多态演示遇见两个问题 1.在类里写show方法时犹豫要不要写参数,其实不用写参数也可以获取到类的信息 public void show(){//括号里面写参数吗System.out.println(getName()", "getAge());} 2.在测试类里面写方法时,写了一个show方法带参数,其实这里应该是…

【网站项目】229企业员工薪酬关系系统

&#x1f64a;作者简介&#xff1a;拥有多年开发工作经验&#xff0c;分享技术代码帮助学生学习&#xff0c;独立完成自己的项目或者毕业设计。 代码可以私聊博主获取。&#x1f339;赠送计算机毕业设计600个选题excel文件&#xff0c;帮助大学选题。赠送开题报告模板&#xff…

【计算机是如何工作的】编程语言是如何与CPU指令对应起来

编程语⾔&#xff08;Program Language&#xff09; 程序&#xff08;Program&#xff09;早期编程编程语⾔发展操作系统&#xff08;Operating System&#xff09;什么是进程/任务&#xff08;Process/Task&#xff09;进程控制块抽象(PCB Process Control Block)CPU 分配⸺进…

[OPEN SQL] 新增数据

INSERT语句用于数据的新增操作 本次操作使用的数据库表为SCUSTOM&#xff0c;其字段内容如下所示 航班用户(SCUSTOM) 该数据库表中的部分值如下所示 1.插入单条数据 语法格式 INSERT <dbtab> FROM <wa>. INSERT INTO <dbtab> VALUES <wa>. INSERT &…

【Cocos入门】物理检测

目录 一、物理检测的概念二、点测试三、矩形测试四、射线测试 一、物理检测的概念 CoCos中&#xff0c;物理检测也是物理系统的一部分&#xff0c;它不是用于检测物体的物理特性的&#xff0c;而是用来查询物体的(比如某个地方是否存在物理碰撞体)。其又分成&#xff1a;点检测…

编程和计算机基础

编程 编程&#xff1a;就是让计算机为解决某个问题而使用某种程序设计语言编写程序代码&#xff0c;并最终得到结果的过程。 计算机程序&#xff1a;是计算机所执行的一系列的指令集合&#xff0c;而程序全部都是用我们所掌握的语言来编写的&#xff0c;所以人们控制计算机一…

云备份项目:在云端保护您的数据【一、初识】

桃李不言&#xff0c;下自成蹊 文章目录 项目简介项目设计方案服务端功能划分客户端功能划分 项目环境搭建环境准备第三方库JsonCppbundle数据压缩库httplib 总结 ☘️项目源代码&#xff1a;云备份 ☘️云备份专栏&#xff1a;云备份 项目简介 云备份系统是一个自动化的备份解…

Spring 事务原理总结四

作为一名认知有限的中国人&#xff0c;我对年的喜爱&#xff0c;胜过其他一切&#xff0c;因为它给了我拒绝一切的合理理由。每到这个时候&#xff0c;我都会用各种理由来为自己的不作为开脱&#xff0c;今年亦是如此。看着频频发出警报的假期余额&#xff0c;我内心的焦躁变得…

【优化数学模型】1. 基于Python的线性规划问题求解

【优化数学模型】1. 基于Python的线性规划问题求解 一、线性规划问题1.概述2.三要素 二、示例&#xff1a;药厂生产问题三、使用 Python 绘图求解线性规划问题1.绘制约束条件2.绘制可行域3.绘制目标函数4.绘制最优解 四、使用 scipy.optimize 软件包求解线性规划问题1.导入库2.…

CAN通讯协议学习

介绍 它是一种异步通讯&#xff0c;can_high和can_low两条线利用的是电位差传输信号&#xff0c;抗干扰能力强&#xff0c;但是必须要有can控制器如TJA1050&#xff08;我的开发板&#xff09; 当 CAN 节点需要发送数据时&#xff0c;控制器把要发送的二进制编码通过 CAN_Tx 线…

数仓建模—数据网格

数据网格 随着数字化时代的到来,近几年数据领域的新技术概念不断涌现,无论是数据湖、湖仓一体、流批一体、存算一体、数据编织抑或数据网格,很多还爬上了Gartner曲线,其中数据网格备受关注,数据网格从字面意思来看挺抽象的,会劝退很多人,但当你深入去理解这个概念时,才…