From bef82cb03bf46e255deed371990bac72624607fa Mon Sep 17 00:00:00 2001 From: Joe R Date: Thu, 27 Jul 2023 17:57:17 -0400 Subject: [PATCH] Version 7 of the cardset format with subtype and joker support. --- contrib/customize_cardset.asciidoc | 7 ++- data/images/cards/finder/french/01z.gif | Bin 0 -> 310 bytes data/images/cards/finder/french/01z.png | Bin 0 -> 382 bytes data/images/cards/finder/french/02z.gif | Bin 0 -> 305 bytes data/images/cards/finder/french/02z.png | Bin 0 -> 363 bytes html-src/cardset_customization.html | 9 ++- html-src/glossary.html | 3 +- html-src/rules/thieves.html | 14 +++++ pysollib/app.py | 55 ++++++++++++------ pysollib/cardsetparser.py | 14 +++++ pysollib/gamedb.py | 16 +++-- pysollib/games/golf.py | 14 +++++ pysollib/games/mahjongg/mahjongg.py | 2 +- pysollib/games/mahjongg/shisensho.py | 4 +- pysollib/main.py | 2 +- pysollib/options.py | 74 ++++++++++++++---------- pysollib/pysolgtk/selectgame.py | 13 +++-- pysollib/resource.py | 13 ++++- pysollib/tile/selectgame.py | 13 +++-- pysollib/tk/selectgame.py | 13 +++-- 20 files changed, 187 insertions(+), 79 deletions(-) create mode 100644 data/images/cards/finder/french/01z.gif create mode 100644 data/images/cards/finder/french/01z.png create mode 100644 data/images/cards/finder/french/02z.gif create mode 100644 data/images/cards/finder/french/02z.png create mode 100644 html-src/rules/thieves.html diff --git a/contrib/customize_cardset.asciidoc b/contrib/customize_cardset.asciidoc index b146f11cc2..1807da8c52 100644 --- a/contrib/customize_cardset.asciidoc +++ b/contrib/customize_cardset.asciidoc @@ -8,7 +8,7 @@ config.txt template ------------------- .... -PySolFC solitaire cardset;$A;$FMT;$B;$C;$D,$E;$F +PySolFC solitaire cardset;$A;$FMT;$B;$C;$D,$E;$F;$G;$H ; X Y D XOFF YOFF SXOFF SYOFF @@ -21,7 +21,7 @@ Line 1 *$A:* The cardset version number that belongs to the number of fields divided through ";" on the first line (e.g. `.gif;1;78;8,1016` -> `$A=4`) -( *WARNING:* For Mahjongg, $A must always be 6 and the $F field must be included in the line; however, you can put `0` in `$F` if you wish, in that case. ) +( *WARNING:* For Mahjongg, $A must always be 6 or 7 and the $F field must be included in the line; however, you can put `0` in `$F` if you wish, in that case. ) ( *NOTE:* $D and $E are comma separated and count for one field ) @@ -112,6 +112,9 @@ Cardsets Origins: *$F:* The Year the cardset was created (in the range 1000 to 2299) +*$G:* The subtype of the cardset. Usually 0 - for French type cardsets, a value of 1 is used if there are jokers. + +*$H:* Whether the cardset is a 3D Mahjongg cardset - 1 if it is, 0 if it isn't. For cardsets with a version less than 7, version 6 cardsets treat this value as 1, and older version cardsets treat it as 0. Line 2 ------ diff --git a/data/images/cards/finder/french/01z.gif b/data/images/cards/finder/french/01z.gif new file mode 100644 index 0000000000000000000000000000000000000000..20470649971153f5ee9b5ec175a5f6dd1cf20a78 GIT binary patch literal 310 zcmV-60m=SHNk%w1VI}|~0B`^RA^8LW000I6EC2ui044w;0D=Gj0RH~||NsAhfPkQ& zq`<(y00000000B~Xt3P=FseYSy*TToyYJj5is5Kx<*8EXdbaKepMntBT3rrIKr90m zg9jK0907+8U;!qJ0D^FOEDoeVVztTqT|*r2Z9%9#v4Cxb!wZ6$JW91}d#k79XW_{o zN6mIA91DAdXGL;kfJ{$!e1>^IQHg(bj0=u~lTHm4b2U{1T7qeih@F&}RSlV?0EMRv zQhuUKKxL$7Pi{k$bfHX3TzbTkjGs$CXr`&p;zYK%7_74HAJF{NP&zoH*y|k_yf^zAc=wo10qbgVIe~d0w1nX5TT+) I2?+oIJ8>#~I{*Lx literal 0 HcmV?d00001 diff --git a/data/images/cards/finder/french/01z.png b/data/images/cards/finder/french/01z.png new file mode 100644 index 0000000000000000000000000000000000000000..99af335e4fc3a330f7408341d8f08cb7582f82ab GIT binary patch literal 382 zcmeAS@N?(olHy`uVBq!ia0vp^YCx>S!3-o>ilV!K6k~CayA#8@b22YMV(E^)jtmSN z`?>!lvI6;{0X`wFK>FXmfB*mgZ)j*(uwco70|$U2XBrc404es8AirRs6c8{-c{95K zg*Xd5B8wRq_zr_G3PGN@v;N{RbZ%db#V}fsl#ZhbL%mFu%6Mb?Gwe zt4T@wmaBc=DG;%50=M$6qRG31W`tf?(HK+mX4}WI-=AA!5{iGbe0ye|ahyNwD9Z^U T)iqW?uQGVL`njxgN@xNA96FnF literal 0 HcmV?d00001 diff --git a/data/images/cards/finder/french/02z.gif b/data/images/cards/finder/french/02z.gif new file mode 100644 index 0000000000000000000000000000000000000000..7041320f093c36f0efb710e6b013a803b2d5be83 GIT binary patch literal 305 zcmV-10nYwMNk%w1VI}|~0B`^RA^8LW000I6EC2ui044w;0D=Gj0RH~||NsB}005w% zq`<(y00000000B_Xt3P=FseYSy*TToyYJj5is5Kx<*8EXdbaKepMntBT3rtOK=FiM zZzvf0j5>gYCj<(g#Q|X&01|kD6!RKnR(;$XuTc9IzFB33IsQJqQL@d8)gA|DC)+2+ zm+1p(OLuvAUtxW6ZfJIgjzbl3e|&XnZ-#n3kz+McQ4AoSFZ1!@1IhrckMGYr5^b)AeR1Q01Wt{AHfR-4^~L1FaQ7r5h6;IkN^NX D$pL`) literal 0 HcmV?d00001 diff --git a/data/images/cards/finder/french/02z.png b/data/images/cards/finder/french/02z.png new file mode 100644 index 0000000000000000000000000000000000000000..8c2a21874b6bec74b87e40a1caad5e78b65f9371 GIT binary patch literal 363 zcmeAS@N?(olHy`uVBq!ia0vp^YCx>S!3-o>ilV!K6k~CayA#8@b22YMV(E^)jtmSN z`?>!lvI6;{0X`wFK>FXmfB*mg|I5IzV8N0D2Mz#5o;Tc$0aENGL4LtNDIj2w@@94e z3UL;AL>4nJ@ErzW#^d=bQh*s&}b8-e(FE07IHFXN( z-G__RZg14(xUf%Q!qs0I^*uA+hWT1{?iI-N4^CQmd9T49mZombXYV5374R0%=sLlo zo#JL}ts}n5(^h=hRL<^>`x_lX9~q0W8gJb?VawqQ&dZIDmA!D+$u9O^Go>xF@<3Kl z->+?~T`xB*x^w7LTU1c5?&t;ucLK6U0NsX}p literal 0 HcmV?d00001 diff --git a/html-src/cardset_customization.html b/html-src/cardset_customization.html index 30182c43b2..3ffdcd261c 100644 --- a/html-src/cardset_customization.html +++ b/html-src/cardset_customization.html @@ -1,6 +1,6 @@

