mirror of
https://github.com/shlomif/PySolFC.git
synced 2025-04-05 00:02:29 -04:00
Compare commits
9 commits
4711919942
...
6bc5b53995
Author | SHA1 | Date | |
---|---|---|---|
|
6bc5b53995 | ||
|
dd42ac10ea | ||
|
d6ca6d226b | ||
|
e4e2e99031 | ||
|
054c0f0368 | ||
|
487d1c52f3 | ||
|
6852bb40ff | ||
|
6006e0f4c0 | ||
|
68138c7284 |
27 changed files with 306 additions and 53 deletions
|
@ -2,7 +2,7 @@
|
|||
image: Visual Studio 2022
|
||||
environment:
|
||||
matrix:
|
||||
- PYTHON: "C:\\Python312"
|
||||
- PYTHON: "C:\\Python313"
|
||||
# Shamelessly taken from https://github.com/plicease/Dist-Zilla-PluginBundle-Author-Plicease/blob/master/.appveyor.yml
|
||||
# Thanks!
|
||||
install:
|
||||
|
|
15
html-src/rules/colours.html
Normal file
15
html-src/rules/colours.html
Normal file
|
@ -0,0 +1,15 @@
|
|||
<h1>Colours</h1>
|
||||
<p>
|
||||
Numerica type. 1 deck. No redeal.
|
||||
|
||||
<h3>Object</h3>
|
||||
<p>
|
||||
Move all cards to the foundations.
|
||||
|
||||
<h3>Quick Description</h3>
|
||||
<p>
|
||||
Like <a href="ladybetty.html">Lady Betty</a>,
|
||||
but the foundations are built up by same color, and
|
||||
wrap from king to ace. At the start of the game, a
|
||||
two through five are dealt to the foundations, in
|
||||
alternating colors.
|
12
html-src/rules/littleishido.html
Normal file
12
html-src/rules/littleishido.html
Normal file
|
@ -0,0 +1,12 @@
|
|||
<h1>Little Ishido</h1>
|
||||
<p>
|
||||
Ishido game type. 2 decks. No redeal.
|
||||
|
||||
<h3>Object</h3>
|
||||
<p>
|
||||
Move all tiles to the playing area.
|
||||
|
||||
<h3>Quick Description</h3>
|
||||
<p>
|
||||
Like <a href='ishido.html'>Ishido</a>, but with four colors and symbols,
|
||||
and a 6X8 grid. The initial tiles are placed in the four corners only.
|
14
html-src/rules/littleishidorelaxed.html
Normal file
14
html-src/rules/littleishidorelaxed.html
Normal file
|
@ -0,0 +1,14 @@
|
|||
<h1>Little Ishido Relaxed</h1>
|
||||
<p>
|
||||
Ishido game type. 2 decks. No redeal.
|
||||
|
||||
<h3>Object</h3>
|
||||
<p>
|
||||
Move all tiles to the playing area.
|
||||
|
||||
<h3>Quick Description</h3>
|
||||
<p>
|
||||
Like <a href='ishido.html'>Ishido</a>, but with four colors and symbols,
|
||||
and a 6X8 grid. The initial tiles are placed in the four corners only.
|
||||
Also, there are no restrictions when placing a tile next to two or more
|
||||
other tiles - they just have to match the color or symbol of each.
|
|
@ -4370,6 +4370,9 @@ msgstr "Aktuelle Sitzung"
|
|||
msgid "Log"
|
||||
msgstr "Protokoll"
|
||||
|
||||
msgid "Demo Log"
|
||||
msgstr ""
|
||||
|
||||
#: pysollib/tile/tkstats.py:523 data/pysolfc.glade:1404
|
||||
msgid "Full log"
|
||||
msgstr "Volles Protokoll"
|
||||
|
@ -5171,6 +5174,9 @@ msgstr "Kommentare..."
|
|||
msgid "Log..."
|
||||
msgstr ""
|
||||
|
||||
msgid "Demo Log..."
|
||||
msgstr ""
|
||||
|
||||
#: pysollib/ui/tktile/menubar.py:427
|
||||
msgid "D&emo statistics..."
|
||||
msgstr "D&emo Statistiken..."
|
||||
|
|
|
@ -4421,6 +4421,9 @@ msgstr "Session en cours"
|
|||
msgid "Log"
|
||||
msgstr "Journal"
|
||||
|
||||
msgid "Demo Log"
|
||||
msgstr ""
|
||||
|
||||
#: pysollib/tile/tkstats.py:523 data/pysolfc.glade:1404
|
||||
msgid "Full log"
|
||||
msgstr "Journal complet"
|
||||
|
@ -5222,6 +5225,9 @@ msgstr "&Commentaires..."
|
|||
msgid "Log..."
|
||||
msgstr "Journal..."
|
||||
|
||||
msgid "Demo Log..."
|
||||
msgstr ""
|
||||
|
||||
#: pysollib/ui/tktile/menubar.py:427
|
||||
msgid "D&emo statistics..."
|
||||
msgstr "Statistiques d&émo..."
|
||||
|
|
|
@ -4485,6 +4485,9 @@ msgstr "Questa sessione"
|
|||
msgid "Log"
|
||||
msgstr "Log"
|
||||
|
||||
msgid "Demo Log"
|
||||
msgstr ""
|
||||
|
||||
#: pysollib/tile/tkstats.py:523 data/pysolfc.glade:1404
|
||||
msgid "Full log"
|
||||
msgstr "Log completo"
|
||||
|
@ -5288,6 +5291,9 @@ msgstr "&Commenti..."
|
|||
msgid "Log..."
|
||||
msgstr "Log..."
|
||||
|
||||
msgid "Demo Log..."
|
||||
msgstr ""
|
||||
|
||||
#: pysollib/ui/tktile/menubar.py:427
|
||||
msgid "D&emo statistics..."
|
||||
msgstr "Statistiche d&emo..."
|
||||
|
|
|
@ -4438,6 +4438,9 @@ msgstr "Bieżąca sesja"
|
|||
msgid "Log"
|
||||
msgstr "Log"
|
||||
|
||||
msgid "Demo Log"
|
||||
msgstr ""
|
||||
|
||||
#: pysollib/tile/tkstats.py:523 data/pysolfc.glade:1404
|
||||
msgid "Full log"
|
||||
msgstr "Kompletny log"
|
||||
|
@ -5242,6 +5245,9 @@ msgstr "Komentarze..."
|
|||
msgid "Log..."
|
||||
msgstr "Log..."
|
||||
|
||||
msgid "Demo Log..."
|
||||
msgstr ""
|
||||
|
||||
#: pysollib/ui/tktile/menubar.py:427
|
||||
msgid "D&emo statistics..."
|
||||
msgstr "D&emo statystyk..."
|
||||
|
|
|
@ -4444,6 +4444,9 @@ msgstr "Sessão atual"
|
|||
msgid "Log"
|
||||
msgstr "registro"
|
||||
|
||||
msgid "Demo Log"
|
||||
msgstr ""
|
||||
|
||||
#: pysollib/tile/tkstats.py:523 data/pysolfc.glade:1404
|
||||
msgid "Full log"
|
||||
msgstr "Registro completo"
|
||||
|
@ -5244,6 +5247,9 @@ msgstr "&Comentários..."
|
|||
msgid "Log..."
|
||||
msgstr "Registro"
|
||||
|
||||
msgid "Demo Log..."
|
||||
msgstr ""
|
||||
|
||||
#: pysollib/ui/tktile/menubar.py:427
|
||||
msgid "D&emo statistics..."
|
||||
msgstr "Estatísticas de D&emo..."
|
||||
|
|
|
@ -4224,6 +4224,9 @@ msgstr ""
|
|||
msgid "Log"
|
||||
msgstr ""
|
||||
|
||||
msgid "Demo Log"
|
||||
msgstr ""
|
||||
|
||||
#: pysollib/tile/tkstats.py:523 data/pysolfc.glade:1404
|
||||
msgid "Full log"
|
||||
msgstr ""
|
||||
|
@ -4974,6 +4977,9 @@ msgstr ""
|
|||
msgid "Log..."
|
||||
msgstr ""
|
||||
|
||||
msgid "Demo Log..."
|
||||
msgstr ""
|
||||
|
||||
#: pysollib/ui/tktile/menubar.py:427
|
||||
msgid "D&emo statistics..."
|
||||
msgstr ""
|
||||
|
|
|
@ -4494,6 +4494,9 @@ msgstr "Текущая сессия"
|
|||
msgid "Log"
|
||||
msgstr "Лог"
|
||||
|
||||
msgid "Demo Log"
|
||||
msgstr ""
|
||||
|
||||
#: pysollib/tile/tkstats.py:523 data/pysolfc.glade:1404
|
||||
msgid "Full log"
|
||||
msgstr "Полный лог"
|
||||
|
@ -5311,6 +5314,9 @@ msgstr "&Комментарии..."
|
|||
msgid "Log..."
|
||||
msgstr "Лог..."
|
||||
|
||||
msgid "Demo Log..."
|
||||
msgstr ""
|
||||
|
||||
#: pysollib/ui/tktile/menubar.py:427
|
||||
msgid "D&emo statistics..."
|
||||
msgstr "Статистика демо..."
|
||||
|
|
|
@ -115,11 +115,6 @@ class Statistics:
|
|||
game.GAME_VERSION)
|
||||
# full log
|
||||
if status >= 0:
|
||||
if player is None:
|
||||
# demo
|
||||
ret = self.updateGameStat(player, game, status)
|
||||
else:
|
||||
# player
|
||||
if player not in self.prev_games:
|
||||
self.prev_games[player] = []
|
||||
self.prev_games[player].append(log)
|
||||
|
|
|
@ -595,13 +595,12 @@ class GI:
|
|||
tuple(range(19000, 19012)) + tuple(range(22303, 22311)) +
|
||||
tuple(range(22353, 22361))),
|
||||
('fc-3.1', tuple(range(961, 971))),
|
||||
('dev', tuple(range(971, 972))),
|
||||
('dev', tuple(range(971, 973)) + tuple(range(18005, 18007))),
|
||||
)
|
||||
|
||||
# deprecated - the correct way is to or a GI.GT_XXX flag
|
||||
# in the registerGame() call
|
||||
_CHILDREN_GAMES = [16, 33, 55, 90, 91, 96, 97, 176, 328, 329, 862, 865,
|
||||
886, 903, ]
|
||||
_CHILDREN_GAMES = []
|
||||
|
||||
_OPEN_GAMES = []
|
||||
|
||||
|
|
|
@ -504,7 +504,7 @@ class MaineCoon(TabbyCat):
|
|||
|
||||
# register the game
|
||||
registerGame(GameInfo(903, AcesUp, "Aces Up", # was: 52
|
||||
GI.GT_1DECK_TYPE, 1, 0, GI.SL_LUCK,
|
||||
GI.GT_1DECK_TYPE | GI.GT_CHILDREN, 1, 0, GI.SL_LUCK,
|
||||
altnames=("Aces High", "Drivel", "Discard")))
|
||||
registerGame(GameInfo(206, Fortunes, "Fortunes",
|
||||
GI.GT_1DECK_TYPE, 1, 0, GI.SL_LUCK))
|
||||
|
@ -514,7 +514,7 @@ registerGame(GameInfo(130, PerpetualMotion, "Perpetual Motion",
|
|||
GI.GT_1DECK_TYPE, 1, -1, GI.SL_MOSTLY_LUCK,
|
||||
altnames=("First Law", "Narcotic")))
|
||||
registerGame(GameInfo(353, AcesUp5, "Aces Up 5",
|
||||
GI.GT_1DECK_TYPE, 1, 0, GI.SL_LUCK))
|
||||
GI.GT_1DECK_TYPE | GI.GT_CHILDREN, 1, 0, GI.SL_LUCK))
|
||||
registerGame(GameInfo(552, Cover, "Cover",
|
||||
GI.GT_1DECK_TYPE, 1, 0, GI.SL_LUCK))
|
||||
registerGame(GameInfo(583, FiringSquad, "Firing Squad",
|
||||
|
|
|
@ -105,6 +105,7 @@ class StrictEiffelTower(EiffelTower):
|
|||
|
||||
# register the game
|
||||
registerGame(GameInfo(16, EiffelTower, "Eiffel Tower",
|
||||
GI.GT_PAIRING_TYPE, 2, 0, GI.SL_MOSTLY_LUCK))
|
||||
GI.GT_PAIRING_TYPE | GI.GT_CHILDREN, 2, 0,
|
||||
GI.SL_MOSTLY_LUCK))
|
||||
# registerGame(GameInfo(801, StrictEiffelTower, "Strict Eiffel Tower",
|
||||
# GI.GT_PAIRING_TYPE, 2, 0))
|
||||
|
|
|
@ -776,11 +776,11 @@ registerGame(GameInfo(697, BigBen, "Big Ben",
|
|||
GI.GT_2DECK_TYPE, 2, 0, GI.SL_BALANCED,
|
||||
altnames=("Father Time")))
|
||||
registerGame(GameInfo(737, Clock, "Clock",
|
||||
GI.GT_1DECK_TYPE, 1, 0, GI.SL_LUCK,
|
||||
GI.GT_1DECK_TYPE | GI.GT_CHILDREN, 1, 0, GI.SL_LUCK,
|
||||
altnames=("Travellers", "Sundial")))
|
||||
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")))
|
||||
GI.GT_1DECK_TYPE | GI.GT_RELAXED | GI.GT_CHILDREN, 1, 0,
|
||||
GI.SL_LUCK, altnames=("Watch")))
|
||||
|
|
|
@ -170,5 +170,5 @@ registerGame(GameInfo(774, HitOrMiss, "Hit or Miss",
|
|||
GI.GT_1DECK_TYPE, 1, VARIABLE_REDEALS,
|
||||
GI.SL_LUCK, altnames=("Roll Call",)))
|
||||
registerGame(GameInfo(865, HitOrMissUnlimited, "Hit or Miss Unlimited",
|
||||
GI.GT_1DECK_TYPE, 1, UNLIMITED_REDEALS,
|
||||
GI.GT_1DECK_TYPE | GI.GT_CHILDREN, 1, UNLIMITED_REDEALS,
|
||||
GI.SL_LUCK))
|
||||
|
|
|
@ -1640,7 +1640,8 @@ registerGame(GameInfo(66, Eastcliff, "Eastcliff",
|
|||
registerGame(GameInfo(224, Easthaven, "Easthaven",
|
||||
GI.GT_GYPSY, 1, 0, GI.SL_MOSTLY_LUCK))
|
||||
registerGame(GameInfo(33, Westcliff, "Westcliff",
|
||||
GI.GT_KLONDIKE, 1, 0, GI.SL_MOSTLY_LUCK))
|
||||
GI.GT_KLONDIKE | GI.GT_CHILDREN, 1, 0,
|
||||
GI.SL_MOSTLY_LUCK))
|
||||
registerGame(GameInfo(225, Westhaven, "Westhaven",
|
||||
GI.GT_GYPSY, 1, 0, GI.SL_BALANCED))
|
||||
registerGame(GameInfo(107, PasSeul, "Pas Seul",
|
||||
|
|
|
@ -1118,15 +1118,16 @@ registerGame(GameInfo(216, MonteCarlo2Decks, "Monte Carlo (2 Decks)",
|
|||
registerGame(GameInfo(212, Weddings, "Weddings",
|
||||
GI.GT_PAIRING_TYPE, 1, 0, GI.SL_MOSTLY_LUCK))
|
||||
registerGame(GameInfo(90, SimpleCarlo, "Simple Carlo",
|
||||
GI.GT_PAIRING_TYPE, 1, 0, GI.SL_MOSTLY_LUCK))
|
||||
GI.GT_PAIRING_TYPE | GI.GT_CHILDREN, 1, 0,
|
||||
GI.SL_MOSTLY_LUCK))
|
||||
registerGame(GameInfo(91, SimplePairs, "Simple Pairs",
|
||||
GI.GT_PAIRING_TYPE, 1, 0, GI.SL_LUCK,
|
||||
altnames=("Jamestown", "Pirate Gold", "Treasure Hunt",
|
||||
"Hunter")))
|
||||
GI.GT_PAIRING_TYPE | GI.GT_CHILDREN, 1, 0,
|
||||
GI.SL_LUCK, altnames=("Jamestown", "Pirate Gold",
|
||||
"Treasure Hunt", "Hunter")))
|
||||
registerGame(GameInfo(92, Neighbour, "Neighbour",
|
||||
GI.GT_PAIRING_TYPE, 1, 0, GI.SL_MOSTLY_LUCK))
|
||||
registerGame(GameInfo(96, Fourteen, "Fourteen",
|
||||
GI.GT_PAIRING_TYPE | GI.GT_OPEN, 1, 0,
|
||||
GI.GT_PAIRING_TYPE | GI.GT_OPEN | GI.GT_CHILDREN, 1, 0,
|
||||
GI.SL_MOSTLY_LUCK, altnames=("Fourteen Out",
|
||||
"Fourteen Puzzle",
|
||||
"Take Fourteen")))
|
||||
|
@ -1137,12 +1138,13 @@ registerGame(GameInfo(152, DerLetzteMonarch, "The Last Monarch",
|
|||
GI.GT_1DECK_TYPE | GI.GT_OPEN, 1, 0, GI.SL_MOSTLY_SKILL,
|
||||
altnames=("Der letzte Monarch",)))
|
||||
registerGame(GameInfo(328, TheWish, "The Wish",
|
||||
GI.GT_PAIRING_TYPE | GI.GT_STRIPPED, 1, 0,
|
||||
GI.SL_MOSTLY_LUCK, ranks=(0, 6, 7, 8, 9, 10, 11, 12)))
|
||||
GI.GT_PAIRING_TYPE | GI.GT_STRIPPED | GI.GT_CHILDREN,
|
||||
1, 0, GI.SL_MOSTLY_LUCK,
|
||||
ranks=(0, 6, 7, 8, 9, 10, 11, 12)))
|
||||
registerGame(GameInfo(329, TheWishOpen, "The Wish (Open)",
|
||||
GI.GT_PAIRING_TYPE | GI.GT_OPEN | GI.GT_ORIGINAL |
|
||||
GI.GT_STRIPPED, 1, 0, GI.SL_MOSTLY_SKILL,
|
||||
ranks=(0, 6, 7, 8, 9, 10, 11, 12),
|
||||
GI.GT_STRIPPED | GI.GT_CHILDREN, 1, 0,
|
||||
GI.SL_MOSTLY_SKILL, ranks=(0, 6, 7, 8, 9, 10, 11, 12),
|
||||
rules_filename="thewish.html"))
|
||||
registerGame(GameInfo(368, Vertical, "Vertical",
|
||||
GI.GT_PAIRING_TYPE | GI.GT_OPEN, 1, 0,
|
||||
|
@ -1162,8 +1164,8 @@ registerGame(GameInfo(810, Quatorze, "Quatorze",
|
|||
registerGame(GameInfo(829, BlockTen, "Block Ten",
|
||||
GI.GT_PAIRING_TYPE, 1, 0, GI.SL_LUCK))
|
||||
registerGame(GameInfo(862, SimpleTens, "Simple Tens",
|
||||
GI.GT_PAIRING_TYPE | GI.GT_STRIPPED, 1, 0, GI.SL_LUCK,
|
||||
ranks=(0, 1, 2, 3, 4, 5, 6, 7, 8),
|
||||
GI.GT_PAIRING_TYPE | GI.GT_STRIPPED | GI.GT_CHILDREN,
|
||||
1, 0, GI.SL_LUCK, ranks=(0, 1, 2, 3, 4, 5, 6, 7, 8),
|
||||
altnames=("Add Up Tens",)))
|
||||
registerGame(GameInfo(867, DoubleFourteen, "Double Fourteen",
|
||||
GI.GT_PAIRING_TYPE | GI.GT_OPEN, 2, 0,
|
||||
|
|
|
@ -41,6 +41,7 @@ from pysollib.stack import \
|
|||
RK_FoundationStack, \
|
||||
RK_RowStack, \
|
||||
ReserveStack, \
|
||||
SC_FoundationStack, \
|
||||
SS_FoundationStack, \
|
||||
Stack, \
|
||||
StackWrapper, \
|
||||
|
@ -176,6 +177,7 @@ class Numerica2Decks(Numerica):
|
|||
# ************************************************************************
|
||||
# * Lady Betty
|
||||
# * Last Chance
|
||||
# * Colours
|
||||
# ************************************************************************
|
||||
|
||||
class LadyBetty(Numerica):
|
||||
|
@ -215,6 +217,40 @@ class LastChance(LadyBetty):
|
|||
self.s.talon.dealCards()
|
||||
|
||||
|
||||
class Colours(LadyBetty):
|
||||
Foundation_Class = StackWrapper(SC_FoundationStack, mod=13, suit=ANY_SUIT)
|
||||
|
||||
def startGame(self):
|
||||
self.startDealSample()
|
||||
self.s.talon.dealRow(rows=self.s.foundations)
|
||||
self.s.talon.dealCards() # deal first card to WasteStack
|
||||
|
||||
def _shuffleHook(self, cards):
|
||||
# prepare first cards
|
||||
topcards = [None] * 4
|
||||
evencolor = -1
|
||||
oddcolor = -1
|
||||
for c in cards[:]:
|
||||
if 0 < c.rank <= 4 and topcards[c.rank - 1] is None:
|
||||
if c.rank % 2 == 0:
|
||||
if evencolor != -1 and c.color != evencolor:
|
||||
continue
|
||||
if oddcolor != -1 and c.color == oddcolor:
|
||||
continue
|
||||
evencolor = c.color
|
||||
elif c.rank % 2 == 1:
|
||||
if oddcolor != -1 and c.color != oddcolor:
|
||||
continue
|
||||
if evencolor != -1 and c.color == evencolor:
|
||||
continue
|
||||
oddcolor = c.color
|
||||
|
||||
topcards[c.rank - 1] = c
|
||||
cards.remove(c)
|
||||
topcards.reverse()
|
||||
return cards + topcards
|
||||
|
||||
|
||||
# ************************************************************************
|
||||
# * Puss in the Corner
|
||||
# ************************************************************************
|
||||
|
@ -1460,3 +1496,5 @@ registerGame(GameInfo(931, TheBogey, "The Bogey",
|
|||
GI.GT_1DECK_TYPE, 1, -1, GI.SL_BALANCED))
|
||||
registerGame(GameInfo(958, NinetyOne, "Ninety-One",
|
||||
GI.GT_1DECK_TYPE, 1, 0, GI.SL_MOSTLY_SKILL))
|
||||
registerGame(GameInfo(972, Colours, "Colours",
|
||||
GI.GT_NUMERICA, 1, 0, GI.SL_BALANCED))
|
||||
|
|
|
@ -1573,13 +1573,14 @@ registerGame(GameInfo(54, RoyalCotillion, "Royal Cotillion",
|
|||
GI.GT_2DECK_TYPE, 2, 0, GI.SL_LUCK,
|
||||
altnames=("Lords and Ladies",)))
|
||||
registerGame(GameInfo(55, OddAndEven, "Odd and Even",
|
||||
GI.GT_2DECK_TYPE, 2, 1, GI.SL_LUCK))
|
||||
GI.GT_2DECK_TYPE | GI.GT_CHILDREN, 2, 1, GI.SL_LUCK))
|
||||
registerGame(GameInfo(143, Kingdom, "Kingdom",
|
||||
GI.GT_2DECK_TYPE, 2, 0, GI.SL_MOSTLY_LUCK))
|
||||
registerGame(GameInfo(234, Alhambra, "Alhambra",
|
||||
GI.GT_2DECK_TYPE, 2, 2, GI.SL_BALANCED))
|
||||
registerGame(GameInfo(97, Carpet, "Carpet",
|
||||
GI.GT_1DECK_TYPE, 1, 0, GI.SL_MOSTLY_LUCK))
|
||||
GI.GT_1DECK_TYPE | GI.GT_CHILDREN, 1, 0,
|
||||
GI.SL_MOSTLY_LUCK))
|
||||
registerGame(GameInfo(391, BritishConstitution, "British Constitution",
|
||||
GI.GT_2DECK_TYPE | GI.GT_STRIPPED, 2, 0, GI.SL_BALANCED,
|
||||
ranks=list(range(11)), # without Queens and Kings
|
||||
|
|
|
@ -99,6 +99,9 @@ class Ishido(Game):
|
|||
STRICT_FOUR_WAYS = True
|
||||
SCORING = False
|
||||
|
||||
COLS = 12
|
||||
ROWS = 8
|
||||
|
||||
#
|
||||
# game layout
|
||||
#
|
||||
|
@ -115,13 +118,13 @@ class Ishido(Game):
|
|||
|
||||
w2 = max(2 * l.XS, x)
|
||||
# set window
|
||||
w, h = w2 + l.XM * 2 + l.CW * 12, l.YM * 2 + l.CH * 8
|
||||
w, h = w2 + l.XM * 2 + l.CW * self.COLS, l.YM * 2 + l.CH * self.ROWS
|
||||
self.setSize(w, h)
|
||||
|
||||
# Create rows
|
||||
for j in range(8):
|
||||
for j in range(self.ROWS):
|
||||
x, y = w2 + l.XM, l.YM + l.CH * j
|
||||
for i in range(12):
|
||||
for i in range(self.COLS):
|
||||
s.rows.append(self.RowStack_Class(x, y, self))
|
||||
x = x + l.CW
|
||||
|
||||
|
@ -269,17 +272,17 @@ class Ishido(Game):
|
|||
|
||||
def getAdjacent(self, playSpace):
|
||||
adjacentRows = []
|
||||
if playSpace % 12 != 11:
|
||||
if playSpace % self.COLS != self.COLS - 1:
|
||||
adjacentRows.append(self.s.rows[playSpace + 1])
|
||||
|
||||
if playSpace % 12 != 0:
|
||||
if playSpace % self.COLS != 0:
|
||||
adjacentRows.append(self.s.rows[playSpace - 1])
|
||||
|
||||
if playSpace + 12 < 96:
|
||||
adjacentRows.append(self.s.rows[playSpace + 12])
|
||||
if playSpace + self.COLS < (self.COLS * self.ROWS):
|
||||
adjacentRows.append(self.s.rows[playSpace + self.COLS])
|
||||
|
||||
if playSpace - 12 > -1:
|
||||
adjacentRows.append(self.s.rows[playSpace - 12])
|
||||
if playSpace - self.COLS > -1:
|
||||
adjacentRows.append(self.s.rows[playSpace - self.COLS])
|
||||
|
||||
return adjacentRows
|
||||
|
||||
|
@ -301,10 +304,46 @@ class IshidoScored(Ishido):
|
|||
SCORING = True
|
||||
|
||||
|
||||
class LittleIshido(Ishido):
|
||||
ROWS = 6
|
||||
COLS = 8
|
||||
|
||||
def startGame(self):
|
||||
self.score = 0
|
||||
self.fourways = 0
|
||||
self.moveMove(1, self.s.talon, self.s.rows[0], frames=0)
|
||||
self.s.rows[0].flipMove()
|
||||
self.moveMove(1, self.s.talon, self.s.rows[7], frames=0)
|
||||
self.s.rows[7].flipMove()
|
||||
self.moveMove(1, self.s.talon, self.s.rows[40], frames=0)
|
||||
self.s.rows[40].flipMove()
|
||||
self.moveMove(1, self.s.talon, self.s.rows[47], frames=0)
|
||||
self.s.rows[47].flipMove()
|
||||
self.s.talon.fillStack()
|
||||
|
||||
def _shuffleHook(self, cards):
|
||||
# prepare first cards
|
||||
symbols = []
|
||||
colors = []
|
||||
topcards = []
|
||||
for c in cards[:]:
|
||||
if c.suit not in colors and c.rank not in symbols:
|
||||
topcards.append(c)
|
||||
cards.remove(c)
|
||||
symbols.append(c.rank)
|
||||
colors.append(c.suit)
|
||||
if len(colors) >= 4 or len(symbols) >= 4:
|
||||
break
|
||||
return cards + topcards
|
||||
|
||||
class LittleIshidoRelaxed(LittleIshido):
|
||||
STRICT_FOUR_WAYS = False
|
||||
|
||||
|
||||
def r(id, gameclass, name, decks, redeals, skill_level,
|
||||
game_type=GI.GT_ISHIDO):
|
||||
game_type=GI.GT_ISHIDO, colors=6):
|
||||
gi = GameInfo(id, gameclass, name, game_type, decks, redeals, skill_level,
|
||||
ranks=list(range(6)), suits=list(range(6)),
|
||||
ranks=list(range(colors)), suits=list(range(colors)),
|
||||
category=GI.GC_ISHIDO)
|
||||
registerGame(gi)
|
||||
return gi
|
||||
|
@ -316,3 +355,6 @@ r(18002, FreeIshido, 'Free Ishido', 2, 0, GI.SL_MOSTLY_SKILL)
|
|||
r(18003, FreeIshidoRelaxed, 'Free Ishido Relaxed', 2, 0, GI.SL_MOSTLY_SKILL)
|
||||
r(18004, IshidoScored, 'Ishido Scored', 2, 0, GI.SL_MOSTLY_SKILL,
|
||||
game_type=GI.GT_ISHIDO | GI.GT_SCORE)
|
||||
r(18005, LittleIshido, 'Little Ishido', 2, 0, GI.SL_MOSTLY_SKILL, colors=4)
|
||||
r(18006, LittleIshidoRelaxed, 'Little Ishido Relaxed', 2, 0,
|
||||
GI.SL_MOSTLY_SKILL, colors=4)
|
||||
|
|
|
@ -392,12 +392,12 @@ class MemorySequence(Memory24):
|
|||
|
||||
# register the game
|
||||
registerGame(GameInfo(886, Memory16, "Memory 16",
|
||||
GI.GT_MEMORY | GI.GT_SCORE, 2, 0, GI.SL_SKILL,
|
||||
category=GI.GC_MATCHING,
|
||||
GI.GT_MEMORY | GI.GT_SCORE | GI.GT_CHILDREN, 2, 0,
|
||||
GI.SL_SKILL, category=GI.GC_MATCHING,
|
||||
suits=(), ranks=(), trumps=list(range(8))))
|
||||
registerGame(GameInfo(176, Memory24, "Memory 24",
|
||||
GI.GT_MEMORY | GI.GT_SCORE, 2, 0, GI.SL_SKILL,
|
||||
category=GI.GC_MATCHING,
|
||||
GI.GT_MEMORY | GI.GT_SCORE | GI.GT_CHILDREN, 2, 0,
|
||||
GI.SL_SKILL, category=GI.GC_MATCHING,
|
||||
suits=(), ranks=(), trumps=list(range(12))))
|
||||
registerGame(GameInfo(219, Memory30, "Memory 30",
|
||||
GI.GT_MEMORY | GI.GT_SCORE, 2, 0, GI.SL_SKILL,
|
||||
|
|
|
@ -26,6 +26,8 @@ import os
|
|||
import re
|
||||
import subprocess
|
||||
import time
|
||||
from collections import OrderedDict
|
||||
|
||||
from io import BytesIO
|
||||
|
||||
from pysollib.mfxutil import destruct
|
||||
|
@ -996,6 +998,72 @@ class FreeCellSolver_Hint(Base_Solver_Hint):
|
|||
-1
|
||||
)
|
||||
|
||||
def calcBoardXML(self):
|
||||
from io import StringIO
|
||||
from xml.sax.saxutils import XMLGenerator
|
||||
game = self.game
|
||||
self.board = ''
|
||||
is_simple_simon = self._isSimpleSimon()
|
||||
b = []
|
||||
for s in game.s.foundations:
|
||||
if s.cards:
|
||||
b.append(s.cards[0 if is_simple_simon else -1])
|
||||
assert len(b) == 0
|
||||
|
||||
b = []
|
||||
for s in game.s.reserves:
|
||||
b.append((s.cards[-1]) if s.cards else None)
|
||||
assert all(x is None for x in b)
|
||||
|
||||
nextid = 1
|
||||
ids = {}
|
||||
out = StringIO("")
|
||||
xmler = XMLGenerator(out=out, encoding='UTF-8')
|
||||
xmler.startDocument()
|
||||
xmler.startElement(name='state', attrs={})
|
||||
for row_idx, s in enumerate(game.s.rows):
|
||||
moveattrs = []
|
||||
moveattrs.append(('pile', 'store{}'.format(row_idx)))
|
||||
moveattrs.append(('position', '{}'.format(0)))
|
||||
moveattrs.sort()
|
||||
dmoveattrs = OrderedDict(moveattrs)
|
||||
|
||||
xmler.startElement(name='move', attrs=dmoveattrs)
|
||||
b = []
|
||||
for c in s.cards:
|
||||
cardattrs = []
|
||||
cs = self.card2str1(c)
|
||||
if cs in ids:
|
||||
this_id = ids[cs]
|
||||
else:
|
||||
this_id = nextid
|
||||
nextid += 1
|
||||
ids[cs] = this_id
|
||||
cardattrs.append(('id', '{}'.format(this_id)))
|
||||
this_rank = [
|
||||
"ace", "two", "three", "four", "five", "six", "seven",
|
||||
"eight", "nine", "ten", "jack", "queen", "king"
|
||||
][c.rank]
|
||||
cardattrs.append(('rank', '{}'.format(this_rank)))
|
||||
this_suit = [
|
||||
"clubs", "spades", "hearts", "diamonds",
|
||||
][c.suit]
|
||||
cardattrs.append(('suit', '{}'.format(this_suit)))
|
||||
cardattrs.append(('turn', '{}'.format("face-up")))
|
||||
cardattrs.sort()
|
||||
dcardattrs = OrderedDict(cardattrs)
|
||||
|
||||
xmler.startElement(name='card', attrs=dcardattrs)
|
||||
if not c.face_up:
|
||||
cs = '<%s>' % cs
|
||||
xmler.endElement(name='card')
|
||||
xmler.endElement(name='move')
|
||||
xmler.endElement(name='state')
|
||||
xmler.endDocument()
|
||||
|
||||
ret = out.getvalue()
|
||||
return ret
|
||||
|
||||
def calcBoardString(self):
|
||||
game = self.game
|
||||
self.board = ''
|
||||
|
|
|
@ -377,7 +377,7 @@ class TreeFormatter(PysolStatsFormatter):
|
|||
return 1
|
||||
|
||||
def writeLog(self, player, prev_games, sort_by='date'):
|
||||
if not player or not prev_games:
|
||||
if not prev_games:
|
||||
return 0
|
||||
num_rows = 0
|
||||
results = self.getLogResults(player, prev_games)
|
||||
|
@ -520,6 +520,8 @@ class LogDialog(MfxDialog):
|
|||
|
||||
kw = self.initKw(kw)
|
||||
title = _('Log')
|
||||
if player is None:
|
||||
title = _('Demo Log')
|
||||
MfxDialog.__init__(self, parent, title, kw.resizable, kw.default)
|
||||
|
||||
self.top.wm_minsize(400, 200)
|
||||
|
|
|
@ -620,6 +620,9 @@ class PysolMenubarTkCommon:
|
|||
menu.add_command(
|
||||
label=n_("Log..."),
|
||||
command=lambda: self.mPlayerStats(mode=103))
|
||||
menu.add_command(
|
||||
label=n_("Demo Log..."),
|
||||
command=lambda: self.mPlayerStats(mode=1103))
|
||||
menu.add_separator()
|
||||
menu.add_command(
|
||||
label=n_("&Comments..."),
|
||||
|
|
|
@ -50,6 +50,24 @@ class ImportFileTests(unittest.TestCase):
|
|||
def _successful_import(self, fn, want_s, blurb):
|
||||
self.assertEqual(self._calc_hint(fn).calcBoardString(), want_s, blurb)
|
||||
|
||||
def _successful_import__XML_test(self, fn, expected_regex, blurb):
|
||||
hint = self._calc_hint(fn)
|
||||
xml_output = hint.calcBoardXML()
|
||||
# import sys
|
||||
# print(xml_output, file=sys.stderr)
|
||||
self.assertRegex(
|
||||
text=xml_output, expected_regex=expected_regex, msg=blurb)
|
||||
|
||||
def test_import_XML(self):
|
||||
return self._successful_import__XML_test(
|
||||
fn='tests/unit/data/with-10-for-rank.txt',
|
||||
expected_regex=(
|
||||
'''<state><move pile="store0" position="0">'''
|
||||
'''<card id="[0-9]+" rank="four"'''
|
||||
''' suit="clubs" turn="face-up"></card>'''
|
||||
),
|
||||
blurb='xml import worked')
|
||||
|
||||
def test_import(self):
|
||||
return self._successful_import('tests/unit/data/with-10-for-rank.txt',
|
||||
'''FC: - - - -
|
||||
|
|
Loading…
Add table
Reference in a new issue