after running a lint + format
This commit is contained in:
parent
1a47184c29
commit
2b2e1ec0c9
4 changed files with 131 additions and 111 deletions
|
@ -8,5 +8,5 @@ module.exports = {
|
|||
node: true,
|
||||
mocha: true,
|
||||
},
|
||||
extends: ["eslint:recommended", "prettier"]
|
||||
extends: ["eslint:recommended", "prettier"],
|
||||
};
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
# 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/):
|
||||
|
@ -10,4 +11,3 @@ You can see it in action on my [website](https://igniparoustempest.github.io/tri
|
|||
## Notes
|
||||
|
||||
This is probably quite a poor implementation. Please don't fault me, I am teaching myself javascript.
|
||||
|
||||
|
|
62
solver.js
62
solver.js
|
@ -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
10
test.js
|
@ -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);
|
||||
});
|
||||
|
|
Loading…
Reference in a new issue