Skip to content

Commit

Permalink
Added Valentine game.
Browse files Browse the repository at this point in the history
  • Loading branch information
joeraz committed Nov 29, 2023
1 parent 288bd92 commit a99bacb
Show file tree
Hide file tree
Showing 3 changed files with 132 additions and 5 deletions.
28 changes: 28 additions & 0 deletions html-src/rules/valentine.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<h1>Valentine</h1>
<p>
One-Deck game type. 1 deck. Unlimited redeals.

<h3>Object</h3>
<p>
Organize all cards in four columns with complete same suit sequences
from king to ace.

<h3>Rules</h3>
<p>
A card is dealt to each of four piles. A single card is dealt to a
waste pile. Cards can be moved to the four piles, building down by
same suit. If a pile is empty, it is filled by the card on the waste.
<p>
Only a single card can be in the waste pile at a time. If there are
no more moves, you can place the four tableau piles at the bottom of
the deck, without shuffling them, then move the waste card to one of
the piles, and deal a single card from the stock to the other three.
<p>
As play continues, the cards will slowly move into sequence. The
game is won if all the cards can be organized into four same suit
columns.

<h3>Strategy</h3>
<p>
Valentine is a game of pure luck. It was mostly designed as a way to
kill time.
6 changes: 3 additions & 3 deletions pysollib/gamedb.py
Original file line number Diff line number Diff line change
Expand Up @@ -370,15 +370,15 @@ def _callback(gi, gt=game_type):
# Gnome AisleRiot 2.2.0 (we have 65 out of 70 games)
# Gnome AisleRiot 3.22.7
# still missing:
# Hamilton, Labyrinth, Treize, Valentine, Wall
# Hamilton, Labyrinth, Treize, Wall
("Gnome AisleRiot", (
1, 2, 8, 9, 11, 12, 13, 19, 24, 27, 29, 31, 33, 34, 35, 36,
38, 40, 41, 42, 43, 45, 48, 58, 65, 67, 89, 91, 92, 93, 94,
95, 96, 97, 100, 104, 105, 111, 112, 113, 130, 135, 139, 144,
146, 147, 148, 200, 201, 206, 224, 225, 229, 230, 233, 257,
258, 277, 280, 281, 282, 283, 284, 334, 384, 479, 495, 551,
552, 553, 572, 593, 674, 700, 715, 716, 737, 772, 810, 819,
824, 829, 859, 874, 906, 22231,
824, 829, 859, 874, 906, 934, 22231,
)),

# Hoyle Card Games
Expand Down Expand Up @@ -592,7 +592,7 @@ def _callback(gi, gt=game_type):
('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, 934)) + tuple(range(11017, 11020)) +
('dev', tuple(range(906, 935)) + tuple(range(11017, 11020)) +
tuple(range(5600, 5624)) + tuple(range(18000, 18004)) +
tuple(range(22303, 22311)) + tuple(range(22353, 22361))),
)
Expand Down
103 changes: 101 additions & 2 deletions pysollib/games/acesup.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,18 @@
AutoDealTalonStack, \
BasicRowStack, \
DealRowTalonStack, \
InvisibleStack, \
OpenStack, \
RK_RowStack, \
ReserveStack, \
SS_RowStack, \
Spider_RK_Foundation, \
Stack, \
StackWrapper, \
isRankSequence
WasteStack, \
WasteTalonStack, \
isRankSequence, \
isSameSuitSequence
from pysollib.util import ACE, ANY_RANK, ANY_SUIT, NO_RANK, \
UNLIMITED_ACCEPTS, \
UNLIMITED_MOVES
Expand Down Expand Up @@ -252,7 +257,99 @@ def shallHighlightMatch(self, stack1, card1, stack2, card2):


# ************************************************************************
# *
# * Valentine
# ************************************************************************

class Valentine_Talon(WasteTalonStack):
def canDealCards(self):
# FIXME: this is to avoid loops in the demo
if self.game.demo and self.game.moves.index >= 500:
return False
return not self.game.isGameWon()

def dealCards(self, sound=False):
if not self.game.s.waste.cards and self.cards:
return WasteTalonStack.dealCards(self, sound=sound)
game, num_cards = self.game, len(self.cards)
rows = list(game.s.rows)[:]
rows.reverse()
for r in rows:
while r.cards:
num_cards = num_cards + 1
game.moveMove(1, r, game.s.internals[0], frames=0)
if game.s.internals[0].cards[-1].face_up:
game.flipMove(game.s.internals[0])
if len(self.cards) > 0:
game.moveMove(len(self.cards), self, game.s.internals[0], frames=0)
game.moveMove(len(game.s.internals[0].cards), game.s.internals[0],
self, frames=0)
rows.reverse()
game.startDealSample()
for r in rows:
game.fillStack(r)
WasteTalonStack.dealCards(self, sound=sound)
game.stopSamples()


class Valentine(Game):

#
# game layout
#

def createGame(self, **layout):
# create layout
l, s = Layout(self), self.s

# set window
self.setSize(l.XM + 6.5 * l.XS, l.YM + l.YS + (13 * l.YOFFSET))

self.s.internals.append(InvisibleStack(self))

# create stacks
x, y, = l.XM, l.YM
s.talon = Valentine_Talon(x, y, self, max_rounds=-1)
l.createText(s.talon, "s")
x += l.XS
s.waste = WasteStack(x, y, self, max_cards=1)
x += 1.5 * l.XS
for i in range(4):
s.rows.append(SS_RowStack(x, y, self, base_rank=NO_RANK))
x = x + l.XS

# define stack-groups
l.defaultStackGroups()

#
# game overrides
#

def startGame(self):
self._startAndDealRow()
self.s.talon.dealCards()

def fillStack(self, stack):
if not stack.cards:
if stack in self.s.rows:
if self.s.waste.cards:
old_state = self.enterState(self.S_FILL)
self.s.waste.moveMove(1, stack)
self.leaveState(old_state)
elif self.s.talon.cards:
old_state = self.enterState(self.S_FILL)
self.s.talon.flipMove()
self.s.talon.moveMove(1, stack)
self.leaveState(old_state)

def isGameWon(self):
for s in self.s.rows:
if len(s.cards) != 13 or not isSameSuitSequence(s.cards):
return False
return True


# ************************************************************************
# * Aces Up 5
# ************************************************************************

class AcesUp5(AcesUp):
Expand Down Expand Up @@ -431,3 +528,5 @@ def createGame(self):
GI.GT_1DECK_TYPE, 1, 0, GI.SL_MOSTLY_SKILL))
registerGame(GameInfo(758, MaineCoon, "Maine Coon",
GI.GT_2DECK_TYPE, 2, 0, GI.SL_MOSTLY_SKILL))
registerGame(GameInfo(934, Valentine, "Valentine",
GI.GT_1DECK_TYPE, 1, -1, GI.SL_LUCK))

0 comments on commit a99bacb

Please sign in to comment.