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:
@@ -423,6 +423,52 @@ func TestAutoSendsEverythingItCanHome(t *testing.T) {
|
||||
refuses(t, next, Move{Kind: "auto"}, ErrNothingHome)
|
||||
}
|
||||
|
||||
// Won is the state the finish button finishes: every card face up, the stock and
|
||||
// waste drained, so a single auto sweeps the lot home. The button is only honest
|
||||
// if these two agree — Won lighting up on a board auto can't clear would stall.
|
||||
func TestWonIsExactlyWhatAutoCanFinish(t *testing.T) {
|
||||
s := board(patient(), 5200)
|
||||
// A won board: three short face-up runs across the columns, nothing face down,
|
||||
// nothing in the stock or waste. Every card is reachable.
|
||||
s.Table[0].Up = []cards.Card{card(2, cards.Spades), card(cards.Ace, cards.Hearts)}
|
||||
s.Table[1].Up = []cards.Card{card(2, cards.Hearts), card(cards.Ace, cards.Spades)}
|
||||
s.Table[2].Up = []cards.Card{card(2, cards.Diamonds), card(cards.Ace, cards.Clubs)}
|
||||
s.Table[3].Up = []cards.Card{card(2, cards.Clubs), card(cards.Ace, cards.Diamonds)}
|
||||
|
||||
if !s.Won() {
|
||||
t.Fatalf("a board with everything face up and the piles empty is won")
|
||||
}
|
||||
|
||||
next, _ := apply(t, s, Move{Kind: "auto"})
|
||||
if next.Home() != 8 { // the eight cards laid out above
|
||||
t.Fatalf("auto homed %d cards, want 8 — the whole won board", next.Home())
|
||||
}
|
||||
|
||||
// Anything still hidden or still in a pile is not won: auto would stall on it.
|
||||
withStock := s.clone()
|
||||
withStock.Stock = cards.Deck{card(5, cards.Spades)}
|
||||
if withStock.Won() {
|
||||
t.Errorf("a board with a card still in the stock is not won — auto won't turn it over")
|
||||
}
|
||||
withWaste := s.clone()
|
||||
withWaste.Waste = []cards.Card{card(5, cards.Spades)}
|
||||
if withWaste.Won() {
|
||||
t.Errorf("a board with a card still in the waste is not won")
|
||||
}
|
||||
withDown := s.clone()
|
||||
withDown.Table[5].Down = []cards.Card{card(5, cards.Spades)}
|
||||
if withDown.Won() {
|
||||
t.Errorf("a board with a face-down card is not won")
|
||||
}
|
||||
|
||||
// A finished board is never won: the button belongs to a game still in play.
|
||||
cleared := s.clone()
|
||||
cleared.Phase = PhaseDone
|
||||
if cleared.Won() {
|
||||
t.Errorf("a settled board reports won")
|
||||
}
|
||||
}
|
||||
|
||||
// ---- the money -------------------------------------------------------------
|
||||
|
||||
// The number the felt quotes while you play and the number settle() lands on are
|
||||
|
||||
Reference in New Issue
Block a user