Cardset Customization Tutorial

config.txt template

-
PySolFC solitaire cardset;$A;$FMT;$B;$C;$D,$E;$F
+            
PySolFC solitaire cardset;$A;$FMT;$B;$C;$D,$E;$F;$G;$H
 <internal_name>;<cardset_name>
 X Y D
 XOFF YOFF SXOFF SYOFF
@@ -9,7 +9,7 @@ 

config.txt template

Line 1

$A: The cardset version number that belongs to the number of fields divided through ";" on the first line (e.g. .gif;1;78;8,1016$A=4)

-

(WARNING: For Mahjongg, $A must always be 6 and the $F +

(WARNING: For Mahjongg, $A must always be 6 or 7 and the $F field must be included in the line; however, you can put 0 in $F if you wish, in that case.)

(NOTE: $D and $E are comma separated and count for one field)

@@ -220,6 +220,11 @@

Cardsets Origins:

$F: The Year the cardset was created (in the range 1000 to 2299)

+

$G: The subtype of the cardset. Usually 0 - for French type + cardsets, a value of 1 is used if there are jokers.

+

$H: Whether the cardset is a 3D Mahjongg cardset - 1 if it is, 0 + if it isn't. For cardsets with a version less than 7, version 6 cardsets + treat this value as 1, and older version cardsets treat it as 0.

Line 2

<internal_name>: A name for PySolFC to identify your cardset (without spaces)

diff --git a/html-src/glossary.html b/html-src/glossary.html index e08922e582..435806d1d4 100644 --- a/html-src/glossary.html +++ b/html-src/glossary.html @@ -143,8 +143,7 @@

Glossary

A deck of cards consisting of a STANDARD DECK and two jokers -making a total of 54 cards. Currently, joker decks are not -used in PySol.

+making a total of 54 cards.

OPEN
diff --git a/html-src/rules/thieves.html b/html-src/rules/thieves.html new file mode 100644 index 0000000000..b98fd9ee3a --- /dev/null +++ b/html-src/rules/thieves.html @@ -0,0 +1,14 @@ +

Thieves

+

+Golf type. 1 joker deck. No redeal. + +

Object

+

+Move all cards to the waste stack. + +

Quick Description

+

+Like Golf, +but with two jokers. Jokers are wild, any card +can be played on a joker, and a joker can be played +on any card. diff --git a/pysollib/app.py b/pysollib/app.py index b106cbd93e..f9ae6369e7 100644 --- a/pysollib/app.py +++ b/pysollib/app.py @@ -652,22 +652,25 @@ def updateCardset(self, id=0, update=7): self.images.setNegative(self.opt.negative_bottom) self.subsampled_images.setNegative(self.opt.negative_bottom) if update & 1: - self.opt.cardset[0] = (cs.name, cs.backname) + self.opt.cardset[0][0] = (cs.name, cs.backname) if update & 2: - self.opt.cardset[cs.si.type] = (cs.name, cs.backname) + self.opt.cardset[cs.si.type][cs.si.subtype] = (cs.name, + cs.backname) gi = self.getGameInfo(id) if gi: if update & 256: try: - del self.opt.cardset[(1, gi.id)] + del self.opt.cardset[(1, gi.id)][gi.subcategory] except KeyError: pass t = self.checkCompatibleCardsetType(gi, cs) if not t[1]: if update & 4: - self.opt.cardset[gi.category] = (cs.name, cs.backname) + self.opt.cardset[gi.category][gi.subcategory] = \ + (cs.name, cs.backname) if update & 8: - self.opt.cardset[(1, gi.id)] = (cs.name, cs.backname) + self.opt.cardset[(1, gi.id)][gi.subcategory] = \ + (cs.name, cs.backname) # from pprint import pprint; pprint(self.opt.cardset) def loadCardset(self, cs, id=0, update=7, progress=None, @@ -685,14 +688,16 @@ def loadCardset(self, cs, id=0, update=7, progress=None, # key: Cardset.type # value: (Cardset.ident, Images, SubsampledImages) c = self.cardsets_cache.get(cs.type) - if c and c[0] == cs.ident: - # print 'load from cache', c - self.images, self.subsampled_images = c[1], c[2] - if not tocache: - self.updateCardset(id, update=update) - if self.menubar is not None: - self.menubar.updateBackgroundImagesMenu() - return 1 + if c: + c2 = c.get(cs.subtype) + if c2 and c2[0] == cs.ident: + # print 'load from cache', c + self.images, self.subsampled_images = c2[1], c2[2] + if not tocache: + self.updateCardset(id, update=update) + if self.menubar is not None: + self.menubar.updateBackgroundImagesMenu() + return 1 # if progress is None and not noprogress: self.wm_save_state() @@ -718,9 +723,13 @@ def loadCardset(self, cs, id=0, update=7, progress=None, # if self.opt.save_cardsets: c = self.cardsets_cache.get(cs.type) if c: - # c[1].destruct() - destruct(c[1]) - self.cardsets_cache[cs.type] = (cs.ident, images, simages) + c2 = c.get(cs.subtype) + if c2: + # c2[1].destruct() + destruct(c2[1]) + self.cardsets_cache[cs.type] = {} + self.cardsets_cache[cs.type][cs.subtype] = (cs.ident, images, + simages) if not tocache: # elif self.images is not None: # # self.images.destruct() @@ -757,7 +766,9 @@ def checkCompatibleCardsetType(self, gi, cs): assert gi is not None assert cs is not None gc = gi.category + gs = gi.subcategory cs_type = cs.si.type + cs_subtype = cs.si.subtype t0, t1 = None, None if gc == GI.GC_FRENCH: t0 = "French" @@ -765,6 +776,9 @@ def checkCompatibleCardsetType(self, gi, cs): # CSI.TYPE_TAROCK, ): t1 = t0 + if (cs_subtype == CSI.SUBTYPE_NONE + and gs == CSI.SUBTYPE_JOKER_DECK): + t1 = t0 elif gc == GI.GC_HANAFUDA: t0 = "Hanafuda" if cs_type not in (CSI.TYPE_HANAFUDA,): @@ -823,14 +837,17 @@ def getCompatibleCardset(self, gi, cs, trychange=True): # try by gameid / category for key, flag in (((1, gi.id), 8), (gi.category, 4)): c = self.opt.cardset.get(key) - if not c or len(c) != 2: + c2 = None + if c: + c2 = c.get(gi.subcategory) + if not c2 or len(c2) != 2: continue - cs = self.cardset_manager.getByName(c[0]) + cs = self.cardset_manager.getByName(c2[0]) if not cs: continue t = self.checkCompatibleCardsetType(gi, cs) if not t[1]: - cs.updateCardback(backname=c[1]) + cs.updateCardback(backname=c2[1]) return cs, flag, t # ask return None, 0, t diff --git a/pysollib/cardsetparser.py b/pysollib/cardsetparser.py index 2f99f8aa74..b690c5cc55 100644 --- a/pysollib/cardsetparser.py +++ b/pysollib/cardsetparser.py @@ -100,6 +100,20 @@ def parse_cardset_config(lines_list): except ValueError: _perr(1, 6, 'not integer') return None + if cs.version >= 7: + if len(fields) < 9: + _perr(1, msg='not enough fields') + return None + try: + cs.subtype = int(fields[7]) + except ValueError: + _perr(1, 7, 'not integer') + return None + try: + cs.mahjongg3d = bool(fields[8]) + except ValueError: + _perr(1, 8, 'not boolean') + return None if len(cs.ext) < 2 or cs.ext[0] != ".": _perr(1, msg='specifies an invalid file extension') return None diff --git a/pysollib/gamedb.py b/pysollib/gamedb.py index 95b7bdc24c..e3c6c1e4b3 100644 --- a/pysollib/gamedb.py +++ b/pysollib/gamedb.py @@ -59,6 +59,10 @@ class GI: NUM_CATEGORIES = CSI.TYPE_MATCHING + # game subcategory + GS_NONE = CSI.SUBTYPE_NONE + GS_JOKER_DECK = CSI.SUBTYPE_JOKER_DECK + # game type GT_1DECK_TYPE = 0 GT_2DECK_TYPE = 1 @@ -341,7 +345,7 @@ def _callback(gi, gt=game_type): # Gnome AisleRiot 2.2.0 (we have 65 out of 70 games) # Gnome AisleRiot 3.22.7 # still missing: - # Hamilton, Labyrinth, Thieves, Treize, Valentine, Wall + # Hamilton, Labyrinth, Treize, Valentine, Wall ("Gnome AisleRiot", ( 1, 2, 8, 9, 11, 12, 13, 19, 24, 27, 29, 31, 33, 34, 35, 36, 38, 40, 41, 42, 43, 45, 48, 58, 65, 67, 89, 91, 92, 93, 94, @@ -349,7 +353,7 @@ def _callback(gi, gt=game_type): 146, 147, 148, 200, 201, 206, 224, 225, 229, 230, 233, 257, 258, 277, 280, 281, 282, 283, 284, 334, 384, 479, 495, 551, 552, 553, 572, 593, 674, 700, 715, 716, 737, 772, 810, 819, - 824, 829, 859, 874, 22231, + 824, 829, 859, 874, 906, 22231, )), # Hoyle Card Games @@ -560,7 +564,8 @@ def _callback(gi, gt=game_type): ('fc-2.15', tuple(range(827, 855)) + tuple(range(22400, 22407))), ('fc-2.20', tuple(range(855, 897))), ('fc-2.21', tuple(range(897, 900)) + tuple(range(11014, 11017)) + - tuple(range(13160, 13163)) + (16682,)) + tuple(range(13160, 13163)) + (16682,)), + ('dev', tuple(range(906, 907))), ) # deprecated - the correct way is to or a GI.GT_XXX flag @@ -608,7 +613,7 @@ def __init__(self, id, gameclass, name, game_type, decks, redeals, skill_level=None, # keyword arguments: - si={}, category=0, + si={}, category=0, subcategory=GI.GS_NONE, short_name=None, altnames=(), suits=list(range(4)), ranks=list(range(13)), trumps=(), rules_filename=None, @@ -692,7 +697,8 @@ def to_unicode(s): name=name, short_name=short_name, altnames=tuple(altnames), en_name=en_name, decks=decks, redeals=redeals, ncards=ncards, - category=category, skill_level=skill_level, + category=category, subcategory=subcategory, + skill_level=skill_level, suits=tuple(suits), ranks=tuple(ranks), trumps=tuple(trumps), si=gi_si, rules_filename=rules_filename) diff --git a/pysollib/games/golf.py b/pysollib/games/golf.py index 978c7e8097..60b31858d1 100644 --- a/pysollib/games/golf.py +++ b/pysollib/games/golf.py @@ -107,6 +107,9 @@ def acceptsCards(self, from_stack, cards): return True if not WasteStack.acceptsCards(self, from_stack, cards): return False + # if there are jokers, they're wild + if self.cards[-1].suit == 4 or cards[0].suit == 4: + return True # check cards r1, r2 = self.cards[-1].rank, cards[0].rank if self.game.getStrictness() == 1: @@ -217,6 +220,14 @@ def startGame(self): Golf.startGame(self, 7) +# ************************************************************************ +# * Thieves +# ************************************************************************ + +class Thieves(Golf): + pass + + # ************************************************************************ # * # ************************************************************************ @@ -1491,3 +1502,6 @@ def fillStack(self, stack): GI.GT_GOLF | GI.GT_OPEN, 1, 0, GI.SL_MOSTLY_SKILL)) registerGame(GameInfo(892, DoublePutt, "Double Putt", GI.GT_GOLF, 2, 0, GI.SL_BALANCED)) +registerGame(GameInfo(906, Thieves, "Thieves", + GI.GT_GOLF, 1, 0, GI.SL_BALANCED, + subcategory=GI.GS_JOKER_DECK, trumps=list(range(2)))) diff --git a/pysollib/games/mahjongg/mahjongg.py b/pysollib/games/mahjongg/mahjongg.py index a8cbf4791b..b4c31e523a 100644 --- a/pysollib/games/mahjongg/mahjongg.py +++ b/pysollib/games/mahjongg/mahjongg.py @@ -383,7 +383,7 @@ def createGame(self): # dx, dy = 2, -2 # dx, dy = 3, -3 cs = self.app.images.cs - if cs.version >= 6: + if cs.version == 6 or cs.mahjongg3d: dx = l.XOFFSET dy = -l.YOFFSET d_x = cs.SHADOW_XOFFSET diff --git a/pysollib/games/mahjongg/shisensho.py b/pysollib/games/mahjongg/shisensho.py index 21c472a3ab..da3a2600a0 100644 --- a/pysollib/games/mahjongg/shisensho.py +++ b/pysollib/games/mahjongg/shisensho.py @@ -256,7 +256,7 @@ def drawArrow(self, other_stack, sleep): x0, y0 = (game.XMARGIN + game.center_offset[0], game.YMARGIN + game.center_offset[1]) cardw, cardh = images.CARDW, images.CARDH - if cs.version >= 6: + if cs.version == 6 or cs.mahjongg3d: cardw -= cs.SHADOW_XOFFSET cardh -= cs.SHADOW_YOFFSET coords = [] @@ -314,7 +314,7 @@ def createGame(self): # dx, dy = 3, -3 cs = self.app.images.cs - if cs.version >= 6: + if cs.version == 6 or cs.mahjongg3d: dx = l.XOFFSET dy = -l.YOFFSET d_x = cs.SHADOW_XOFFSET diff --git a/pysollib/main.py b/pysollib/main.py index d36ffe1df7..8cf1d69b71 100644 --- a/pysollib/main.py +++ b/pysollib/main.py @@ -316,7 +316,7 @@ def progressCallback(*args): # init cardsets app.initCardsets() cardset = None - c = app.opt.cardset.get(0) + c = app.opt.cardset.get(0).get(0) if c: cardset = app.cardset_manager.getByName(c[0]) if cardset and c[1]: diff --git a/pysollib/options.py b/pysollib/options.py index 10b4547927..ea747e204f 100644 --- a/pysollib/options.py +++ b/pysollib/options.py @@ -192,6 +192,7 @@ def calcCustomMouseButtonsBinding(binding_format): [cardsets] 0 = string_list(min=2, max=2) 1 = string_list(min=2, max=2) +1_1 = string_list(min=2, max=2) 2 = string_list(min=2, max=2) 3 = string_list(min=2, max=2) 4 = string_list(min=2, max=2) @@ -546,34 +547,36 @@ def setDefaults(self, top=None): # c = 'Dondorf' if USE_PIL: self.cardset = { - 0: ("Neo", ""), - CSI.TYPE_FRENCH: ("Neo", ""), - CSI.TYPE_HANAFUDA: ("Louie Mantia Hanafuda", ""), - CSI.TYPE_MAHJONGG: ("Uni Mahjongg", ""), - CSI.TYPE_TAROCK: ("Neo Tarock", ""), - CSI.TYPE_HEXADECK: ("Neo Hex", ""), - CSI.TYPE_MUGHAL_GANJIFA: ("Mughal Ganjifa XL", ""), - # CSI.TYPE_NAVAGRAHA_GANJIFA: ("Navagraha Ganjifa", ""), - CSI.TYPE_NAVAGRAHA_GANJIFA: ("Dashavatara Ganjifa XL", ""), - CSI.TYPE_DASHAVATARA_GANJIFA: ("Dashavatara Ganjifa XL", ""), - CSI.TYPE_TRUMP_ONLY: ("Next Matrix", ""), - CSI.TYPE_MATCHING: ("Neo", "") + 0: {0: ("Neo", "")}, + CSI.TYPE_FRENCH: {0: ("Neo", ""), 1: ("Neo", "")}, + CSI.TYPE_HANAFUDA: {0: ("Louie Mantia Hanafuda", "")}, + CSI.TYPE_MAHJONGG: {0: ("Uni Mahjongg", "")}, + CSI.TYPE_TAROCK: {0: ("Neo Tarock", "")}, + CSI.TYPE_HEXADECK: {0: ("Neo Hex", "")}, + CSI.TYPE_MUGHAL_GANJIFA: {0: ("Mughal Ganjifa XL", "")}, + # CSI.TYPE_NAVAGRAHA_GANJIFA: {0: ("Navagraha Ganjifa", "")}, + CSI.TYPE_NAVAGRAHA_GANJIFA: + {0: ("Dashavatara Ganjifa XL", "")}, + CSI.TYPE_DASHAVATARA_GANJIFA: + {0: ("Dashavatara Ganjifa XL", "")}, + CSI.TYPE_TRUMP_ONLY: {0: ("Next Matrix", "")}, + CSI.TYPE_MATCHING: {0: ("Neo", "")} } else: self.cardset = { # game_type: (cardset_name, back_file) - 0: (c, ""), - CSI.TYPE_FRENCH: (c, ""), - CSI.TYPE_HANAFUDA: ("Kintengu", ""), - CSI.TYPE_MAHJONGG: ("Crystal Mahjongg", ""), - CSI.TYPE_TAROCK: ("Vienna 2K", ""), - CSI.TYPE_HEXADECK: ("Hex A Deck", ""), - CSI.TYPE_MUGHAL_GANJIFA: ("Mughal Ganjifa", ""), - # CSI.TYPE_NAVAGRAHA_GANJIFA: ("Navagraha Ganjifa", ""), - CSI.TYPE_NAVAGRAHA_GANJIFA: ("Dashavatara Ganjifa", ""), - CSI.TYPE_DASHAVATARA_GANJIFA: ("Dashavatara Ganjifa", ""), - CSI.TYPE_TRUMP_ONLY: ("Matrix", ""), - CSI.TYPE_MATCHING: (c, ""), + 0: {0: (c, "")}, + CSI.TYPE_FRENCH: {0: (c, ""), 1: (c, "")}, + CSI.TYPE_HANAFUDA: {0: ("Kintengu", "")}, + CSI.TYPE_MAHJONGG: {0: ("Crystal Mahjongg", "")}, + CSI.TYPE_TAROCK: {0: ("Vienna 2K", "")}, + CSI.TYPE_HEXADECK: {0: ("Hex A Deck", "")}, + CSI.TYPE_MUGHAL_GANJIFA: {0: ("Mughal Ganjifa", "")}, + # CSI.TYPE_NAVAGRAHA_GANJIFA: {0: ("Navagraha Ganjifa", "")}, + CSI.TYPE_NAVAGRAHA_GANJIFA: {0: ("Dashavatara Ganjifa", "")}, + CSI.TYPE_DASHAVATARA_GANJIFA: {0: ("Dashavatara Ganjifa", "")}, + CSI.TYPE_TRUMP_ONLY: {0: ("Matrix", "")}, + CSI.TYPE_MATCHING: {0: (c, "")} } # not changeable options @@ -635,7 +638,11 @@ def save(self, filename): # cardsets for key, val in self.cardset.items(): - config['cardsets'][str(key)] = val + for key2, val2 in val.items(): + if key2 > 0: + config['cardsets'][str(key) + "_" + str(key2)] = val2 + else: + config['cardsets'][str(key)] = val2 for key in ('scale_cards', 'scale_x', 'scale_y', 'auto_scale', 'spread_stacks', 'preserve_aspect_ratio', 'resampling'): @@ -802,12 +809,17 @@ def load(self, filename): # cardsets for key in self.cardset: - val = self._getOption('cardsets', str(key), 'list') - if val is not None: - try: - self.cardset[int(key)] = val - except Exception: - traceback.print_exc() + for key2 in self.cardset[key]: + if key2 > 0: + val = self._getOption('cardsets', + str(key) + "_" + str(key2), 'list') + else: + val = self._getOption('cardsets', str(key), 'list') + if val is not None: + try: + self.cardset[int(key)][int(key2)] = val + except Exception: + traceback.print_exc() for key, t in (('scale_cards', 'bool'), ('scale_x', 'float'), ('scale_y', 'float'), diff --git a/pysollib/pysolgtk/selectgame.py b/pysollib/pysolgtk/selectgame.py index 60dc6028d6..80b4fbeed2 100644 --- a/pysollib/pysolgtk/selectgame.py +++ b/pysollib/pysolgtk/selectgame.py @@ -416,14 +416,19 @@ def updatePreview(self, gameid, animations=10): # c = self.app.cardsets_cache.get(gi.category) - if not c: + c2 = None + if c: + c2 = c.get(gi.subcategory) + if not c2: cardset = self.app.cardset_manager.getByName( - self.app.opt.cardset[gi.category][0]) + self.app.opt.cardset[gi.category][gi.subcategory][0]) self.app.loadCardset(cardset, id=gi.category, tocache=True, noprogress=True) c = self.app.cardsets_cache.get(gi.category) - if c: - self.preview_app.images = c[2] + if c: + c2 = c.get(gi.subcategory) + if c2: + self.preview_app.images = c2[2] else: self.preview_app.images = self.app.subsampled_images diff --git a/pysollib/resource.py b/pysollib/resource.py index 66e05d0481..3c2916679d 100644 --- a/pysollib/resource.py +++ b/pysollib/resource.py @@ -182,6 +182,10 @@ class CSI: TYPE_TRUMP_ONLY = 9 TYPE_MATCHING = 10 + # cardset subtypes + SUBTYPE_NONE = 0 + SUBTYPE_JOKER_DECK = 1 + TYPE = { 1: _("French type (52 cards)"), 2: _("Hanafuda type (48 cards)"), @@ -351,6 +355,8 @@ def __init__(self): ncards=-1, styles=[], year=0, + subtype=0, + mahjongg3d=False, # line[1] ident="", name="", @@ -380,7 +386,8 @@ def __init__(self, **kw): kw = KwStruct(config.__dict__, **kw) # si is the SelectionInfo struct that will be queried by # the "select cardset" dialogs. It can be freely modified. - si = Struct(type=0, size=0, styles=[], nationalities=[], dates=[]) + si = Struct(type=0, subtype=0, size=0, styles=[], + nationalities=[], dates=[]) kw = KwStruct( kw, # essentials @@ -452,11 +459,13 @@ def _check(self, cs): if s not in CSI.TYPE: return 0 cs.si.type = s + cs.si.subtype = cs.subtype cs.suits = CSI.TYPE_SUITS[s] cs.ranks = CSI.TYPE_RANKS[s] cs.trumps = CSI.TYPE_TRUMPS[s] if s == CSI.TYPE_FRENCH: - pass + if cs.subtype == 1: + cs.trumps = list(range(2)) elif s == CSI.TYPE_HANAFUDA: cs.nbottoms = 15 elif s == CSI.TYPE_TAROCK: diff --git a/pysollib/tile/selectgame.py b/pysollib/tile/selectgame.py index 7534f351cc..5238e79ae1 100644 --- a/pysollib/tile/selectgame.py +++ b/pysollib/tile/selectgame.py @@ -734,14 +734,19 @@ def updatePreview(self, gameid, animations=10): # c = self.app.cardsets_cache.get(gi.category) - if not c: + c2 = None + if c: + c2 = c.get(gi.subcategory) + if not c2: cardset = self.app.cardset_manager.getByName( - self.app.opt.cardset[gi.category][0]) + self.app.opt.cardset[gi.category][gi.subcategory][0]) self.app.loadCardset(cardset, id=gi.category, tocache=True, noprogress=True) c = self.app.cardsets_cache.get(gi.category) - if c: - self.preview_app.images = c[2] + if c: + c2 = c.get(gi.subcategory) + if c2: + self.preview_app.images = c2[2] else: self.preview_app.images = self.app.subsampled_images diff --git a/pysollib/tk/selectgame.py b/pysollib/tk/selectgame.py index 431065a460..bbe226efe4 100644 --- a/pysollib/tk/selectgame.py +++ b/pysollib/tk/selectgame.py @@ -509,14 +509,19 @@ def updatePreview(self, gameid, animations=10): # c = self.app.cardsets_cache.get(gi.category) - if not c: + c2 = None + if c: + cs = c.get(gi.subcategory) + if not c2: cardset = self.app.cardset_manager.getByName( - self.app.opt.cardset[gi.category][0]) + self.app.opt.cardset[gi.category][gi.subcategory][0]) self.app.loadCardset(cardset, id=gi.category, tocache=True, noprogress=True) c = self.app.cardsets_cache.get(gi.category) - if c: - self.preview_app.images = c[2] + if c: + c2 = c.get(gi.subcategory) + if c2: + self.preview_app.images = c2[2] else: self.preview_app.images = self.app.subsampled_images