NEWS

[C# - Console] - Tạo ứng dụng đơn giản Lấy random Item theo Phần trăm xuất hiện

[C# - Console] - Tạo ứng dụng đơn giản Lấy random Item theo Phần trăm xuất hiện
Đăng bởi: TONA Cody - Lượt xem: 8139 15:28:52, 28/11/2020C#   In bài viết

Hôm nay mình làm một ví dụ đơn giản về một bài lấy random số theo một tỷ lệ % xuất hiện được cho.

Làm thế nào để tính phần trăm xuất hiện một cách ngẩu nhiên của một Item trong một list ?

Bài toán như sau:

Cho một danh sách các item, ứng với mỗi item là một tỷ lệ khác nhau. Tỷ lệ này sẽ quyết định xác suất xuất hiện khi mình thực hiện lệnh random. Giống như các trò chơi quay thưởng trong các game vậy đó.

Thực hiện: 

Đầu tiên mình có List này: Tạo cho nó 1 kiểu là kiểu Item. Trong list này, mình để thông số % là tròn 100% và các mức tỷ lệ không giống nhau cho nó dễ nhất.

Thực hiện Sort List cho nó tăng dần theo tỷ lệ phần trăm.

Tạo một ramdom từ 0 tới 100, nếu nó ra số nàm ở mức nào thì return luôn kết quả.

Done ! Ez game :)

Ở Ví dụ mẫu mình có thêm một vòng Do While, để thử tính coi, trong 1 lần nhấn thì mất bao nhiêu lần vòng lặp để có được kết quả là Item có tỷ lệ thấp nhất.

Vấn đề mình gặp phải là khi mình Random trong một vòng lặp thì kết quả của random sẽ bị sử dụng lại. Do đó, khá nhiều lần random sẽ có kết quả như nhau. Điều này làm sai đi ý nghĩa của Random. Do đó, để mỗi vòng lặp phải cho kết quả Random khác nhau, mình buộc phải viết thêm một chút về hàm Random:

private static readonly Random random = new Random();
private static readonly object syncLock = new object();

public static int RandomNumber(int min, int max)
        {
            lock (syncLock)
            { // synchronize
                return random.Next(min, max);
            }
        }

Và đây là toàn bộ code, C# console:

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

namespace PercentageItemXample
{
    class Program
    {
        static void Main(string[] args)
        {
            List<Item> Bonus = new List<Item>() { 
                new Item() { ID=1,Name="Gỗ", Percentage=100},
                new Item() { ID=2,Name="Sắt", Percentage=60},
                new Item() { ID=3,Name="Đồng", Percentage=30},
                new Item() { ID=4,Name="Bạc", Percentage=15},
                new Item() { ID=5,Name="Vàng", Percentage=8},
                new Item() { ID=6,Name="Bạch Kim", Percentage=4},
                new Item() { ID=7,Name="Kim Cương", Percentage=2},
                new Item() { ID=8,Name="Ngọc Trai Đen", Percentage=1},
                //new Item() { ID=9,Name="Vibranium", Percentage=0.05},
                //new Item() { ID=10,Name="Adamantium", Percentage=0.03},
                //new Item() { ID=11,Name="Infinity Stones", Percentage=0.012},
                //new Item() { ID=12,Name="Nhện cắn thành Anh Hùng", Percentage=0.008}
            };
            List<Item> SortedList = Bonus.OrderBy(o => o.Percentage).ToList();
            
            //Console.WriteLine($"The Percent is: {randomPercentage} %");
            Console.OutputEncoding = Encoding.UTF8;

            double per = 0 ;
            int count = 0;
            int randomPercentage=999;
        Go:
            do
            {
                count++;
                randomPercentage = RandomNumber(0, 100);

                foreach (Item i in SortedList)
                {
                    if (randomPercentage <= i.Percentage)
                    {
                        per = i.Percentage;
                        Console.WriteLine($"Item you have got is: {i.Name} 
Number:{randomPercentage} 
After: {count} times.  
The Percent is: {per} %");

                        break;
                    }
                }
            } while (randomPercentage > 1);

            count = 0; 
            Console.WriteLine("

===============================================");
            Console.WriteLine("Again? Press Enter. Otherwise press any key.");
            ConsoleKeyInfo again = Console.ReadKey();
            if (again.Key == ConsoleKey.Enter)
                goto Go;

                Console.ReadLine();
        }

        private static readonly Random random = new Random();
        private static readonly object syncLock = new object();
        public static int RandomNumber(int min, int max)
        {
            lock (syncLock)
            { // synchronize
                return random.Next(min, max);
            }
        }
    }

    public class Item
    {
        public int ID { get; set; }
        public string Name { get; set; }
        public double Percentage { get; set; }
    }
}

Các dạng Random này sẽ gặp nhiều trong các game, sự kiện quay thưởng. Trên đây chỉ là một VD siêu nhỏ trong đó. Ngoài ra dễ gặp nhất còn có quay thưởng mà tỷ lệ các Item còn nhỏ hơn 1, thậm chí là nhỏ hơn 0.01 (Mấy bạn chơi game quay súng chắc biết :D). Nếu thấy bài viết hay, hãy like và share. Hoặc để lại ý kiến góp ý trong phần Comment để chúng mình hoàn thiện và có những bài viết tốt hơn.

Cám ơn đã theo dõi bài viết của mình !

DOWNLOAD SOURCE

THÔNG TIN TÁC GIẢ

BÀI VIẾT LIÊN QUAN

[C# - Console] - Tạo ứng dụng đơn giản Lấy random Item theo Phần trăm xuất hiện
Đăng bởi: TONA Cody - Lượt xem: 8139 15:28:52, 28/11/2020C#   In bài viết

CÁC BÀI CÙNG CHỦ ĐỀ

Đọc tiếp
.