mirror of
https://github.com/shlomif/PySolFC.git
synced 2025-04-05 00:02:29 -04:00
Added Ricochet game.
This commit is contained in:
parent
7dd94e551c
commit
55d5111fb4
3 changed files with 223 additions and 1 deletions
29
html-src/rules/ricochet.html
Normal file
29
html-src/rules/ricochet.html
Normal file
|
@ -0,0 +1,29 @@
|
|||
<h1>Ricochet</h1>
|
||||
<p>
|
||||
Golf type. 1 deck. No redeal.
|
||||
|
||||
<h3>Object</h3>
|
||||
Remove all cards from the tableau.
|
||||
|
||||
<h3>Rules</h3>
|
||||
<p>
|
||||
The tableau piles are built in four pyramid-esque "walls", with each
|
||||
wall having four cards in the top layer, three in the middle, and two
|
||||
in the bottom. One wall is facing in each direction, and the cards
|
||||
on the edge of the top layer are shared between the adjoining walls.
|
||||
The tableau and foundation are placed in the center of the four
|
||||
walls.
|
||||
<p>
|
||||
Cards can be dealt from the tableau one at a time. Exposed cards from
|
||||
the walls can be moved from the tableau if they are one rank higher or
|
||||
lower than the card currently on the foundation. Turning the corner is
|
||||
allowed, so kings can be played on aces, and vice versa. After a card
|
||||
is played, the next card cannot be played from the same wall. The cards
|
||||
in the corners are treated as part of both walls they overlap.
|
||||
<p>
|
||||
The game is won if all cards are removed from the tableau.
|
||||
|
||||
<h3>Notes</h3>
|
||||
<p>
|
||||
Ricochet was invented by Bram Tebbutt. More details can be found on
|
||||
<a href="https://www.riffleshuffleandroll.com/ricochet">his website</a>.
|
|
@ -487,6 +487,7 @@ class GI:
|
|||
("John Stoneham", (201,)),
|
||||
("Bryan Stout", (655,)),
|
||||
("Bill Taylor", (349,)),
|
||||
("Bram Tebbutt", (924,)),
|
||||
("Peter Voke", (876,)),
|
||||
("Thomas Warfield", (189, 264, 300, 320, 336, 337, 359,
|
||||
415, 427, 458, 495, 496, 497, 508,
|
||||
|
@ -575,7 +576,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, 924)) + tuple(range(11017, 11020)) +
|
||||
('dev', tuple(range(906, 925)) + tuple(range(11017, 11020)) +
|
||||
tuple(range(22303, 22311)) + tuple(range(22353, 22361))),
|
||||
)
|
||||
|
||||
|
|
|
@ -284,6 +284,196 @@ class ThreePeaksOpenScored(ThreePeaks):
|
|||
ThreePeaks.startGame(self, flip=1)
|
||||
|
||||
|
||||
# ************************************************************************
|
||||
# * Ricochet
|
||||
# ************************************************************************
|
||||
|
||||
class Ricochet_Talon(ThreePeaks_TalonStack):
|
||||
def dealCards(self, sound=False):
|
||||
old_state = self.game.enterState(self.game.S_FILL)
|
||||
self.game.saveStateMove(2 | 16) # for undo
|
||||
self.game.lastStack = -1
|
||||
self.game.saveStateMove(1 | 16) # for redo
|
||||
self.game.leaveState(old_state)
|
||||
ThreePeaks_TalonStack.dealCards(self, sound)
|
||||
|
||||
|
||||
class Ricochet_Waste(Golf_Waste):
|
||||
def acceptsCards(self, from_stack, cards):
|
||||
for wall in self.game.walls:
|
||||
if self.game.lastStack in wall and from_stack.id in wall:
|
||||
return False
|
||||
return Golf_Waste.acceptsCards(self, from_stack, cards)
|
||||
|
||||
|
||||
class Ricochet_RowStack(ThreePeaks_RowStack):
|
||||
|
||||
def basicIsBlocked(self):
|
||||
r = self.game.s.rows
|
||||
step = (8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 12, 12, 12, 12,
|
||||
12, 12, 12, 12, 12, 12)
|
||||
i = self.id
|
||||
while i < 20:
|
||||
i = i + step[i]
|
||||
for j in range(2):
|
||||
d = i + j
|
||||
if d > 31:
|
||||
d = 20
|
||||
if r[d].cards:
|
||||
return True
|
||||
return False
|
||||
|
||||
def clickHandler(self, event):
|
||||
result = OpenStack.doubleclickHandler(self, event)
|
||||
return result
|
||||
|
||||
def moveMove(self, ncards, to_stack, frames=-1, shadow=-1):
|
||||
x = OpenStack.moveMove(self, ncards, to_stack, frames, shadow)
|
||||
old_state = self.game.enterState(self.game.S_FILL)
|
||||
self.game.saveStateMove(2 | 16) # for undo
|
||||
self.game.lastStack = self.id
|
||||
self.game.saveStateMove(1 | 16) # for redo
|
||||
self.game.leaveState(old_state)
|
||||
return x
|
||||
|
||||
|
||||
class Ricochet(Game):
|
||||
|
||||
Waste_Class = StackWrapper(Ricochet_Waste, mod=13)
|
||||
Hint_Class = Golf_Hint
|
||||
|
||||
#
|
||||
# Game layout
|
||||
#
|
||||
|
||||
def createGame(self):
|
||||
# create layout
|
||||
l, s = Layout(self), self.s
|
||||
|
||||
# set window
|
||||
# compute best XOFFSET
|
||||
xoffset = int(l.XS * 8 / self.gameinfo.ncards)
|
||||
if xoffset < l.XOFFSET:
|
||||
l.XOFFSET = xoffset
|
||||
|
||||
# Set window size
|
||||
w, h = l.XM + l.XS * 6, l.YM + l.YS * 6
|
||||
self.setSize(w, h)
|
||||
self.lastStack = -1
|
||||
self.walls = ((0, 1, 8, 9, 10, 20, 21, 22, 23),
|
||||
(2, 3, 11, 12, 13, 23, 24, 25, 26),
|
||||
(4, 5, 14, 15, 16, 26, 27, 28, 29),
|
||||
(6, 7, 17, 18, 19, 29, 30, 31, 20))
|
||||
|
||||
# Create rows
|
||||
x, y = l.XM + l.XS * 2, l.YM
|
||||
|
||||
s.rows.append(Ricochet_RowStack(x, y, self))
|
||||
x += l.XS
|
||||
s.rows.append(Ricochet_RowStack(x, y, self))
|
||||
x += l.XS * 2
|
||||
y += l.YS * 2
|
||||
s.rows.append(Ricochet_RowStack(x, y, self))
|
||||
y += l.YS
|
||||
s.rows.append(Ricochet_RowStack(x, y, self))
|
||||
x -= l.XS * 2
|
||||
y += l.YS * 2
|
||||
s.rows.append(Ricochet_RowStack(x, y, self))
|
||||
x -= l.XS
|
||||
s.rows.append(Ricochet_RowStack(x, y, self))
|
||||
x -= l.XS * 2
|
||||
y -= l.YS * 2
|
||||
s.rows.append(Ricochet_RowStack(x, y, self))
|
||||
y -= l.YS
|
||||
s.rows.append(Ricochet_RowStack(x, y, self))
|
||||
|
||||
x, y = l.XM + l.XS * .5, l.YM + l.YS * .5
|
||||
for i in range(3):
|
||||
x += l.XS
|
||||
s.rows.append(Ricochet_RowStack(x, y, self))
|
||||
x += l.XS
|
||||
for i in range(3):
|
||||
y += l.YS
|
||||
s.rows.append(Ricochet_RowStack(x, y, self))
|
||||
y += l.YS
|
||||
for i in range(3):
|
||||
x -= l.XS
|
||||
s.rows.append(Ricochet_RowStack(x, y, self))
|
||||
x -= l.XS
|
||||
for i in range(3):
|
||||
y -= l.YS
|
||||
s.rows.append(Ricochet_RowStack(x, y, self))
|
||||
|
||||
x, y = l.XM, l.YM + l.YS
|
||||
for i in range(4):
|
||||
x += l.XS
|
||||
s.rows.append(Ricochet_RowStack(x, y, self))
|
||||
for i in range(3):
|
||||
y += l.YS
|
||||
s.rows.append(Ricochet_RowStack(x, y, self))
|
||||
for i in range(3):
|
||||
x -= l.XS
|
||||
s.rows.append(Ricochet_RowStack(x, y, self))
|
||||
for i in range(2):
|
||||
y -= l.YS
|
||||
s.rows.append(Ricochet_RowStack(x, y, self))
|
||||
|
||||
# Create talon
|
||||
x, y = l.XM + l.XS * 2, l.YM + l.YS * 2.5
|
||||
s.talon = Ricochet_Talon(x, y, self, num_deal=1, max_rounds=1)
|
||||
l.createText(s.talon, "s")
|
||||
x += l.XS
|
||||
s.waste = self.Waste_Class(x, y, self)
|
||||
s.foundations.append(s.waste)
|
||||
l.createText(s.waste, "s")
|
||||
|
||||
# Create text for scores
|
||||
if self.preview <= 1:
|
||||
self.texts.info = MfxCanvasText(
|
||||
self.canvas,
|
||||
l.XM + l.XS * 3, h - l.YM,
|
||||
anchor="sw",
|
||||
font=self.app.getFont("canvas_default"))
|
||||
|
||||
# Define stack groups
|
||||
l.defaultStackGroups()
|
||||
|
||||
#
|
||||
# Game over rides
|
||||
#
|
||||
|
||||
def startGame(self, flip=0):
|
||||
self.lastStack = -1
|
||||
self.startDealSample()
|
||||
self.s.talon.dealRow(rows=self.s.rows[:20], flip=flip, frames=4)
|
||||
self.s.talon.dealRow(rows=self.s.rows[20:], flip=1, frames=4)
|
||||
self.s.talon.dealCards()
|
||||
|
||||
def isGameWon(self):
|
||||
for r in self.s.rows:
|
||||
if r.cards:
|
||||
return False
|
||||
return True
|
||||
|
||||
def _restoreGameHook(self, game):
|
||||
self.lastStack = game.loadinfo.dval.get('lastStack')
|
||||
|
||||
def _loadGameHook(self, p):
|
||||
self.loadinfo.addattr(dval=p.load())
|
||||
|
||||
def _saveGameHook(self, p):
|
||||
dval = {'lastStack': self.lastStack}
|
||||
p.dump(dval)
|
||||
|
||||
def setState(self, state):
|
||||
# restore saved vars (from undo/redo)
|
||||
self.lastStack = state[0]
|
||||
|
||||
def getState(self):
|
||||
# save vars (for undo/redo)
|
||||
return [self.lastStack]
|
||||
|
||||
|
||||
registerGame(GameInfo(22216, ThreePeaks, "Three Peaks (Scored)",
|
||||
GI.GT_GOLF | GI.GT_SCORE, 1, 0, GI.SL_BALANCED,
|
||||
rules_filename="threepeaks.html"))
|
||||
|
@ -296,3 +486,5 @@ registerGame(GameInfo(22218, ThreePeaksOpenScored, "Three Peaks (Scored/Open)",
|
|||
registerGame(GameInfo(22231, ThreePeaksNoScore, "Three Peaks",
|
||||
GI.GT_GOLF, 1, 0, GI.SL_BALANCED,
|
||||
altnames=("Tri Peaks",)))
|
||||
registerGame(GameInfo(924, Ricochet, "Ricochet",
|
||||
GI.GT_GOLF, 1, 0, GI.SL_BALANCED))
|
||||
|
|
Loading…
Add table
Reference in a new issue