2023年5月23日 星期二

[.net]Mylottery樂透中獎程式練習

最近改版之前喜歡作的樂透開獎程式,不知道為什麼就是喜歡做這種小程式練習自己小專案的執行能力。
這次程式是改版之前第一板之後的第二板,這次多學會一些Linq的技巧,放在這個小專案來練習一下,順便想起要中頭獎的機率低到還是回頭寫Code來得實際。

buy:購買一張彩券,看是否有中獎。
clear: 清除之前購買的彩券紀錄,重新統計資料。
autobuy:自動購買彩券直到中獎為止,若機率太低程式會跑一段時間。


另外可以自行設置要配對的數字個數(中幾個數字Set Match),與可選球池的最大數字(Number1~??)`。所有數字都是隨機產出,不需要手動Key購買的彩券。

程式碼如下:

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Windows.Forms;

namespace Mylotterytest
{
    public partial class Form1 : Form
    {
        private Random myWinnum = new Random();
        private Label[] lbwinnum = new Label[6];
        private TextBox[] tbnum = new TextBox[6];
        private double count = 0;
        private double wincount = 0;
        private int maxNum = 36;
        private int setMatch = 3;
        public Form1()
        {
            InitializeComponent();

            lbwinnum[0] = lb_win1;
            lbwinnum[1] = lb_win2;
            lbwinnum[2] = lb_win3;
            lbwinnum[3] = lb_win4;
            lbwinnum[4] = lb_win5;
            lbwinnum[5] = lb_win6;
            tbnum[0] = tb_lot1;
            tbnum[1] = tb_lot2;
            tbnum[2] = tb_lot3;
            tbnum[3] = tb_lot4;
            tbnum[4] = tb_lot5;
            tbnum[5] = tb_lot6;
        }

        private void btn_buy_Click(object sender, EventArgs e)
        {
            List<int> numlist = new List<int>() ;
            List<int> buynumlist = new List<int>();
            maxNum = Convert.ToInt32(tb_maxNum.Text) + 1;
            for (int i = 0; i < 6; i++)
            {
                buynumlist.Add(Convert.ToInt32(tbnum[i].Text));
            }

            RandomList(numlist);

            for (int i = 0; i < lbwinnum.Length; i++)
            {
                lbwinnum[i].Text = numlist[i].ToString();
            }
            
            var SameNum = numlist.Where(i => buynumlist.Contains(i)).Count();
            lb_match.Text = SameNum.ToString();
            lb_buycount.Text = count.ToString();
            count++;
            if (SameNum >= 3)
                MessageBox.Show("3 Match!");
        }

        private void btn_countclear_Click(object sender, EventArgs e)
        {
            count = 0;
            wincount = 0;
        }
        private void RandomList(List<int> numlist)
        {
            for (int i = 0; i < 6; i++)
                numlist.Add(myWinnum.Next(1, maxNum));

            var same = numlist.GroupBy(x => x).Any(g => g.Count() > 1);
            while (same)
            {
                numlist.Clear();
                for (int i = 0; i < 6; i++)
                    numlist.Add(myWinnum.Next(1, maxNum));
                same = numlist.GroupBy(x => x).Any(g => g.Count() > 1);
            }
            numlist.Sort();
        }

        private void btn_autobuy_Click(object sender, EventArgs e)
        {
            List<int> numlist = new List<int>();
            List<int> buynumlist = new List<int>();
            maxNum = Convert.ToInt32(tb_maxNum.Text) + 1;
            setMatch = Convert.ToInt32(tb_setMatch.Text);
            //count = 0;
            RandomList(numlist);
            RandomList(buynumlist);
            var SameNum = numlist.Where(i => buynumlist.Contains(i)).Count();
            count++;
            while (SameNum < setMatch)
            {
                numlist.Clear();
                buynumlist.Clear();
                RandomList(numlist);
                RandomList(buynumlist);
                SameNum = numlist.Where(i => buynumlist.Contains(i)).Count();
                count++;
            }
            wincount++;
            for (int i = 0; i < lbwinnum.Length; i++)
            {
                lbwinnum[i].Text = numlist[i].ToString();
                tbnum[i].Text = buynumlist[i].ToString();
            }
            lb_match.Text = SameNum.ToString();
            lb_matchcount.Text = wincount.ToString();
            lb_buycount.Text = count.ToString();
            lb_winrate.Text = ((wincount / count) * 100).ToString("0.00000000") + "%";
        }
    }
}

操作起來非常簡單,只需要設定球池最大數以及配對成功數量即可運轉。



要配對三個數字的大樂透原來機率這麼低呀!要中100次需要買5654張樂透才有機會。



看到頭獎的機率,還是回頭是岸吧!腳踏實地賺錢比較實在!


裡面有使用Linq中的GroupBy算是很初階的使用方式,學了Linq才發現程式好玩的地方,如傳言學習Linq就回不去了。好用簡潔方便維護的程式碼真的好吃又不黏牙。


[.net]使用計時器作後台運算使用Stopwatch

最近在統計設備運轉的時間,計時器意外的好用,可以知道每個動作需要花多少時間完成,其中有異常的部份可以抓出發生的頻率以及發生的固定模式。

統計運轉效率也是客戶的需求之一,提昇設備整體速度首要作的是尋找瓶頸工程,在該處動刀才能改善設備速度,降低運轉時間。

這邊自行作一個簡單的範例使用C#提供的Stopwatch,可以紀錄經過時間到毫秒。簡單界面如下圖:



與一般使用Timer的計時器不同,Stopwatch是使用系統時間作紀錄,Timer會佔用運算時間導致不準確的情況。

 
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
 public partial class Form1 : Form
    {
        System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch();

        public Form1()
        {
            InitializeComponent();
        }

        private void btn_Startsw_Click(object sender, EventArgs e)
        {
            sw.Start();
        }

        private void btn_Stopsw_Click(object sender, EventArgs e)
        {
            sw.Stop();
            label1.Text = sw.Elapsed.TotalSeconds.ToString("0.000") + "(s).";
        }

        private void btn_Resetsw_Click(object sender, EventArgs e)
        {
            sw.Reset();
            label1.Text = "0" + "(s).";
        }
    }


使用Stopwatch統計資料得心應手,簡單方便不受Thread的限制免去處理跨執行序的問題。