Compare commits

..

No commits in common. "f5faff57913cbe8230dedea60e4065e82f8adb85" and "60971a2d1350c8d17a3df0b67cc01514129081c3" have entirely different histories.

15 changed files with 372 additions and 391 deletions

File diff suppressed because one or more lines are too long

2
dist/index.html vendored

File diff suppressed because one or more lines are too long

View file

@ -1,6 +1,6 @@
{ {
"name": "tripeaks-solitaire-solver-js-73k", "name": "tripeaks-solitaire-solver-js-73k",
"version": "1.0.4", "version": "1.0.3",
"description": "A brute force solver for tri peaks solitaire written in javascript. Forked from work by Courtney Pitcher at https://github.com/IgniparousTempest/javascript-tri-peaks-solitaire-solver", "description": "A brute force solver for tri peaks solitaire written in javascript. Forked from work by Courtney Pitcher at https://github.com/IgniparousTempest/javascript-tri-peaks-solitaire-solver",
"keywords": [ "keywords": [
"tripeaks", "tripeaks",

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 35 KiB

After

Width:  |  Height:  |  Size: 35 KiB

View file

@ -1,3 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="28" height="28" fill="currentColor" class="bi bi-github" viewBox="0 0 16 16"> <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-github" viewBox="0 0 16 16">
<path d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.012 8.012 0 0 0 16 8c0-4.42-3.58-8-8-8z"/> <path d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.012 8.012 0 0 0 16 8c0-4.42-3.58-8-8-8z"/>
</svg> </svg>

Before

Width:  |  Height:  |  Size: 716 B

After

Width:  |  Height:  |  Size: 716 B

View file

@ -1,3 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="28" height="28" fill="currentColor" class="bi bi-twitter" viewBox="0 0 16 16"> <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-twitter" viewBox="0 0 16 16">
<path d="M5.026 15c6.038 0 9.341-5.003 9.341-9.334 0-.14 0-.282-.006-.422A6.685 6.685 0 0 0 16 3.542a6.658 6.658 0 0 1-1.889.518 3.301 3.301 0 0 0 1.447-1.817 6.533 6.533 0 0 1-2.087.793A3.286 3.286 0 0 0 7.875 6.03a9.325 9.325 0 0 1-6.767-3.429 3.289 3.289 0 0 0 1.018 4.382A3.323 3.323 0 0 1 .64 6.575v.045a3.288 3.288 0 0 0 2.632 3.218 3.203 3.203 0 0 1-.865.115 3.23 3.23 0 0 1-.614-.057 3.283 3.283 0 0 0 3.067 2.277A6.588 6.588 0 0 1 .78 13.58a6.32 6.32 0 0 1-.78-.045A9.344 9.344 0 0 0 5.026 15z"/> <path d="M5.026 15c6.038 0 9.341-5.003 9.341-9.334 0-.14 0-.282-.006-.422A6.685 6.685 0 0 0 16 3.542a6.658 6.658 0 0 1-1.889.518 3.301 3.301 0 0 0 1.447-1.817 6.533 6.533 0 0 1-2.087.793A3.286 3.286 0 0 0 7.875 6.03a9.325 9.325 0 0 1-6.767-3.429 3.289 3.289 0 0 0 1.018 4.382A3.323 3.323 0 0 1 .64 6.575v.045a3.288 3.288 0 0 0 2.632 3.218 3.203 3.203 0 0 1-.865.115 3.23 3.23 0 0 1-.614-.057 3.283 3.283 0 0 0 3.067 2.277A6.588 6.588 0 0 1 .78 13.58a6.32 6.32 0 0 1-.78-.045A9.344 9.344 0 0 0 5.026 15z"/>
</svg> </svg>

Before

Width:  |  Height:  |  Size: 640 B

After

Width:  |  Height:  |  Size: 640 B

View file

@ -1,5 +1,3 @@
import { suits, ranks, deck } from "./deck";
// backs & joker // backs & joker
import card1B from "../cards/1B.svg?raw"; import card1B from "../cards/1B.svg?raw";
import card2B from "../cards/2B.svg?raw"; import card2B from "../cards/2B.svg?raw";
@ -127,31 +125,4 @@ let cardSvgs = {
KS: cardKS, KS: cardKS,
}; };
// Do some SVG processing
const cardSvgTitle = (ckey) => {
return deck.includes(ckey)
? `${ranks[ckey[0]]} of ${suits[ckey[1]]}`
: "Unknown Card";
};
Object.keys(cardSvgs).forEach((ckey) => {
var cardDoc = new DOMParser().parseFromString(
cardSvgs[ckey],
"image/svg+xml"
);
var svgRoot = cardDoc.documentElement;
svgRoot.removeAttribute("height");
svgRoot.removeAttribute("width");
svgRoot.removeAttribute("class");
var titleEl = cardDoc.createElementNS(
svgRoot.lookupNamespaceURI(null),
"title"
);
var titleText = document.createTextNode(cardSvgTitle(ckey));
titleEl.appendChild(titleText);
svgRoot.insertBefore(titleEl, svgRoot.firstElementChild);
cardSvgs[ckey] = new XMLSerializer().serializeToString(
cardDoc.documentElement
);
});
export default cardSvgs; export default cardSvgs;

View file

@ -1,111 +0,0 @@
import { deck } from "./deck";
export default {
// "constants" for validation etc
deck,
nonAlphaNumRegEx: /[\W_]+/g,
// input validation
inputValue: "",
validCards: [],
dupedCards: [],
invalidCards: [],
validMessages: [],
invalidMessages: [],
get isFormValid() {
return this.isValidCardsLengthInRange && this.invalidMessages.length === 0;
},
get isValidCardsLengthTooSmall() {
return this.validCards.length < 34;
},
get isValidCardsLengthTooBig() {
return this.validCards.length > this.deck.length;
},
get isValidCardsLengthInRange() {
return !this.isValidCardsLengthTooSmall && !this.isValidCardsLengthTooBig;
},
validateCardsInput() {
// reset arrays and parse the input
this.validCards = [];
this.invalidCards = [];
this.dupedCards = [];
this.validMessages = [];
this.invalidMessages = [];
// handle if input has alphanum chars - treat them as delimeters
// if no alphanum chars, split by 2 chars except for 0
let userCards = this.nonAlphaNumRegEx.test(this.inputValue)
? this.inputValue
.toUpperCase()
.replace(this.nonAlphaNumRegEx, " ")
.split(" ")
.filter((c) => c)
: this.inputValue
.toUpperCase()
.split(/0|(..)/g)
.filter((c) => c !== "")
.map((c) => (!c ? "0" : c));
// check the input
userCards.forEach((card) => {
if (card === "0") {
// user marking a slot with an unknown card
this.validCards.push(card);
} else if (this.validCards.includes(card)) {
// this card was already seen in user's input, now it's a duplicate
this.dupedCards.push(card);
} else if (this.deck.includes(card)) {
// not a duplicate, and in the reference deck? Valid, add to valid cards
this.validCards.push(card);
} else {
// not a dupe, but not in reference deck: invalid, add to invalid cards
this.invalidCards.push(card);
}
});
// set validation messages based on length
if (this.isValidCardsLengthTooSmall) {
this.invalidMessages.push(`Must enter at least 34 cards`);
} else if (this.isValidCardsLengthTooBig) {
this.invalidMessages.push(
`Must not enter more than ${this.deck.length} cards`
);
}
if (this.validCards.slice(this.validCards.length - 34).includes("0")) {
this.invalidMessages.push(
`Stock + bottom row (last 34 cards) must not contain unknown ('0') cards`
);
}
// set other validation messages
if (this.dupedCards.length > 0) {
let s = this.dupedCards.length > 1 ? "s" : "";
this.invalidMessages.push(
`${this.dupedCards.length} duplicate card${s}: ${this.dupedCards.join(
" "
)}`
);
}
if (this.invalidCards.length > 0) {
let s = this.invalidCards.length > 1 ? "s" : "";
this.invalidMessages.push(
`${this.invalidCards.length} invalid card${s}: ${this.invalidCards.join(
" "
)}`
);
}
if (this.validCards.length > 0) {
let s = this.validCards.length > 1 ? "s" : "";
this.validMessages.push(
`${this.validCards.length} valid card${s}: ${this.validCards.join(" ")}`
);
}
// set the game cards to try solving, based on current input
this.$store.global.cardsToSolve = Array(
this.deck.length - this.validCards.length
)
.fill(0)
.concat(this.validCards)
.map((c) => (c === "0" ? 0 : c));
},
};

View file

@ -1,28 +0,0 @@
const suits = {
C: "Clubs",
D: "Diamonds",
H: "Hearts",
S: "Spades",
};
const ranks = {
A: "Ace",
2: "Two",
3: "Three",
4: "Four",
5: "Five",
6: "Six",
7: "Seven",
8: "Eight",
9: "Nine",
T: "Ten",
J: "Jack",
Q: "Queen",
K: "King",
};
const deck = Object.keys(suits).flatMap((suit) => {
return Object.keys(ranks).map((cval) => {
return cval + suit;
});
});
export { suits, ranks, deck };

View file

@ -1,42 +0,0 @@
// long-running solve messages
export default [
"Hang in there!",
"Let go like a bird flies, not fighting the wind but gliding on it",
"Stay patient and trust the journey.",
"Everything is coming together…",
"Solitaire is a journey, not a destination.",
"For things to reveal themselves to us, we need to be ready to abandon our views about them.",
"Patience is bitter, but its fruit is sweet.",
"Strive for progress, not perfection.",
"I wish only to be alive and to experience this living to the fullest.",
"This too shall pass.",
"Life is available only in the present moment.",
"Patience is the companion of wisdom.",
"The mountains are calling and I must go.",
"Give time time.",
"If you find a path with no obstacles, it probably doesn't lead anywhere",
"A smooth sea never made a good sailor.",
"To be upset over what you dont have is to waste what you do have.",
"The ultimate freedom lies in being able to wait patiently for a good thing.",
"If it isn't good, let it die. If it doesn't die, make it good.",
"A watched pot never boils without applying heat.",
"Stick with the winners.",
"I immerse myself in the experience of living without having to evaluate or understand it.",
"Why fit in when you were born to stand out?",
"Don't let yesterday take up too much of today.",
"The least I owe the mountains is a body.",
"Getting so close!",
"Many people think excitement is happiness. But when you are excited you are not peaceful.",
"Misery is optional.",
"Mistakes are proof that you're trying.",
"Life would be so much easier if we only had the source code.",
"A computer once beat me at chess, but it was no match for me at kickboxing.",
"Patience is not simply the ability to wait, it's how we behave while we're waiting.",
"We must let go of the life we have planned so as to accept the one that is waiting for us.",
"Somewhere, something incredible is waiting to be known.",
"If you spend your whole life waiting for the storm, you'll never enjoy the sunshine.",
"My actions are my only true belongings.",
"The way to have enough time is to never be in a hurry.",
"The more you know, the less you think you know.",
"Patience is also a form of action.",
];

View file

@ -1,77 +0,0 @@
import encouragements from "./encouragements";
import SolverWorker from "./solverWorker?worker";
export default {
encouragements,
encourageIndex: null,
solverWorker: null,
headerText: "Solution",
moveCount: 23,
statusMessages: [],
solutionMoves: [],
nodesTried: 0,
nodesTriedFloor: 0,
reset() {
this.$store.global.solvingInProgress = false;
this.moveCount = 0;
this.statusMessages = [];
this.nodesTried = 0;
this.nodesTriedFloor = 0;
this.encourageIndex = null;
},
onInit() {
this.solverWorker = new SolverWorker();
this.solverWorker.addEventListener("message", async (e) => {
if (e.data.msg === "solve-progress") {
this.nodesTried++;
this.moveCount = e.data.moveCount;
this.statusMessages[0] = `${this.moveCount} card-clearing moves found so far.`;
let newFloor = Math.floor(this.nodesTried / 10000) * 10000;
if (newFloor > this.nodesTriedFloor) {
this.nodesTriedFloor = newFloor;
if (this.nodesTriedFloor > 50000) {
this.statusMessages[1] = `Over ${this.nodesTriedFloor.toLocaleString(
"en"
)} possibilities tried. Still working`;
}
if (this.nodesTriedFloor % 250000 === 0) {
if (this.encourageIndex === null) {
this.encourageIndex = Math.floor(
Math.random() * this.encouragements.length
);
}
this.statusMessages.splice(
2,
0,
this.encouragements[this.encourageIndex]
);
let newEncourageIndex = this.encourageIndex + 1;
this.encourageIndex =
newEncourageIndex === this.encouragements.length
? 0
: newEncourageIndex;
}
}
} else if (e.data.msg === "solve-result") {
if (e.data.result[0]) {
this.headerText = "Solution found:";
this.solutionMoves = e.data.result[1];
this.reset();
} else {
this.headerText = "Could not solve. Best moves found:";
this.solutionMoves = e.data.result[2];
this.reset();
}
}
});
},
async startSolver() {
this.headerText = "Solving…";
this.solutionMoves = [];
this.$store.global.solvingInProgress = true;
await this.$nextTick();
let game = JSON.parse(JSON.stringify(this.$store.global.cardsToSolve));
this.solverWorker.postMessage({ msg: "try-to-solve", game: game });
},
};

View file

@ -1,25 +1,321 @@
import "../scss/style.scss"; import "../scss/style.scss";
import Alpine from "alpinejs"; import Alpine from "alpinejs";
import globalStore from "./store"; import cardSvgs from "./cardSvgs";
import navbar from "./navbar"; import SolverWorker from "./solverWorker?worker";
import cardsInputForm from "./cardsInputForm";
import playingCardsPreview from "./playingCardsPreview"; // navbar svg icons
import gameSolving from "./gameSolving"; import svg73k from "../img/73k.svg?raw";
import biTwitter from "../img/bi-twitter.svg?raw";
import biGithub from "../img/bi-github.svg?raw";
// Some helpful constants
const suits = {
C: "Clubs",
D: "Diamonds",
H: "Hearts",
S: "Spades",
};
const ranks = {
A: "Ace",
2: "Two",
3: "Three",
4: "Four",
5: "Five",
6: "Six",
7: "Seven",
8: "Eight",
9: "Nine",
T: "Ten",
J: "Jack",
Q: "Queen",
K: "King",
};
const deck = Object.keys(suits).flatMap((suit) => {
return Object.keys(ranks).map((cval) => {
return cval + suit;
});
});
// Do some SVG processing
const cardSvgTitle = (ckey) => {
return deck.includes(ckey)
? `${ranks[ckey[0]]} of ${suits[ckey[1]]}`
: "Unknown Card";
};
Object.keys(cardSvgs).forEach((ckey) => {
var cardDoc = new DOMParser().parseFromString(
cardSvgs[ckey],
"image/svg+xml"
);
var svgRoot = cardDoc.documentElement;
svgRoot.removeAttribute("height");
svgRoot.removeAttribute("width");
svgRoot.removeAttribute("class");
var titleEl = cardDoc.createElementNS(
svgRoot.lookupNamespaceURI(null),
"title"
);
var titleText = document.createTextNode(cardSvgTitle(ckey));
titleEl.appendChild(titleText);
svgRoot.insertBefore(titleEl, svgRoot.firstElementChild);
cardSvgs[ckey] = new XMLSerializer().serializeToString(
cardDoc.documentElement
);
});
// Keep some constants in global store for components // Keep some constants in global store for components
Alpine.store("global", globalStore); Alpine.store("global", {
deck,
cardsToSolve: Array(deck.length).fill(0),
solvingInProgress: false,
});
// navbar logic // navbar logic
Alpine.data("navbar", () => navbar); Alpine.data("navbar", () => ({
svg73k: svg73k.replaceAll('="16"', '="24"'),
// input component logic biTwitter: biTwitter.replaceAll('="16"', '="24"'),
Alpine.data("cardsInputForm", () => cardsInputForm); biGithub: biGithub.replaceAll('="16"', '="24"'),
}));
// card preview component logic // card preview component logic
Alpine.data("playingCardsPreview", () => playingCardsPreview); Alpine.data("playingCardsPreview", () => ({
cardSvgs,
cardsBySlice(start, length) {
return this.$store.global.cardsToSolve.slice(start, length);
},
cardSvg(card) {
return card === 0 ? this.cardSvgs["2B"] : this.cardSvgs[card];
},
}));
// input component logic
Alpine.data("cardsInputForm", () => ({
// "constants" for validation etc
nonAlphaNumRegEx: /[\W_]+/g,
// input validation
inputValue: "",
validCards: [],
dupedCards: [],
invalidCards: [],
validMessages: [],
invalidMessages: [],
get isFormValid() {
return this.isValidCardsLengthInRange && this.invalidMessages.length === 0;
},
get isValidCardsLengthTooSmall() {
return this.validCards.length < 34;
},
get isValidCardsLengthTooBig() {
return this.validCards.length > this.$store.global.deck.length;
},
get isValidCardsLengthInRange() {
return !this.isValidCardsLengthTooSmall && !this.isValidCardsLengthTooBig;
},
validateCardsInput() {
// reset arrays and parse the input
this.validCards = [];
this.invalidCards = [];
this.dupedCards = [];
this.validMessages = [];
this.invalidMessages = [];
// handle if input has alphanum chars - treat them as delimeters
// if no alphanum chars, split by 2 chars except for 0
let userCards = this.nonAlphaNumRegEx.test(this.inputValue)
? this.inputValue
.toUpperCase()
.replace(this.nonAlphaNumRegEx, " ")
.split(" ")
.filter((c) => c)
: this.inputValue
.toUpperCase()
.split(/0|(..)/g)
.filter((c) => c !== "")
.map((c) => (!c ? "0" : c));
// check the input
userCards.forEach((card) => {
if (card === "0") {
// user marking a slot with an unknown card
this.validCards.push(card);
} else if (this.validCards.includes(card)) {
// this card was already seen in user's input, now it's a duplicate
this.dupedCards.push(card);
} else if (this.$store.global.deck.includes(card)) {
// not a duplicate, and in the reference deck? Valid, add to valid cards
this.validCards.push(card);
} else {
// not a dupe, but not in reference deck: invalid, add to invalid cards
this.invalidCards.push(card);
}
});
// set validation messages based on length
if (this.isValidCardsLengthTooSmall) {
this.invalidMessages.push(`Must enter at least 34 cards`);
} else if (this.isValidCardsLengthTooBig) {
this.invalidMessages.push(
`Must not enter more than ${this.$store.global.deck.length} cards`
);
}
if (this.validCards.slice(this.validCards.length - 34).includes("0")) {
this.invalidMessages.push(
`Stock + bottom row (last 34 cards) must not contain unknown ('0') cards`
);
}
// set other validation messages
if (this.dupedCards.length > 0) {
let s = this.dupedCards.length > 1 ? "s" : "";
this.invalidMessages.push(
`${this.dupedCards.length} duplicate card${s}: ${this.dupedCards.join(
" "
)}`
);
}
if (this.invalidCards.length > 0) {
let s = this.invalidCards.length > 1 ? "s" : "";
this.invalidMessages.push(
`${this.invalidCards.length} invalid card${s}: ${this.invalidCards.join(
" "
)}`
);
}
if (this.validCards.length > 0) {
let s = this.validCards.length > 1 ? "s" : "";
this.validMessages.push(
`${this.validCards.length} valid card${s}: ${this.validCards.join(" ")}`
);
}
// set the game cards to try solving, based on current input
this.$store.global.cardsToSolve = Array(
this.$store.global.deck.length - this.validCards.length
)
.fill(0)
.concat(this.validCards)
.map((c) => (c === "0" ? 0 : c));
},
}));
// long-running solve messages
const encouragements = [
"Hang in there!",
"Let go like a bird flies, not fighting the wind but gliding on it",
"Stay patient and trust the journey.",
"Everything is coming together…",
"Solitaire is a journey, not a destination.",
"For things to reveal themselves to us, we need to be ready to abandon our views about them.",
"Patience is bitter, but its fruit is sweet.",
"Strive for progress, not perfection.",
"I wish only to be alive and to experience this living to the fullest.",
"This too shall pass.",
"Life is available only in the present moment.",
"Patience is the companion of wisdom.",
"The mountains are calling and I must go.",
"Give time time.",
"If you find a path with no obstacles, it probably doesn't lead anywhere",
"A smooth sea never made a good sailor.",
"To be upset over what you dont have is to waste what you do have.",
"The ultimate freedom lies in being able to wait patiently for a good thing.",
"If it isn't good, let it die. If it doesn't die, make it good.",
"A watched pot never boils without applying heat.",
"Stick with the winners.",
"I immerse myself in the experience of living without having to evaluate or understand it.",
"Why fit in when you were born to stand out?",
"Don't let yesterday take up too much of today.",
"The least I owe the mountains is a body.",
"Getting so close!",
"Many people think excitement is happiness. But when you are excited you are not peaceful.",
"Misery is optional.",
"Mistakes are proof that you're trying.",
"Life would be so much easier if we only had the source code.",
"A computer once beat me at chess, but it was no match for me at kickboxing.",
"Patience is not simply the ability to wait, it's how we behave while we're waiting.",
"We must let go of the life we have planned so as to accept the one that is waiting for us.",
"Somewhere, something incredible is waiting to be known.",
"If you spend your whole life waiting for the storm, you'll never enjoy the sunshine.",
"My actions are my only true belongings.",
"The way to have enough time is to never be in a hurry.",
"The more you know, the less you think you know.",
"Patience is also a form of action.",
];
// game solving component logic // game solving component logic
Alpine.data("gameSolving", () => gameSolving); Alpine.data("gameSolving", () => ({
encouragements,
encourageIndex: null,
solverWorker: null,
headerText: "Solution",
moveCount: 23,
statusMessages: [],
solutionMoves: [],
nodesTried: 0,
nodesTriedFloor: 0,
reset() {
this.$store.global.solvingInProgress = false;
this.moveCount = 0;
this.statusMessages = [];
this.nodesTried = 0;
this.nodesTriedFloor = 0;
this.encourageIndex = null;
},
onInit() {
this.solverWorker = new SolverWorker();
this.solverWorker.addEventListener("message", async (e) => {
if (e.data.msg === "solve-progress") {
this.nodesTried++;
this.moveCount = e.data.moveCount;
this.statusMessages[0] = `${this.moveCount} card-clearing moves found so far.`;
let newFloor = Math.floor(this.nodesTried / 10000) * 10000;
if (newFloor > this.nodesTriedFloor) {
this.nodesTriedFloor = newFloor;
if (this.nodesTriedFloor > 50000) {
this.statusMessages[1] = `Over ${this.nodesTriedFloor.toLocaleString(
"en"
)} possibilities tried. Still working`;
}
if (this.nodesTriedFloor % 250000 === 0) {
if (this.encourageIndex === null) {
this.encourageIndex = Math.floor(
Math.random() * this.encouragements.length
);
}
this.statusMessages.splice(
2,
0,
this.encouragements[this.encourageIndex]
);
let newEncourageIndex = this.encourageIndex + 1;
this.encourageIndex =
newEncourageIndex === this.encouragements.length
? 0
: newEncourageIndex;
}
}
} else if (e.data.msg === "solve-result") {
if (e.data.result[0]) {
this.headerText = "Solution found:";
this.solutionMoves = e.data.result[1];
this.reset();
} else {
this.headerText = "Could not solve. Best moves found:";
this.solutionMoves = e.data.result[2];
this.reset();
}
}
});
},
async startSolver() {
this.headerText = "Solving…";
this.solutionMoves = [];
this.$store.global.solvingInProgress = true;
await this.$nextTick();
let game = JSON.parse(JSON.stringify(this.$store.global.cardsToSolve));
this.solverWorker.postMessage({ msg: "try-to-solve", game: game });
},
}));
window.Alpine = Alpine; window.Alpine = Alpine;

View file

@ -1,10 +0,0 @@
// navbar svg icons
import svg73k from "../img/73k.svg?raw";
import biTwitter from "../img/bi-twitter.svg?raw";
import biGithub from "../img/bi-github.svg?raw";
export default {
svg73k,
biTwitter,
biGithub,
};

View file

@ -1,11 +0,0 @@
import cardSvgs from "./cardSvgs";
export default {
cardSvgs,
cardsBySlice(start, length) {
return this.$store.global.cardsToSolve.slice(start, length);
},
cardSvg(card) {
return card === 0 ? this.cardSvgs["2B"] : this.cardSvgs[card];
},
};

View file

@ -1,7 +0,0 @@
import { deck } from "./deck";
export default {
deck,
cardsToSolve: Array(deck.length).fill(0),
solvingInProgress: false,
};