1
0
Fork 0
mirror of https://github.com/shlomif/PySolFC.git synced 2025-04-05 00:02:29 -04:00

Compare commits

...

5 commits

Author SHA1 Message Date
Joe R
054c0f0368 Enable log for demo games 2025-01-28 23:32:15 -05:00
Joe R
487d1c52f3 Use Python 3.13 in AppVeyor 2025-01-28 19:38:23 -05:00
Joe R
6852bb40ff Add Little Ishido game 2025-01-24 21:58:56 -05:00
Joe R
6006e0f4c0 Shift children's games to use tag rather than deprecated list 2025-01-24 20:03:08 -05:00
Joe R
68138c7284 Add Colours game 2025-01-23 18:01:20 -05:00
25 changed files with 220 additions and 53 deletions

View file

@ -2,7 +2,7 @@
image: Visual Studio 2022 image: Visual Studio 2022
environment: environment:
matrix: matrix:
- PYTHON: "C:\\Python312" - PYTHON: "C:\\Python313"
# Shamelessly taken from https://github.com/plicease/Dist-Zilla-PluginBundle-Author-Plicease/blob/master/.appveyor.yml # Shamelessly taken from https://github.com/plicease/Dist-Zilla-PluginBundle-Author-Plicease/blob/master/.appveyor.yml
# Thanks! # Thanks!
install: install:

View 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.

View 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.

View 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.

View file

@ -4370,6 +4370,9 @@ msgstr "Aktuelle Sitzung"
msgid "Log" msgid "Log"
msgstr "Protokoll" msgstr "Protokoll"
msgid "Demo Log"
msgstr ""
#: pysollib/tile/tkstats.py:523 data/pysolfc.glade:1404 #: pysollib/tile/tkstats.py:523 data/pysolfc.glade:1404
msgid "Full log" msgid "Full log"
msgstr "Volles Protokoll" msgstr "Volles Protokoll"
@ -5171,6 +5174,9 @@ msgstr "Kommentare..."
msgid "Log..." msgid "Log..."
msgstr "" msgstr ""
msgid "Demo Log..."
msgstr ""
#: pysollib/ui/tktile/menubar.py:427 #: pysollib/ui/tktile/menubar.py:427
msgid "D&emo statistics..." msgid "D&emo statistics..."
msgstr "D&emo Statistiken..." msgstr "D&emo Statistiken..."

View file

@ -4421,6 +4421,9 @@ msgstr "Session en cours"
msgid "Log" msgid "Log"
msgstr "Journal" msgstr "Journal"
msgid "Demo Log"
msgstr ""
#: pysollib/tile/tkstats.py:523 data/pysolfc.glade:1404 #: pysollib/tile/tkstats.py:523 data/pysolfc.glade:1404
msgid "Full log" msgid "Full log"
msgstr "Journal complet" msgstr "Journal complet"
@ -5222,6 +5225,9 @@ msgstr "&Commentaires..."
msgid "Log..." msgid "Log..."
msgstr "Journal..." msgstr "Journal..."
msgid "Demo Log..."
msgstr ""
#: pysollib/ui/tktile/menubar.py:427 #: pysollib/ui/tktile/menubar.py:427
msgid "D&emo statistics..." msgid "D&emo statistics..."
msgstr "Statistiques d&émo..." msgstr "Statistiques d&émo..."

View file

@ -4485,6 +4485,9 @@ msgstr "Questa sessione"
msgid "Log" msgid "Log"
msgstr "Log" msgstr "Log"
msgid "Demo Log"
msgstr ""
#: pysollib/tile/tkstats.py:523 data/pysolfc.glade:1404 #: pysollib/tile/tkstats.py:523 data/pysolfc.glade:1404
msgid "Full log" msgid "Full log"
msgstr "Log completo" msgstr "Log completo"
@ -5288,6 +5291,9 @@ msgstr "&Commenti..."
msgid "Log..." msgid "Log..."
msgstr "Log..." msgstr "Log..."
msgid "Demo Log..."
msgstr ""
#: pysollib/ui/tktile/menubar.py:427 #: pysollib/ui/tktile/menubar.py:427
msgid "D&emo statistics..." msgid "D&emo statistics..."
msgstr "Statistiche d&emo..." msgstr "Statistiche d&emo..."

