Made single-level evaluation
This commit is contained in:
+1
-1
@@ -26,7 +26,7 @@
|
||||
</main-panel>
|
||||
<main-panel>
|
||||
<button onclick="reset();">Reset</button>
|
||||
<button onclick="document.getElementById('result').innerHTML = getPatterns();">Analyze</button>
|
||||
<input type="checkbox" onclick="toggleAutoDraw(this)" id="autoDrawToggle" /><label for="autoDrawToggle">Auto-Draw</label>
|
||||
<br>
|
||||
<div style="margin-top: 1.4em;" id="result">?</div>
|
||||
</main-panel>
|
||||
|
||||
@@ -1,21 +1,44 @@
|
||||
var deck = {};
|
||||
var hand = {};
|
||||
var maxNumber = 8; // the maximum number on cards (cards always start at one)
|
||||
var colors = [ "red", "blue", "yellow" ]; // the available numbers
|
||||
var handSize = (colors.length * 2) - 1; // the maximum hand size
|
||||
var seriesLength = colors.length; // the minimum required length of series
|
||||
var pointsMultiplier = 10; // useless "big number feel" multiplier
|
||||
var sameNumberExtra = 1; // extra points given for sets of same numbers
|
||||
var sameColorExtra = 4; // extra points given for sets of the same color if they are in a series
|
||||
|
||||
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 allCards = undefined;
|
||||
var deck = undefined;
|
||||
var hand = undefined;
|
||||
var recommendations = undefined;
|
||||
|
||||
var deckElement = document.getElementById('deck');
|
||||
var handElement = document.getElementById('hand');
|
||||
var recommendElement = document.getElementById('result');
|
||||
|
||||
var colors = [ "red", "blue", "yellow" ];
|
||||
var handSize = 5;
|
||||
var maxNumber = 8;
|
||||
reset();
|
||||
|
||||
fillDeck();
|
||||
updateUI();
|
||||
function toggleAutoDraw(element) {
|
||||
if (element.checked) {
|
||||
autoDraw = true;
|
||||
fillHand();
|
||||
}
|
||||
else {
|
||||
autoDraw = false;
|
||||
}
|
||||
}
|
||||
|
||||
function cardToId(card) {
|
||||
return card.color + "_" + card.number.toString();
|
||||
}
|
||||
|
||||
function cardToElement(card, forDeck = false) {
|
||||
function idToCard(cardId) {
|
||||
return allCards[cardId];
|
||||
}
|
||||
|
||||
function cardToElement(card, forDeck = false, drawn = false) {
|
||||
var element = document.createElement("okey-card");
|
||||
element.innerHTML = card.number.toString();
|
||||
|
||||
@@ -29,7 +52,7 @@ function cardToElement(card, forDeck = false) {
|
||||
element.setAttribute("onclick", "discard('" + cardToId(card) + "')");
|
||||
}
|
||||
|
||||
if (forDeck && card.drawn) {
|
||||
if (forDeck && drawn) {
|
||||
element.classList.add("drawn-" + card.color);
|
||||
}
|
||||
else {
|
||||
@@ -40,82 +63,309 @@ function cardToElement(card, forDeck = false) {
|
||||
return element.outerHTML;
|
||||
}
|
||||
|
||||
function isHandFull() {
|
||||
function isHandFull(thisHand = null) {
|
||||
if (thisHand == null) {
|
||||
thisHand = hand;
|
||||
}
|
||||
|
||||
return Object.entries(hand).length >= handSize;
|
||||
}
|
||||
|
||||
function fillDeck() {
|
||||
function generateCards() {
|
||||
for (let color of colors)
|
||||
{
|
||||
for (let i = 1; i <= maxNumber; i++)
|
||||
{
|
||||
let card = {
|
||||
color: color,
|
||||
number: i,
|
||||
drawn: false
|
||||
number: i
|
||||
};
|
||||
card.id = cardToId(card);
|
||||
|
||||
deck[cardToId(card)] = card;
|
||||
allCards[card.id] = card;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function discard(cardId) {
|
||||
delete hand[cardId];
|
||||
function fillDeck() {
|
||||
for (let cardId of Object.keys(allCards)) {
|
||||
deck.push(cardId);
|
||||
}
|
||||
}
|
||||
|
||||
function fillHand() {
|
||||
let draws = handSize - hand.length;
|
||||
for (let i = 0; i < draws; i++) {
|
||||
let deckPos = Math.floor(Math.random()*deck.length);
|
||||
drawCard(deck[deckPos]);
|
||||
}
|
||||
}
|
||||
|
||||
function discard(cardId, thisHand = null) {
|
||||
let handGiven = true;
|
||||
if (thisHand == null) {
|
||||
thisHand = hand;
|
||||
handGiven = false;
|
||||
}
|
||||
|
||||
if (thisHand.indexOf(cardId) !== -1) {
|
||||
thisHand.splice(thisHand.indexOf(cardId), 1);
|
||||
}
|
||||
|
||||
if (autoDraw) {
|
||||
fillHand();
|
||||
}
|
||||
|
||||
if (!handGiven) {
|
||||
updateUI();
|
||||
}
|
||||
}
|
||||
|
||||
function drawCard(cardId) {
|
||||
if (!deck[cardId].drawn && !isHandFull()) {
|
||||
hand[cardId] = deck[cardId];
|
||||
deck[cardId].drawn = true;
|
||||
function drawCard(cardId, thisHand = null, thisDeck = null) {
|
||||
let handGiven = true;
|
||||
if (thisHand == null) {
|
||||
thisHand = hand;
|
||||
handGiven = false;
|
||||
}
|
||||
|
||||
if (thisDeck == null) {
|
||||
thisDeck = deck;
|
||||
handGiven = false;
|
||||
}
|
||||
|
||||
if (!isHandFull(thisHand) && thisDeck.includes(cardId)) {
|
||||
thisDeck.splice(thisDeck.indexOf(cardId), 1);
|
||||
thisHand.push(cardId);
|
||||
}
|
||||
|
||||
if (!handGiven) {
|
||||
updateUI();
|
||||
}
|
||||
}
|
||||
|
||||
function recommend() {
|
||||
recommendOfDepth();
|
||||
updateUI(true);
|
||||
}
|
||||
|
||||
function getPatterns(thisHand = null) {
|
||||
if (thisHand == null) {
|
||||
thisHand = hand;
|
||||
}
|
||||
|
||||
let patterns = [];
|
||||
let patterns = {};
|
||||
|
||||
for (let i = 1; i <= maxNumber; i++) {
|
||||
sameNumber = 0;
|
||||
for (let card of Object.values(thisHand)) {
|
||||
if (card.number == i) {
|
||||
sameNumber++;
|
||||
cardsByNumbers = [];
|
||||
cardColorsByNumbers = [];
|
||||
|
||||
// set up empty arrays for each number
|
||||
for (let i = 0; i < maxNumber; i++) {
|
||||
cardsByNumbers.push([]);
|
||||
cardColorsByNumbers.push([]);
|
||||
}
|
||||
|
||||
// fill them with the current hand's cards
|
||||
for (let cardId of thisHand) {
|
||||
let card = idToCard(cardId);
|
||||
cardColorsByNumbers[card.number - 1].push(card.color);
|
||||
cardsByNumbers[card.number - 1].push(card);
|
||||
}
|
||||
|
||||
// check if there are "color" amount of any
|
||||
for (let i = 0; i < maxNumber; i++) {
|
||||
if (cardsByNumbers[i].length >= colors.length) {
|
||||
let patternName = (i + 1).toString();
|
||||
for (let j = 1; j < colors.length; j++) {
|
||||
patternName += "-" + (i + 1).toString();
|
||||
}
|
||||
|
||||
// "i" is lagging behind, adjustment needed
|
||||
let points = (i + 1 + sameNumberExtra)
|
||||
patterns[patternName] = {};
|
||||
patterns[patternName].pattern = patternName;
|
||||
patterns[patternName].points = points;
|
||||
}
|
||||
}
|
||||
|
||||
if (sameNumber >= colors.length) {
|
||||
let patternName = i + "-" + i + "-" + i;
|
||||
patterns[patternName] = (i + 1) * 10;
|
||||
// check if there are series present
|
||||
for (let i = 0; i <= (maxNumber - seriesLength); i++) {
|
||||
let isSeries = true;
|
||||
let theseColors = colors;
|
||||
for (let numberOffset = 0; numberOffset < seriesLength; numberOffset++) {
|
||||
if (cardColorsByNumbers[i + numberOffset] < 1) {
|
||||
isSeries = false;
|
||||
break;
|
||||
}
|
||||
|
||||
// intersect
|
||||
theseColors = [theseColors, cardColorsByNumbers[i + numberOffset]].reduce((a, c) => a.filter(i => c.includes(i)));
|
||||
}
|
||||
|
||||
if (isSeries) {
|
||||
let patternName = (i + 1).toString();
|
||||
for (let numberOffset = 1; numberOffset < seriesLength; numberOffset++) {
|
||||
patternName += "-" + (i + numberOffset + 1).toString();
|
||||
}
|
||||
|
||||
// "i" is lagging behind, adjustment needed
|
||||
let points = (i + 1);
|
||||
|
||||
// check if they are of the same color
|
||||
if (theseColors.length > 0) {
|
||||
points = ((i + 1) + sameColorExtra);
|
||||
patternName += "*";
|
||||
}
|
||||
|
||||
patterns[patternName] = {};
|
||||
patterns[patternName].pattern = patternName;
|
||||
patterns[patternName].points = points;
|
||||
}
|
||||
}
|
||||
|
||||
console.log(Object.keys(patterns));
|
||||
let points = Object.values(patterns).map(pattern => pattern.points);
|
||||
let maxPoints = Math.max(...points);
|
||||
|
||||
patterns = patterns.sort((a,b) => (a.last_nom > b.last_nom) ? -1 : ((b.last_nom > a.last_nom) ? 1 : 0));
|
||||
let selectedPatterns = Object.values(patterns).filter(pattern => pattern.points == maxPoints);
|
||||
|
||||
return Object.keys(patterns);
|
||||
return selectedPatterns;
|
||||
}
|
||||
|
||||
function updateUI() {
|
||||
function getHandPoints(hand = null) {
|
||||
let patterns = getPatterns(hand);
|
||||
if (patterns.length > 0) {
|
||||
return patterns[0].points;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
function recommendOfDepth(depth = 4) {
|
||||
var t0 = performance.now();
|
||||
|
||||
recommendations = [];
|
||||
recommendThrowaway(depth);
|
||||
let current = getHandPoints();
|
||||
if (current > 0) {
|
||||
let choice = {
|
||||
burnedCard: "CASH OUT",
|
||||
points: current,
|
||||
chance: 1
|
||||
};
|
||||
recommendations.unshift(choice);
|
||||
}
|
||||
|
||||
var t1 = performance.now();
|
||||
console.log("Took " + (t1 - t0) + " milliseconds.");
|
||||
}
|
||||
|
||||
function recommendThrowaway(depth = 0, thisHand = null, thisDeck = null, chance = 1, startingFunction = true) {
|
||||
if (thisHand == null) {
|
||||
thisHand = hand;
|
||||
}
|
||||
|
||||
if (thisDeck == null) {
|
||||
thisDeck = deck;
|
||||
}
|
||||
|
||||
if (Object.keys(thisHand).length < 1) {
|
||||
return [0, "nothing", 0];
|
||||
}
|
||||
|
||||
let decks = [];
|
||||
let hands = [];
|
||||
let choices = [];
|
||||
|
||||
let loopDuration = Math.min(handSize, thisHand.length);
|
||||
|
||||
for (let i = 0; i < loopDuration; i++) {
|
||||
for (let deckIndex = 0; deckIndex < thisDeck.length; deckIndex++) {
|
||||
let newHand = [...thisHand];
|
||||
let newDeck = [...thisDeck];
|
||||
|
||||
choices.push({ burnedCard: newHand[i], index: i });
|
||||
|
||||
newHand.splice(i, 1);
|
||||
newHand.push(newDeck[deckIndex]);
|
||||
newDeck.splice(deckIndex, 1);
|
||||
|
||||
hands.push(newHand);
|
||||
decks.push(newDeck);
|
||||
}
|
||||
}
|
||||
|
||||
if (startingFunction) {
|
||||
console.log(choices);
|
||||
for (let choice of choices) {
|
||||
let points = getHandPoints(hands[choice.index]);
|
||||
if (points > 0) {
|
||||
choice.points = points;
|
||||
|
||||
let thisChance = 1;
|
||||
if (thisDeck.length > 0) {
|
||||
thisChance = chance * (1/thisDeck.length);
|
||||
}
|
||||
|
||||
choice.chance = thisChance
|
||||
recommendations.push(choice);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function getRecommendationText(rec) {
|
||||
if (Object.keys(allCards).includes(rec.burnedCard)) {
|
||||
return "Burn <b><u>" +
|
||||
rec.burnedCard.replace("_", " ") +
|
||||
"</u></b> and earn potentially " +
|
||||
(rec.points * pointsMultiplier) +
|
||||
" points. (" +
|
||||
(rec.chance * 100).toFixed(2) +
|
||||
"% chance)";
|
||||
}
|
||||
return "<b><u>Cash out</u></b> and get " +
|
||||
(rec.points * pointsMultiplier) +
|
||||
" points instantly!";
|
||||
}
|
||||
|
||||
function updateUI(skipAuto = false) {
|
||||
if (autoRecommend && !skipAuto) {
|
||||
recommend();
|
||||
}
|
||||
recommendationArray = [];
|
||||
for (let recommendation of recommendations) {
|
||||
recommendationArray.push(getRecommendationText(recommendation));
|
||||
|
||||
}
|
||||
recommendationArray = [...new Set(recommendationArray)];
|
||||
recommendElement.innerHTML = recommendationArray.join("<br>");
|
||||
|
||||
handElement.innerHTML = "";
|
||||
for (let card of Object.values(hand)) {
|
||||
for (let cardId of hand) {
|
||||
let card = idToCard(cardId);
|
||||
handElement.innerHTML += cardToElement(card);
|
||||
}
|
||||
|
||||
deckElement.innerHTML = "";
|
||||
for (let card of Object.values(deck)) {
|
||||
for (let cardId of Object.keys(allCards)) {
|
||||
let card = idToCard(cardId);
|
||||
if (deck.includes(cardId)) {
|
||||
deckElement.innerHTML += cardToElement(card, true);
|
||||
}
|
||||
else {
|
||||
deckElement.innerHTML += cardToElement(card, true, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function reset() {
|
||||
deck = {};
|
||||
hand = {};
|
||||
allCards = {};
|
||||
deck = [];
|
||||
hand = [];
|
||||
recommendations = [];
|
||||
generateCards();
|
||||
fillDeck();
|
||||
if (autoDraw) {
|
||||
fillHand();
|
||||
}
|
||||
updateUI();
|
||||
}
|
||||
Reference in New Issue
Block a user