solitaire: detect a won board and finish it in one press
A drained, all-face-up board is a guaranteed clear that auto() sweeps home in a single cascade, but the only way to trigger it was double-clicking thirty cards home by hand. Add State.Won(), surface it in the view, and swap the ordinary controls for one pulsing finish button when it's true.
This commit is contained in:
@@ -620,6 +620,31 @@ func (s State) Net() int64 {
|
||||
// cleared reports whether every card is home.
|
||||
func (s State) cleared() bool { return s.Home() == FullDeck }
|
||||
|
||||
// Won reports that the board is a guaranteed clear: nothing left in the stock or
|
||||
// waste, and not a single face-down card under any column. From here every card
|
||||
// is a face-up run and a single auto() drains the whole board to the foundations
|
||||
// without a choice left to make — which is exactly the tedious tail the felt
|
||||
// should offer to finish in one gesture instead of thirty double-clicks.
|
||||
//
|
||||
// It's deliberately narrower than "solvable": a draw-one board with cards still
|
||||
// in the stock is winnable too, but auto() won't turn the stock over, so calling
|
||||
// that won would light a finish button that then stalls. This is the state the
|
||||
// finish button actually finishes.
|
||||
func (s State) Won() bool {
|
||||
if s.Phase == PhaseDone || s.cleared() {
|
||||
return false
|
||||
}
|
||||
if len(s.Stock) > 0 || len(s.Waste) > 0 {
|
||||
return false
|
||||
}
|
||||
for _, p := range s.Table {
|
||||
if len(p.Down) > 0 {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// CanAuto reports whether anything can go home at all — which is what greys the
|
||||
// finish button out rather than letting it be pressed at a board that has nothing
|
||||
// for it.
|
||||
|
||||
Reference in New Issue
Block a user