diff --git a/Games/KlondikeEx/Model/Game.ts b/Games/KlondikeEx/Model/Game.ts index 19e9826..d29ead7 100644 --- a/Games/KlondikeEx/Model/Game.ts +++ b/Games/KlondikeEx/Model/Game.ts @@ -193,7 +193,7 @@ export class Game extends GameBase implements IGame { ); } - protected *dropCard_(card: Card, pile: Pile) { + protected *dropCard_(card: Card, pile: Pile): Generator { if (this.isTableauxDrop_(card, pile)) { yield* this.doTableauxDrop_(card, pile); yield* this.doAutoMoves_(); @@ -385,8 +385,8 @@ export class Game extends GameBase implements IGame { const card = pile.peek(); if (card && this.getCardValue_(card) <= foundationMin + this.options.autoMoveToFoundation) { for (const foundation of this.foundations) { - if (this.isFoundationDrop_(card, foundation)) { - yield* this.doFoundationDrop_(card, foundation); + if (this.previewDrop_(card, foundation)) { + yield* this.dropCard_(card, foundation); continue mainLoop; } } @@ -398,8 +398,8 @@ export class Game extends GameBase implements IGame { const card = pile.at(i); if (this.getCardValue_(card) <= foundationMin + this.options.autoMoveToFoundation) { for (const foundation of this.foundations) { - if (this.isFoundationDrop_(card, foundation)) { - yield* this.doFoundationDrop_(card, foundation); + if (this.previewDrop_(card, foundation)) { + yield* this.dropCard_(card, foundation); continue mainLoop; } } @@ -408,6 +408,60 @@ export class Game extends GameBase implements IGame { } } + if (this.options.autoCollateKings) { + const openTableaux = []; + let nextAutoMoveValue = 0; + + for (const tableau of this.tableaux) { + if (tableau.length > 0) { + const bottomCard = tableau.at(0); + if (bottomCard && bottomCard.rank === Rank.King && bottomCard.faceUp) { + openTableaux.push(tableau); + nextAutoMoveValue = Math.max(nextAutoMoveValue, 13 - tableau.length); + } + } + } + + for (const tableau of this.tableaux) { + if (openTableaux.length < 4 && tableau.length === 0) { + openTableaux.push(tableau); + nextAutoMoveValue = Math.max(nextAutoMoveValue, 13 - tableau.length); + } + } + + if (openTableaux.length === 4 && nextAutoMoveValue >= 3) { + for (const pile of this.autoMoveSources_) { + if (openTableaux.indexOf(pile) >= 0) continue; + + for (const card of pile) { + if (card.faceUp && this.getCardValue_(card) === nextAutoMoveValue) { + for (const openTableau of openTableaux) { + if (this.previewDrop_(card, openTableau)) { + yield* this.dropCard_(card, openTableau); + continue mainLoop; + } + } + } + } + } + + for (const pile of this.autoMoveAnySources_) { + for (let i = pile.length; i-- > 0; ) { + const card = pile.at(i); + + if (this.getCardValue_(card) === nextAutoMoveValue) { + for (const openTableau of openTableaux) { + if (this.previewDrop_(card, openTableau)) { + yield* this.dropCard_(card, openTableau); + continue mainLoop; + } + } + } + } + } + } + } + break; } } diff --git a/Games/KlondikeEx/Model/GameOptions.ts b/Games/KlondikeEx/Model/GameOptions.ts index 5ae3565..84f10e3 100644 --- a/Games/KlondikeEx/Model/GameOptions.ts +++ b/Games/KlondikeEx/Model/GameOptions.ts @@ -4,6 +4,7 @@ import * as URLSearchParamsEx from "~CardLib/URLSearchParamsEx"; export class GameOptions extends GameOptionsBase { public autoReveal = true; public autoMoveToFoundation = 2; + public autoCollateKings = true; public get saveKey() { return {}; @@ -13,12 +14,14 @@ export class GameOptions extends GameOptionsBase { super(); this.autoReveal = URLSearchParamsEx.getBool(params, "autoReveal", true); this.autoMoveToFoundation = Math.max(0, URLSearchParamsEx.getNumber(params, "autoMoveToFoundation", 2)); + this.autoCollateKings = URLSearchParamsEx.getBool(params, "autoCollateKings", true); } public toURLSearchParams(): URLSearchParams { const params = new URLSearchParams(); URLSearchParamsEx.setBool(params, "autoReveal", this.autoReveal, true); URLSearchParamsEx.setNumber(params, "autoMoveToFoundation", this.autoMoveToFoundation, 2); + URLSearchParamsEx.setBool(params, "autoCollateKings", this.autoCollateKings, true); return params; } }