Skip to content

Commit

Permalink
Added Relaxed Clock game.
Browse files Browse the repository at this point in the history
  • Loading branch information
joeraz committed Sep 3, 2023
1 parent 8c6310c commit f10379a
Show file tree
Hide file tree
Showing 3 changed files with 87 additions and 9 deletions.
14 changes: 14 additions & 0 deletions html-src/rules/relaxedclock.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<h1>Relaxed Clock</h1>
<p>
One-Deck game type. 1 deck. No redeals.

<h3>Object</h3>
<p>
Move all cards to the correct pile in the tableau, before the fourth
king is revealed, and the extra pile you drew a card from is filled.

<h3>Quick Description</h3>
<p>
Just like <a href="clock.html">Clock</a>,
but once per game, after all four kings have been revealed, you are
allowed to take a face-down card from another pile and continue playing.
2 changes: 1 addition & 1 deletion pysollib/gamedb.py
Original file line number Diff line number Diff line change
Expand Up @@ -575,7 +575,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, 915)) + tuple(range(11017, 11020)) +
('dev', tuple(range(906, 916)) + tuple(range(11017, 11020)) +
tuple(range(22303, 22311)) + tuple(range(22353, 22361))),
)

Expand Down
80 changes: 72 additions & 8 deletions pysollib/games/grandfathersclock.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
from pysollib.gamedb import GI, GameInfo, registerGame
from pysollib.hint import CautiousDefaultHint, DefaultHint
from pysollib.layout import Layout
from pysollib.mygettext import _
from pysollib.pysoltk import MfxCanvasText
from pysollib.stack import \
AC_FoundationStack, \
Expand Down Expand Up @@ -488,6 +489,7 @@ def _autoDeal(self, sound=True):

# ************************************************************************
# * Clock
# * Relaxed Clock
# ************************************************************************

class Clock_RowStack(RK_RowStack):
Expand All @@ -500,8 +502,25 @@ def _numFaceDown(self):
ncards += 1
return ncards

def clickHandler(self, event):
game = self.game
if game.s.rows[12].cards[-1].rank == KING \
and game.DrawsLeft > 0 and not self.cards[-1].face_up:
old_state = game.enterState(game.S_FILL)
game.flipMove(self)
game.saveStateMove(2 | 16)
game.playSample("move", priority=10)
game.moveMove(1, self, game.s.rows[12])
game.DrawsLeft -= 1
game.saveStateMove(1 | 16)
game.leaveState(old_state)
game.finishMove()
else:
return RK_RowStack.clickHandler(self, event)

def acceptsCards(self, from_stack, cards):
return cards[0].rank == self.id
return cards[0].rank == self.id or \
(self.cards[-1].face_up and self.cards[-1].rank == KING)

def moveMove(self, ncards, to_stack, frames=-1, shadow=-1):
self._swapPairMove(ncards, to_stack, frames=-1, shadow=0)
Expand All @@ -512,15 +531,17 @@ def _swapPairMove(self, n, other_stack, frames=-1, shadow=-1):
old_state = game.enterState(game.S_FILL)
swap = game.s.internals[0]
ncards = other_stack._numFaceDown()

for i in range(ncards):
game.moveMove(n, other_stack, swap, frames=0)
game.moveMove(n, self, other_stack, frames=0)
for i in range(ncards):
game.moveMove(n, swap, other_stack, frames=0)
game.flipMove(other_stack)
game.moveMove(n, other_stack, self)
if is_king:
self._moveKingToBottom()
if ncards > 0:
for i in range(ncards):
game.moveMove(n, swap, other_stack, frames=0)
game.flipMove(other_stack)
game.moveMove(n, other_stack, self)
if is_king:
self._moveKingToBottom()
game.leaveState(old_state)

def _moveKingToBottom(self):
Expand Down Expand Up @@ -549,13 +570,19 @@ def _fillStack(self):
def canFlipCard(self):
return False

def getHelp(self):
return _('Tableau. Build by same rank.')


class Clock(Game):
RowStack_Class = Clock_RowStack
Talon_Class = InitialDealTalonStack

HAS_WASTE = False

Draws = 0
DrawsLeft = 0

def createGame(self):
# create layout
l, s = Layout(self), self.s
Expand Down Expand Up @@ -641,6 +668,7 @@ def createGame(self):
l.defaultStackGroups()

def startGame(self):
self.DrawsLeft = self.Draws
for i in range(3):
self.s.talon.dealRow(frames=0, flip=False)
self.startDealSample()
Expand All @@ -650,16 +678,49 @@ def startGame(self):

def isGameWon(self):
for r in self.s.rows:
if not r.cards[-1].face_up:
if len(r.cards) != 4 or not r.cards[-1].face_up:
return False
return True

def _restoreGameHook(self, game):
if self.Draws > 0:
self.DrawsLeft = game.loadinfo.DrawsLeft

def _loadGameHook(self, p):
if self.Draws > 0:
self.loadinfo.addattr(DrawsLeft=p.load())

def _saveGameHook(self, p):
if self.Draws > 0:
DrawsLeft = self.DrawsLeft
p.dump(DrawsLeft)

def setState(self, state):
# restore saved vars (from undo/redo)
self.DrawsLeft = state[0]
for s in self.s.foundations:
s.cap.DrawsLeft = state[0]
break

def getState(self):
# save vars (for undo/redo)
return [self.DrawsLeft]

def getHighlightPilesStacks(self):
return ()

def getAutoStacks(self, event=None):
return (), (), ()

def getStuck(self):
if self.DrawsLeft > 0:
return True
return Game.getStuck(self)


class RelaxedClock(Clock):
Draws = 1


# ************************************************************************
# * German Clock
Expand Down Expand Up @@ -715,3 +776,6 @@ def getAutoStacks(self, event=None):
registerGame(GameInfo(827, GermanClock, "German Clock",
GI.GT_1DECK_TYPE, 1, 1, GI.SL_MOSTLY_LUCK,
altnames=("Die Uhr",)))
registerGame(GameInfo(915, RelaxedClock, "Relaxed Clock",
GI.GT_1DECK_TYPE | GI.GT_RELAXED, 1, 0, GI.SL_LUCK,
altnames=("Watch")))

0 comments on commit f10379a

Please sign in to comment.