炸金花-模擬輸贏概率計算程式01
阿新 • • 發佈:2019-01-24
之前講到過用程式模擬炸金花這個過程,然後統計各種牌面的情況。最終通過大量的資料模擬,然後得到使用者輸贏的可能性。
由於前兩天是用java寫的,在控制檯裡面執行出來的。感覺不太過癮,逼格不搞,湊巧今天家裡停電了,百無聊賴之際打開了VS。
幾個月沒怎麼碰VS的了,用C#寫程式都有點生疏了。和java裡面還是有些不同的。
上圖說話:
控制檯裡面的,基本沒啥毛病的。
燃鵝寫的winform程式裡面還有個大bug,模擬洗牌的那個過程好像有點毛病,陣列的值並沒有被打亂。在java裡好好的,到C#裡怎麼有問題了的呢
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using CCWin; namespace 炸金花_概率計算 { public partial class Form1 : Skin_Color { public Form1() { InitializeComponent(); } static string[] DZ = new string[] { "A", "2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K" }; static string[] HS = new string[] { "紅心", "黑桃", "梅花", "方塊" }; public string[] data = new string[52]; private void Form1_Load(object sender, EventArgs e) { //初始化,一副新牌 int k = 0; for (int i = 0; i < DZ.Length; i++) { for (int j = 0; j < HS.Length; j++) { data[k] = DZ[i] + " " + HS[j]; //繫結到下拉列表中 //cb_Pai1.Items.Add(data[k]); //cb_Pai2.Items.Add(data[k]); //cb_Pai3.Items.Add(data[k]); k++; } } //繫結到下拉列表中,直接判斷陣列,相比上面一個個的新增要省事不少 cb_Pai1.Items.AddRange(data); cb_Pai2.Items.AddRange(data); cb_Pai3.Items.AddRange(data); } private void But_Static_Click(object sender, EventArgs e) { //檢查所選的三張牌是否合法 string cb_p1 = this.cb_Pai1.Text, cb_p2 = this.cb_Pai2.Text, cb_p3 = this.cb_Pai3.Text; if (cb_p1.Equals("") || cb_p2.Equals("")|| cb_p3.Equals(""))//判斷是否有底牌沒有選 { MessageBox.Show("請選擇你的底牌喲!", "親,這樣不對哦", MessageBoxButtons.OK, MessageBoxIcon.Warning); return; } else if (cb_p1.Equals(cb_p2) || cb_p2.Equals(cb_p3) || cb_p3.Equals(cb_p1))//判斷選擇的底牌是否有重複的 { MessageBox.Show("所選的底牌不合法,請重新選擇!", "親,這樣不對哦", MessageBoxButtons.OK, MessageBoxIcon.Warning); return; } //從陣列中剔除使用者所選的三張牌(也就是將這三張牌放到陣列的最後面),剩下的隨機組合和使用者所選的三張牌比大小 int index1 = cb_Pai1.SelectedIndex, index2 = cb_Pai2.SelectedIndex, index3 = cb_Pai3.SelectedIndex; data[index1] = data[51]; data[index2] = data[50]; data[index3] = data[49]; //獲取使用者手中牌的級別 int Boos = getJB(cb_p1, cb_p2, cb_p3); //模擬次數,預設十萬次,當rb_Count1選中時,則模擬一萬次 int count = 100 * 10; if (rb_Count1.Checked) { count = 100; } //設定進度條的最大值 pb_jingdu.Maximum = count; pb_Win.Maximum = count; pb_Shu.Maximum = count; //獲取參與遊戲的人數 int proper =int.Parse(nud_Num.Value.ToString()); //模擬count次牌局 for (int k = 0; k < count; k++) { getXP();//先洗牌一次 pb_jingdu.Value++; bool fa = true; for (int i = 0; i < proper - 1; i++) { int jibie = getJB(data[i * 3], data[i * 3 + 1], data[i * 3 + 2]); if (jibie > Boos) { pb_Shu.Value++; fa = false; break; } } if (fa) pb_Win.Value++; } } /// <summary> /// 判斷牌的大小級別 /// </summary> /// <param name="index1">第一張牌</param> /// <param name="index2">第二張牌</param> /// <param name="index3">第三張牌</param> /// <returns>級別大小說明:0-->散牌,1-->對子,2-->順子,3-->金花,4-->同花順,5-->三條</returns> private int getJB(string cb_p1, string cb_p2, string cb_p3) { //分割牌,hs為花色,ds為點數 string[] str1 = cb_p1.Split(' '); string[] str2 = cb_p2.Split(' '); string[] str3 = cb_p3.Split(' '); //點數,用於對子,順子的比較 string ds1 = str1[0]; string ds2 = str2[0]; string ds3 = str3[0]; //花色,用於金花的比較 string hs1 = str1[1]; string hs2 = str2[1]; string hs3 = str3[1]; //對子a==b或者a==c或者b==c if (ds1.Equals(ds2) || ds2.Equals(ds3) || ds3.Equals(ds1)) { //三條,只有先是對子,才可能是三條的,a==b,a==c if (ds1.Equals(ds2) && ds1.Equals(ds3)) { return 5;//三條,返回級別5 } else { return 1;//對子,返回級別2 } }else if(BoolShunzi(ds1,ds2,ds3))//判斷是否為順子,需將AJQK轉換成數字,然後再排序判斷 { //判斷是否為,同花順,花色要是一樣的 if (hs1.Equals(hs2) && hs1.Equals(hs3)) { return 4;//同花順,返回級別4 } else { return 2;//普通順子,返回級別2 } }else if (hs1.Equals(hs2) && hs1.Equals(hs3))//判斷是否為金花,即花色都一樣 { return 3;//金花,返回級別3 } else { return 0; //排除以上所有情況,剩下的就只有散牌嘍 } } /// <summary> /// 判斷是否為順子 /// </summary> /// <param name="ds1"></param> /// <param name="ds2"></param> /// <param name="ds3"></param> /// <returns></returns> private bool BoolShunzi(string ds1, string ds2, string ds3) { int[] arr = new int[3]; string[] shunzi = new string[] { ds1, ds2, ds3 }; //將AJQK轉換成數子 for (int i = 0; i < shunzi.Length; i++) { try { arr[i] = int.Parse(shunzi[i]); } catch (Exception e) { if (shunzi[i].Equals("A")) arr[i] = 1; else if (shunzi[i].Equals("J")) arr[i] = 11; else if (shunzi[i].Equals("Q")) arr[i] = 12; else arr[i] = 13; } } //排序 for (int i = 0; i < arr.Length; i++) { for (int j = 0; j < arr.Length; j++) { if (arr[i] > arr[j]) { int t = arr[i]; arr[i] = arr[j]; arr[j] = t; } } } //判斷 if (arr[0] - arr[1] == 1 && arr[1] - arr[2] == 1) { return true; } else if (arr[0] == 13 && arr[1] == 12 && arr[2] == 1)//QKA{ return true; else return false; } /// <summary> /// 洗牌,隨機交換兩次牌,次數100就可以模擬洗牌的過程 /// </summary> private void getXP() { for (int i = 0; i < 200; i++) { //兩個隨機數,然後交換牌的順序 Random r = new Random(); int r1 = r.Next(0, 49); int r2 = r.Next(0, 49); string temp = data[r1]; data[r1] = data[r2]; data[r2] = temp; } } } }
PS:半下午的時間,第一次寫這麼多的註釋,調理還算清晰,演算法也還算簡潔,介面也還湊合。還有一個地方解決下就好了!!操,突然家裡斷網了。還讓不讓人發表了