1
0
Fork 0
mirror of https://github.com/shlomif/PySolFC.git synced 2025-04-05 00:02:29 -04:00
PySolFC/pysollib/games/demonsandthieves.py
2023-01-31 19:48:09 -05:00

175 lines
5.8 KiB
Python

from pysollib.game import Game
from pysollib.gamedb import GI, GameInfo, registerGame
from pysollib.layout import Layout
from pysollib.pysoltk import MfxCanvasText
from pysollib.stack import \
AC_RowStack, \
OpenStack, \
SS_FoundationStack, \
SS_RowStack, \
WasteStack, \
WasteTalonStack
from pysollib.util import ANY_RANK, RANKS
# ************************************************************************
# * Demons and Thieves
# ************************************************************************
class DemonsAndThieves_StackMethods:
def acceptsCards(self, from_stack, cards):
if not self.basicAcceptsCards(from_stack, cards):
return False
# [topcard + bottomcard] must be an acceptable sequence
if (self.cards and not
self._isAcceptableSequence([self.cards[-1]] + [cards[0]])):
return False
return True
class DemonsAndThieves_AC_RowStack(DemonsAndThieves_StackMethods, AC_RowStack):
pass
class DemonsAndThieves_SS_RowStack(DemonsAndThieves_StackMethods, SS_RowStack):
pass
class DemonsAndThieves(Game):
def createGame(self, max_rounds=3, num_deal=1,
text=True, round_text=True, dir=-1):
# create layout
lay, s = Layout(self), self.s
decks = self.gameinfo.decks
# (piles up to 20 cards are playable in default window size)
h = max(3 * lay.YS, lay.YS + 13 * 10)
if round_text:
h += lay.TEXT_HEIGHT
self.setSize(
lay.XM + (2 + max(9.5, 4 * decks)) * lay.XS + lay.XM,
lay.YM + lay.YS + lay.TEXT_HEIGHT + h)
# extra settings
self.base_card = None
# create stacks
x, y = lay.XM, lay.YM
if round_text:
y += lay.TEXT_HEIGHT
s.talon = WasteTalonStack(x, y, self,
max_rounds=max_rounds, num_deal=num_deal)
lay.createText(s.talon, "s")
if round_text:
lay.createRoundText(s.talon, 'n')
x += lay.XS
s.waste = WasteStack(x, y, self)
lay.createText(s.waste, "s")
x += lay.XM
y = lay.YM
if round_text:
y += lay.TEXT_HEIGHT
for i in range(4):
for j in range(decks):
x += lay.XS
s.foundations.append(SS_FoundationStack(x, y, self, i,
mod=13, max_move=0))
if text:
if 10 > 4 * decks:
tx, ty, ta, tf = lay.getTextAttr(None, "se")
tx, ty = x + tx + lay.XM, y + ty
else:
tx, ty, ta, tf = lay.getTextAttr(None, "s")
tx, ty = x + tx, y + ty
font = self.app.getFont("canvas_default")
self.texts.info = MfxCanvasText(self.canvas, tx, ty,
anchor=ta, font=font)
x, y = lay.XM, lay.YM + lay.YS + lay.TEXT_HEIGHT
if round_text:
y += lay.TEXT_HEIGHT
s.reserves.append(OpenStack(x, y, self))
s.reserves[0].CARD_YOFFSET = 10
x, y = lay.XM + 2 * lay.XS + lay.XM, lay.YM + lay.YS
if round_text:
y += lay.TEXT_HEIGHT
if text:
y += lay.TEXT_HEIGHT
for i in range(4):
s.rows.append(DemonsAndThieves_AC_RowStack(x, y, self,
base_rank=ANY_RANK,
dir=dir))
x += lay.XS
x += (lay.XS * .5)
for i in range(5):
s.rows.append(DemonsAndThieves_SS_RowStack(x, y, self,
base_rank=ANY_RANK,
dir=dir))
x += lay.XS
# define stack-groups
lay.defaultStackGroups()
#
# game extras
#
def updateText(self):
if self.preview > 1:
return
if not self.texts.info:
return
if not self.base_card:
t = ""
else:
t = RANKS[self.base_card.rank]
self.texts.info.config(text=t)
#
# game overrides
#
def startGame(self):
self.startDealSample()
self.base_card = None
self.updateText()
for i in range(7):
self.s.talon.dealRow(rows=self.s.rows[4:9], flip=1, frames=0)
self.s.talon.dealRow()
# deal base_card to Foundations, update foundations cap.base_rank
self.base_card = self.s.talon.getCard()
for s in self.s.foundations:
s.cap.base_rank = self.base_card.rank
n = self.base_card.suit * self.gameinfo.decks
if self.s.foundations[n].cards:
assert self.gameinfo.decks > 1
n = n + 1
self.flipMove(self.s.talon)
self.moveMove(1, self.s.talon, self.s.foundations[n])
self.updateText()
# fill the Reserve
for i in range(13):
self.moveMove(
1, self.s.talon, self.s.reserves[0], frames=4, shadow=0)
if self.s.reserves[0].canFlipCard():
self.flipMove(self.s.reserves[0])
self.s.talon.dealCards()
shallHighlightMatch = Game._shallHighlightMatch_ACW
def _restoreGameHook(self, game):
self.base_card = self.cards[game.loadinfo.base_card_id]
for s in self.s.foundations:
s.cap.base_rank = self.base_card.rank
def _loadGameHook(self, p):
self.loadinfo.addattr(base_card_id=None) # register extra load var.
self.loadinfo.base_card_id = p.load()
def _saveGameHook(self, p):
p.dump(self.base_card.id)
# register the game
registerGame(GameInfo(889, DemonsAndThieves, "Demons and Thieves",
GI.GT_FORTY_THIEVES, 2, 2, GI.SL_MOSTLY_SKILL))