Download app.py from testrro/RNG2: direct link, hf CLI and curl.
- Browser
- Download file 13.3 kB
-
https://huggingface.co/spaces/testrro/RNG2/resolve/main/app.py
- Command line
-
hf download hf://spaces/testrro/RNG2/app.py
-
curl -L -o app.py https://huggingface.co/spaces/testrro/RNG2/resolve/main/app.py
13.3 kB
| import gradio as gr | |
| import numpy as np | |
| import matplotlib.pyplot as plt | |
| import random | |
| # ============================================ | |
| # র্যান্ডম ডাটা জেনারেটর | |
| # ============================================ | |
| def generate_random_multipliers(num_rounds=30, house_edge=0.03): | |
| multipliers = [] | |
| for _ in range(num_rounds): | |
| if random.random() < 0.025: | |
| multipliers.append(1.00) | |
| continue | |
| r = random.random() | |
| if r >= 0.999999: | |
| r = 0.999999 | |
| m = (1 - house_edge) / (1 - r) | |
| multipliers.append(round(m, 2)) | |
| return multipliers | |
| # ============================================ | |
| # অ্যানালাইসিস ফাংশন | |
| # ============================================ | |
| def parse_multipliers(multiplier_text): | |
| try: | |
| text = multiplier_text.replace('x', '').replace('X', '') | |
| parts = text.replace(',', ' ').split() | |
| multipliers = [float(p.strip()) for p in parts if p.strip()] | |
| return multipliers | |
| except: | |
| return [] | |
| def format_multipliers_text(multipliers): | |
| return ', '.join([f"{m:.2f}x" for m in multipliers]) | |
| def analyze_multipliers(multiplier_text, rounds_limit=10000): | |
| multipliers = parse_multipliers(multiplier_text) | |
| if not multipliers: | |
| return "❌ ইনপুট সঠিক নয়। উদাহরণ: 1.02, 1.15, 2.34", None | |
| if len(multipliers) > rounds_limit: | |
| return f"⚠️ সর্বোচ্চ {rounds_limit} রাউন্ড পর্যন্ত সাপোর্ট করে। আপনি {len(multipliers)} দিয়েছেন।", None | |
| if len(multipliers) < 3: | |
| return "⚠️ কমপক্ষে ৩টি মাল্টিপ্লায়ার দরকার।", None | |
| rounds = len(multipliers) | |
| buckets = { | |
| "1x - 2x": 0, | |
| "2x - 5x": 0, | |
| "5x - 10x": 0, | |
| "10x - 50x": 0, | |
| "50x +": 0 | |
| } | |
| for m in multipliers: | |
| if m < 2: | |
| buckets["1x - 2x"] += 1 | |
| elif m < 5: | |
| buckets["2x - 5x"] += 1 | |
| elif m < 10: | |
| buckets["5x - 10x"] += 1 | |
| elif m < 50: | |
| buckets["10x - 50x"] += 1 | |
| else: | |
| buckets["50x +"] += 1 | |
| avg_multiplier = np.mean(multipliers) | |
| median_multiplier = np.median(multipliers) | |
| max_multiplier = max(multipliers) | |
| min_multiplier = min(multipliers) | |
| std_multiplier = np.std(multipliers) | |
| if avg_multiplier > 1: | |
| estimated_house_edge = (1 - (1 / avg_multiplier)) * 100 | |
| estimated_rtp = 100 - estimated_house_edge | |
| else: | |
| estimated_house_edge = 0 | |
| estimated_rtp = 100 | |
| instant_crash = len([m for m in multipliers if m == 1.00]) | |
| instant_crash_pct = (instant_crash / rounds) * 100 | |
| # রিপোর্ট তৈরি | |
| report = "## 📊 অ্যানালাইসিস রিপোর্ট\n\n" | |
| report += "| মেট্রিক | মান |\n" | |
| report += "|---------|-----|\n" | |
| report += f"| **মোট রাউন্ড** | {rounds} |\n" | |
| report += f"| **গড় মাল্টিপ্লায়ার** | {avg_multiplier:.4f}x |\n" | |
| report += f"| **মধ্যমান (মিডিয়ান)** | {median_multiplier:.4f}x |\n" | |
| report += f"| **সর্বোচ্চ** | {max_multiplier:.2f}x |\n" | |
| report += f"| **সর্বনিম্ন** | {min_multiplier:.2f}x |\n" | |
| report += f"| **স্ট্যান্ডার্ড ডেভিয়েশন** | {std_multiplier:.4f} |\n\n" | |
| report += "---\n\n" | |
| report += "### 🎲 হাউস এজ অনুমান\n" | |
| report += f"- **হাউস এজ:** {estimated_house_edge:.2f}%\n" | |
| report += f"- **RTP:** {estimated_rtp:.2f}%\n\n" | |
| report += "---\n\n" | |
| report += "### ⚡ ইন্সট্যান্ট ক্র্যাশ\n" | |
| report += f"- **1.00x এসেছে:** {instant_crash} বার ({instant_crash_pct:.2f}%)\n\n" | |
| report += "---\n\n" | |
| report += "### 📈 রেঞ্জ ভিত্তিক ডিস্ট্রিবিউশন\n" | |
| for key, value in buckets.items(): | |
| pct = (value / rounds) * 100 | |
| bar = "█" * int(pct / 2) | |
| report += f"\n- **{key}:** {value} বার ({pct:.2f}%) {bar}" | |
| big_hits = len([m for m in multipliers if m >= 10]) | |
| report += "\n\n---\n\n" | |
| report += "### 🔥 বড় হিট (10x+)\n" | |
| report += f"- **মোট:** {big_hits} বার ({big_hits/rounds*100:.2f}%)\n\n" | |
| report += "---\n\n" | |
| report += "### 🧠 বিশ্লেষণ\n" | |
| if estimated_house_edge < 3: | |
| report += "✅ হাউস এজ খুব কম — গেমটি প্লেয়ার-ফ্রেন্ডলি মনে হচ্ছে।" | |
| elif estimated_house_edge < 8: | |
| report += "📊 হাউস এজ স্বাভাবিক সীমার মধ্যে (2-8%)।" | |
| else: | |
| report += "⚠️ হাউস এজ অনেক বেশি! ডাটা কম হলে এটা হতে পারে। 1000+ রাউন্ড দিয়ে আবার চেক করুন।" | |
| if instant_crash_pct > 5: | |
| report += f"\n⚠️ ইন্সট্যান্ট ক্র্যাশ ({instant_crash_pct:.1f}%) স্বাভাবিকের চেয়ে বেশি। সাধারণত 2-3% হয়।" | |
| elif instant_crash_pct < 1: | |
| report += f"\n📊 ইন্সট্যান্ট ক্র্যাশ ({instant_crash_pct:.1f}%) স্বাভাবিকের চেয়ে কম।" | |
| else: | |
| report += f"\n✅ ইন্সট্যান্ট ক্র্যাশ ({instant_crash_pct:.1f}%) স্বাভাবিক সীমার মধ্যে।" | |
| report += "\n\n---\n\n" | |
| report += "### 💡 টিপস\n" | |
| report += "- যত বেশি রাউন্ডের ডাটা দেবেন, অনুমান তত সঠিক হবে\n" | |
| report += "- 500+ রাউন্ড দিলে হাউস এজ প্রায় নির্ভুল হয়\n" | |
| report += "- 1x-2x রেঞ্জে 60-80% রাউন্ড হওয়া স্বাভাবিক\n" | |
| # গ্রাফ বানানো | |
| fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(12, 5)) | |
| ax1.hist(multipliers, bins=min(30, max(5, rounds//2)), edgecolor='black', alpha=0.7, color='skyblue') | |
| ax1.axvline(avg_multiplier, color='red', linestyle='--', linewidth=2, label=f'গড়: {avg_multiplier:.2f}x') | |
| ax1.axvline(median_multiplier, color='green', linestyle='--', linewidth=2, label=f'মিডিয়ান: {median_multiplier:.2f}x') | |
| ax1.set_xlabel('মাল্টিপ্লায়ার') | |
| ax1.set_ylabel('কতবার এসেছে') | |
| ax1.set_title('মাল্টিপ্লায়ার ডিস্ট্রিবিউশন') | |
| ax1.legend() | |
| ax1.grid(True, alpha=0.3) | |
| categories = list(buckets.keys()) | |
| values = list(buckets.values()) | |
| colors = ['#2ecc71', '#3498db', '#f39c12', '#e74c3c', '#9b59b6'] | |
| bars = ax2.bar(categories, values, color=colors[:len(categories)], edgecolor='black') | |
| ax2.set_xlabel('রেঞ্জ') | |
| ax2.set_ylabel('রাউন্ড সংখ্যা') | |
| ax2.set_title('রেঞ্জ ভিত্তিক ডিস্ট্রিবিউশন') | |
| ax2.tick_params(axis='x', rotation=45) | |
| for bar, val in zip(bars, values): | |
| if val > 0: | |
| ax2.text(bar.get_x() + bar.get_width()/2, bar.get_height() + 0.2, | |
| str(val), ha='center', va='bottom', fontsize=10) | |
| plt.tight_layout() | |
| return report, fig | |
| # ============================================ | |
| # রিজেনারেট ফাংশন | |
| # ============================================ | |
| def regenerate_data(num_rounds, house_edge): | |
| multipliers = generate_random_multipliers(int(num_rounds), house_edge/100) | |
| text = format_multipliers_text(multipliers) | |
| return text | |
| # ============================================ | |
| # গ্র্যাডিও UI | |
| # ============================================ | |
| with gr.Blocks(title="RNG2 - মাল্টিপ্লায়ার অ্যানালাইসার", theme=gr.themes.Soft()) as demo: | |
| gr.Markdown( | |
| """ | |
| # 🎲 RNG2 - মাল্টিপ্লায়ার অ্যানালাইসার | |
| ক্র্যাশ/এভিয়েটর টাইপ গেমের মাল্টিপ্লায়ার ডাটা বিশ্লেষণ করুন। | |
| """ | |
| ) | |
| with gr.Tabs(): | |
| with gr.TabItem("📝 ম্যানুয়াল ইনপুট"): | |
| with gr.Row(): | |
| with gr.Column(scale=3): | |
| multiplier_input = gr.Textbox( | |
| label="মাল্টিপ্লায়ার ইনপুট", | |
| placeholder="যেমন: 1.02, 1.15, 2.34, 1.05", | |
| lines=6, | |
| value="1.00, 17.11, 1.17, 1.00, 1.35, 1.98, 4.26, 1.72, 1.66, 2.33, 1.45, 2.02, 1.27, 2.47, 2.06, 2.46, 1.07, 1.12, 2.17, 13.19, 1.38, 2.35, 2.02, 3.80, 1.64, 1.43, 1.94, 2.00" | |
| ) | |
| with gr.Row(): | |
| rounds_limit = gr.Slider( | |
| minimum=100, | |
| maximum=10000, | |
| value=5000, | |
| step=100, | |
| label="সর্বোচ্চ রাউন্ড সংখ্যা" | |
| ) | |
| analyze_btn = gr.Button("🔍 অ্যানালাইসিস করুন", variant="primary") | |
| with gr.Column(scale=2): | |
| report_output = gr.Markdown(label="📊 রিপোর্ট") | |
| with gr.Row(): | |
| plot_output = gr.Plot(label="📈 গ্রাফ") | |
| with gr.TabItem("🎲 র্যান্ডম জেনারেটর"): | |
| gr.Markdown( | |
| """ | |
| ### র্যান্ডম ডাটা জেনারেট করুন | |
| এখান থেকে নতুন র্যান্ডম মাল্টিপ্লায়ার জেনারেট করে অ্যানালাইসিস করতে পারেন। | |
| """ | |
| ) | |
| with gr.Row(): | |
| with gr.Column(): | |
| num_rounds = gr.Slider( | |
| minimum=10, | |
| maximum=500, | |
| value=30, | |
| step=10, | |
| label="রাউন্ড সংখ্যা" | |
| ) | |
| house_edge_input = gr.Slider( | |
| minimum=0, | |
| maximum=10, | |
| value=3, | |
| step=0.5, | |
| label="হাউস এজ (%)", | |
| info="সাধারণত 1-5% এর মধ্যে" | |
| ) | |
| regenerate_btn = gr.Button("🔄 রিজেনারেট ডাটা", variant="secondary") | |
| with gr.Column(): | |
| random_data_output = gr.Textbox( | |
| label="জেনারেটেড ডাটা", | |
| lines=6, | |
| interactive=False | |
| ) | |
| with gr.Row(): | |
| random_analyze_btn = gr.Button("📊 এই ডাটা অ্যানালাইসিস করুন", variant="primary") | |
| with gr.TabItem("📖 গাইড"): | |
| gr.Markdown( | |
| """ | |
| ## কিভাবে ব্যবহার করবেন? | |
| ### ম্যানুয়াল ইনপুট | |
| 1. প্রথম ট্যাবে মাল্টিপ্লায়ার লিখুন | |
| 2. কমা (,) বা স্পেস দিয়ে আলাদা করুন | |
| 3. x ব্যবহার করলেও সমস্যা নেই | |
| 4. অ্যানালাইসিস করুন বাটন ক্লিক করুন | |
| ### র্যান্ডম জেনারেটর | |
| 1. দ্বিতীয় ট্যাবে যান | |
| 2. রাউন্ড সংখ্যা সেট করুন | |
| 3. হাউস এজ সেট করুন (সাধারণত 1-5%) | |
| 4. রিজেনারেট ডাটা ক্লিক করুন | |
| 5. এই ডাটা অ্যানালাইসিস করুন ক্লিক করুন | |
| ### উদাহরণ ইনপুট |