瀏覽代碼

Initial commit

Foppe Hemminga 6 年之前
當前提交
ca956f99b4
共有 1 個文件被更改,包括 372 次插入0 次删除
  1. 372 0
      High-Low.user.js

+ 372 - 0
High-Low.user.js

@@ -0,0 +1,372 @@
+// ==UserScript==
+// @name         High-Low
+// @namespace    http://tampermonkey.net/
+// @version      0.1.2
+// @description  try to take over the world!
+// @author       You
+// @match        https://www.torn.com/loader.php?sid=high*ow
+// @require      https://cdnjs.cloudflare.com/ajax/libs/vue/2.3.3/vue.js
+// @resource     sourceCodePro https://fonts.googleapis.com/css?family=Source+Code+Pro
+// @require      https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.10.0/highlight.min.js
+// @resource     json-formatter_css https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.10.0/styles/default.min.css
+// @grant        GM_getResourceText
+// @grant        GM_addStyle
+// @grant        GM_setValue
+// @grant        GM_getValue
+// ==/UserScript==
+
+/* jshint -W097 */
+/*global
+   $, console, Raven, GM_addStyle, GM_getResourceText, Vue, hljs
+*/
+
+(function() {
+    'use strict';
+	var sourceCodePro = GM_getResourceText("codeSourcePro");
+	GM_addStyle(sourceCodePro);
+	GM_addStyle("pre,code {font-family: 'Source Code Pro', monospace; font-size: 14px;}");
+	var js_css = GM_getResourceText("json-formatter_css");
+	GM_addStyle(js_css);
+	//var bootstrap_css = GM_getResourceText("bootstrap_css");
+	//GM_addStyle(bootstrap_css);
+
+	GM_addStyle(".hljs-number { color: blue; }");
+
+	var formatterConfig = {
+		hoverPreviewEnabled: false,
+		hoverPreviewArrayCount: 100,
+		hoverPreviewFieldCount: 5,
+		theme: 'dark',
+		animateOpen: true,
+		animateClose: true,
+		open: 20
+	};
+
+	var changeTimeout = function() {
+		var oldTimeout = setTimeout;
+		/*global setTimeout:true */
+		setTimeout = function(a, b) {
+			return oldTimeout(a, b/3);
+		};
+		console.log("setTimout: changed");
+	};
+	let script = document.createElement('script');
+	script.appendChild(document.createTextNode('('+ changeTimeout +')();'));
+	(document.head || document.body || document.documentElement).appendChild(script);
+
+	class Card {
+		constructor(number) {
+			let card = this.getCardFromNumber(number);
+			this.color = card[0];
+			this.rank = card[1];
+		}
+
+		getCardFromNumber(number) {
+			let mod = (number-1) % 4;
+			let color = "";
+			if (mod === 0) {
+				color = "spades";
+			}
+			if (mod === 1) {
+				color = "diamonds";
+			}
+			if (mod === 2) {
+				color = "hearts";
+			}
+			if (mod === 3) {
+				color = "clubs";
+			}
+			let offset = 0;
+			offset += 4; // Counter for 2 being first card, not 1
+			offset += 3; // Counter for using floor
+			let rank = Math.floor((parseInt(number, 10)+offset)/4);
+			return [color, rank];
+		}
+
+		toString() {
+			let rank = this.rank.toString();
+			console.log("rank:", rank);
+			/* if (rank === "10") {
+				rank = "T";
+			} */
+			if (rank === "11") {
+				rank = "J";
+			}
+			if (rank === "12") {
+				rank = "Q";
+			}
+			if (rank === "13") {
+				rank = "K";
+			}
+			if (rank === "14") {
+				rank = "A";
+			}
+			return this.color + "-" + rank;
+		}
+
+		toValue() {
+			return this.rank;
+		}
+	}
+
+    /* Initialize deck */
+    let deck = GM_getValue('deck', []);
+    let createDeck = (deck) => {
+        for (let i = 1; i <= 52; i++) {
+            deck.push(i);
+        }
+        GM_setValue('[createDeck] deck', deck);
+        // console.log(deck);
+        return deck;
+    }
+    if (deck.length === 0) {
+        deck = createDeck(deck);
+    }
+
+    let removeCard = (deck, card) => {
+        /*
+        console.log('[removeCard] card:', card);
+        console.log('typeof card:', typeof card);
+        console.log('typeof deck[5]:', typeof deck[5]);
+        */
+        for( var i = 0; i < deck.length; i++) {
+            if ( deck[i] === card) {
+                deck.splice(i, 1);
+            }
+        }
+        GM_setValue('[removeCard] deck', deck);
+        // console.log(deck);
+    }
+
+	//********
+	// Controller
+	//********
+
+	let processStartGame = function(db) {
+		let formulaStats = db.DB.formulaStats[0];
+		let previousMultiplier = 0;
+		let currentMultiplier = 0;
+		if (formulaStats) {
+			currentMultiplier = formulaStats.currentRatio;
+			previousMultiplier = formulaStats.previousRatio;
+			if (previousMultiplier !== currentMultiplier) {
+				console.log("Multiplier changed!. Old: " + previousMultiplier + " => New: " + currentMultiplier);
+			}
+		}
+		//$("pre code.json").empty().append(JSON.stringify(db, null, 4));
+		console.log('myVue:', myVue);
+		myVue.jsonobject = JSON.stringify(db, null, 4);
+		// myVue.jsonobject = "Test";
+        // action.header = "Test";
+		Vue.nextTick(function() {
+			hljs.initHighlighting.called = false;
+			hljs.initHighlighting();
+		});
+		console.log("Multiplier:", currentMultiplier);
+	};
+
+	let processGameStarted = function(db) {
+		// dealerCard is revealed; player picks High or Low
+		// Note: Player also has the option to cash in but that is never considered
+		console.log("dealerCard:", db.currentGame[0].dealerCard);
+		let dealerCard = new Card(db.currentGame[0].dealerCard);
+
+		console.assert(dealerCard.toString() === db.currentGame[0].dealerCardInfo.classCode,
+					   "Mismatch dealerCard " + dealerCard + " <-> " + db.currentGame[0].dealerCardInfo.classCode);
+		console.log("dealerCard:", dealerCard.toString());
+		let arrayWithOdds = calculateOdds(dealerCard, deck);
+		let lower = arrayWithOdds[0];
+		let higher = arrayWithOdds[1];
+		let numberOfCards = arrayWithOdds[2];
+        // testing
+        //$('div.action-c.action-btn-wrap.active.low').addClass('iconPulseExpiring');
+		//$('div.action-r.action-btn-wrap.active.high').removeClass('active');
+
+	};
+
+	let processMakeChoice = function(db) {
+		// The deal has ended. The choice is cash in or play on.
+		if (db.currentGame[0].dealerCard !== db.currentGame[0].lastDealerCard) {
+			// Reveal dealerCard of next deal
+			// Page has been refreshed
+			// There is no playerCard (there is a lastPlayerCard)
+			db.currentGame[0].playerCard = db.currentGame[0].lastPlayerCard;
+			db.currentGame[0].playerCardInfo = db.currentGame[0].lastPlayerCardInfo;
+			// dealerCard assert will fail!
+		}
+		console.log("step:", db.currentGame[0].step);
+		let dealerCard = new Card(db.currentGame[0].dealerCard);
+		console.assert(dealerCard.toString() === db.currentGame[0].dealerCardInfo.classCode,
+					   "Mismatch dealerCard " + dealerCard + " <-> " + db.currentGame[0].dealerCardInfo.classCode);
+		console.log("dealerCard:", dealerCard.toString());
+        removeCard(deck, parseInt(db.currentGame[0].dealerCard, 10));
+		let playerCard = new Card(db.currentGame[0].playerCard);
+		console.assert(playerCard.toString() === db.currentGame[0].playerCardInfo.classCode,
+					   "Mismatch playerCard " + playerCard + " <-> " + db.currentGame[0].playerCardInfo.classCode);
+		console.log("playerCard:", playerCard.toString());
+        removeCard(deck, parseInt(db.currentGame[0].playerCard, 10));
+        if (db.DB.deckShuffled) {
+            console.log('[processMakeChoice] deckShuffled', db.DB.deckShuffled);
+            // New deck
+            deck = [];
+            deck = createDeck(deck);
+        }
+	};
+
+    $(document).ajaxSuccess(
+		// On every detected Ajax communication
+		function(event, jqxhr, settings, data) {
+			// Make sure it was to or from /loader.php?sid=hiloJson&rfcv=<rfcv>
+			if (settings.url.indexOf("loader.php?sid=hiloJson") != -1) {
+				//console.log("event:", event);
+				//console.log("jqxhr:", jqxhr);
+				//console.log("settings:", settings);
+				let db = JSON.parse(data);
+				$("pre code.json").empty().append(JSON.stringify(db.currentGame, null, 4));
+				hljs.initHighlighting.called = false;
+				hljs.initHighlighting();
+				console.log("db:", db);
+				let status = db.status;
+				console.log("db.status:", db.status);
+				if (status === "startGame") {
+					processStartGame(db);
+				}
+				if (status === "gameStarted") {
+					processGameStarted(db);
+				}
+				if (status === "makeChoice") {
+					processMakeChoice(db);
+				}
+				//console.log("db.currentGame:", db.currentGame);
+			}
+		});
+
+	//********
+	// VIEW
+	//********
+	let boxTitle = "Let's play High-Low";
+	let boxHTML = "<div class=\"tutorial-cont m-top10\">" +
+		"<div class=\"title-gray top-round\" role=\"heading\" aria-level=\"5\">" +
+		"<i class=\"tutorial-icon\"></i>" +
+		"<span style=\"padding-left: 6px\">" + boxTitle + "</span>" +
+		"</div>" +
+		"<div class=\"bottom-round cont-gray p10\">"+
+		"<div id=\"app\" style=\"min-height: 450px;\">" +
+		"<div style=\"float: left; width: 50%;\">" +
+		"<current-action v-bind:action=\"action\"></current-action>" +
+		"</div><div id=\"right\" style=\"float: right; width: 50%;\">"+
+		//"<pre><code class=\"json\"></code></pre>" +
+		"<vue-object v-bind:jsonobject=\"jsonobject\"></vue-object>" +
+		"</div></div><div class=\"clear\"></div>" +
+		"<hr class=\"page-head-delimiter m-top10\">" +
+		"</div>";
+	$('.highlow-main-wrap').after(boxHTML);
+
+	// Vue.js template
+	//creating component
+	var currentAction = Vue.extend({
+		template: '<h1 v-bind:style="actionStyle">{{ action.header }}</h1>',
+		data: function() {
+			return {
+				// action: "Current Action",
+				actionStyle: {
+					marginTop: "0px"
+				}
+			};
+		},
+        props: ['action']
+	});
+	var vueObject = Vue.extend({
+		template: '<div v-bind:style="vueObjectStyle"><pre><code class="json" v-html="jsonobject"></code></pre></div>',
+		data: function() {
+			return {
+				vueObjectStyle: {
+					marginTop: "0px"
+				}
+			};
+		},
+		props: ['jsonobject']
+	});
+	//registering component
+	Vue.component('current-action', currentAction);
+	Vue.component('vue-object', vueObject);
+	//initializing the Vue application
+    let action = {};
+    action.header = "Current Action";
+	let myVue = new Vue({
+		el: "#app",
+		data: function() {
+			return {
+				jsonobject: "Start",
+                action: action
+			};
+		}
+	});
+
+	//********
+	// MODEL
+	//********
+
+	/**
+	 * @param {array} deck, cards by number
+	 * @return {array} number of cards by rank where key is the rank \
+	 * and val is the number of that rank in the deck
+	 */
+	let parseDeck = function(dealerCard, deck) {
+		let parsedDeck = [];
+        // parsedDeck runs from 0 to 14 where 0 and 1 are always 0.
+        // Real deck values count from 2 to 14 (ace)
+        for (let i = 0; i < 15; i++) {
+            parsedDeck[i] = 0;
+        }
+		let deckLength = deck.length;
+		for (let i = 0; i < deckLength; i++) {
+            /*
+            if (i < 10) {
+                console.log('first cards:', deck[i]);
+            }
+            */
+			let offset = 0;
+			offset += 4; // Counter for 2 being first card, not 1
+			offset += 3; // Counter for using floor
+			let rank = Math.floor((parseInt(deck[i], 10)+offset)/4);
+			// console.log("[parseDeck] rank:", rank);
+			if (!(rank in parsedDeck)) {
+				parsedDeck[rank] = 0;
+			}
+			parsedDeck[rank]++;
+		}
+		if (deckLength === 0) {
+			// Shuffle -> create new deck
+			for (let i = 2; i < 15; i++) {
+				parsedDeck[i] = 4;
+			}
+			// Remove dealerCard
+			parseDeck[dealerCard.rank]--;
+		}
+        // console.table(parsedDeck);
+		return parsedDeck;
+	};
+
+	let calculateOdds = function(dealerCard, deck) {
+		let parsedDeck = parseDeck(dealerCard, deck);
+		let deckLength = parsedDeck.length;
+		let numberOfCards = 0;
+		let lowerDoesNotLose = 0; // Equals count as 'not lose'
+		let higherDoesNotLose = 0; // Equals count as 'not lose'
+		for (let i = 0; i < deckLength; i++) {
+			if (i <= dealerCard.rank) {
+				lowerDoesNotLose += parsedDeck[i];
+			}
+			if (i >= dealerCard.rank) {
+				higherDoesNotLose += parsedDeck[i];
+			}
+			numberOfCards += parsedDeck[i];
+		}
+		// console.log("[calculteOdds] parsedDeck;", parsedDeck);
+		console.log("[calculateOdds] lowerDoesNotLose:", lowerDoesNotLose);
+		console.log("[calculateOdds] higherDoesNotLose:", higherDoesNotLose);
+		console.log("[calculateodds] numberOfCards:", numberOfCards);
+		return [lowerDoesNotLose, higherDoesNotLose, numberOfCards];
+	};
+})();