diff --git a/html-src/rules/thebogey.html b/html-src/rules/thebogey.html new file mode 100644 index 00000000..5148f053 --- /dev/null +++ b/html-src/rules/thebogey.html @@ -0,0 +1,40 @@ +

The Bogey

+

+One-Deck game type. 1 deck. Unlimited redeals. + +

Object

+

+Move all cards to the columns. + +

Rules

+

+Deal five cards to your hand. Cards in your hand may be either moved +to one of twelve columns, discarded, or held. Any card can be played to +an empty column, but if a column is not empty, only a card of the same suit +but a lower rank can be played on the column. +

+When you are finished moving cards from your hand, draw one card from the +talon - this is the Bogey's card. You must immediately play this card to +one of the columns. If you cannot do so, the game is lost. Once the Bogey's +card has been played, draw cards from the talon until you have a new five +card hand, and then you can play these cards as before. +

+When the talon is empty, the discarded cards are shuffled to form a new talon, +and play continues until you get stuck by one of the Bogey's cards, or you +win by moving all cards to the columns. + +

Notes

+

+The goal of The Bogey is to get all the cards in as few columns as possible. +Though the maximum you are allowed to win the game is 12, you can get a better +score by using even fewer columns: +

+

History

+

+The Bogey was invented by Katharine Turner. diff --git a/pysollib/gamedb.py b/pysollib/gamedb.py index 6677596c..95e81445 100644 --- a/pysollib/gamedb.py +++ b/pysollib/gamedb.py @@ -499,6 +499,7 @@ class GI: ("Bryan Stout", (655,)), ("Bill Taylor", (349,)), ("Bram Tebbutt", (924,)), + ("Katharine Turner", (931,)), ("Peter Voke", (876,)), ("Thomas Warfield", (189, 264, 300, 320, 336, 337, 359, 415, 427, 458, 495, 496, 497, 508, @@ -587,7 +588,7 @@ class GI: ('fc-2.20', tuple(range(855, 897))), ('fc-2.21', tuple(range(897, 900)) + tuple(range(11014, 11017)) + tuple(range(13160, 13163)) + (16682,)), - ('dev', tuple(range(906, 931)) + tuple(range(11017, 11020)) + + ('dev', tuple(range(906, 932)) + tuple(range(11017, 11020)) + tuple(range(5600, 5624)) + tuple(range(18000, 18004)) + tuple(range(22303, 22311)) + tuple(range(22353, 22361))), ) diff --git a/pysollib/games/numerica.py b/pysollib/games/numerica.py index 72211faf..23a02946 100644 --- a/pysollib/games/numerica.py +++ b/pysollib/games/numerica.py @@ -1196,6 +1196,123 @@ class Ladybug(Game): return [self.used] +# ************************************************************************ +# * The Bogey +# ************************************************************************ + +class TheBogey_Foundation(SS_FoundationStack): + def acceptsCards(self, from_stack, cards): + if not self.cards: + return 1 + return (self.cards[-1].rank > cards[0].rank + and self.cards[-1].suit == cards[0].suit) + + def canMoveCards(self, cards): + return False + + +class TheBogey_BogeyDraw(OpenStack): + def moveMove(self, ncards, to_stack, frames=-1, shadow=-1): + OpenStack.moveMove(self, ncards, to_stack, frames=frames, + shadow=shadow) + rows = [r for r in self.game.s.rows if not len(r.cards) > 0] + self.game.startDealSample() + self.game.s.talon.dealRowAvail(rows=rows) + rows2 = [r for r in self.game.s.rows if not len(r.cards) > 0] + if len(rows2) > 0: + self.game.s.talon.redeal(sound=False) + self.game.s.talon.dealRowAvail(rows=rows2) + self.game.stopSamples() + + +class TheBogey_RowStack(OpenStack): + + def canMoveCards(self, cards): + if len(self.game.s.reserves[0].cards) > 0: + return False + return OpenStack.canMoveCards(self, cards) + + +class TheBogey_Talon(TalonStack): + def canDealCards(self): + return (len(self.game.s.reserves[0].cards) < 1 and + (len(self.cards) > 0 or + len(self.game.s.reserves[0].cards) > 0)) + + def dealCards(self, sound=False): + if len(self.cards) < 1: + self.redeal(sound=sound) + if sound: + self.game.playSample("dealwaste") + self.flipMove() + self.moveMove(1, self.game.s.reserves[0]) + + def redeal(self, sound=False): + if len(self.game.s.reserves[1].cards) > 0: + assert len(self.cards) == 0 + if sound: + self.game.playSample("turnwaste", priority=20) + self.game.turnStackMove(self.game.s.reserves[1], self) + self.game.shuffleStackMove(self) + self.game.nextRoundMove(self) + + +class TheBogey_Discard(OpenStack): + getBottomImage = Stack._getReserveBottomImage + + def acceptsCards(self, from_stack, cards): + return len(self.game.s.reserves[0].cards) < 1 + + def canMoveCards(self, cards): + return False + + +class TheBogey(Game): + + def createGame(self): + # create layout + l, s = Layout(self), self.s + + # set window + self.setSize(l.XM + 12 * l.XS, l.YM + 2 * l.YS + 13 * l.YOFFSET) + + # create stacks + x, y = l.XM, l.YM + for i in range(12): + s.foundations.append(TheBogey_Foundation(x, y, self, dir=-1, + suit=ANY_SUIT)) + s.foundations[i].CARD_YOFFSET = l.YOFFSET + x += l.XS + + x, y = l.XM, self.height - l.YS + + s.talon = TheBogey_Talon(x, y, self, max_rounds=-1) + l.createText(s.talon, 'n') + + x += l.XS + s.reserves.append(TheBogey_BogeyDraw(x, y, self)) + + x += 3 * l.XS + + for i in range(5): + s.rows.append(TheBogey_RowStack(x, y, self, max_cards=1, + max_accept=0)) + x += l.XS + + x += 2 * l.XS + s.reserves.append(TheBogey_Discard(x, y, self)) + l.createText(s.reserves[1], 'n') + + self.setRegion(s.reserves, (-999, y - l.CH // 2, 999999, 999999)) + + # define stack-groups + l.defaultStackGroups() + + def startGame(self): + self.startDealSample() + self.s.talon.dealRow(rows=self.s.rows) + + # register the game registerGame(GameInfo(257, Numerica, "Numerica", GI.GT_NUMERICA | GI.GT_CONTRIB, 1, 0, GI.SL_BALANCED, @@ -1250,3 +1367,5 @@ registerGame(GameInfo(836, Ladybug, "Ladybug", GI.GT_1DECK_TYPE, 1, -2, GI.SL_BALANCED)) registerGame(GameInfo(899, Housefly, "Housefly", GI.GT_NUMERICA, 1, 0, GI.SL_BALANCED)) +registerGame(GameInfo(931, TheBogey, "The Bogey", + GI.GT_1DECK_TYPE, 1, -1, GI.SL_BALANCED))