View file

@ -4438,6 +4438,9 @@ msgstr "Bieżąca sesja"
msgid "Log" msgid "Log"
msgstr "Log" msgstr "Log"
msgid "Demo Log"
msgstr ""
#: pysollib/tile/tkstats.py:523 data/pysolfc.glade:1404 #: pysollib/tile/tkstats.py:523 data/pysolfc.glade:1404
msgid "Full log" msgid "Full log"
msgstr "Kompletny log" msgstr "Kompletny log"
@ -5242,6 +5245,9 @@ msgstr "Komentarze..."
msgid "Log..." msgid "Log..."
msgstr "Log..." msgstr "Log..."
msgid "Demo Log..."
msgstr ""
#: pysollib/ui/tktile/menubar.py:427 #: pysollib/ui/tktile/menubar.py:427
msgid "D&emo statistics..." msgid "D&emo statistics..."
msgstr "D&emo statystyk..." msgstr "D&emo statystyk..."

View file

@ -4444,6 +4444,9 @@ msgstr "Sessão atual"
msgid "Log" msgid "Log"
msgstr "registro" msgstr "registro"
msgid "Demo Log"
msgstr ""
#: pysollib/tile/tkstats.py:523 data/pysolfc.glade:1404 #: pysollib/tile/tkstats.py:523 data/pysolfc.glade:1404
msgid "Full log" msgid "Full log"
msgstr "Registro completo" msgstr "Registro completo"
@ -5244,6 +5247,9 @@ msgstr "&Comentários..."
msgid "Log..." msgid "Log..."
msgstr "Registro" msgstr "Registro"
msgid "Demo Log..."
msgstr ""
#: pysollib/ui/tktile/menubar.py:427 #: pysollib/ui/tktile/menubar.py:427
msgid "D&emo statistics..." msgid "D&emo statistics..."
msgstr "Estatísticas de D&emo..." msgstr "Estatísticas de D&emo..."

View file

@ -4224,6 +4224,9 @@ msgstr ""
msgid "Log" msgid "Log"
msgstr "" msgstr ""
msgid "Demo Log"
msgstr ""
#: pysollib/tile/tkstats.py:523 data/pysolfc.glade:1404 #: pysollib/tile/tkstats.py:523 data/pysolfc.glade:1404
msgid "Full log" msgid "Full log"
msgstr "" msgstr ""
@ -4974,6 +4977,9 @@ msgstr ""
msgid "Log..." msgid "Log..."
msgstr "" msgstr ""
msgid "Demo Log..."
msgstr ""
#: pysollib/ui/tktile/menubar.py:427 #: pysollib/ui/tktile/menubar.py:427
msgid "D&emo statistics..." msgid "D&emo statistics..."
msgstr "" msgstr ""

View file

@ -4494,6 +4494,9 @@ msgstr "Текущая сессия"
msgid "Log" msgid "Log"
msgstr "Лог" msgstr "Лог"
msgid "Demo Log"
msgstr ""
#: pysollib/tile/tkstats.py:523 data/pysolfc.glade:1404 #: pysollib/tile/tkstats.py:523 data/pysolfc.glade:1404
msgid "Full log" msgid "Full log"
msgstr "Полный лог" msgstr "Полный лог"
@ -5311,6 +5314,9 @@ msgstr "&Комментарии..."
msgid "Log..." msgid "Log..."
msgstr "Лог..." msgstr "Лог..."
msgid "Demo Log..."
msgstr ""
#: pysollib/ui/tktile/menubar.py:427 #: pysollib/ui/tktile/menubar.py:427
msgid "D&emo statistics..." msgid "D&emo statistics..."
msgstr "Статистика демо..." msgstr "Статистика демо..."

