after running a lint + format

This commit is contained in:
Adam Piontek 2022-09-07 08:49:25 -04:00
parent 1a47184c29
commit 2b2e1ec0c9
4 changed files with 131 additions and 111 deletions

View file

@ -8,5 +8,5 @@ module.exports = {
node: true,
mocha: true,
},
extends: ["eslint:recommended", "prettier"]
extends: ["eslint:recommended", "prettier"],
};

View file

@ -1,13 +1,13 @@
# javascript-tri-peaks-solitaire-solver
A brute force solver for Microsoft Tri-Peaks solitaire written in javascript.
You can see it in action on my [website](https://igniparoustempest.github.io/tri-peaks-solitaire-solver/):
1. Enter the string "8S TS 4D 7S 5D 7C 2D JH AC 3S 2H 3H 9H KC QC TD 8D 9C 7H 9D JS QS 4H 5C 5S 4C 2C QD 8C KD 3D KS JD 2S 7D KH AH 5H 9S 4S QH 6S 6D 3C JC TC 8H 6C TH AS AD 6H" into the textfield.
2. Click "import"
3. Click "solve"
1. Enter the string "8S TS 4D 7S 5D 7C 2D JH AC 3S 2H 3H 9H KC QC TD 8D 9C 7H 9D JS QS 4H 5C 5S 4C 2C QD 8C KD 3D KS JD 2S 7D KH AH 5H 9S 4S QH 6S 6D 3C JC TC 8H 6C TH AS AD 6H" into the textfield.
2. Click "import"
3. Click "solve"
## Notes
This is probably quite a poor implementation. Please don't fault me, I am teaching myself javascript.

View file

@ -18,7 +18,10 @@ class Card {
* @returns {boolean} True if sequential, false otherwise.
*/
isSequential(card) {
return (this.integerValue + 1) % 13 === card.integerValue || (this.integerValue - 1) % 13 === card.integerValue;
return (
(this.integerValue + 1) % 13 === card.integerValue ||
(this.integerValue - 1) % 13 === card.integerValue
);
}
get toString() {
@ -33,8 +36,7 @@ class Pyramid {
get isCleared() {
for (let i = 0; i < this.array.length; i++) {
if (this.array[i] !== 0)
return false;
if (this.array[i] !== 0) return false;
}
return true;
}
@ -42,20 +44,33 @@ class Pyramid {
get freeCardIndices() {
let freeIndices = [];
for (let i = this.array.length - 1; i >= 0; i--) {
if (this.array[i] === 0)
continue;
if (this.array[i] === 0) continue;
const secondOffset = Math.floor((i - 3) / 2);
// This is the last row
if (i >= 18)
freeIndices.push(i);
if (i >= 18) freeIndices.push(i);
// Third row
else if (i <= 17 && i >= 9 && this.array[i + 9] === 0 && this.array[i + 10] === 0)
else if (
i <= 17 &&
i >= 9 &&
this.array[i + 9] === 0 &&
this.array[i + 10] === 0
)
freeIndices.push(i);
// Second row
else if (i <= 8 && i >= 3 && this.array[i + 6 + secondOffset] === 0 && this.array[i + 7 + secondOffset] === 0)
else if (
i <= 8 &&
i >= 3 &&
this.array[i + 6 + secondOffset] === 0 &&
this.array[i + 7 + secondOffset] === 0
)
freeIndices.push(i);
// First row
else if (i <= 2 && i >= 0 && this.array[i + 3 + i] === 0 && this.array[i + 4 + i] === 0)
else if (
i <= 2 &&
i >= 0 &&
this.array[i + 3 + i] === 0 &&
this.array[i + 4 + i] === 0
)
freeIndices.push(i);
}
return freeIndices;
@ -63,13 +78,21 @@ class Pyramid {
}
class MoveString {
static gameWon() {return "You have won.";}
static gameLost() {return "There are no more valid moves.";}
static match(cardA) {return "Move " + cardA + " onto the stock.";}
static flipStock() {return "Draw a new stock card.";}
static gameWon() {
return "You have won.";
}
static gameLost() {
return "There are no more valid moves.";
}
static match(cardA) {
return "Move " + cardA + " onto the stock.";
}
static flipStock() {
return "Draw a new stock card.";
}
}
const GameStates = Object.freeze({"won": true, "lost": false});
const GameStates = Object.freeze({ won: true, lost: false });
/**
* Solves a Tri Peaks solitaire game.
@ -101,8 +124,7 @@ function solve(pyramidArray, stockArray, stockIndex = 0, moveArray = []) {
// match free cards with stock
for (let i = 0; i < freeCardsIndices.length; i++) {
let cardA = new Card(pyramidArray[freeCardsIndices[i]]);
if (!cardA.isSequential(topStock))
continue;
if (!cardA.isSequential(topStock)) continue;
let newStock = JSON.parse(JSON.stringify(stockArray));
newStock.splice(stockIndex + 1, 0, cardA.toString);
stockIndex++;
@ -114,16 +136,14 @@ function solve(pyramidArray, stockArray, stockIndex = 0, moveArray = []) {
newPyramidArray[freeCardsIndices[i]] = 0;
let result = solve(newPyramidArray, newStock, stockIndex, newMoveArray);
if (result[0] === GameStates.won)
return result;
if (result[0] === GameStates.won) return result;
}
// Flip over a new card
newMoveArray = JSON.parse(JSON.stringify(moveArray));
newMoveArray.push(MoveString.flipStock());
let result = solve(pyramidArray, stockArray, stockIndex + 1, newMoveArray);
if (result[0] === GameStates.won)
return result;
if (result[0] === GameStates.won) return result;
// This node was useless
return [GameStates.lost, moveArray];

10
test.js
View file

@ -1,15 +1,15 @@
const assert = require('assert');
const solver = require('./solver');
const assert = require("assert");
const solver = require("./solver");
const solvable_games = [
"8S TS 4D 7S 5D 7C 2D JH AC 3S 2H 3H 9H KC QC TD 8D 9C 7H 9D JS QS 4H 5C 5S 4C 2C QD 8C KD 3D KS JD 2S 7D KH AH 5H 9S 4S QH 6S 6D 3C JC TC 8H 6C TH AS AD 6H",
"5D 9C 5S QS 8S 9D AS 5C 2S QD KC 9H 4H QC 2H 8D 4C 4D JC TS 6D 7H QH 3S 5H JH 6H 2D AC 7S 7C 3D KD 9S 3C TH 6C AH 8H TC 4S 8C AD 3H KS 6S JS 7D JD TD 2C KH"
"5D 9C 5S QS 8S 9D AS 5C 2S QD KC 9H 4H QC 2H 8D 4C 4D JC TS 6D 7H QH 3S 5H JH 6H 2D AC 7S 7C 3D KD 9S 3C TH 6C AH 8H TC 4S 8C AD 3H KS 6S JS 7D JD TD 2C KH",
];
it('should solve known games', () => {
it("should solve known games", () => {
assert.equal(true, true);
solvable_games.forEach(function (i) {
const array = i.split(' ');
const array = i.split(" ");
const result = solver.solve(array.slice(0, 28), array.slice(28, 52), 0, []);
assert.equal(result[0], true);
});