[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.rhkb.cn/news/257390.html

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

相关文章

Virt a Mate(VAM)游戏折腾记录

如有更新见原文&#xff1a;https://blog.iyatt.com/?p13283 1 前言 如果在网上看到有些视频名字带有 VAM 的&#xff0c;可能就是玩这个游戏录屏的。这个游戏可以建模、操作模型动作、构建场景等等。之前大致知道有这么个东西&#xff0c;只是电脑配置太差了&#xff0c;新…

文件上传-第三方服务阿里云OSS

JAVA后端实现文件上传,比如图片上床功能,有很多实现方案,可以将图片保存到服务器的硬盘上。也可以建立分布式集群,专门的微服务来存储文件常见的技术比如Minio。对于中小型公司&#xff0c;并且上传文件私密性不高的话可以使用第三方的存储服务&#xff0c;比如阿里云、华为云等…

投资银行在网络安全生态中的作用

文章目录 一、投资银行的含义(一)并购买方。(二)并购卖方。(三)IPO辅助。(四)投资银行业务的另一方面是帮助这些交易融资。二、从投资银行角度看网络安全产业(一)行业的短期前景三、复杂的网络安全并购(一)行业知识对投资银行业务很重要(二)在网络安全领域,技术…

文案馆头像壁纸微信小程序源码【支持流量主】

文案馆头像壁纸微信小程序源码【支持流量主】 源码介绍&#xff1a;文案馆头像壁纸微信小程序源码是一款可以获取套图、头像、壁纸的小程序。小程序源码内置流量主功能 需求环境&#xff1a;微信小程序phpmysql 下载地址&#xff1a; https://www.changyouzuhao.cn/13453.ht…

分析一个项目(微信小程序篇)二

目录 首页&#xff1a; 发现&#xff1a; 购物车&#xff1a; 我的&#xff1a; 分析一个项目讲究的是如何进行对项目的解析分解&#xff0c;进一步了解项目的整体结构&#xff0c;熟悉项目的结构&#xff0c;能够知道每个组件所处在哪个位置&#xff0c;发挥什么作用。 接…

(三十八)大数据实战——Atlas元数据管理平台的部署安装

前言 Apache Atlas 是一个开源的数据治理和元数据管理平台&#xff0c;旨在帮助组织有效管理和利用其数据资产。为组织提供开放式元数据管理和治理功能 &#xff0c;用以构建其数据资产目录&#xff0c;对这些资产进行分类和管理&#xff0c;形成数据字典 。并为数据分析师和数…

JVM(4)原理篇

1 栈上的数据存储 在Java中有8大基本数据类型&#xff1a; 这里的内存占用&#xff0c;指的是堆上或者数组中内存分配的空间大小&#xff0c;栈上的实现更加复杂。 以基础篇的这段代码为例&#xff1a; Java中的8大数据类型在虚拟机中的实现&#xff1a; boolean、byte、char…

基于LightGBM的回归任务案例

在本文中&#xff0c;我们将学习先进的机器学习模型之一&#xff1a;Lightgbm。在对XGB模型进行了越来越多的改进以获得更好的性能之后&#xff0c;XGBoost是一种极限梯度提升机器&#xff0c;但通过lightgbm&#xff0c;我们可以在没有太多计算的情况下实现类似或更好的结果&a…

洛谷C++简单题小练习day11—字母转换,分可乐两个小程序

day11--字母转换--2.14 习题概述 题目描述 输入一个小写字母&#xff0c;输出其对应的大写字母。例如输入 q[回车] 时&#xff0c;会输出 Q。 代码部分 #include<bits/stdc.h> using namespace std; int main() { char n;cin>>n;cout<<char(n-32)<…

为自监督学习重构去噪扩散模型

在这项研究中&#xff0c;作者检验了最初用于图像生成的去噪扩散模型&#xff08;DDM&#xff09;的表示学习能力。其理念是解构DDM&#xff0c;逐渐将其转化为经典的去噪自动编码器&#xff08;DAE&#xff09;。这一解构过程让大家能够探索现代DDM的各个组成部分如何影响自监…

18 19 SPI接口的74HC595驱动数码管实验

1. 串行移位寄存器原理&#xff08;以四个移位寄存器为例&#xff09; 1. 通过移位寄存器实现串转并&#xff1a;一个数据输入端口可得到四位并行数据。 通过给data输送0101数据&#xff0c;那么在经过四个时钟周期后&#xff0c;与data相连的四个寄存器的输出端口得到了0101…

FileZilla Server 1.8.1内网搭建

配置环境服务器服务器下载服务器配置服务器配置 Server - ConfigureServer Listeners - Port 协议设置 Protocols settingsFTP and FTP over TLS(FTPS) Rights management(权利管理)Users(用户) 客户端建立连接 配置环境 服务器处于局域网内: 客户端 < -访问- > 公网 &l…

Stable Diffusion 模型下载:DreamShaper(梦想塑造者)

本文收录于《AI绘画从入门到精通》专栏&#xff0c;专栏总目录&#xff1a;点这里。 文章目录 模型介绍生成案例案例一案例二案例三案例四案例五案例六案例七案例八案例九案例十 下载地址 模型介绍 DreamShaper 是一个分格多样的大模型&#xff0c;可以生成写实、原画、2.5D 等…

实例分割论文阅读之:FCN:《Fully Convolutional Networks for Semantica Segmentation》

论文地址:https://openaccess.thecvf.com/content_cvpr_2015/papers/Long_Fully_Convolutional_Networks_2015_CVPR_paper.pdf 代码链接&#xff1a;https://github.com/pytorch/vision 摘要 卷积网络是强大的视觉模型&#xff0c;可以产生特征层次结构。我们证明&#xff0c…

ChatGPT高效提问—prompt实践(漏洞风险分析-重构建议-识别内存泄漏)

ChatGPT高效提问—prompt实践&#xff08;漏洞风险分析-重构建议-识别内存泄漏&#xff09; 1.1 漏洞和风险分析 ChatGPT还可以帮助开发人员预测代码的潜在风险&#xff0c;识别其中的安全漏洞&#xff0c;而不必先运行它&#xff0c;这可以让开发人员及早发现错误&#xff0…

测试开发-2-概念篇

文章目录 衡量软件测试结果的依据—需求1.需求的概念2.从软件测试人员角度看需求3.为什么需求对软件测试人员如此重要4.如何才可以深入理解被测试软件的需求5.测试用例的概念6.软件错误&#xff08;BUG&#xff09;的概念7.开发模型和测试模型8.软件的生命周期9.瀑布模型&#…

Spring Boot 笔记 007 创建接口_登录

1.1 登录接口需求 1.2 JWT令牌 1.2.1 JWT原理 1.2.2 引入JWT坐标 1.2.3 单元测试 1.2.3.1 引入springboot单元测试坐标 1.2.3.2 在单元测试文件夹中创建测试类 1.2.3.3 运行测试类中的生成和解析方法 package com.geji;import com.auth0.jwt.JWT; import com.auth0.jwt.JWTV…

gem5 garnet 合成流量: packet注入流程

代码流程 下图就是全部. 剩下文字部分是细节补充,但是内容不变: bash调用python,用python配置好configuration, 一个cpu每个tick运行一次,requestport发出pkt. bash 启动 python文件并配置 ./build/NULL/gem5.debug configs/example/garnet_synth_traffic.py \--num-cpus…

kafka如何保证消息不丢?

概述 我们知道Kafka架构如下&#xff0c;主要由 Producer、Broker、Consumer 三部分组成。一条消息从生产到消费完成这个过程&#xff0c;可以划分三个阶段&#xff0c;生产阶段、存储阶段、消费阶段。 产阶段: 在这个阶段&#xff0c;从消息在 Producer 创建出来&#xff0c;…

mac IDEA基础配置和激活+maven配置+scala插件导入+scala文件打包

文章目录 下载IDEA通过插件激活下载Maven在IDEA上配置Maven在IDEA上加载Scala插件在IDEA中创建Maven项目在IDEA上通过Maven打包scala文件 下载IDEA通过插件激活 IDEA从这里下载&#xff0c;下载首次登陆需要创建一个IntelliJ账号&#xff0c;登陆后点击start trail开启一个月的…