mirror of
https://github.com/shlomif/PySolFC.git
synced 2025-04-05 00:02:29 -04:00
Add Four Kingdoms game
This commit is contained in:
parent
792fbca78a
commit
bd2edf2f19
10 changed files with 314 additions and 13 deletions
51
html-src/rules/fourkingdoms.html
Normal file
51
html-src/rules/fourkingdoms.html
Normal file
|
@ -0,0 +1,51 @@
|
|||
<h1>Four Kingdoms</h1>
|
||||
<p>
|
||||
One-Deck game type. 1 deck. No redeal.
|
||||
|
||||
<h3>Object</h3>
|
||||
<p>
|
||||
Move all cards to the different foundations.
|
||||
|
||||
<h3>Rules</h3>
|
||||
<p>
|
||||
Cards are dealt to seven piles of four cards each, with only the top
|
||||
card of each pile face-up. These are the free lands, and may be built
|
||||
up by same suit. Any valid sequence can be moved, and any card or
|
||||
sequence can be played in an empty space.
|
||||
<p>
|
||||
Above the free lands are multiple columns of foundations/reserves,
|
||||
which accept different cards according depending on which other
|
||||
piles have been played to. There is one row of these piles for each
|
||||
suit. From left to right, these are:
|
||||
<ul>
|
||||
<li>Dungeon - Aces represent dragons - no card can be played on an ace,
|
||||
as such, an ace will essentially block its pile until it can be "banished"
|
||||
to a dungeon. The ace can only be moved to the dungeon if the king, queen,
|
||||
jack, and ten of the same suit are played in the tower/castle for that suit,
|
||||
appropriately.
|
||||
<li>Tower - Tens represent wizards - the ten of each suit can be played
|
||||
to the appropriate tower at any time.
|
||||
<li>Guest Chamber - The guest chamber acts as a free cell for each suit. Any
|
||||
single card other than the ace of that suit can be temporarily played to the
|
||||
guest chamber, until it can be moved to a space in the free lands or another
|
||||
foundation later. It can only be used if the king and queen of the same suit
|
||||
are played to the castle.
|
||||
<li>Castle - The castle is a series of three foundations for each suit,
|
||||
and the king, queen, and jack can be played to them, in that order.
|
||||
<li>Subjects - The remaining cards are played to the subjects foundation,
|
||||
built down by same suit from nine through two. Cards can only be moved to
|
||||
the subjects foundation once the king, queen, and jack of the same suit
|
||||
have all been played to the castle.
|
||||
</ul>
|
||||
<p>
|
||||
Cards can be dealt from the talon one at a time, and moved to an
|
||||
appropriate pile in the free lands, or any of the aforementioned
|
||||
foundation/reserve piles. No redeal is allowed.
|
||||
<p>
|
||||
The game is won if all cards can be moved to their appropriate foundations,
|
||||
thus uniting the four kingdoms.
|
||||
|
||||
<h3>Notes</h3>
|
||||
<p>
|
||||
Four Kingdoms was invented by David Bernazzani. It was designed to try and
|
||||
reclaim some of the original historical feel for the cards.
|
|
@ -3,7 +3,7 @@ msgstr ""
|
|||
"Project-Id-Version: PySol 0.0.1\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2021-12-10 10:19-0500\n"
|
||||
"PO-Revision-Date: 2024-08-04 20:21-0400\n"
|
||||
"PO-Revision-Date: 2024-09-08 09:52-0400\n"
|
||||
"Last-Translator: H. Schaekel <Holger.Schaekel@web.de>\n"
|
||||
"Language-Team: German\n"
|
||||
"Language: de\n"
|
||||
|
@ -2347,6 +2347,21 @@ msgstr ""
|
|||
"7: A 8 2 9 3 T 4 J 5 Q 6 K\n"
|
||||
"8: 3 J 6 A 9 4 Q 7 2 T 5 K"
|
||||
|
||||
msgid "Dungeon"
|
||||
msgstr ""
|
||||
|
||||
msgid "Tower"
|
||||
msgstr ""
|
||||
|
||||
msgid "Guest"
|
||||
msgstr ""
|
||||
|
||||
msgid "Castle"
|
||||
msgstr ""
|
||||
|
||||
msgid "Subjects"
|
||||
msgstr ""
|
||||
|
||||
#: pysollib/games/curdsandwhey.py:76
|
||||
msgid "Tableau. Build down by suit or of the same rank."
|
||||
msgstr "Tableau. Erstellt nach unten nach Farbe oder denselben Rang."
|
||||
|
|
|
@ -8,7 +8,7 @@ msgstr ""
|
|||
"Project-Id-Version: 1.02\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2021-12-10 10:19-0500\n"
|
||||
"PO-Revision-Date: 2024-08-04 20:20-0400\n"
|
||||
"PO-Revision-Date: 2024-09-08 09:52-0400\n"
|
||||
"Last-Translator: Eric Rausch <neelix570@gmail.com>\n"
|
||||
"Language-Team: French\n"
|
||||
"Language: fr\n"
|
||||
|
@ -2387,6 +2387,21 @@ msgstr ""
|
|||
"7: A 8 2 9 3 T 4 J 5 Q 6 K\n"
|
||||
"8: 3 J 6 A 9 4 Q 7 2 T 5 K"
|
||||
|
||||
msgid "Dungeon"
|
||||
msgstr ""
|
||||
|
||||
msgid "Tower"
|
||||
msgstr ""
|
||||
|
||||
msgid "Guest"
|
||||
msgstr ""
|
||||
|
||||
msgid "Castle"
|
||||
msgstr ""
|
||||
|
||||
msgid "Subjects"
|
||||
msgstr ""
|
||||
|
||||
#: pysollib/games/curdsandwhey.py:76
|
||||
msgid "Tableau. Build down by suit or of the same rank."
|
||||
msgstr "Tableau. Décroissant par enseigne ou de même valeur."
|
||||
|
|
|
@ -12,7 +12,7 @@ msgstr ""
|
|||
"Project-Id-Version: it_pysol\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2021-12-10 10:19-0500\n"
|
||||
"PO-Revision-Date: 2024-08-04 20:19-0400\n"
|
||||
"PO-Revision-Date: 2024-09-08 09:54-0400\n"
|
||||
"Last-Translator: Giuliano Colla <giuliano.colla@gmail.com>\n"
|
||||
"Language-Team: Italiano <it@li.org>\n"
|
||||
"Language: it\n"
|
||||
|
@ -2395,6 +2395,21 @@ msgstr ""
|
|||
"7: A 8 2 9 3 T 4 J 5 Q 6 K\n"
|
||||
"8: 3 J 6 A 9 4 Q 7 2 T 5 K"
|
||||
|
||||
msgid "Dungeon"
|
||||
msgstr ""
|
||||
|
||||
msgid "Tower"
|
||||
msgstr ""
|
||||
|
||||
msgid "Guest"
|
||||
msgstr ""
|
||||
|
||||
msgid "Castle"
|
||||
msgstr ""
|
||||
|
||||
msgid "Subjects"
|
||||
msgstr ""
|
||||
|
||||
#: pysollib/games/curdsandwhey.py:76
|
||||
msgid "Tableau. Build down by suit or of the same rank."
|
||||
msgstr "Tableau: Sequenza decrescente dello stesso seme"
|
||||
|
|
|
@ -8,7 +8,7 @@ msgstr ""
|
|||
"Project-Id-Version: PySolFC\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2021-12-10 10:19-0500\n"
|
||||
"PO-Revision-Date: 2024-08-04 20:19-0400\n"
|
||||
"PO-Revision-Date: 2024-09-08 09:53-0400\n"
|
||||
"Last-Translator: Jerzy Trzeciak <artusek@wp.pl>\n"
|
||||
"Language-Team: Polish <pl@li.org>\n"
|
||||
"Language: pl\n"
|
||||
|
@ -2401,6 +2401,21 @@ msgstr ""
|
|||
"7: A 8 2 9 3 T 4 J 5 Q 6 K\n"
|
||||
"8: 3 J 6 A 9 4 Q 7 2 T 5 K"
|
||||
|
||||
msgid "Dungeon"
|
||||
msgstr ""
|
||||
|
||||
msgid "Tower"
|
||||
msgstr ""
|
||||
|
||||
msgid "Guest"
|
||||
msgstr ""
|
||||
|
||||
msgid "Castle"
|
||||
msgstr ""
|
||||
|
||||
msgid "Subjects"
|
||||
msgstr ""
|
||||
|
||||
#: pysollib/games/curdsandwhey.py:76
|
||||
msgid "Tableau. Build down by suit or of the same rank."
|
||||
msgstr "Stół gry. Układaj w dół wg koloru lub wg tej samej wartości."
|
||||
|
|
|
@ -8,7 +8,7 @@ msgstr ""
|
|||
"Project-Id-Version: \n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2021-12-10 10:19-0500\n"
|
||||
"PO-Revision-Date: 2024-08-04 20:18-0400\n"
|
||||
"PO-Revision-Date: 2024-09-08 09:53-0400\n"
|
||||
"Last-Translator: Matheus Knack <mtknack555@gmail.com>\n"
|
||||
"Language-Team: \n"
|
||||
"Language: pt_BR\n"
|
||||
|
@ -2408,6 +2408,21 @@ msgstr ""
|
|||
"7: A 8 2 9 3 T 4 J 5 Q 6 K\n"
|
||||
"8: 3 J 6 A 9 4 Q 7 2 T 5 K"
|
||||
|
||||
msgid "Dungeon"
|
||||
msgstr ""
|
||||
|
||||
msgid "Tower"
|
||||
msgstr ""
|
||||
|
||||
msgid "Guest"
|
||||
msgstr ""
|
||||
|
||||
msgid "Castle"
|
||||
msgstr ""
|
||||
|
||||
msgid "Subjects"
|
||||
msgstr ""
|
||||
|
||||
#: pysollib/games/curdsandwhey.py:76
|
||||
msgid "Tableau. Build down by suit or of the same rank."
|
||||
msgstr "Tableau. Construa decrescente por naipe or por valor igual."
|
||||
|
|
15
po/pysol.pot
15
po/pysol.pot
|
@ -2234,6 +2234,21 @@ msgid "\n"
|
|||
"8: 3 J 6 A 9 4 Q 7 2 T 5 K"
|
||||
msgstr ""
|
||||
|
||||
msgid "Dungeon"
|
||||
msgstr ""
|
||||
|
||||
msgid "Tower"
|
||||
msgstr ""
|
||||
|
||||
msgid "Guest"
|
||||
msgstr ""
|
||||
|
||||
msgid "Castle"
|
||||
msgstr ""
|
||||
|
||||
msgid "Subjects"
|
||||
msgstr ""
|
||||
|
||||
#: pysollib/games/curdsandwhey.py:76
|
||||
msgid "Tableau. Build down by suit or of the same rank."
|
||||
msgstr ""
|
||||
|
|
|
@ -7,7 +7,7 @@ msgstr ""
|
|||
"Project-Id-Version: \n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2021-12-10 10:19-0500\n"
|
||||
"PO-Revision-Date: 2024-08-04 20:17-0400\n"
|
||||
"PO-Revision-Date: 2024-09-08 09:54-0400\n"
|
||||
"Last-Translator: Skomoroh <skomoroh@gmail.com>\n"
|
||||
"Language-Team: Russian <ru@li.org>\n"
|
||||
"Language: ru\n"
|
||||
|
@ -2393,6 +2393,21 @@ msgstr ""
|
|||
"7: A 8 2 9 3 10 4 В 5 Д 6 K\n"
|
||||
"8: 3 В 6 A 9 4 Д 7 2 10 5 K"
|
||||
|
||||
msgid "Dungeon"
|
||||
msgstr ""
|
||||
|
||||
msgid "Tower"
|
||||
msgstr ""
|
||||
|
||||
msgid "Guest"
|
||||
msgstr ""
|
||||
|
||||
msgid "Castle"
|
||||
msgstr ""
|
||||
|
||||
msgid "Subjects"
|
||||
msgstr ""
|
||||
|
||||
#: pysollib/games/curdsandwhey.py:76
|
||||
msgid "Tableau. Build down by suit or of the same rank."
|
||||
msgstr ""
|
||||
|
|
|
@ -418,7 +418,7 @@ class GI:
|
|||
|
||||
# Solitude for Windows
|
||||
# still missing:
|
||||
# Bowling (Sackson version), Four Kingdoms, Icicles
|
||||
# Bowling (Sackson version), Icicles
|
||||
("Solitude for Windows", (
|
||||
2, 8, 11, 13, 19, 24, 25, 29, 30, 31, 33, 34, 36, 38, 42,
|
||||
43, 45, 48, 50, 53, 56, 57, 58, 62, 64, 67, 69, 71, 86, 87,
|
||||
|
@ -426,7 +426,7 @@ class GI:
|
|||
128, 133, 134, 135, 139, 146, 147, 171, 172, 173, 221, 222,
|
||||
224, 228, 233, 234, 235, 256, 257, 258, 282, 314, 327, 330,
|
||||
355, 356, 398, 406, 414, 418, 434, 437, 484, 593, 715, 716,
|
||||
737, 751, 805, 830, 845, 847, 888, 901, 903
|
||||
737, 751, 805, 830, 845, 847, 888, 901, 903, 970
|
||||
)),
|
||||
|
||||
# XM Solitaire
|
||||
|
@ -479,7 +479,7 @@ class GI:
|
|||
("Paul Alfille", (8,)),
|
||||
("C.L. Baker", (45,)),
|
||||
("Mark S. Ball", (909,)),
|
||||
("David Bernazzani", (314, 830,)),
|
||||
("David Bernazzani", (314, 830, 970,)),
|
||||
("Gordon Bower", (763, 783, 852, 959,)),
|
||||
("Art Cabral", (9,)),
|
||||
("Richard A. Canfield", (105, 835,)),
|
||||
|
@ -603,7 +603,7 @@ class GI:
|
|||
tuple(range(13168, 13170)) + tuple(range(18000, 18005)) +
|
||||
tuple(range(19000, 19012)) + tuple(range(22303, 22311)) +
|
||||
tuple(range(22353, 22361))),
|
||||
('dev', tuple(range(961, 970))),
|
||||
('dev', tuple(range(961, 971))),
|
||||
)
|
||||
|
||||
# deprecated - the correct way is to or a GI.GT_XXX flag
|
||||
|
|
|
@ -24,17 +24,25 @@
|
|||
from pysollib.game import Game
|
||||
from pysollib.gamedb import GI, GameInfo, registerGame
|
||||
from pysollib.layout import Layout
|
||||
from pysollib.mygettext import _
|
||||
from pysollib.pysoltk import MfxCanvasText
|
||||
from pysollib.stack import \
|
||||
DealRowTalonStack, \
|
||||
OpenStack, \
|
||||
RK_FoundationStack
|
||||
from pysollib.util import ACE, ANY_SUIT, KING
|
||||
RK_FoundationStack, \
|
||||
ReserveStack, \
|
||||
SS_FoundationStack, \
|
||||
SS_RowStack, \
|
||||
Stack, \
|
||||
WasteStack, \
|
||||
WasteTalonStack
|
||||
from pysollib.util import ACE, ANY_SUIT, JACK, KING, QUEEN
|
||||
|
||||
|
||||
# ************************************************************************
|
||||
# * Moojub
|
||||
# ************************************************************************
|
||||
|
||||
|
||||
class Moojub_Foundation(RK_FoundationStack):
|
||||
def acceptsCards(self, from_stack, cards):
|
||||
if len(self.cards) > 0:
|
||||
|
@ -107,6 +115,143 @@ class Moojub(Game):
|
|||
self._startAndDealRow()
|
||||
|
||||
|
||||
# ************************************************************************
|
||||
# * Four Kingdoms
|
||||
# ************************************************************************
|
||||
|
||||
class FourKingdoms_Foundation(SS_FoundationStack):
|
||||
RequiredStacks = ()
|
||||
|
||||
def acceptsCards(self, from_stack, cards):
|
||||
for stackID in self.RequiredStacks:
|
||||
if len(self.game.s.foundations[self.id + stackID].cards) == 0:
|
||||
return False
|
||||
return SS_FoundationStack.acceptsCards(self, from_stack, cards)
|
||||
|
||||
def getHelp(self):
|
||||
return _('Foundation.')
|
||||
|
||||
|
||||
class FourKingdoms_DungeonFoundation(FourKingdoms_Foundation):
|
||||
RequiredStacks = (1, 2, 3, 4)
|
||||
|
||||
|
||||
class FourKingdoms_QueenFoundation(FourKingdoms_Foundation):
|
||||
RequiredStacks = (-1,)
|
||||
|
||||
|
||||
class FourKingdoms_JackFoundation(FourKingdoms_Foundation):
|
||||
RequiredStacks = (-1, -2)
|
||||
|
||||
|
||||
class FourKingdoms_SubjectsFoundation(FourKingdoms_Foundation):
|
||||
RequiredStacks = (-1, -2, -3)
|
||||
|
||||
|
||||
class FourKingdoms_Reserve(ReserveStack):
|
||||
getBottomImage = Stack._getSuitBottomImage
|
||||
|
||||
def acceptsCards(self, from_stack, cards):
|
||||
if cards[0].rank == ACE:
|
||||
return False
|
||||
checkStack = (6 * self.cap.base_suit) + 2
|
||||
for s in range(2):
|
||||
if len(self.game.s.foundations[checkStack + s].cards) == 0:
|
||||
return False
|
||||
return ReserveStack.acceptsCards(self, from_stack, cards)
|
||||
|
||||
|
||||
class FourKingdoms_RowStack(SS_RowStack):
|
||||
|
||||
def acceptsCards(self, from_stack, cards):
|
||||
if self.cards and self.cards[-1].rank == ACE:
|
||||
return False
|
||||
return SS_RowStack.acceptsCards(self, from_stack, cards)
|
||||
|
||||
|
||||
class FourKingdoms(Game):
|
||||
|
||||
def createGame(self):
|
||||
# create layout
|
||||
l, s = Layout(self), self.s
|
||||
|
||||
# set window
|
||||
self.setSize(l.XM + (l.XS * 9),
|
||||
l.YM + (6 * l.YS) + l.TEXT_HEIGHT)
|
||||
|
||||
# create stacks
|
||||
for i in range(4):
|
||||
x, y = l.XM, l.YM + l.TEXT_HEIGHT + (l.YS * i)
|
||||
s.foundations.append(
|
||||
FourKingdoms_DungeonFoundation(x, y, self, i, base_rank=ACE,
|
||||
max_cards=1, max_accept=1))
|
||||
x += (1.5 * l.XS)
|
||||
s.foundations.append(
|
||||
FourKingdoms_Foundation(x, y, self, i, base_rank=9,
|
||||
max_cards=1, max_accept=1))
|
||||
x += (3 * l.XS)
|
||||
s.foundations.append(
|
||||
FourKingdoms_Foundation(x, y, self, i, base_rank=KING,
|
||||
max_cards=1, max_accept=1))
|
||||
x += l.XS
|
||||
s.foundations.append(
|
||||
FourKingdoms_QueenFoundation(x, y, self, i, base_rank=QUEEN,
|
||||
max_cards=1, max_accept=1))
|
||||
x += l.XS
|
||||
s.foundations.append(
|
||||
FourKingdoms_JackFoundation(x, y, self, i, base_rank=JACK,
|
||||
max_cards=1, max_accept=1))
|
||||
x += (1.5 * l.XS)
|
||||
s.foundations.append(
|
||||
FourKingdoms_SubjectsFoundation(x, y, self, i, base_rank=8,
|
||||
dir=-1, max_cards=8,
|
||||
max_accept=1))
|
||||
|
||||
for i in range(4):
|
||||
x, y = l.XM + (l.XS * 3), l.YM + l.TEXT_HEIGHT + (l.YS * i)
|
||||
s.reserves.append(
|
||||
FourKingdoms_Reserve(x, y, self, max_cards=1, max_accept=1))
|
||||
s.reserves[i].cap.base_suit = i
|
||||
|
||||
if self.preview <= 1:
|
||||
self.setLabel(l, self.s.foundations[0], "Dungeon")
|
||||
self.setLabel(l, self.s.foundations[1], "Tower")
|
||||
self.setLabel(l, self.s.foundations[3], "Castle")
|
||||
self.setLabel(l, self.s.foundations[5], "Subjects")
|
||||
self.setLabel(l, self.s.reserves[0], "Guest")
|
||||
|
||||
x, y, = l.XM, l.YM + l.TEXT_HEIGHT + (l.YS * 4)
|
||||
s.talon = WasteTalonStack(x, y, self, max_rounds=1)
|
||||
l.createText(s.talon, 'se')
|
||||
y += l.YS
|
||||
s.waste = WasteStack(x, y, self)
|
||||
l.createText(s.waste, 'se')
|
||||
|
||||
x, y, = l.XM + l.XS, l.YM + l.TEXT_HEIGHT + (l.YS * 4)
|
||||
for i in range(7):
|
||||
x += l.XS
|
||||
s.rows.append(FourKingdoms_RowStack(x, y, self, dir=1))
|
||||
|
||||
# define stack-groups
|
||||
l.defaultStackGroups()
|
||||
|
||||
def setLabel(self, layout, stack, text):
|
||||
font = self.app.getFont("canvas_default")
|
||||
tx, ty, ta, tf = layout.getTextAttr(stack, anchor="n")
|
||||
stack.texts.misc = MfxCanvasText(self.canvas,
|
||||
tx, ty,
|
||||
anchor=ta,
|
||||
font=font)
|
||||
stack.texts.misc.config(text=_(text))
|
||||
|
||||
def startGame(self):
|
||||
for i in range(3):
|
||||
self.s.talon.dealRow(frames=0, flip=0)
|
||||
self._startAndDealRowAndCards()
|
||||
|
||||
|
||||
# register the game
|
||||
registerGame(GameInfo(845, Moojub, "Moojub",
|
||||
GI.GT_1DECK_TYPE, 1, 0, GI.SL_MOSTLY_LUCK))
|
||||
registerGame(GameInfo(970, FourKingdoms, "Four Kingdoms",
|
||||
GI.GT_1DECK_TYPE, 1, 0, GI.SL_BALANCED))
|
||||
|
|
Loading…
Add table
Reference in a new issue