Enhanced Poker Odds Calculator for Torn

Advanced poker calculator with starting hand guidance for Torn

// ==UserScript==
// @name         Enhanced Poker Odds Calculator for Torn
// @namespace    https://openuserjs.org/users/torn/pokerodds
// @version      2.0.0
// @description  Advanced poker calculator with starting hand guidance for Torn
// @author       Your Name
// @match        https://www.torn.com/page.php?sid=holdem*
// @grant        none
// ==/UserScript==

// Starting Hand Rankings (Chen Formula)
const STARTING_HAND_SCORES = {
    // Pocket Pairs
    'AA': 'Premium (10.0)', 'KK': 'Premium (9.0)', 'QQ': 'Premium (8.0)',
    'JJ': 'Strong (7.0)', 'TT': 'Strong (6.0)', '99': 'Playable (5.0)',
    '88': 'Playable (4.0)', '77': 'Speculative (3.0)', '66': 'Speculative (2.0)',
    '55': 'Speculative (2.0)', '44': 'Marginal (1.0)', '33': 'Marginal (1.0)', '22': 'Marginal (1.0)',
    
    // Suited Connectors
    'AKs': 'Premium (8.0)', 'AQs': 'Premium (7.0)', 'AJs': 'Strong (6.5)',
    'KQs': 'Strong (6.0)', 'ATs': 'Strong (6.0)', 'KJs': 'Strong (5.5)',
    'QJs': 'Playable (5.0)', 'JTs': 'Playable (4.5)', 'T9s': 'Speculative (3.5)',
    '98s': 'Speculative (3.0)', '87s': 'Speculative (2.5)', '76s': 'Speculative (2.0)',
    
    // Offsuit Broadway
    'AK': 'Premium (7.0)', 'AQ': 'Strong (6.5)', 'AJ': 'Playable (5.5)',
    'KQ': 'Playable (5.0)', 'AT': 'Playable (5.0)', 'KJ': 'Playable (4.5)',
    'QJ': 'Speculative (4.0)', 'JT': 'Speculative (3.5)'
};

class EnhancedPokerCalculator {
    constructor() {
        this.setupStyles();
        this.setupUI();
        this.startMonitoring();
    }

    setupStyles() {
        const styles = `
            .poker-helper {
                background: #fff;
                border: 1px solid #ddd;
                border-radius: 4px;
                margin: 10px;
                padding: 15px;
                font-family: Arial, sans-serif;
            }

            .hand-strength {
                display: flex;
                justify-content: space-between;
                margin-bottom: 10px;
            }

            .hand-advice {
                background: #f5f5f5;
                padding: 10px;
                border-radius: 4px;
                margin-top: 10px;
            }

            .premium { color: #2ecc71; }
            .strong { color: #3498db; }
            .playable { color: #f1c40f; }
            .speculative { color: #e67e22; }
            .marginal { color: #e74c3c; }

            .stats-table {
                width: 100%;
                border-collapse: collapse;
                margin-top: 10px;
            }

            .stats-table th, .stats-table td {
                border: 1px solid #ddd;
                padding: 8px;
                text-align: left;
            }

            .stats-table th {
                background: #f5f5f5;
            }
        `;

        const styleElement = document.createElement('style');
        styleElement.textContent = styles;
        document.head.appendChild(styleElement);
    }

    setupUI() {
        const container = document.createElement('div');
        container.className = 'poker-helper';
        container.innerHTML = `
            <div class="hand-strength">
                <div>
                    <h3>Current Hand</h3>
                    <div id="current-hand"></div>
                </div>
                <div>
                    <h3>Hand Strength</h3>
                    <div id="hand-rating"></div>
                </div>
            </div>
            <div class="hand-advice" id="hand-advice"></div>
            <table class="stats-table">
                <thead>
                    <tr>
                        <th>Stat</th>
                        <th>Value</th>
                        <th>Action</th>
                    </tr>
                </thead>
                <tbody id="stats-body"></tbody>
            </table>
        `;

        // Insert after the poker table
        const pokerTable = document.querySelector('.poker-table');
        if (pokerTable) {
            pokerTable.parentNode.insertBefore(container, pokerTable.nextSibling);
        }
    }

    getHandRating(cards) {
        if (cards.length !== 2) return null;
        
        const [card1, card2] = cards.sort((a, b) => b.value - a.value);
        const suited = card1.suit === card2.suit;
        
        let key = '';
        if (card1.value === card2.value) {
            // Pocket pair
            key = `${this.valueToRank(card1.value)}${this.valueToRank(card2.value)}`;
        } else {
            // Non-pair
            key = `${this.valueToRank(card1.value)}${this.valueToRank(card2.value)}${suited ? 's' : ''}`;
        }
        
        return STARTING_HAND_SCORES[key] || 'Fold';
    }

    valueToRank(value) {
        const ranks = {
            14: 'A', 13: 'K', 12: 'Q', 11: 'J', 10: 'T'
        };
        return ranks[value] || value.toString();
    }

    getPlayAdvice(handRating) {
        const advice = {
            'Premium': 'Raise from any position. Re-raise if raised before you.',
            'Strong': 'Raise from middle/late position. Call or re-raise if raised before you.',
            'Playable': 'Raise from late position. Call from middle position if no raises.',
            'Speculative': 'Call from late position if no raises. Fold to significant action.',
            'Marginal': 'Fold from early position. Only play if getting good pot odds.'
        };

        return advice[handRating.split(' ')[0]] || 'Consider folding this hand.';
    }

    updateDisplay(cards) {
        const handRating = this.getHandRating(cards);
        if (!handRating) return;

        document.getElementById('current-hand').textContent = cards.map(c => 
            `${this.valueToRank(c.value)}${c.suit.charAt(0)}`).join(' ');
        
        document.getElementById('hand-rating').textContent = handRating;
        document.getElementById('hand-advice').textContent = this.getPlayAdvice(handRating);
    }

    startMonitoring() {
        setInterval(() => {
            // Monitor for changes in the player's cards
            const playerCards = this.getPlayerCards();
            if (playerCards) {
                this.updateDisplay(playerCards);
            }
        }, 1000);
    }

    getPlayerCards() {
        // Implementation depends on Torn's DOM structure
        // This is a placeholder - needs to be adapted to actual DOM
        const cardElements = document.querySelectorAll('.player-cards .card');
        if (cardElements.length !== 2) return null;

        return Array.from(cardElements).map(el => ({
            value: this.parseCardValue(el.dataset.value),
            suit: el.dataset.suit
        }));
    }

    parseCardValue(value) {
        const values = { 'A': 14, 'K': 13, 'Q': 12, 'J': 11 };
        return values[value] || parseInt(value);
    }
}

// Initialize when the page loads
window.addEventListener('load', () => {
    new EnhancedPokerCalculator();
});