mirror of
https://github.com/shlomif/PySolFC.git
synced 2025-04-05 00:02:29 -04:00
Compare commits
2 commits
a0ea7a3870
...
bd2edf2f19
Author | SHA1 | Date | |
---|---|---|---|
|
bd2edf2f19 | ||
|
792fbca78a |
12 changed files with 363 additions and 29 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"
|
"Project-Id-Version: PySol 0.0.1\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2021-12-10 10:19-0500\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"
|
"Last-Translator: H. Schaekel <Holger.Schaekel@web.de>\n"
|
||||||
"Language-Team: German\n"
|
"Language-Team: German\n"
|
||||||
"Language: de\n"
|
"Language: de\n"
|
||||||
|
@ -2347,6 +2347,21 @@ msgstr ""
|
||||||
"7: A 8 2 9 3 T 4 J 5 Q 6 K\n"
|
"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"
|
"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
|
#: pysollib/games/curdsandwhey.py:76
|
||||||
msgid "Tableau. Build down by suit or of the same rank."
|
msgid "Tableau. Build down by suit or of the same rank."
|
||||||
msgstr "Tableau. Erstellt nach unten nach Farbe oder denselben Rang."
|
msgstr "Tableau. Erstellt nach unten nach Farbe oder denselben Rang."
|
||||||
|
|
|
@ -8,7 +8,7 @@ msgstr ""
|
||||||
"Project-Id-Version: 1.02\n"
|
"Project-Id-Version: 1.02\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2021-12-10 10:19-0500\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"
|
"Last-Translator: Eric Rausch <neelix570@gmail.com>\n"
|
||||||
"Language-Team: French\n"
|
"Language-Team: French\n"
|
||||||
"Language: fr\n"
|
"Language: fr\n"
|
||||||
|
@ -2387,6 +2387,21 @@ msgstr ""
|
||||||
"7: A 8 2 9 3 T 4 J 5 Q 6 K\n"
|
"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"
|
"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
|
#: pysollib/games/curdsandwhey.py:76
|
||||||
msgid "Tableau. Build down by suit or of the same rank."
|
msgid "Tableau. Build down by suit or of the same rank."
|
||||||
msgstr "Tableau. Décroissant par enseigne ou de même valeur."
|
msgstr "Tableau. Décroissant par enseigne ou de même valeur."
|
||||||
|
|
|
@ -12,7 +12,7 @@ msgstr ""
|
||||||
"Project-Id-Version: it_pysol\n"
|
"Project-Id-Version: it_pysol\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2021-12-10 10:19-0500\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"
|
"Last-Translator: Giuliano Colla <giuliano.colla@gmail.com>\n"
|
||||||
"Language-Team: Italiano <it@li.org>\n"
|
"Language-Team: Italiano <it@li.org>\n"
|
||||||
"Language: it\n"
|
"Language: it\n"
|
||||||
|
@ -2395,6 +2395,21 @@ msgstr ""
|
||||||
"7: A 8 2 9 3 T 4 J 5 Q 6 K\n"
|
"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"
|
"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
|
#: pysollib/games/curdsandwhey.py:76
|
||||||
msgid "Tableau. Build down by suit or of the same rank."
|
msgid "Tableau. Build down by suit or of the same rank."
|
||||||
msgstr "Tableau: Sequenza decrescente dello stesso seme"
|
msgstr "Tableau: Sequenza decrescente dello stesso seme"
|
||||||
|
|
|
@ -8,7 +8,7 @@ msgstr ""
|
||||||
"Project-Id-Version: PySolFC\n"
|
"Project-Id-Version: PySolFC\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2021-12-10 10:19-0500\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"
|
"Last-Translator: Jerzy Trzeciak <artusek@wp.pl>\n"
|
||||||
"Language-Team: Polish <pl@li.org>\n"
|
"Language-Team: Polish <pl@li.org>\n"
|
||||||
"Language: pl\n"
|
"Language: pl\n"
|
||||||
|
@ -2401,6 +2401,21 @@ msgstr ""
|
||||||
"7: A 8 2 9 3 T 4 J 5 Q 6 K\n"
|
"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"
|
"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
|
#: pysollib/games/curdsandwhey.py:76
|
||||||
msgid "Tableau. Build down by suit or of the same rank."
|
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."
|
msgstr "Stół gry. Układaj w dół wg koloru lub wg tej samej wartości."
|
||||||
|
|
|
@ -8,7 +8,7 @@ msgstr ""
|
||||||
"Project-Id-Version: \n"
|
"Project-Id-Version: \n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2021-12-10 10:19-0500\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"
|
"Last-Translator: Matheus Knack <mtknack555@gmail.com>\n"
|
||||||
"Language-Team: \n"
|
"Language-Team: \n"
|
||||||
"Language: pt_BR\n"
|
"Language: pt_BR\n"
|
||||||
|
@ -2408,6 +2408,21 @@ msgstr ""
|
||||||
"7: A 8 2 9 3 T 4 J 5 Q 6 K\n"
|
"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"
|
"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
|
#: pysollib/games/curdsandwhey.py:76
|
||||||
msgid "Tableau. Build down by suit or of the same rank."
|
msgid "Tableau. Build down by suit or of the same rank."
|
||||||
msgstr "Tableau. Construa decrescente por naipe or por valor igual."
|
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"
|
"8: 3 J 6 A 9 4 Q 7 2 T 5 K"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Dungeon"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Tower"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Guest"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Castle"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Subjects"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: pysollib/games/curdsandwhey.py:76
|
#: pysollib/games/curdsandwhey.py:76
|
||||||
msgid "Tableau. Build down by suit or of the same rank."
|
msgid "Tableau. Build down by suit or of the same rank."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
|
@ -7,7 +7,7 @@ msgstr ""
|
||||||
"Project-Id-Version: \n"
|
"Project-Id-Version: \n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2021-12-10 10:19-0500\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"
|
"Last-Translator: Skomoroh <skomoroh@gmail.com>\n"
|
||||||
"Language-Team: Russian <ru@li.org>\n"
|
"Language-Team: Russian <ru@li.org>\n"
|
||||||
"Language: ru\n"
|
"Language: ru\n"
|
||||||
|
@ -2393,6 +2393,21 @@ msgstr ""
|
||||||
"7: A 8 2 9 3 10 4 В 5 Д 6 K\n"
|
"7: A 8 2 9 3 10 4 В 5 Д 6 K\n"
|
||||||
"8: 3 В 6 A 9 4 Д 7 2 10 5 K"
|
"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
|
#: pysollib/games/curdsandwhey.py:76
|
||||||
msgid "Tableau. Build down by suit or of the same rank."
|
msgid "Tableau. Build down by suit or of the same rank."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
|
@ -606,6 +606,7 @@ class PysolMenubar(PysolMenubarTk):
|
||||||
mode = kw.get("mode", 101)
|
mode = kw.get("mode", 101)
|
||||||
demo = 0
|
demo = 0
|
||||||
gameid = None
|
gameid = None
|
||||||
|
gamenum = None
|
||||||
while mode > 0:
|
while mode > 0:
|
||||||
if mode > 1000:
|
if mode > 1000:
|
||||||
demo = not demo
|
demo = not demo
|
||||||
|
@ -640,10 +641,14 @@ class PysolMenubar(PysolMenubarTk):
|
||||||
header = (_("%(app)s Demo Full log") if demo
|
header = (_("%(app)s Demo Full log") if demo
|
||||||
else _("Full log for %(player)s")) % transkw
|
else _("Full log for %(player)s")) % transkw
|
||||||
d = FullLog_StatsDialog(self.top, header, self.app, player)
|
d = FullLog_StatsDialog(self.top, header, self.app, player)
|
||||||
|
gameid = d.selected_game
|
||||||
|
gamenum = d.selected_game_num
|
||||||
elif mode == 104:
|
elif mode == 104:
|
||||||
header = (_("%(app)s Demo Session log") if demo
|
header = (_("%(app)s Demo Session log") if demo
|
||||||
else _("Session log for %(player)s")) % transkw
|
else _("Session log for %(player)s")) % transkw
|
||||||
d = SessionLog_StatsDialog(self.top, header, self.app, player)
|
d = SessionLog_StatsDialog(self.top, header, self.app, player)
|
||||||
|
gameid = d.selected_game
|
||||||
|
gamenum = d.selected_game_num
|
||||||
elif mode == 105:
|
elif mode == 105:
|
||||||
# TRANSLATORS: eg. top 10 or top 5 results for a certain game
|
# TRANSLATORS: eg. top 10 or top 5 results for a certain game
|
||||||
header = (_("%(app)s Demo Top %(tops)d for %(game)s") if demo
|
header = (_("%(app)s Demo Top %(tops)d for %(game)s") if demo
|
||||||
|
@ -698,8 +703,12 @@ class PysolMenubar(PysolMenubarTk):
|
||||||
self.game.quitGame(gameid)
|
self.game.quitGame(gameid)
|
||||||
elif mode == 402:
|
elif mode == 402:
|
||||||
# start a new game with a gameid / gamenumber
|
# start a new game with a gameid / gamenumber
|
||||||
# TODO
|
if (gameid and gamenum and
|
||||||
pass
|
(gameid != self.game.id or
|
||||||
|
gamenum != self.game.getGameNumber(format=0))):
|
||||||
|
self.game.endGame()
|
||||||
|
self.game.quitGame(gameid,
|
||||||
|
random=construct_random(gamenum))
|
||||||
else:
|
else:
|
||||||
print_err("stats problem: %s %s %s" % (mode, demo, player))
|
print_err("stats problem: %s %s %s" % (mode, demo, player))
|
||||||
pass
|
pass
|
||||||
|
|
|
@ -418,7 +418,7 @@ class GI:
|
||||||
|
|
||||||
# Solitude for Windows
|
# Solitude for Windows
|
||||||
# still missing:
|
# still missing:
|
||||||
# Bowling (Sackson version), Four Kingdoms, Icicles
|
# Bowling (Sackson version), Icicles
|
||||||
("Solitude for Windows", (
|
("Solitude for Windows", (
|
||||||
2, 8, 11, 13, 19, 24, 25, 29, 30, 31, 33, 34, 36, 38, 42,
|
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,
|
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,
|
128, 133, 134, 135, 139, 146, 147, 171, 172, 173, 221, 222,
|
||||||
224, 228, 233, 234, 235, 256, 257, 258, 282, 314, 327, 330,
|
224, 228, 233, 234, 235, 256, 257, 258, 282, 314, 327, 330,
|
||||||
355, 356, 398, 406, 414, 418, 434, 437, 484, 593, 715, 716,
|
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
|
# XM Solitaire
|
||||||
|
@ -479,7 +479,7 @@ class GI:
|
||||||
("Paul Alfille", (8,)),
|
("Paul Alfille", (8,)),
|
||||||
("C.L. Baker", (45,)),
|
("C.L. Baker", (45,)),
|
||||||
("Mark S. Ball", (909,)),
|
("Mark S. Ball", (909,)),
|
||||||
("David Bernazzani", (314, 830,)),
|
("David Bernazzani", (314, 830, 970,)),
|
||||||
("Gordon Bower", (763, 783, 852, 959,)),
|
("Gordon Bower", (763, 783, 852, 959,)),
|
||||||
("Art Cabral", (9,)),
|
("Art Cabral", (9,)),
|
||||||
("Richard A. Canfield", (105, 835,)),
|
("Richard A. Canfield", (105, 835,)),
|
||||||
|
@ -603,7 +603,7 @@ class GI:
|
||||||
tuple(range(13168, 13170)) + tuple(range(18000, 18005)) +
|
tuple(range(13168, 13170)) + tuple(range(18000, 18005)) +
|
||||||
tuple(range(19000, 19012)) + tuple(range(22303, 22311)) +
|
tuple(range(19000, 19012)) + tuple(range(22303, 22311)) +
|
||||||
tuple(range(22353, 22361))),
|
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
|
# deprecated - the correct way is to or a GI.GT_XXX flag
|
||||||
|
|
|
@ -24,17 +24,25 @@
|
||||||
from pysollib.game import Game
|
from pysollib.game import Game
|
||||||
from pysollib.gamedb import GI, GameInfo, registerGame
|
from pysollib.gamedb import GI, GameInfo, registerGame
|
||||||
from pysollib.layout import Layout
|
from pysollib.layout import Layout
|
||||||
|
from pysollib.mygettext import _
|
||||||
|
from pysollib.pysoltk import MfxCanvasText
|
||||||
from pysollib.stack import \
|
from pysollib.stack import \
|
||||||
DealRowTalonStack, \
|
DealRowTalonStack, \
|
||||||
OpenStack, \
|
OpenStack, \
|
||||||
RK_FoundationStack
|
RK_FoundationStack, \
|
||||||
from pysollib.util import ACE, ANY_SUIT, KING
|
ReserveStack, \
|
||||||
|
SS_FoundationStack, \
|
||||||
|
SS_RowStack, \
|
||||||
|
Stack, \
|
||||||
|
WasteStack, \
|
||||||
|
WasteTalonStack
|
||||||
|
from pysollib.util import ACE, ANY_SUIT, JACK, KING, QUEEN
|
||||||
|
|
||||||
|
|
||||||
# ************************************************************************
|
# ************************************************************************
|
||||||
# * Moojub
|
# * Moojub
|
||||||
# ************************************************************************
|
# ************************************************************************
|
||||||
|
|
||||||
|
|
||||||
class Moojub_Foundation(RK_FoundationStack):
|
class Moojub_Foundation(RK_FoundationStack):
|
||||||
def acceptsCards(self, from_stack, cards):
|
def acceptsCards(self, from_stack, cards):
|
||||||
if len(self.cards) > 0:
|
if len(self.cards) > 0:
|
||||||
|
@ -107,6 +115,143 @@ class Moojub(Game):
|
||||||
self._startAndDealRow()
|
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
|
# register the game
|
||||||
registerGame(GameInfo(845, Moojub, "Moojub",
|
registerGame(GameInfo(845, Moojub, "Moojub",
|
||||||
GI.GT_1DECK_TYPE, 1, 0, GI.SL_MOSTLY_LUCK))
|
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))
|
||||||
|
|
|
@ -383,6 +383,7 @@ class TreeFormatter(PysolStatsFormatter):
|
||||||
t1, t2, t3, t4, t5, t6 = result
|
t1, t2, t3, t4, t5, t6 = result
|
||||||
id = self.tree.insert("", "end", text=t1, values=(t2, t3, t4))
|
id = self.tree.insert("", "end", text=t1, values=(t2, t3, t4))
|
||||||
self.parent_window.tree_items.append(id)
|
self.parent_window.tree_items.append(id)
|
||||||
|
self.parent_window.games[id] = (t6, t2)
|
||||||
num_rows += 1
|
num_rows += 1
|
||||||
if num_rows > self.MAX_ROWS:
|
if num_rows > self.MAX_ROWS:
|
||||||
break
|
break
|
||||||
|
@ -512,7 +513,8 @@ class LogDialog(MfxDialog):
|
||||||
title = _('Log')
|
title = _('Log')
|
||||||
MfxDialog.__init__(self, parent, title, kw.resizable, kw.default)
|
MfxDialog.__init__(self, parent, title, kw.resizable, kw.default)
|
||||||
|
|
||||||
# self.selected_game = None
|
self.selected_game = None
|
||||||
|
self.selected_game_num = None
|
||||||
|
|
||||||
top_frame, bottom_frame = self.createFrames(kw)
|
top_frame, bottom_frame = self.createFrames(kw)
|
||||||
notebook = ttk.Notebook(top_frame)
|
notebook = ttk.Notebook(top_frame)
|
||||||
|
@ -522,24 +524,40 @@ class LogDialog(MfxDialog):
|
||||||
|
|
||||||
full_frame = FullLogFrame(self, notebook, app, player)
|
full_frame = FullLogFrame(self, notebook, app, player)
|
||||||
notebook.add(full_frame, text=_('Full log'))
|
notebook.add(full_frame, text=_('Full log'))
|
||||||
|
self.full_log_frame = full_frame
|
||||||
self.notebook_tabs.append(full_frame._w)
|
self.notebook_tabs.append(full_frame._w)
|
||||||
|
|
||||||
session_frame = SessionLogFrame(self, notebook, app, player)
|
session_frame = SessionLogFrame(self, notebook, app, player)
|
||||||
notebook.add(session_frame, text=_('Session log'))
|
notebook.add(session_frame, text=_('Session log'))
|
||||||
|
self.session_log_frame = session_frame
|
||||||
self.notebook_tabs.append(session_frame._w)
|
self.notebook_tabs.append(session_frame._w)
|
||||||
|
|
||||||
notebook.select(LogDialog.SELECTED_TAB)
|
notebook.select(LogDialog.SELECTED_TAB)
|
||||||
# bind(notebook, '<<NotebookTabChanged>>', self.tabChanged)
|
bind(notebook, '<<NotebookTabChanged>>', self.tabChanged)
|
||||||
|
|
||||||
self.notebook = notebook
|
self.notebook = notebook
|
||||||
|
|
||||||
focus = self.createButtons(bottom_frame, kw)
|
focus = self.createButtons(bottom_frame, kw)
|
||||||
# self.tabChanged() # configure buttons state
|
self.tabChanged() # configure buttons state
|
||||||
self.mainloop(focus, kw.timeout)
|
self.mainloop(focus, kw.timeout)
|
||||||
|
|
||||||
|
def tabChanged(self, *args):
|
||||||
|
w = self.notebook.select()
|
||||||
|
run_button = self.buttons[0]
|
||||||
|
indx = self.notebook_tabs.index(w)
|
||||||
|
if indx == 0:
|
||||||
|
g = self.full_log_frame.getSelectedGame()
|
||||||
|
else:
|
||||||
|
g = self.session_log_frame.getSelectedGame()
|
||||||
|
if g[0] is None:
|
||||||
|
run_button.config(state='disabled')
|
||||||
|
else:
|
||||||
|
run_button.config(state='normal')
|
||||||
|
|
||||||
def initKw(self, kw):
|
def initKw(self, kw):
|
||||||
kw = KwStruct(kw,
|
kw = KwStruct(kw,
|
||||||
strings=(_("&OK"),
|
strings=((_("&Play this game"), 402),
|
||||||
|
"sep", _("&OK"),
|
||||||
(_("&Save to file"), 500)),
|
(_("&Save to file"), 500)),
|
||||||
default=0,
|
default=0,
|
||||||
width=76*self.CHAR_W,
|
width=76*self.CHAR_W,
|
||||||
|
@ -548,16 +566,17 @@ class LogDialog(MfxDialog):
|
||||||
return MfxDialog.initKw(self, kw)
|
return MfxDialog.initKw(self, kw)
|
||||||
|
|
||||||
def mDone(self, button):
|
def mDone(self, button):
|
||||||
# self.selected_game = self.all_games_frame.getSelectedGame()
|
|
||||||
w = self.notebook.select()
|
w = self.notebook.select()
|
||||||
indx = self.notebook_tabs.index(w)
|
indx = self.notebook_tabs.index(w)
|
||||||
LogDialog.SELECTED_TAB = indx
|
LogDialog.SELECTED_TAB = indx
|
||||||
if button == 500: # "Save to file"
|
if indx == 0:
|
||||||
assert indx in (0, 1)
|
self.selected_game, self.selected_game_num \
|
||||||
if indx == 0: # "Full log"
|
= self.full_log_frame.getSelectedGame()
|
||||||
button = 203
|
else:
|
||||||
else: # "Session log"
|
self.selected_game, self.selected_game_num \
|
||||||
button = 204
|
= self.session_log_frame.getSelectedGame()
|
||||||
|
|
||||||
MfxDialog.mDone(self, button)
|
MfxDialog.mDone(self, button)
|
||||||
|
|
||||||
|
|
||||||
|
@ -576,6 +595,7 @@ class FullLogFrame(AllGamesFrame):
|
||||||
AllGamesFrame.__init__(self, dialog, parent, app, player, **kw)
|
AllGamesFrame.__init__(self, dialog, parent, app, player, **kw)
|
||||||
header = ('', '99999999999999999999', '9999-99-99 99:99',
|
header = ('', '99999999999999999999', '9999-99-99 99:99',
|
||||||
'XXXXXXXXXXXX')
|
'XXXXXXXXXXXX')
|
||||||
|
self.games = {}
|
||||||
self.formatter.resizeHeader(player, header)
|
self.formatter.resizeHeader(player, header)
|
||||||
|
|
||||||
def createHeader(self, player):
|
def createHeader(self, player):
|
||||||
|
@ -587,12 +607,16 @@ class FullLogFrame(AllGamesFrame):
|
||||||
return
|
return
|
||||||
self.formatter.writeFullLog(player)
|
self.formatter.writeFullLog(player)
|
||||||
|
|
||||||
def treeviewSelected(self, *args):
|
|
||||||
pass
|
|
||||||
|
|
||||||
def headerClick(self, column):
|
def headerClick(self, column):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
def getSelectedGame(self):
|
||||||
|
sel = self.tree.selection()
|
||||||
|
if sel and len(sel) == 1:
|
||||||
|
if sel[0] in self.games:
|
||||||
|
return self.games[sel[0]]
|
||||||
|
return (None, None)
|
||||||
|
|
||||||
|
|
||||||
class SessionLogFrame(FullLogFrame):
|
class SessionLogFrame(FullLogFrame):
|
||||||
def fillTreeview(self, player):
|
def fillTreeview(self, player):
|
||||||
|
|
Loading…
Add table
Reference in a new issue