View file

@ -115,18 +115,13 @@ class Statistics:
game.GAME_VERSION) game.GAME_VERSION)
# full log # full log
if status >= 0: if status >= 0:
if player is None: if player not in self.prev_games:
# demo self.prev_games[player] = []
ret = self.updateGameStat(player, game, status) self.prev_games[player].append(log)
else: if player not in self.all_prev_games:
# player self.all_prev_games[player] = []
if player not in self.prev_games: self.all_prev_games[player].append(log)
self.prev_games[player] = [] ret = self.updateGameStat(player, game, status)
self.prev_games[player].append(log)
if player not in self.all_prev_games:
self.all_prev_games[player] = []
self.all_prev_games[player].append(log)
ret = self.updateGameStat(player, game, status)
# session log # session log
if player not in self.session_games: if player not in self.session_games:
self.session_games[player] = [] self.session_games[player] = []

View file

@ -595,13 +595,12 @@ class GI:
tuple(range(19000, 19012)) + tuple(range(22303, 22311)) + tuple(range(19000, 19012)) + tuple(range(22303, 22311)) +
tuple(range(22353, 22361))), tuple(range(22353, 22361))),
('fc-3.1', tuple(range(961, 971))), ('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 # deprecated - the correct way is to or a GI.GT_XXX flag
# in the registerGame() call # in the registerGame() call
_CHILDREN_GAMES = [16, 33, 55, 90, 91, 96, 97, 176, 328, 329, 862, 865, _CHILDREN_GAMES = []
886, 903, ]
_OPEN_GAMES = [] _OPEN_GAMES = []

View file

@ -504,7 +504,7 @@ class MaineCoon(TabbyCat):
# register the game # register the game
registerGame(GameInfo(903, AcesUp, "Aces Up", # was: 52 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"))) altnames=("Aces High", "Drivel", "Discard")))
registerGame(GameInfo(206, Fortunes, "Fortunes", registerGame(GameInfo(206, Fortunes, "Fortunes",
GI.GT_1DECK_TYPE, 1, 0, GI.SL_LUCK)) 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, GI.GT_1DECK_TYPE, 1, -1, GI.SL_MOSTLY_LUCK,
altnames=("First Law", "Narcotic"))) altnames=("First Law", "Narcotic")))
registerGame(GameInfo(353, AcesUp5, "Aces Up 5", 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", registerGame(GameInfo(552, Cover, "Cover",
GI.GT_1DECK_TYPE, 1, 0, GI.SL_LUCK)) GI.GT_1DECK_TYPE, 1, 0, GI.SL_LUCK))
registerGame(GameInfo(583, FiringSquad, "Firing Squad", registerGame(GameInfo(583, FiringSquad, "Firing Squad",

View file

@ -105,6 +105,7 @@ class StrictEiffelTower(EiffelTower):
# register the game # register the game
registerGame(GameInfo(16, EiffelTower, "Eiffel Tower", 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", # registerGame(GameInfo(801, StrictEiffelTower, "Strict Eiffel Tower",
# GI.GT_PAIRING_TYPE, 2, 0)) # GI.GT_PAIRING_TYPE, 2, 0))

View file

@ -776,11 +776,11 @@ registerGame(GameInfo(697, BigBen, "Big Ben",
GI.GT_2DECK_TYPE, 2, 0, GI.SL_BALANCED, GI.GT_2DECK_TYPE, 2, 0, GI.SL_BALANCED,
altnames=("Father Time"))) altnames=("Father Time")))
registerGame(GameInfo(737, Clock, "Clock", 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"))) altnames=("Travellers", "Sundial")))
registerGame(GameInfo(827, GermanClock, "German Clock", registerGame(GameInfo(827, GermanClock, "German Clock",
GI.GT_1DECK_TYPE, 1, 1, GI.SL_MOSTLY_LUCK, GI.GT_1DECK_TYPE, 1, 1, GI.SL_MOSTLY_LUCK,
altnames=("Die Uhr",))) altnames=("Die Uhr",)))
registerGame(GameInfo(915, RelaxedClock, "Relaxed Clock", registerGame(GameInfo(915, RelaxedClock, "Relaxed Clock",
GI.GT_1DECK_TYPE | GI.GT_RELAXED, 1, 0, GI.SL_LUCK, GI.GT_1DECK_TYPE | GI.GT_RELAXED | GI.GT_CHILDREN, 1, 0,
altnames=("Watch"))) GI.SL_LUCK, altnames=("Watch")))

View file

@ -170,5 +170,5 @@ registerGame(GameInfo(774, HitOrMiss, "Hit or Miss",
GI.GT_1DECK_TYPE, 1, VARIABLE_REDEALS, GI.GT_1DECK_TYPE, 1, VARIABLE_REDEALS,
GI.SL_LUCK, altnames=("Roll Call",))) GI.SL_LUCK, altnames=("Roll Call",)))
registerGame(GameInfo(865, HitOrMissUnlimited, "Hit or Miss Unlimited", 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)) GI.SL_LUCK))

View file

@ -1640,7 +1640,8 @@ registerGame(GameInfo(66, Eastcliff, "Eastcliff",
registerGame(GameInfo(224, Easthaven, "Easthaven", registerGame(GameInfo(224, Easthaven, "Easthaven",
GI.GT_GYPSY, 1, 0, GI.SL_MOSTLY_LUCK)) GI.GT_GYPSY, 1, 0, GI.SL_MOSTLY_LUCK))
registerGame(GameInfo(33, Westcliff, "Westcliff", 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", registerGame(GameInfo(225, Westhaven, "Westhaven",
GI.GT_GYPSY, 1, 0, GI.SL_BALANCED)) GI.GT_GYPSY, 1, 0, GI.SL_BALANCED))
registerGame(GameInfo(107, PasSeul, "Pas Seul", registerGame(GameInfo(107, PasSeul, "Pas Seul",

View file

@ -1118,15 +1118,16 @@ registerGame(GameInfo(216, MonteCarlo2Decks, "Monte Carlo (2 Decks)",
registerGame(GameInfo(212, Weddings, "Weddings", registerGame(GameInfo(212, Weddings, "Weddings",
GI.GT_PAIRING_TYPE, 1, 0, GI.SL_MOSTLY_LUCK)) GI.GT_PAIRING_TYPE, 1, 0, GI.SL_MOSTLY_LUCK))
registerGame(GameInfo(90, SimpleCarlo, "Simple Carlo", 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", registerGame(GameInfo(91, SimplePairs, "Simple Pairs",
GI.GT_PAIRING_TYPE, 1, 0, GI.SL_LUCK, GI.GT_PAIRING_TYPE | GI.GT_CHILDREN, 1, 0,
altnames=("Jamestown", "Pirate Gold", "Treasure Hunt", GI.SL_LUCK, altnames=("Jamestown", "Pirate Gold",
"Hunter"))) "Treasure Hunt", "Hunter")))
registerGame(GameInfo(92, Neighbour, "Neighbour", registerGame(GameInfo(92, Neighbour, "Neighbour",
GI.GT_PAIRING_TYPE, 1, 0, GI.SL_MOSTLY_LUCK)) GI.GT_PAIRING_TYPE, 1, 0, GI.SL_MOSTLY_LUCK))
registerGame(GameInfo(96, Fourteen, "Fourteen", 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", GI.SL_MOSTLY_LUCK, altnames=("Fourteen Out",
"Fourteen Puzzle", "Fourteen Puzzle",
"Take Fourteen"))) "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, GI.GT_1DECK_TYPE | GI.GT_OPEN, 1, 0, GI.SL_MOSTLY_SKILL,
altnames=("Der letzte Monarch",))) altnames=("Der letzte Monarch",)))
registerGame(GameInfo(328, TheWish, "The Wish", registerGame(GameInfo(328, TheWish, "The Wish",
GI.GT_PAIRING_TYPE | GI.GT_STRIPPED, 1, 0, GI.GT_PAIRING_TYPE | GI.GT_STRIPPED | GI.GT_CHILDREN,
GI.SL_MOSTLY_LUCK, ranks=(0, 6, 7, 8, 9, 10, 11, 12))) 1, 0, GI.SL_MOSTLY_LUCK,
ranks=(0, 6, 7, 8, 9, 10, 11, 12)))
registerGame(GameInfo(329, TheWishOpen, "The Wish (Open)", registerGame(GameInfo(329, TheWishOpen, "The Wish (Open)",
GI.GT_PAIRING_TYPE | GI.GT_OPEN | GI.GT_ORIGINAL | GI.GT_PAIRING_TYPE | GI.GT_OPEN | GI.GT_ORIGINAL |
GI.GT_STRIPPED, 1, 0, GI.SL_MOSTLY_SKILL, GI.GT_STRIPPED | GI.GT_CHILDREN, 1, 0,
ranks=(0, 6, 7, 8, 9, 10, 11, 12), GI.SL_MOSTLY_SKILL, ranks=(0, 6, 7, 8, 9, 10, 11, 12),
rules_filename="thewish.html")) rules_filename="thewish.html"))
registerGame(GameInfo(368, Vertical, "Vertical", registerGame(GameInfo(368, Vertical, "Vertical",
GI.GT_PAIRING_TYPE | GI.GT_OPEN, 1, 0, GI.GT_PAIRING_TYPE | GI.GT_OPEN, 1, 0,
@ -1162,8 +1164,8 @@ registerGame(GameInfo(810, Quatorze, "Quatorze",
registerGame(GameInfo(829, BlockTen, "Block Ten", registerGame(GameInfo(829, BlockTen, "Block Ten",
GI.GT_PAIRING_TYPE, 1, 0, GI.SL_LUCK)) GI.GT_PAIRING_TYPE, 1, 0, GI.SL_LUCK))
registerGame(GameInfo(862, SimpleTens, "Simple Tens", registerGame(GameInfo(862, SimpleTens, "Simple Tens",
GI.GT_PAIRING_TYPE | GI.GT_STRIPPED, 1, 0, GI.SL_LUCK, GI.GT_PAIRING_TYPE | GI.GT_STRIPPED | GI.GT_CHILDREN,
ranks=(0, 1, 2, 3, 4, 5, 6, 7, 8), 1, 0, GI.SL_LUCK, ranks=(0, 1, 2, 3, 4, 5, 6, 7, 8),
altnames=("Add Up Tens",))) altnames=("Add Up Tens",)))
registerGame(GameInfo(867, DoubleFourteen, "Double Fourteen", registerGame(GameInfo(867, DoubleFourteen, "Double Fourteen",
GI.GT_PAIRING_TYPE | GI.GT_OPEN, 2, 0, GI.GT_PAIRING_TYPE | GI.GT_OPEN, 2, 0,

View file

@ -41,6 +41,7 @@ from pysollib.stack import \
RK_FoundationStack, \ RK_FoundationStack, \
RK_RowStack, \ RK_RowStack, \
ReserveStack, \ ReserveStack, \
SC_FoundationStack, \
SS_FoundationStack, \ SS_FoundationStack, \
Stack, \ Stack, \
StackWrapper, \ StackWrapper, \
@ -176,6 +177,7 @@ class Numerica2Decks(Numerica):
# ************************************************************************ # ************************************************************************
# * Lady Betty # * Lady Betty
# * Last Chance # * Last Chance
# * Colours
# ************************************************************************ # ************************************************************************
class LadyBetty(Numerica): class LadyBetty(Numerica):
@ -215,6 +217,40 @@ class LastChance(LadyBetty):
self.s.talon.dealCards() 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 # * Puss in the Corner
# ************************************************************************ # ************************************************************************
@ -1460,3 +1496,5 @@ registerGame(GameInfo(931, TheBogey, "The Bogey",
GI.GT_1DECK_TYPE, 1, -1, GI.SL_BALANCED)) GI.GT_1DECK_TYPE, 1, -1, GI.SL_BALANCED))
registerGame(GameInfo(958, NinetyOne, "Ninety-One", registerGame(GameInfo(958, NinetyOne, "Ninety-One",
GI.GT_1DECK_TYPE, 1, 0, GI.SL_MOSTLY_SKILL)) GI.GT_1DECK_TYPE, 1, 0, GI.SL_MOSTLY_SKILL))
registerGame(GameInfo(972, Colours, "Colours",
GI.GT_NUMERICA, 1, 0, GI.SL_BALANCED))

View file

@ -1573,13 +1573,14 @@ registerGame(GameInfo(54, RoyalCotillion, "Royal Cotillion",
GI.GT_2DECK_TYPE, 2, 0, GI.SL_LUCK, GI.GT_2DECK_TYPE, 2, 0, GI.SL_LUCK,
altnames=("Lords and Ladies",))) altnames=("Lords and Ladies",)))
registerGame(GameInfo(55, OddAndEven, "Odd and Even", 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", registerGame(GameInfo(143, Kingdom, "Kingdom",
GI.GT_2DECK_TYPE, 2, 0, GI.SL_MOSTLY_LUCK)) GI.GT_2DECK_TYPE, 2, 0, GI.SL_MOSTLY_LUCK))
registerGame(GameInfo(234, Alhambra, "Alhambra", registerGame(GameInfo(234, Alhambra, "Alhambra",
GI.GT_2DECK_TYPE, 2, 2, GI.SL_BALANCED)) GI.GT_2DECK_TYPE, 2, 2, GI.SL_BALANCED))
registerGame(GameInfo(97, Carpet, "Carpet", 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", registerGame(GameInfo(391, BritishConstitution, "British Constitution",
GI.GT_2DECK_TYPE | GI.GT_STRIPPED, 2, 0, GI.SL_BALANCED, GI.GT_2DECK_TYPE | GI.GT_STRIPPED, 2, 0, GI.SL_BALANCED,
ranks=list(range(11)), # without Queens and Kings ranks=list(range(11)), # without Queens and Kings

View file

@ -99,6 +99,9 @@ class Ishido(Game):
STRICT_FOUR_WAYS = True STRICT_FOUR_WAYS = True
SCORING = False SCORING = False
COLS = 12
ROWS = 8
# #
# game layout # game layout
# #
@ -115,13 +118,13 @@ class Ishido(Game):
w2 = max(2 * l.XS, x) w2 = max(2 * l.XS, x)
# set window # 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) self.setSize(w, h)
# Create rows # Create rows
for j in range(8): for j in range(self.ROWS):
x, y = w2 + l.XM, l.YM + l.CH * j 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)) s.rows.append(self.RowStack_Class(x, y, self))
x = x + l.CW x = x + l.CW
@ -269,17 +272,17 @@ class Ishido(Game):
def getAdjacent(self, playSpace): def getAdjacent(self, playSpace):
adjacentRows = [] adjacentRows = []
if playSpace % 12 != 11: if playSpace % self.COLS != self.COLS - 1:
adjacentRows.append(self.s.rows[playSpace + 1]) adjacentRows.append(self.s.rows[playSpace + 1])
if playSpace % 12 != 0: if playSpace % self.COLS != 0:
adjacentRows.append(self.s.rows[playSpace - 1]) adjacentRows.append(self.s.rows[playSpace - 1])
if playSpace + 12 < 96: if playSpace + self.COLS < (self.COLS * self.ROWS):
adjacentRows.append(self.s.rows[playSpace + 12]) adjacentRows.append(self.s.rows[playSpace + self.COLS])
if playSpace - 12 > -1: if playSpace - self.COLS > -1:
adjacentRows.append(self.s.rows[playSpace - 12]) adjacentRows.append(self.s.rows[playSpace - self.COLS])
return adjacentRows return adjacentRows
@ -301,10 +304,46 @@ class IshidoScored(Ishido):
SCORING = True 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, 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, 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) category=GI.GC_ISHIDO)
registerGame(gi) registerGame(gi)
return 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(18003, FreeIshidoRelaxed, 'Free Ishido Relaxed', 2, 0, GI.SL_MOSTLY_SKILL)
r(18004, IshidoScored, 'Ishido Scored', 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) 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)

View file

@ -392,12 +392,12 @@ class MemorySequence(Memory24):
# register the game # register the game
registerGame(GameInfo(886, Memory16, "Memory 16", registerGame(GameInfo(886, Memory16, "Memory 16",
GI.GT_MEMORY | GI.GT_SCORE, 2, 0, GI.SL_SKILL, GI.GT_MEMORY | GI.GT_SCORE | GI.GT_CHILDREN, 2, 0,
category=GI.GC_MATCHING, GI.SL_SKILL, category=GI.GC_MATCHING,
suits=(), ranks=(), trumps=list(range(8)))) suits=(), ranks=(), trumps=list(range(8))))
registerGame(GameInfo(176, Memory24, "Memory 24", registerGame(GameInfo(176, Memory24, "Memory 24",
GI.GT_MEMORY | GI.GT_SCORE, 2, 0, GI.SL_SKILL, GI.GT_MEMORY | GI.GT_SCORE | GI.GT_CHILDREN, 2, 0,
category=GI.GC_MATCHING, GI.SL_SKILL, category=GI.GC_MATCHING,
suits=(), ranks=(), trumps=list(range(12)))) suits=(), ranks=(), trumps=list(range(12))))
registerGame(GameInfo(219, Memory30, "Memory 30", registerGame(GameInfo(219, Memory30, "Memory 30",
GI.GT_MEMORY | GI.GT_SCORE, 2, 0, GI.SL_SKILL, GI.GT_MEMORY | GI.GT_SCORE, 2, 0, GI.SL_SKILL,

View file

@ -377,7 +377,7 @@ class TreeFormatter(PysolStatsFormatter):
return 1 return 1
def writeLog(self, player, prev_games, sort_by='date'): def writeLog(self, player, prev_games, sort_by='date'):
if not player or not prev_games: if not prev_games:
return 0 return 0
num_rows = 0 num_rows = 0
results = self.getLogResults(player, prev_games) results = self.getLogResults(player, prev_games)
@ -520,6 +520,8 @@ class LogDialog(MfxDialog):
kw = self.initKw(kw) kw = self.initKw(kw)
title = _('Log') title = _('Log')
if player is None:
title = _('Demo Log')
MfxDialog.__init__(self, parent, title, kw.resizable, kw.default) MfxDialog.__init__(self, parent, title, kw.resizable, kw.default)
self.top.wm_minsize(400, 200) self.top.wm_minsize(400, 200)

View file

@ -620,6 +620,9 @@ class PysolMenubarTkCommon:
menu.add_command( menu.add_command(
label=n_("Log..."), label=n_("Log..."),
command=lambda: self.mPlayerStats(mode=103)) command=lambda: self.mPlayerStats(mode=103))
menu.add_command(
label=n_("Demo Log..."),
command=lambda: self.mPlayerStats(mode=1103))
menu.add_separator() menu.add_separator()
menu.add_command( menu.add_command(
label=n_("&Comments..."), label=n_("&Comments..."),