feat(farkel): add set-aside dice support and improve score-all
- Extend selection scoring to include set-aside dice combined with currently selected dice - Replace greedy score-all with exhaustive search over all subsets of rolled dice, finding the optimal combination with set-aside dice - Update turn score display to correctly show combined points during pick phase
This commit is contained in:
parent
0849ea0446
commit
23c0804a54
|
|
@ -425,8 +425,8 @@ export default class FarkelGame extends Phaser.Scene {
|
||||||
const hasPending = this.gs.turn.kept > 0 || (this.gs.phase === 'awaitPick' && this.selectionScore() > 0);
|
const hasPending = this.gs.turn.kept > 0 || (this.gs.phase === 'awaitPick' && this.selectionScore() > 0);
|
||||||
const showTurn = (seat === cur && !isGameOver(this.gs) && hasPending);
|
const showTurn = (seat === cur && !isGameOver(this.gs) && hasPending);
|
||||||
if (showTurn) {
|
if (showTurn) {
|
||||||
const sel = (this.gs.phase === 'awaitPick') ? this.selectionScore() : 0;
|
const total = (this.gs.phase === 'awaitPick') ? this.selectionScore() : this.gs.turn.kept;
|
||||||
row.score.setText(`${p.score} +${this.gs.turn.kept + sel}`);
|
row.score.setText(`${p.score} +${total}`);
|
||||||
} else {
|
} else {
|
||||||
row.score.setText(String(p.score));
|
row.score.setText(String(p.score));
|
||||||
}
|
}
|
||||||
|
|
@ -498,8 +498,16 @@ export default class FarkelGame extends Phaser.Scene {
|
||||||
|
|
||||||
// ── selection helpers ─────────────────────────────────────────────────────────
|
// ── selection helpers ─────────────────────────────────────────────────────────
|
||||||
selectionValues() { return [...this.selected].map((i) => this.gs.turn.rolled[i]); }
|
selectionValues() { return [...this.selected].map((i) => this.gs.turn.rolled[i]); }
|
||||||
selectionValid() { return scoreSelection(this.selectionValues()).valid; }
|
selectionValid() {
|
||||||
selectionScore() { const r = scoreSelection(this.selectionValues()); return r.valid ? r.points : 0; }
|
const combined = [...this.gs.turn.setAsideDice, ...this.selectionValues()];
|
||||||
|
return scoreSelection(combined).valid;
|
||||||
|
}
|
||||||
|
selectionScore() {
|
||||||
|
const combined = [...this.gs.turn.setAsideDice, ...this.selectionValues()];
|
||||||
|
if (combined.length === 0) return 0;
|
||||||
|
const r = scoreSelection(combined);
|
||||||
|
return r.valid ? r.points : 0;
|
||||||
|
}
|
||||||
|
|
||||||
// ── input ──────────────────────────────────────────────────────────────────────
|
// ── input ──────────────────────────────────────────────────────────────────────
|
||||||
onDieClick(i) {
|
onDieClick(i) {
|
||||||
|
|
@ -512,8 +520,29 @@ export default class FarkelGame extends Phaser.Scene {
|
||||||
|
|
||||||
onScoreAll() {
|
onScoreAll() {
|
||||||
if (this.busy || !this.isHumanTurn() || this.gs.phase !== 'awaitPick') return;
|
if (this.busy || !this.isHumanTurn() || this.gs.phase !== 'awaitPick') return;
|
||||||
const best = bestScoring(this.gs.turn.rolled);
|
const rolled = this.gs.turn.rolled;
|
||||||
this.selected = new Set(best.indices);
|
const kept = this.gs.turn.setAsideDice;
|
||||||
|
|
||||||
|
// Try all subsets of rolled dice, combine with kept, find best total score
|
||||||
|
let bestScore = 0;
|
||||||
|
let bestIndices = new Set();
|
||||||
|
for (let mask = 0; mask < (1 << rolled.length); mask++) {
|
||||||
|
const subset = [];
|
||||||
|
for (let i = 0; i < rolled.length; i++) {
|
||||||
|
if (mask & (1 << i)) subset.push(rolled[i]);
|
||||||
|
}
|
||||||
|
const combined = [...kept, ...subset];
|
||||||
|
const result = scoreSelection(combined);
|
||||||
|
if (result.valid && result.points > bestScore) {
|
||||||
|
bestScore = result.points;
|
||||||
|
bestIndices = new Set();
|
||||||
|
for (let i = 0; i < rolled.length; i++) {
|
||||||
|
if (mask & (1 << i)) bestIndices.add(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.selected = bestIndices;
|
||||||
playSound(this, SFX.PIECE_CLICK);
|
playSound(this, SFX.PIECE_CLICK);
|
||||||
this.render();
|
this.render();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue