diff --git a/index.html b/index.html index 6ed6c10..daad7ca 100644 --- a/index.html +++ b/index.html @@ -25,7 +25,10 @@ + Points: ? +
+
?
diff --git a/script.js b/script.js index 77ce7a1..7d08460 100644 --- a/script.js +++ b/script.js @@ -8,15 +8,19 @@ var sameColorExtra = 4; // extra points given for sets of the same color if they var autoDraw = false; // whether the script should automatically draw on start and on discard var autoRecommend = true; // whether the script should automatically recommend on change +var measurePerformance = false; // whether the performance should be logged into the console var allCards = undefined; var deck = undefined; var hand = undefined; +var globalPoints = undefined; var recommendations = undefined; +var minimumRecommendations = 1; var deckElement = document.getElementById('deck'); var handElement = document.getElementById('hand'); var recommendElement = document.getElementById('result'); +var pointsElement = document.getElementById('points'); reset(); @@ -62,8 +66,10 @@ function cardToElement(card, forDeck = false, drawn = false) { if (!forDeck) { if (recommendations.length > 0 ) { - if (recommendations[0].burnedCard && recommendations[0].burnedCard == card.id) { - element.classList.add("discard"); + if (recommendations[0].burnedCard) { + if (recommendations[0].burnedCard == card.id) { + element.classList.add("discard"); + } } else if (recommendations[0].cards && recommendations[0].cards.includes(card.id)) { element.classList.add("select"); @@ -112,7 +118,7 @@ function fillHand() { } } -function discard(cardId, thisHand = null) { +function discard(cardId, thisHand = null, update = true) { let handGiven = true; if (thisHand == null) { thisHand = hand; @@ -127,11 +133,52 @@ function discard(cardId, thisHand = null) { fillHand(); } - if (!handGiven) { + if (!handGiven && update) { updateUI(); } } +function cashOut(thisHand = null) { + if (recommendations.length > 0) { + let handGiven = true; + if (thisHand == null) { + thisHand = hand; + handGiven = false; + } + + console.log("Recommendation: "); + console.log(recommendations[0]); + + if (recommendations[0].burnedCard) { + console.log("Discarding: " + recommendations[0].burnedCard); + discard(recommendations[0].burnedCard, thisHand, false); + } + else if (recommendations[0].pattern && recommendations[0].cards) { + let localPoints = recommendations[0].points; + + let localCards = [...recommendations[0].cards]; + + // reset recommendations + recommendations = []; + + for (let cardId of localCards) { + console.log("Redeeming: " + cardId); + discard(cardId, thisHand, false); + } + + globalPoints += localPoints; + console.log("Cashed out: " + (localPoints * pointsMultiplier) + " points"); + } + + if (!handGiven) { + updateUI(); + } + } + else { + console.log("Nothing to cash out."); + } +} + function drawCard(cardId, thisHand = null, thisDeck = null) { let handGiven = true; if (thisHand == null) { @@ -156,8 +203,7 @@ function drawCard(cardId, thisHand = null, thisDeck = null) { function recommend() { var cardCount = Object.keys(allCards).length - var scale = 6; - recommendOfDepth(scale); + recommendOfDepth(6); updateUI(true); } @@ -194,7 +240,6 @@ function getPatterns(thisHand = null) { let cardIds = []; for (let card of cardsByNumbers[i]) { - console.log(card); cardIds.push(cardToId(card)); } @@ -222,6 +267,11 @@ function getPatterns(thisHand = null) { } if (isSeries) { + let sameColor = false; + if (theseColors.length > 0) { + sameColor = true; + } + let patternName = (i + 1).toString(); for (let numberOffset = 1; numberOffset < seriesLength; numberOffset++) { patternName += "-" + (i + numberOffset + 1).toString(); @@ -230,16 +280,30 @@ function getPatterns(thisHand = null) { // "i" is lagging behind, adjustment needed let points = (i + 1); - // check if they are of the same color - if (theseColors.length > 0) { + if (sameColor) { points = ((i + 1) + sameColorExtra); patternName += "*"; } + // try to regather the cards + let allowedColors = theseColors; + let gatheredCards = []; + if (allowedColors.length < 1) { + allowedColors = colors; + } + for (let numberOffset = 0; numberOffset < seriesLength; numberOffset++) { + for (let card of cardsByNumbers[i + numberOffset]) { + if (allowedColors.includes(card.color)) { + gatheredCards.push(card.id); + break; + } + } + } + patterns[patternName] = {}; patterns[patternName].pattern = patternName; patterns[patternName].points = points; - patterns[patternName].cards = []; + patterns[patternName].cards = gatheredCards; } } @@ -260,15 +324,16 @@ function getHandPoints(hand = null) { return { pattern: "none", points: 0 }; } -function recommendOfDepth(depth = 2) { - var t0 = performance.now(); +function recommendOfDepth(depth = 0) { + if (measurePerformance) { + var t0 = performance.now(); + } recommendations = []; recommendThrowaway(depth); let current = getHandPoints(); if (current.points > 0) { let choice = { - burnedCard: "CASH OUT", points: current, chance: 1, points: current.points, @@ -278,8 +343,10 @@ function recommendOfDepth(depth = 2) { recommendations.unshift(choice); } - var t1 = performance.now(); - console.log("Took " + (t1 - t0) + " milliseconds."); + if (measurePerformance) { + var t1 = performance.now(); + console.log("Took " + (t1 - t0) + " milliseconds."); + } } function recommendThrowaway(depth = 0, thisHand = null, thisDeck = null, chance = 1, firstDiscarded = null) { @@ -336,15 +403,32 @@ function recommendThrowaway(depth = 0, thisHand = null, thisDeck = null, chance choice.chance = thisChance recommendations.push(choice); - - if (depth > 0 && recommendations.length < 1) { - recommendThrowaway(depth - 1, hands[choice.index], decks[choice.index], thisChance, choice.burnedCard); + } + } + + // compress recommendations + if (choices.length > 0) { + recommendations = [...new Set(recommendations)]; + + // only allow one recommendation per pattern + let newRecs = []; + for (let rec of recommendations) { + if (!newRecs.map(newRec => newRec.pattern).includes(rec.pattern)) { + newRecs.push(rec); } } + + recommendations = newRecs; + } + + // recursive + for (let choice of choices) { + if (depth > 0 && recommendations.length < minimumRecommendations) { + recommendThrowaway(depth - 1, hands[choice.index], decks[choice.index], choice.chance, choice.burnedCard); + } } if (firstDiscarded == null) { - recommendations = [...new Set(recommendations)]; recommendations.sort((a, b) => { var place = 0 if (a.chance > b.chance) { @@ -361,10 +445,10 @@ function recommendThrowaway(depth = 0, thisHand = null, thisDeck = null, chance } return place; }); - let fewer = recommendations.filter(choice => choice.chance >= 0.01); - if (fewer.length > 0) { - recommendations = fewer; - } + // let fewer = recommendations.filter(choice => choice.chance >= 0.01); + // if (fewer.length > 0) { + // recommendations = fewer; + // } } } @@ -385,7 +469,12 @@ function getRecommendationText(rec) { function updateUI(skipAuto = false) { if (autoRecommend && !skipAuto) { - recommend(); + if (hand.length >= handSize) { + recommend(); + } + else { + // recommendations = []; + } } recommendationArray = []; for (let recommendation of recommendations) { @@ -411,9 +500,12 @@ function updateUI(skipAuto = false) { deckElement.innerHTML += cardToElement(card, true, true); } } + + pointsElement.innerHTML = Math.floor(globalPoints * pointsMultiplier); } function reset() { + globalPoints = 0; allCards = {}; deck = []; hand = []; diff --git a/style.css b/style.css index 885e5ea..a631d1a 100644 --- a/style.css +++ b/style.css @@ -29,11 +29,16 @@ --yellow-card-background: #c49000; --card-inset-shadow: #000000; - --card-border-color: #ffffff; + --card-inset-shadow-variant: #ffffff; + --card-border: #ffffff; + --card-border-variant: #000000; --card-height: 70px; --card-width: 55px; --card-font-size: 30pt; + + --discard: red; + --cash-out: green; } * { @@ -100,8 +105,11 @@ panel-title { color: var(--text-disabled); } -.discard, .select { - box-shadow: inset 0 0 50px -10px white, 0 0 10px -6px red; +.discard { + box-shadow: inset 0 0 50px -10px var(--card-inset-shadow-variant), 0 0 6px 2px var(--discard), inset 0 0 10px -4px var(--discard); +} +.select { + box-shadow: inset 0 0 50px -10px var(--card-inset-shadow-variant), 0 0 6px 2px var(--cash-out), inset 0 0 10px -4px var(--cash-out); } card-container { @@ -139,11 +147,11 @@ okey-card:hover, okey-card:active { } okey-card[clickable]:not([hand-full]):hover { - box-shadow: inset 0 0 50px -10px var(--card-inset-shadow), 0 0 3px 0 var(--card-border-color); + box-shadow: inset 0 0 50px -10px var(--card-inset-shadow), 0 0 3px 0 var(--card-border); } okey-card[clickable]:not([hand-full]):active { - box-shadow: inset 0 0 50px -10px var(--card-inset-shadow), 0 0 3px 0 var(--card-border-color), inset 0 0 0 100px var(--primary); + box-shadow: inset 0 0 50px -10px var(--card-inset-shadow), 0 0 3px 0 var(--card-border), inset 0 0 0 100px var(--primary); } okey-card:not([clickable]):active, okey-card[hand-full]:active {