// ==UserScript== // @name Torn City - High Low Helper // @namespace Goltred.Casino // @version 0.1.1 // @description Calculate odds in casino high low game // @author Goltred // @updateURL https://raw.githubusercontent.com/Goltred/tornscripts/master/tornCasinoHighLow.user.js // @downloadURL https://raw.githubusercontent.com/Goltred/tornscripts/master/tornCasinoHighLow.user.js // @match https://www.torn.com/loader.php?sid=highlow // @grant none // @require https://raw.githubusercontent.com/Goltred/tornscripts/master/classes/Logger.js // ==/UserScript== const logger = new Logger('tornCasinoHighLow'); // Setup listeners $(document).ajaxComplete((evt, xhr, settings) => { if (settings.url.includes('loader.php?sid=hiloJson')) { const response = new AjaxResponse(xhr); const state = new GameState(response); GameController.act(state); } }); class AjaxResponse { constructor(xhr) { const response = JSON.parse(xhr.responseText); Object.keys(response).forEach((k) => { this[k] = response[k]; }) } } class GameState { constructor(response) { this.state = response.status; this.DB = response.DB if (this.state && this.state !== 'startGame') // Only startGame doesn't have a currentGame key this.currentGame = response.currentGame[0]; } } class Card { constructor(name, suite, value) { this.name = name; this.value = value this.suite = suite; this.classCode = `${suite}-${name}`; } toString() { return this.suite + "-" + this.name; } } //Define the Deck class class Deck { constructor(cardValues, suites) { this.cards = []; this.discardPile = []; //Create the whole deck, 12 cards per suite for (var i = 0; i < suites.length; i++) { for (var key in cardValues) { var newCard = new Card(key, suites[i], cardValues[key]); this.cards.push(newCard); } } } reset() { this.cards = this.cards.concat(this.discardPile); this.discardPile = []; } discard(card) { this.discardPile.push(card); } getCard(classCode) { //Get a given card from the deck based on the given //torn classCode. Adding it to the discard pile. for (var i = 0; i < this.cards.length; i++) { var card = this.cards[i]; if (card.classCode == classCode) { this.cards.splice(i, 1); this.discard(card); return card; } } logger.debug(`A card could not be found in the deck for classCode ${classCode}`); } filterCards(card, diff) { //Return an array with cards of higher, lower or same //value as the provided card. //Diff should be 0, positive or a negative number var result = [] for (var i = 0; i < this.cards.length; i++) { var current_card = this.cards[i]; if (diff > 0) { //Retrieve cards that have a higher value if (current_card.value >= card.value) { //Card is lower var current_card = undefined; } } else if (diff == 0) { //filter same value cards if (current_card.value != card.value) { //Card is not the same var current_card = undefined; } } else if (diff < 0) { //filter lower cards if (current_card.value <= card.value) { //Card is higher var current_card = undefined; } } if (current_card !== undefined) { result.push(current_card); } } return result; } calculateOdds(card) { //Calculate the probability of getting a higher or lower card //value 0 is higher than value 12 //Get the number of cards above the current_card var higher = this.filterCards(card, 1); //Get the number of cards below the current_card var lower = this.filterCards(card, -1); //Same cards var same = this.filterCards(card, 0); var higher = ((higher.length / this.cards.length) * 100).toFixed(3); var lower = ((lower.length / this.cards.length) * 100).toFixed(3); var same = ((same.length / this.cards.length) * 100).toFixed(3); logger.debug("Chances are:"); logger.debug(` Higher: ${higher}%`); logger.debug(` Lower: ${lower}%`); logger.debug(` Same: ${same}%`); return { higher, lower, same } } } class GameController { static cardValues = { "A": 0, "K": 1, "Q": 2, "J": 3, "10": 4, "9": 5, "8": 6, "7": 7, "6": 8, "5": 9, "4": 10, "3": 11, "2": 12 }; static suites = [ "diamonds", "clubs", "spades", "hearts" ]; static deck = new Deck(GameController.cardValues, GameController.suites) static act(state) { if (state.currentGame) { // Check if we should calculate odds or not based on the status of the response if (state.state === 'gameStarted' || state.state === 'makeChoice') { const { dealerCardInfo, playerCardInfo } = state.currentGame; if (playerCardInfo) // Game was either lost or we just picked a card GameController.deck.getCard(playerCardInfo.classCode); else { const card = GameController.deck.getCard(dealerCardInfo.classCode); const chances = GameController.deck.calculateOdds(card); UIController.addChances(chances); } } } if (state.DB.deckShuffled) GameController.deck.reset(); logger.debug('Current Deck', GameController.deck); } } class UIController { static addChances(chances) { $('#tchl-low').remove(); $('#tchl-high').remove(); $('div.action-btn-wrap.low').append($(`${chances.lower}%`)); $('div.action-btn-wrap.high').append($(`${chances.higher}%`)); // Hide the bottom item because it is bothering... $('div.item-8').css('display', 'none'); } }