1
0
Fork 0
mirror of https://github.com/shlomif/PySolFC.git synced 2025-04-05 00:02:29 -04:00
This commit is contained in:
Shlomi Fish 2017-04-18 13:42:17 +03:00
parent 1de537bb88
commit 2ea7cf48ea
10 changed files with 801 additions and 552 deletions

View file

@ -1,6 +1,6 @@
#!/usr/bin/env python #!/usr/bin/env python
# -*- mode: python; coding: utf-8; -*- # -*- mode: python; coding: utf-8; -*-
# ---------------------------------------------------------------------------## # ---------------------------------------------------------------------------
# #
# Copyright (C) 1998-2003 Markus Franz Xaver Johannes Oberhumer # Copyright (C) 1998-2003 Markus Franz Xaver Johannes Oberhumer
# Copyright (C) 2003 Mt. Hood Playing Card Co. # Copyright (C) 2003 Mt. Hood Playing Card Co.
@ -19,30 +19,50 @@
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
# #
# ---------------------------------------------------------------------------## # ---------------------------------------------------------------------------
__all__ = [] __all__ = []
# Imports # Imports
import sys, math, time import math
import time
# PySol imports # PySol imports
from pysollib.mygettext import _, n_ from pysollib.mygettext import _
from pysollib.gamedb import registerGame, GameInfo, GI from pysollib.gamedb import registerGame, GameInfo, GI
from pysollib.util import *
from pysollib.mfxutil import kwdefault from pysollib.mfxutil import kwdefault
from pysollib.stack import *
from pysollib.game import Game from pysollib.game import Game
from pysollib.layout import Layout from pysollib.layout import Layout
from pysollib.hint import AbstractHint, DefaultHint, CautiousDefaultHint from pysollib.hint import AbstractHint, DefaultHint, CautiousDefaultHint
from pysollib.pysoltk import MfxCanvasText from pysollib.pysoltk import MfxCanvasText
from pysollib.util import ANY_RANK, ANY_SUIT, NO_RANK, \
UNLIMITED_ACCEPTS, \
UNLIMITED_CARDS, \
UNLIMITED_MOVES
from pysollib.stack import \
AC_RowStack, \
AbstractFoundationStack, \
BasicRowStack, \
DealRowTalonStack, \
InitialDealTalonStack, \
OpenStack, \
RK_RowStack, \
ReserveStack, \
SS_FoundationStack, \
SS_RowStack, \
StackWrapper, \
WasteStack, \
isSameSuitSequence, \
WasteTalonStack
# ************************************************************************ # ************************************************************************
# * Dashavatara Foundation Stacks # * Dashavatara Foundation Stacks
# ***********************************************************************/ # ***********************************************************************/
class Dashavatara_FoundationStack(AbstractFoundationStack): class Dashavatara_FoundationStack(AbstractFoundationStack):
def __init__(self, x, y, game, suit, **cap): def __init__(self, x, y, game, suit, **cap):
@ -70,8 +90,8 @@ class Journey_Foundation(AbstractFoundationStack):
card_dir = (cards[0].rank - self.cards[-1].rank) % self.cap.mod card_dir = (cards[0].rank - self.cards[-1].rank) % self.cap.mod
return card_dir in (1, 11) return card_dir in (1, 11)
else: else:
return (self.cards[-1].rank + stack_dir) % self.cap.mod == cards[0].rank return (self.cards[-1].rank + stack_dir) % \
self.cap.mod == cards[0].rank
class AppachansWaterfall_Foundation(AbstractFoundationStack): class AppachansWaterfall_Foundation(AbstractFoundationStack):
@ -82,7 +102,7 @@ class AppachansWaterfall_Foundation(AbstractFoundationStack):
def acceptsCards(self, from_stack, cards): def acceptsCards(self, from_stack, cards):
if not (from_stack in self.game.s.rows and if not (from_stack in self.game.s.rows and
AbstractFoundationStack.acceptsCards(self, from_stack, cards)): AbstractFoundationStack.acceptsCards(self, from_stack, cards)):
return 0 return 0
pile, rank, suit = from_stack.getPile(), 0, 0 pile, rank, suit = from_stack.getPile(), 0, 0
if self.cards: if self.cards:
@ -94,7 +114,6 @@ class AppachansWaterfall_Foundation(AbstractFoundationStack):
return cards[0].suit == suit and cards[0].rank == rank return cards[0].suit == suit and cards[0].rank == rank
# ************************************************************************ # ************************************************************************
# * Dashavatara Row Stacks # * Dashavatara Row Stacks
# ***********************************************************************/ # ***********************************************************************/
@ -166,8 +185,8 @@ class Dashavatara_OpenStack(OpenStack):
class Dashavatara_AC_RowStack(Dashavatara_OpenStack): class Dashavatara_AC_RowStack(Dashavatara_OpenStack):
def acceptsCards(self, from_stack, cards): def acceptsCards(self, from_stack, cards):
if (not self.basicAcceptsCards(from_stack, cards) if not self.basicAcceptsCards(from_stack, cards) \
or not self.isAlternateColorSequence(cards)): or not self.isAlternateColorSequence(cards):
return 0 return 0
stackcards = self.cards stackcards = self.cards
if not len(stackcards): if not len(stackcards):
@ -178,8 +197,8 @@ class Dashavatara_AC_RowStack(Dashavatara_OpenStack):
class Dashavatara_AF_RowStack(Dashavatara_OpenStack): class Dashavatara_AF_RowStack(Dashavatara_OpenStack):
def acceptsCards(self, from_stack, cards): def acceptsCards(self, from_stack, cards):
if (not self.basicAcceptsCards(from_stack, cards) if not self.basicAcceptsCards(from_stack, cards) \
or not self.isAlternateForceSequence(cards)): or not self.isAlternateForceSequence(cards):
return 0 return 0
stackcards = self.cards stackcards = self.cards
if not len(stackcards): if not len(stackcards):
@ -190,8 +209,8 @@ class Dashavatara_AF_RowStack(Dashavatara_OpenStack):
class Dashavatara_RK_RowStack(Dashavatara_OpenStack): class Dashavatara_RK_RowStack(Dashavatara_OpenStack):
def acceptsCards(self, from_stack, cards): def acceptsCards(self, from_stack, cards):
if (not self.basicAcceptsCards(from_stack, cards) if not self.basicAcceptsCards(from_stack, cards) \
or not self.isRankSequence(cards)): or not self.isRankSequence(cards):
return 0 return 0
stackcards = self.cards stackcards = self.cards
if not len(stackcards): if not len(stackcards):
@ -202,8 +221,8 @@ class Dashavatara_RK_RowStack(Dashavatara_OpenStack):
class Dashavatara_SS_RowStack(Dashavatara_OpenStack): class Dashavatara_SS_RowStack(Dashavatara_OpenStack):
def acceptsCards(self, from_stack, cards): def acceptsCards(self, from_stack, cards):
if (not self.basicAcceptsCards(from_stack, cards) if not self.basicAcceptsCards(from_stack, cards) \
or not self.isSuitSequence(cards)): or not self.isSuitSequence(cards):
return 0 return 0
stackcards = self.cards stackcards = self.cards
if not len(stackcards): if not len(stackcards):
@ -215,7 +234,7 @@ class Circles_RowStack(SS_RowStack):
def __init__(self, x, y, game, base_rank): def __init__(self, x, y, game, base_rank):
SS_RowStack.__init__(self, x, y, game, base_rank=base_rank, SS_RowStack.__init__(self, x, y, game, base_rank=base_rank,
max_accept=1, max_move=1) max_accept=1, max_move=1)
self.CARD_YOFFSET = 1 self.CARD_YOFFSET = 1
@ -223,7 +242,6 @@ class Journey_BraidStack(OpenStack):
def __init__(self, x, y, game, xoffset, yoffset): def __init__(self, x, y, game, xoffset, yoffset):
OpenStack.__init__(self, x, y, game) OpenStack.__init__(self, x, y, game)
CW = self.game.app.images.CARDW
self.CARD_YOFFSET = int(self.game.app.images.CARD_YOFFSET * yoffset) self.CARD_YOFFSET = int(self.game.app.images.CARD_YOFFSET * yoffset)
# use a sine wave for the x offsets # use a sine wave for the x offsets
self.CARD_XOFFSET = [] self.CARD_XOFFSET = []
@ -275,7 +293,7 @@ class Journey_ReserveStack(ReserveStack):
class AppachansWaterfall_RowStack(RK_RowStack): class AppachansWaterfall_RowStack(RK_RowStack):
def canDropCards(self, stacks): def canDropCards(self, stacks):
game, pile, stack, rank = self.game, self.getPile(), stacks[0], 0 pile, stack, rank = self.getPile(), stacks[0], 0
if stack.cards: if stack.cards:
rank = (stack.cards[-1].rank + 1) % 12 rank = (stack.cards[-1].rank + 1) % 12
if (not pile or len(pile) <= 11 - rank if (not pile or len(pile) <= 11 - rank
@ -285,7 +303,6 @@ class AppachansWaterfall_RowStack(RK_RowStack):
return (stack, 1) return (stack, 1)
# ************************************************************************ # ************************************************************************
# * Dashavatara Game Stacks # * Dashavatara Game Stacks
# ************************************************************************ # ************************************************************************
@ -293,7 +310,8 @@ class AppachansWaterfall_RowStack(RK_RowStack):
class Dashavatara_TableauStack(Dashavatara_OpenStack): class Dashavatara_TableauStack(Dashavatara_OpenStack):
def __init__(self, x, y, game, base_rank, yoffset, **cap): def __init__(self, x, y, game, base_rank, yoffset, **cap):
kwdefault(cap, dir=3, max_move=99, max_cards=4, max_accept=1, base_rank=base_rank) kwdefault(cap, dir=3, max_move=99, max_cards=4, max_accept=1,
base_rank=base_rank)
OpenStack.__init__(self, x, y, game, **cap) OpenStack.__init__(self, x, y, game, **cap)
self.CARD_YOFFSET = yoffset self.CARD_YOFFSET = yoffset
@ -358,7 +376,7 @@ class AbstractDashavataraGame(Game):
def shallHighlightMatch(self, stack1, card1, stack2, card2): def shallHighlightMatch(self, stack1, card1, stack2, card2):
return (card1.suit == card2.suit return (card1.suit == card2.suit
and (card1.rank + 1 == card2.rank and (card1.rank + 1 == card2.rank
or card1.rank - 1 == card2.rank)) or card1.rank - 1 == card2.rank))
class Journey_Hint(DefaultHint): class Journey_Hint(DefaultHint):
@ -379,7 +397,6 @@ class DashavataraCircles(AbstractDashavataraGame):
def createGame(self): def createGame(self):
l, s = Layout(self), self.s l, s = Layout(self), self.s
font = self.app.getFont("canvas_default")
# Set window size # Set window size
w, h = l.XM + l.XS * 9, l.YM + l.YS * 7 w, h = l.XM + l.XS * 9, l.YM + l.YS * 7
@ -389,17 +406,21 @@ class DashavataraCircles(AbstractDashavataraGame):
x = w / 2 - l.CW / 2 x = w / 2 - l.CW / 2
y = h / 2 - l.YS / 2 y = h / 2 - l.YS / 2
x0 = (-.7, .3, .7, -.3, x0 = (-.7, .3, .7, -.3,
-1.7, -1.5, -.6, .6, 1.5, 1.7, 1.5, .6, -.6, -1.5, -1.7, -1.5, -.6, .6, 1.5, 1.7, 1.5, .6, -.6, -1.5,
-2.7, -2.5, -1.9, -1, 0, 1, 1.9, 2.5, 2.7, 2.5, 1.9, 1, 0, -1, -1.9, -2.5) -2.7, -2.5, -1.9, -1, 0, 1, 1.9, 2.5, 2.7, 2.5, 1.9,
1, 0, -1, -1.9, -2.5)
y0 = (-.3, -.45, .3, .45, y0 = (-.3, -.45, .3, .45,
0, -.8, -1.25, -1.25, -.8, 0, .8, 1.25, 1.25, .8, 0, -.8, -1.25, -1.25, -.8, 0, .8, 1.25, 1.25, .8,
0, -.9, -1.6, -2, -2.2, -2, -1.6, -.9, 0, .9, 1.6, 2, 2.2, 2, 1.6, .9) 0, -.9, -1.6, -2, -2.2, -2, -1.6, -.9, 0, .9, 1.6,
2, 2.2, 2, 1.6, .9)
for i in range(30): for i in range(30):
# FIXME: # FIXME:
_x, _y = x+l.XS*x0[i], y+l.YS*y0[i]+l.YM*y0[i]*2 _x, _y = x+l.XS*x0[i], y+l.YS*y0[i]+l.YM*y0[i]*2
if _x < 0: _x = 0 if _x < 0:
if _y < 0: _y = 0 _x = 0
s.rows.append(Circles_RowStack(_x, _y, self, base_rank = ANY_RANK)) if _y < 0:
_y = 0
s.rows.append(Circles_RowStack(_x, _y, self, base_rank=ANY_RANK))
# Create reserve stacks # Create reserve stacks
s.reserves.append(ReserveStack(l.XM, h - l.YS, self)) s.reserves.append(ReserveStack(l.XM, h - l.YS, self))
@ -409,13 +430,14 @@ class DashavataraCircles(AbstractDashavataraGame):
x, y = l.XM, l.YM x, y = l.XM, l.YM
for j in range(2): for j in range(2):
for i in range(5): for i in range(5):
s.foundations.append(SS_FoundationStack(x, y, self, i + j * 5, mod=12, s.foundations.append(
max_move=0, max_cards=12)) SS_FoundationStack(x, y, self, i + j * 5, mod=12,
max_move=0, max_cards=12))
y = y + l.YS y = y + l.YS
x, y = w - l.XS, l.YM x, y = w - l.XS, l.YM
## from pprint import pprint # from pprint import pprint
## pprint(s.rows) # pprint(s.rows)
## print (l.XM + l.XS, 0, w - l.XS - l.XM, 999999) # print (l.XM + l.XS, 0, w - l.XS - l.XM, 999999)
self.setRegion(s.rows, (l.XM + l.XS, 0, w - l.XS - l.XM, 999999)) self.setRegion(s.rows, (l.XM + l.XS, 0, w - l.XS - l.XM, 999999))
# Create talon # Create talon
@ -437,7 +459,6 @@ class DashavataraCircles(AbstractDashavataraGame):
self.s.talon.dealCards() self.s.talon.dealCards()
# ************************************************************************ # ************************************************************************
# * Ten Avatars # * Ten Avatars
# ***********************************************************************/ # ***********************************************************************/
@ -450,7 +471,6 @@ class TenAvatars(AbstractDashavataraGame):
def createGame(self): def createGame(self):
l, s = Layout(self), self.s l, s = Layout(self), self.s
font = self.app.getFont("canvas_default")
# Set window size # Set window size
self.setSize(l.XM * 3 + l.XS * 11, l.YM + l.YS * 6) self.setSize(l.XM * 3 + l.XS * 11, l.YM + l.YS * 6)
@ -460,7 +480,7 @@ class TenAvatars(AbstractDashavataraGame):
y = l.YM y = l.YM
for i in range(10): for i in range(10):
s.rows.append(RK_RowStack(x, y, self, base_rank=11, s.rows.append(RK_RowStack(x, y, self, base_rank=11,
max_move=12, max_cards=99)) max_move=12, max_cards=99))
x = x + l.XS x = x + l.XS
# Create reserve stacks # Create reserve stacks
@ -503,7 +523,6 @@ class TenAvatars(AbstractDashavataraGame):
return 1 return 1
# ************************************************************************ # ************************************************************************
# * Balarama # * Balarama
# ***********************************************************************/ # ***********************************************************************/
@ -528,7 +547,7 @@ class Balarama(AbstractDashavataraGame):
# Create foundations # Create foundations
for r in l.s.foundations: for r in l.s.foundations:
s.foundations.append(self.Foundation_Class(r.x, r.y, self, s.foundations.append(self.Foundation_Class(r.x, r.y, self,
r.suit, mod=12, max_cards=12)) r.suit, mod=12, max_cards=12))
# Create reserve stacks # Create reserve stacks
for r in l.s.reserves: for r in l.s.reserves:
@ -537,7 +556,8 @@ class Balarama(AbstractDashavataraGame):
# Create row stacks # Create row stacks
for r in l.s.rows: for r in l.s.rows:
s.rows.append(self.RowStack_Class(r.x, r.y, self, l.YOFFSET, s.rows.append(self.RowStack_Class(r.x, r.y, self, l.YOFFSET,
suit=ANY_SUIT, base_rank=self.BASE_RANK, max_cards=12)) suit=ANY_SUIT, base_rank=self.BASE_RANK,
max_cards=12))
# Create talon # Create talon
s.talon = self.Talon_Class(l.s.talon.x, l.s.talon.y, self) s.talon = self.Talon_Class(l.s.talon.x, l.s.talon.y, self)
@ -561,8 +581,7 @@ class Balarama(AbstractDashavataraGame):
def shallHighlightMatch(self, stack1, card1, stack2, card2): def shallHighlightMatch(self, stack1, card1, stack2, card2):
return (card1.color % 2 != card2.color % 2 and return (card1.color % 2 != card2.color % 2 and
(card1.rank + 1 == card2.rank (card1.rank + 1 == card2.rank
or card2.rank + 1 == card1.rank)) or card2.rank + 1 == card1.rank))
# ************************************************************************ # ************************************************************************
@ -588,7 +607,6 @@ class Hayagriva(Balarama):
or card2.rank + 1 == card1.rank) or card2.rank + 1 == card1.rank)
# ************************************************************************ # ************************************************************************
# * Shanka # * Shanka
# ***********************************************************************/ # ***********************************************************************/
@ -611,12 +629,11 @@ class Shanka(Balarama):
if stack1 in self.s.foundations: if stack1 in self.s.foundations:
return (card1.suit == card2.suit and return (card1.suit == card2.suit and
(card1.rank + 1 == card2.rank (card1.rank + 1 == card2.rank
or card2.rank + 1 == card1.rank)) or card2.rank + 1 == card1.rank))
return (card1.rank + 1 == card2.rank return (card1.rank + 1 == card2.rank
or card2.rank + 1 == card1.rank) or card2.rank + 1 == card1.rank)
# ************************************************************************ # ************************************************************************
# * Surukh # * Surukh
# ***********************************************************************/ # ***********************************************************************/
@ -646,8 +663,7 @@ class Surukh(Balarama):
force1 = 1 force1 = 1
return (force0 != force1 return (force0 != force1
and (card1.rank + 1 == card2.rank and (card1.rank + 1 == card2.rank
or card2.rank + 1 == card1.rank)) or card2.rank + 1 == card1.rank))
# ************************************************************************ # ************************************************************************
@ -673,18 +689,18 @@ class Matsya(AbstractDashavataraGame):
# Create talon # Create talon
s.talon = self.Talon_Class(l.s.talon.x, l.s.talon.y, self, s.talon = self.Talon_Class(l.s.talon.x, l.s.talon.y, self,
max_rounds=max_rounds, num_deal=num_deal) max_rounds=max_rounds, num_deal=num_deal)
s.waste = WasteStack(l.s.waste.x, l.s.waste.y, self) s.waste = WasteStack(l.s.waste.x, l.s.waste.y, self)
# Create foundations # Create foundations
for r in l.s.foundations: for r in l.s.foundations:
s.foundations.append(self.Foundation_Class(r.x, r.y, self, s.foundations.append(self.Foundation_Class(r.x, r.y, self,
r.suit, mod=12, max_cards=12, max_move=0)) r.suit, mod=12, max_cards=12, max_move=0))
# Create row stacks # Create row stacks
for r in l.s.rows: for r in l.s.rows:
s.rows.append(self.RowStack_Class(r.x, r.y, self, s.rows.append(self.RowStack_Class(r.x, r.y, self,
suit=ANY_SUIT, base_rank=self.BASE_RANK)) suit=ANY_SUIT, base_rank=self.BASE_RANK))
# Define stack groups # Define stack groups
l.defaultAll() l.defaultAll()
@ -706,7 +722,6 @@ class Matsya(AbstractDashavataraGame):
or card2.rank + 1 == card1.rank) or card2.rank + 1 == card1.rank)
# ************************************************************************ # ************************************************************************
# * Kurma # * Kurma
# ***********************************************************************/ # ***********************************************************************/
@ -726,7 +741,6 @@ class Kurma(Matsya):
Matsya.createGame(self, max_rounds=-1) Matsya.createGame(self, max_rounds=-1)
# ************************************************************************ # ************************************************************************
# * Varaha # * Varaha
# ***********************************************************************/ # ***********************************************************************/
@ -746,7 +760,6 @@ class Varaha(Matsya):
Matsya.createGame(self, max_rounds=-1, num_deal=3) Matsya.createGame(self, max_rounds=-1, num_deal=3)
# ************************************************************************ # ************************************************************************
# * Narasimha # * Narasimha
# ***********************************************************************/ # ***********************************************************************/
@ -768,8 +781,7 @@ class Narasimha(Matsya):
def shallHighlightMatch(self, stack1, card1, stack2, card2): def shallHighlightMatch(self, stack1, card1, stack2, card2):
return (card1.color % 2 != card2.color % 2 return (card1.color % 2 != card2.color % 2
and (card1.rank + 1 == card2.rank and (card1.rank + 1 == card2.rank
or card2.rank + 1 == card1.rank)) or card2.rank + 1 == card1.rank))
# ************************************************************************ # ************************************************************************
@ -793,8 +805,7 @@ class Vamana(Matsya):
def shallHighlightMatch(self, stack1, card1, stack2, card2): def shallHighlightMatch(self, stack1, card1, stack2, card2):
return (card1.color % 2 != card2.color % 2 return (card1.color % 2 != card2.color % 2
and (card1.rank + 1 == card2.rank and (card1.rank + 1 == card2.rank
or card2.rank + 1 == card1.rank)) or card2.rank + 1 == card1.rank))
# ************************************************************************ # ************************************************************************
@ -820,7 +831,6 @@ class Parashurama(Matsya):
or card2.rank + 1 == card1.rank) or card2.rank + 1 == card1.rank)
# ************************************************************************ # ************************************************************************
# * Journey to Cuddapah # * Journey to Cuddapah
# ************************************************************************ # ************************************************************************
@ -842,7 +852,8 @@ class Journey(AbstractDashavataraGame):
# set window # set window
# (piles up to 20 cards are playable - needed for Braid_BraidStack) # (piles up to 20 cards are playable - needed for Braid_BraidStack)
decks = self.gameinfo.decks decks = self.gameinfo.decks
h = max(5 * l.YS + 35, 2*l.YM + 2*l.YS + (self.BRAID_CARDS - 1) * l.YOFFSET*self.BRAID_OFFSET) h = max(5 * l.YS + 35, 2*l.YM + 2*l.YS +
(self.BRAID_CARDS - 1) * l.YOFFSET*self.BRAID_OFFSET)
self.setSize(l.XM + l.XS * (7 + decks * 2), l.YM + h) self.setSize(l.XM + l.XS * (7 + decks * 2), l.YM + h)
# extra settings # extra settings
@ -855,37 +866,43 @@ class Journey(AbstractDashavataraGame):
for j in range(5): for j in range(5):
for i in range(decks): for i in range(decks):
s.foundations.append(Journey_Foundation(x + l.XS * i, y, self, s.foundations.append(Journey_Foundation(x + l.XS * i, y, self,
j, mod=12, max_cards=12)) j, mod=12, max_cards=12))
s.rows.append(Journey_StrongStack(x + l.XS * decks, y, self)) s.rows.append(Journey_StrongStack(x + l.XS * decks, y, self))
s.rows.append(Journey_ReserveStack(x + l.XS * (1 + decks), y, self)) s.rows.append(
Journey_ReserveStack(x + l.XS * (1 + decks), y, self))
y = y + l.YS y = y + l.YS
x, y = x + l.XS * (5 + decks), l.YM x, y = x + l.XS * (5 + decks), l.YM
for j in range(5): for j in range(5):
s.rows.append(Journey_ReserveStack(x, y, self)) s.rows.append(Journey_ReserveStack(x, y, self))
s.rows.append(Journey_WeakStack(x + l.XS, y, self)) s.rows.append(Journey_WeakStack(x + l.XS, y, self))
for i in range(decks, 0, -1): for i in range(decks, 0, -1):
s.foundations.append(Journey_Foundation(x + l.XS * (1 + i), y, self, s.foundations.append(
j + 5, mod=12, max_cards=12)) Journey_Foundation(x + l.XS * (1 + i), y, self,
j + 5, mod=12, max_cards=12))
y = y + l.YS y = y + l.YS
self.texts.info = MfxCanvasText(self.canvas, self.texts.info = MfxCanvasText(
self.width / 2, h - l.YM / 2, self.canvas,
anchor="center", self.width / 2, h - l.YM / 2,
font = self.app.getFont("canvas_default")) anchor="center",
font=self.app.getFont("canvas_default"))
# Create braids # Create braids
x, y = l.XM + l.XS * 2.15 + l.XS * decks, l.YM x, y = l.XM + l.XS * 2.15 + l.XS * decks, l.YM
s.braidstrong = Journey_BraidStack(x, y, self, xoffset=12, yoffset=self.BRAID_OFFSET) s.braidstrong = Journey_BraidStack(
x, y, self, xoffset=12, yoffset=self.BRAID_OFFSET)
x = x + l.XS * 1.7 x = x + l.XS * 1.7
s.braidweak = Journey_BraidStack(x, y, self, xoffset=-12, yoffset=self.BRAID_OFFSET) s.braidweak = Journey_BraidStack(
x, y, self, xoffset=-12, yoffset=self.BRAID_OFFSET)
# Create talon # Create talon
x, y = l.XM + l.XS * 2 + l.XS * decks, h - l.YS - l.YM x, y = l.XM + l.XS * 2 + l.XS * decks, h - l.YS - l.YM
s.talon = WasteTalonStack(x, y, self, max_rounds=3) s.talon = WasteTalonStack(x, y, self, max_rounds=3)
l.createText(s.talon, "s") l.createText(s.talon, "s")
s.talon.texts.rounds = MfxCanvasText(self.canvas, s.talon.texts.rounds = MfxCanvasText(
self.width / 2, h - l.YM * 2.5, self.canvas,
anchor="center", self.width / 2, h - l.YM * 2.5,
font=self.app.getFont("canvas_default")) anchor="center",
font=self.app.getFont("canvas_default"))
x = x + l.XS * 2 x = x + l.XS * 2
s.waste = WasteStack(x, y, self) s.waste = WasteStack(x, y, self)
l.createText(s.waste, "s") l.createText(s.waste, "s")
@ -893,8 +910,8 @@ class Journey(AbstractDashavataraGame):
# define stack-groups # define stack-groups
self.sg.talonstacks = [s.talon] + [s.waste] self.sg.talonstacks = [s.talon] + [s.waste]
self.sg.openstacks = s.foundations + s.rows self.sg.openstacks = s.foundations + s.rows
self.sg.dropstacks = [s.braidstrong] + [s.braidweak] + s.rows + [s.waste] self.sg.dropstacks = [s.braidstrong] + [s.braidweak] + s.rows \
+ [s.waste]
# #
# game overrides # game overrides
@ -905,13 +922,14 @@ class Journey(AbstractDashavataraGame):
self.base_card = None self.base_card = None
self.updateText() self.updateText()
for i in range(self.BRAID_CARDS): for i in range(self.BRAID_CARDS):
self.s.talon.dealRow(rows = [self.s.braidstrong]) self.s.talon.dealRow(rows=[self.s.braidstrong])
for i in range(self.BRAID_CARDS): for i in range(self.BRAID_CARDS):
self.s.talon.dealRow(rows = [self.s.braidweak]) self.s.talon.dealRow(rows=[self.s.braidweak])
self.s.talon.dealRow() self.s.talon.dealRow()
# deal base_card to foundations, update cap.base_rank # deal base_card to foundations, update cap.base_rank
self.base_card = self.s.talon.getCard() self.base_card = self.s.talon.getCard()
to_stack = self.s.foundations[self.base_card.suit * self.gameinfo.decks] to_stack = self.s.foundations[
self.base_card.suit * self.gameinfo.decks]
self.flipMove(self.s.talon) self.flipMove(self.s.talon)
self.moveMove(1, self.s.talon, to_stack) self.moveMove(1, self.s.talon, to_stack)
self.updateText() self.updateText()
@ -923,7 +941,7 @@ class Journey(AbstractDashavataraGame):
def shallHighlightMatch(self, stack1, card1, stack2, card2): def shallHighlightMatch(self, stack1, card1, stack2, card2):
return (card1.suit == card2.suit and return (card1.suit == card2.suit and
((card1.rank + 1) % 12 == card2.rank ((card1.rank + 1) % 12 == card2.rank
or (card2.rank + 1) % 12 == card1.rank)) or (card2.rank + 1) % 12 == card1.rank))
def getHighlightPilesStacks(self): def getHighlightPilesStacks(self):
return () return ()
@ -940,7 +958,6 @@ class Journey(AbstractDashavataraGame):
def _saveGameHook(self, p): def _saveGameHook(self, p):
p.dump(self.base_card.id) p.dump(self.base_card.id)
# #
# game extras # game extras
# #
@ -957,8 +974,7 @@ class Journey(AbstractDashavataraGame):
t = t + _(" Ascending") t = t + _(" Ascending")
elif dir == 11: elif dir == 11:
t = t + _(" Descending") t = t + _(" Descending")
self.texts.info.config(text = t) self.texts.info.config(text=t)
# ************************************************************************ # ************************************************************************
@ -971,7 +987,6 @@ class LongJourney(Journey):
BRAID_OFFSET = .7 BRAID_OFFSET = .7
# ************************************************************************ # ************************************************************************
# * Appachan's Waterfall # * Appachan's Waterfall
# ***********************************************************************/ # ***********************************************************************/
@ -984,7 +999,6 @@ class AppachansWaterfall(AbstractDashavataraGame):
def createGame(self): def createGame(self):
l, s = Layout(self), self.s l, s = Layout(self), self.s
font = self.app.getFont("canvas_default")
# Set window size # Set window size
w, h = l.XM + l.XS * 10, l.YM + l.YS * 6 w, h = l.XM + l.XS * 10, l.YM + l.YS * 6
@ -993,8 +1007,10 @@ class AppachansWaterfall(AbstractDashavataraGame):
# Create row stacks # Create row stacks
x, y = l.XM, l.YM x, y = l.XM, l.YM
for i in range(10): for i in range(10):
s.rows.append(AppachansWaterfall_RowStack(x, y, self, base_rank=ANY_RANK, s.rows.append(AppachansWaterfall_RowStack(x, y, self,
max_move=12, max_cards=99)) base_rank=ANY_RANK,
max_move=12,
max_cards=99))
x = x + l.XS x = x + l.XS
self.setRegion(s.rows, (-999, -999, 999999, l.YM + l.YS * 5)) self.setRegion(s.rows, (-999, -999, 999999, l.YM + l.YS * 5))
@ -1028,7 +1044,6 @@ class AppachansWaterfall(AbstractDashavataraGame):
return len(self.s.foundations[0].cards) == 120 return len(self.s.foundations[0].cards) == 120
# ************************************************************************ # ************************************************************************
# * Hiranyaksha # * Hiranyaksha
# ************************************************************************ # ************************************************************************
@ -1074,12 +1089,14 @@ class Hiranyaksha(AbstractDashavataraGame):
x, y = l.XM + maxrows * l.XS, l.YM x, y = l.XM + maxrows * l.XS, l.YM
for i in range(2): for i in range(2):
for suit in range(5): for suit in range(5):
s.foundations.append(SS_FoundationStack(x, y, self, suit=suit + (5 * i))) s.foundations.append(SS_FoundationStack(x, y, self,
suit=suit + (5 * i)))
y = y + l.YS y = y + l.YS
x, y = x + l.XS, l.YM x, y = x + l.XS, l.YM
self.setRegion(self.s.foundations, (x - l.XS * 2, -999, 999999, self.setRegion(self.s.foundations, (x - l.XS * 2, -999, 999999,
self.height - (l.YS + l.YM)), priority=1) self.height - (l.YS + l.YM)), priority=1)
s.talon = InitialDealTalonStack(self.width - 3 * l.XS / 2, self.height - l.YS, self) s.talon = InitialDealTalonStack(
self.width - 3 * l.XS / 2, self.height - l.YS, self)
# define stack-groups # define stack-groups
l.defaultStackGroups() l.defaultStackGroups()
@ -1102,7 +1119,8 @@ class Hiranyaksha(AbstractDashavataraGame):
closest, cdist = None, 999999999 closest, cdist = None, 999999999
for stack in stacks: for stack in stacks:
if stack.cards and stack is not dragstack: if stack.cards and stack is not dragstack:
dist = (stack.cards[-1].x - cx)**2 + (stack.cards[-1].y - cy)**2 dist = (stack.cards[-1].x - cx)**2 + \
(stack.cards[-1].y - cy)**2
else: else:
dist = (stack.x - cx)**2 + (stack.y - cy)**2 dist = (stack.x - cx)**2 + (stack.y - cy)**2
if dist < cdist: if dist < cdist:
@ -1115,7 +1133,6 @@ class Hiranyaksha(AbstractDashavataraGame):
return (sequence([card1, card2]) or sequence([card2, card1])) return (sequence([card1, card2]) or sequence([card2, card1]))
# ************************************************************************ # ************************************************************************
# * Dashavatara Hint # * Dashavatara Hint
# ************************************************************************ # ************************************************************************
@ -1213,7 +1230,9 @@ class Dashavatara(Game):
for i in range(3, 0, -1): for i in range(3, 0, -1):
x = l.XM x = l.XM
for j in range(10): for j in range(10):
s.tableaux.append(Dashavatara_TableauStack(x, y, self, i - 1, TABLEAU_YOFFSET)) s.tableaux.append(
Dashavatara_TableauStack(
x, y, self, i - 1, TABLEAU_YOFFSET))
x = x + l.XS x = x + l.XS
x = x + l.XM x = x + l.XM
s.reserves.append(Dashavatara_ReserveStack(x, y, self)) s.reserves.append(Dashavatara_ReserveStack(x, y, self))
@ -1271,22 +1290,34 @@ def r(id, gameclass, name, game_type, decks, redeals, skill_level):
registerGame(gi) registerGame(gi)
return gi return gi
r(15406, Matsya, "Matsya", GI.GT_DASHAVATARA_GANJIFA, 1, 0, GI.SL_BALANCED) r(15406, Matsya, "Matsya", GI.GT_DASHAVATARA_GANJIFA, 1, 0, GI.SL_BALANCED)
r(15407, Kurma, "Kurma", GI.GT_DASHAVATARA_GANJIFA, 1, -1, GI.SL_BALANCED) r(15407, Kurma, "Kurma", GI.GT_DASHAVATARA_GANJIFA, 1, -1, GI.SL_BALANCED)
r(15408, Varaha, "Varaha", GI.GT_DASHAVATARA_GANJIFA, 1, -1, GI.SL_BALANCED) r(15408, Varaha, "Varaha", GI.GT_DASHAVATARA_GANJIFA, 1, -1, GI.SL_BALANCED)
r(15409, Narasimha, "Narasimha", GI.GT_DASHAVATARA_GANJIFA, 1, 0, GI.SL_BALANCED) r(15409, Narasimha, "Narasimha", GI.GT_DASHAVATARA_GANJIFA, 1, 0,
GI.SL_BALANCED)
r(15410, Vamana, "Vamana", GI.GT_DASHAVATARA_GANJIFA, 1, -1, GI.SL_BALANCED) r(15410, Vamana, "Vamana", GI.GT_DASHAVATARA_GANJIFA, 1, -1, GI.SL_BALANCED)
r(15411, Parashurama, "Parashurama", GI.GT_DASHAVATARA_GANJIFA, 1, 1, GI.SL_BALANCED) r(15411, Parashurama, "Parashurama", GI.GT_DASHAVATARA_GANJIFA, 1, 1,
r(15412, TenAvatars, "Ten Avatars", GI.GT_DASHAVATARA_GANJIFA, 1, 0, GI.SL_MOSTLY_SKILL) GI.SL_BALANCED)
r(15413, DashavataraCircles, "Dashavatara Circles", GI.GT_DASHAVATARA_GANJIFA, 1, 0, GI.SL_MOSTLY_SKILL) r(15412, TenAvatars, "Ten Avatars", GI.GT_DASHAVATARA_GANJIFA, 1, 0,
r(15414, Balarama, "Balarama", GI.GT_DASHAVATARA_GANJIFA, 1, 0, GI.SL_MOSTLY_SKILL) GI.SL_MOSTLY_SKILL)
r(15415, Hayagriva, "Hayagriva", GI.GT_DASHAVATARA_GANJIFA, 1, 0, GI.SL_MOSTLY_SKILL) r(15413, DashavataraCircles, "Dashavatara Circles", GI.GT_DASHAVATARA_GANJIFA,
1, 0, GI.SL_MOSTLY_SKILL)
r(15414, Balarama, "Balarama", GI.GT_DASHAVATARA_GANJIFA, 1, 0,
GI.SL_MOSTLY_SKILL)
r(15415, Hayagriva, "Hayagriva", GI.GT_DASHAVATARA_GANJIFA, 1, 0,
GI.SL_MOSTLY_SKILL)
r(15416, Shanka, "Shanka", GI.GT_DASHAVATARA_GANJIFA, 1, 0, GI.SL_MOSTLY_SKILL) r(15416, Shanka, "Shanka", GI.GT_DASHAVATARA_GANJIFA, 1, 0, GI.SL_MOSTLY_SKILL)
r(15417, Journey, "Journey to Cuddapah", GI.GT_DASHAVATARA_GANJIFA, 1, 2, GI.SL_BALANCED) r(15417, Journey, "Journey to Cuddapah", GI.GT_DASHAVATARA_GANJIFA, 1, 2,
r(15418, LongJourney, "Long Journey to Cuddapah", GI.GT_DASHAVATARA_GANJIFA, 2, 2, GI.SL_BALANCED) GI.SL_BALANCED)
r(15418, LongJourney, "Long Journey to Cuddapah", GI.GT_DASHAVATARA_GANJIFA,
2, 2, GI.SL_BALANCED)
r(15419, Surukh, "Surukh", GI.GT_DASHAVATARA_GANJIFA, 1, 0, GI.SL_BALANCED) r(15419, Surukh, "Surukh", GI.GT_DASHAVATARA_GANJIFA, 1, 0, GI.SL_BALANCED)
r(15420, AppachansWaterfall, "Appachan's Waterfall", GI.GT_DASHAVATARA_GANJIFA, 1, 0, GI.SL_MOSTLY_SKILL) r(15420, AppachansWaterfall, "Appachan's Waterfall", GI.GT_DASHAVATARA_GANJIFA,
r(15421, Hiranyaksha, 'Hiranyaksha', GI.GT_DASHAVATARA_GANJIFA, 1, 0, GI.SL_MOSTLY_SKILL) 1, 0, GI.SL_MOSTLY_SKILL)
r(15422, Dashavatara, 'Dashavatara', GI.GT_DASHAVATARA_GANJIFA, 1, 0, GI.SL_BALANCED) r(15421, Hiranyaksha, 'Hiranyaksha', GI.GT_DASHAVATARA_GANJIFA, 1, 0,
GI.SL_MOSTLY_SKILL)
r(15422, Dashavatara, 'Dashavatara', GI.GT_DASHAVATARA_GANJIFA, 1, 0,
GI.SL_BALANCED)
del r del r

View file

@ -24,20 +24,41 @@
__all__ = [] __all__ = []
# Imports # Imports
import sys, math
# PySol imports # PySol imports
from pysollib.mygettext import _, n_ from pysollib.mygettext import _
from pysollib.gamedb import registerGame, GameInfo, GI from pysollib.gamedb import registerGame, GameInfo, GI
from pysollib.util import *
from pysollib.mfxutil import kwdefault from pysollib.mfxutil import kwdefault
from pysollib.stack import *
from pysollib.game import Game
from pysollib.layout import Layout from pysollib.layout import Layout
from pysollib.hint import FreeCellType_Hint from pysollib.hint import FreeCellType_Hint
from pysollib.pysoltk import MfxCanvasText from pysollib.pysoltk import MfxCanvasText
from hanafuda_common import * from hanafuda_common import \
FlowerClock_Foundation, \
FlowerClock_RowStack, \
FourWinds_Foundation, \
FourWinds_RowStack, \
Gaji_Foundation, \
Gaji_RowStack, \
GreatWall_FoundationStack, \
GreatWall_RowStack, \
Hanafuda_SS_FoundationStack, \
Hanafuda_SequenceStack, \
MatsuKiri_Foundation, \
Matsukiri_RowStack, \
Oonsoo_SequenceStack, \
Pagoda_Foundation, \
AbstractFlowerGame
from pysollib.util import ANY_RANK, ANY_SUIT
from pysollib.stack import \
DealRowTalonStack, \
InitialDealTalonStack, \
ReserveStack, \
WasteStack, \
cardsFaceUp, \
WasteTalonStack
# ************************************************************************ # ************************************************************************
@ -58,8 +79,8 @@ class FlowerClock(AbstractFlowerGame):
self.setSize(l.XM + l.XS * 10.5, l.YM + l.YS * 5.5) self.setSize(l.XM + l.XS * 10.5, l.YM + l.YS * 5.5)
# Create clock # Create clock
xoffset = ( 1, 2, 2.5, 2, 1, 0, -1, -2, -2.5, -2, -1, 0 ) xoffset = (1, 2, 2.5, 2, 1, 0, -1, -2, -2.5, -2, -1, 0)
yoffset = ( 0.25, 0.75, 1.9, 3, 3.5, 3.75, 3.5, 3, 1.9, 0.75, 0.25, 0 ) yoffset = (0.25, 0.75, 1.9, 3, 3.5, 3.75, 3.5, 3, 1.9, 0.75, 0.25, 0)
x = l.XM + l.XS * 7 x = l.XM + l.XS * 7
y = l.CH / 3 y = l.CH / 3
for i in range(12): for i in range(12):
@ -82,7 +103,8 @@ class FlowerClock(AbstractFlowerGame):
self.setRegion(s.rows, (0, 0, l.XS * 4, 999999)) self.setRegion(s.rows, (0, 0, l.XS * 4, 999999))
# Create talon # Create talon
s.talon = InitialDealTalonStack(self.width - l.XS, self.height - l.YS, self) s.talon = InitialDealTalonStack(
self.width - l.XS, self.height - l.YS, self)
# Define stack groups # Define stack groups
l.defaultStackGroups() l.defaultStackGroups()
@ -114,7 +136,6 @@ class FlowerClock(AbstractFlowerGame):
return (self.sg.dropstacks, self.sg.dropstacks, self.sg.dropstacks) return (self.sg.dropstacks, self.sg.dropstacks, self.sg.dropstacks)
# ************************************************************************ # ************************************************************************
# * Gaji # * Gaji
# ***********************************************************************/ # ***********************************************************************/
@ -135,25 +156,27 @@ class Gaji(AbstractFlowerGame):
x = l.XM x = l.XM
y = l.YM y = l.YM
s.foundations.append(Gaji_Foundation(x, y, self, -1, base_rank=0)) s.foundations.append(Gaji_Foundation(x, y, self, -1, base_rank=0))
x = x + l.XS x += l.XS
s.foundations.append(Gaji_Foundation(x, y, self, -1, base_rank=1)) s.foundations.append(Gaji_Foundation(x, y, self, -1, base_rank=1))
# Create right foundations # Create right foundations
x = self.width - l.XS * 2 x = self.width - l.XS * 2
s.foundations.append(Gaji_Foundation(x, y, self, -1, base_rank=2)) s.foundations.append(Gaji_Foundation(x, y, self, -1, base_rank=2))
x = x + l.XS x += l.XS
s.foundations.append(Gaji_Foundation(x, y, self, -1, base_rank=3)) s.foundations.append(Gaji_Foundation(x, y, self, -1, base_rank=3))
# Create row stacks # Create row stacks
x = l.XS * 2.5 + l.XM x = l.XS * 2.5 + l.XM
for i in range(8): for i in range(8):
s.rows.append(Gaji_RowStack(x, y, self, yoffset=l.CH/2, s.rows.append(Gaji_RowStack(x, y, self, yoffset=l.CH/2,
max_cards=12, max_accept=12)) max_cards=12, max_accept=12))
x = x + l.XS x += l.XS
self.setRegion(s.rows, (l.XM + l.XS * 2, -999, l.XM + l.XS * 10, 999999)) self.setRegion(
s.rows, (l.XM + l.XS * 2, -999, l.XM + l.XS * 10, 999999))
# Create talon # Create talon
s.talon = InitialDealTalonStack(self.width - l.XS, self.height - l.YS, self) s.talon = InitialDealTalonStack(
self.width - l.XS, self.height - l.YS, self)
# Define stack groups # Define stack groups
l.defaultStackGroups() l.defaultStackGroups()
@ -193,14 +216,13 @@ class Gaji(AbstractFlowerGame):
if stack1 in self.s.foundations: if stack1 in self.s.foundations:
return (card1.rank == card2.rank return (card1.rank == card2.rank
and ((((card1.suit + 1) % 12) == card2.suit) and ((((card1.suit + 1) % 12) == card2.suit)
or (((card1.suit - 1) % 12) == card2.suit))) or (((card1.suit - 1) % 12) == card2.suit)))
else: else:
return ((card1.suit == card2.suit) return ((card1.suit == card2.suit)
and ((card1.rank + 1 == card2.rank) and ((card1.rank + 1 == card2.rank)
or (card1.rank - 1 == card2.rank))) or (card1.rank - 1 == card2.rank)))
# ************************************************************************ # ************************************************************************
# * Oonsoo # * Oonsoo
# ***********************************************************************/ # ***********************************************************************/
@ -256,7 +278,6 @@ class Oonsoo(AbstractFlowerGame):
return 1 return 1
# ************************************************************************ # ************************************************************************
# * Oonsoo Too # * Oonsoo Too
# ************************************************************************ # ************************************************************************
@ -265,7 +286,6 @@ class OonsooToo(Oonsoo):
Reserves = 1 Reserves = 1
# ************************************************************************ # ************************************************************************
# * Oonsoo Strict # * Oonsoo Strict
# ************************************************************************ # ************************************************************************
@ -276,7 +296,6 @@ class OonsooStrict(Oonsoo):
Strictness = 1 Strictness = 1
# ************************************************************************ # ************************************************************************
# * Oonsoo Open # * Oonsoo Open
# ************************************************************************ # ************************************************************************
@ -285,7 +304,6 @@ class OonsooOpen(Oonsoo):
BaseRank = ANY_RANK BaseRank = ANY_RANK
# ************************************************************************ # ************************************************************************
# * Oonsoo Times Two # * Oonsoo Times Two
# ************************************************************************ # ************************************************************************
@ -295,7 +313,6 @@ class OonsooTimesTwo(Oonsoo):
Reserves = 1 Reserves = 1
# ************************************************************************ # ************************************************************************
# * Pagoda # * Pagoda
# ***********************************************************************/ # ***********************************************************************/
@ -328,19 +345,22 @@ class Pagoda(AbstractFlowerGame):
# Build pagoda # Build pagoda
x, y = l.XM + l.XS, l.YM x, y = l.XM + l.XS, l.YM
d = ( 0.4, 0.25, 0, 0.25, 0.4 ) d = (0.4, 0.25, 0, 0.25, 0.4)
for i in range(5): for i in range(5):
s.reserves.append(ReserveStack(x + l.XS * i, y + l.YS * d[i], self)) s.reserves.append(
ReserveStack(x + l.XS * i, y + l.YS * d[i], self))
x, y = l.XM + l.XS * 2, y + l.YS * 1.1 x, y = l.XM + l.XS * 2, y + l.YS * 1.1
d = ( 0.25, 0, 0.25 ) d = (0.25, 0, 0.25)
for i in range(3): for i in range(3):
s.reserves.append(ReserveStack(x + l.XS * i, y + l.YS * d[i], self)) s.reserves.append(
ReserveStack(x + l.XS * i, y + l.YS * d[i], self))
x, y = l.XM, y + l.YS * 1.1 x, y = l.XM, y + l.YS * 1.1
d = ( 0.5, 0.4, 0.25, 0, 0.25, 0.4, 0.5 ) d = (0.5, 0.4, 0.25, 0, 0.25, 0.4, 0.5)
for i in range(7): for i in range(7):
s.reserves.append(ReserveStack(x + l.XS * i, y + l.YS * d[i], self)) s.reserves.append(
ReserveStack(x + l.XS * i, y + l.YS * d[i], self))
x, y = l.XM + l.XS, y + l.YS * 1.5 x, y = l.XM + l.XS, y + l.YS * 1.5
for i in range(5): for i in range(5):
@ -392,7 +412,6 @@ class Pagoda(AbstractFlowerGame):
self.dealCards() self.dealCards()
# ************************************************************************ # ************************************************************************
# * Matsukiri # * Matsukiri
# ***********************************************************************/ # ***********************************************************************/
@ -415,17 +434,19 @@ class MatsuKiri(AbstractFlowerGame):
y = l.YM y = l.YM
for i in range(8): for i in range(8):
s.rows.append(Matsukiri_RowStack(x, y, self, yoffset=l.CH/2, s.rows.append(Matsukiri_RowStack(x, y, self, yoffset=l.CH/2,
max_cards=12, max_accept=12)) max_cards=12, max_accept=12))
x = x + l.XS x = x + l.XS
self.setRegion(s.rows, (-999, -999, l.XM + (l.XS * 8) + 10, 999999)) self.setRegion(s.rows, (-999, -999, l.XM + (l.XS * 8) + 10, 999999))
# Create foundation # Create foundation
x = x + l.XM * 2 x = x + l.XM * 2
s.foundations.append(MatsuKiri_Foundation(x, y, self, ANY_SUIT)) s.foundations.append(MatsuKiri_Foundation(x, y, self, ANY_SUIT))
self.setRegion(s.foundations, (l.XM + (l.XS * 8) + 10, -999, 999999, 999999)) self.setRegion(
s.foundations, (l.XM + (l.XS * 8) + 10, -999, 999999, 999999))
# Create talon # Create talon
s.talon = InitialDealTalonStack(self.width - l.XS, self.height - l.YS, self) s.talon = InitialDealTalonStack(
self.width - l.XS, self.height - l.YS, self)
# Define stack groups # Define stack groups
l.defaultStackGroups() l.defaultStackGroups()
@ -485,9 +506,11 @@ class GreatWall(AbstractFlowerGame):
y = l.YM y = l.YM
for i in range(12): for i in range(12):
s.rows.append(GreatWall_RowStack(x, y, self, yoffset=l.CH/4, s.rows.append(GreatWall_RowStack(x, y, self, yoffset=l.CH/4,
max_cards=26, max_accept=26)) max_cards=26, max_accept=26))
x = x + l.XS x = x + l.XS
self.setRegion(s.rows, (l.XM + l.XS * 1.25, -999, self.width - l.XS * 1.25, 999999)) self.setRegion(
s.rows, (l.XM + l.XS * 1.25, -999, self.width - l.XS * 1.25,
999999))
# Create talon # Create talon
x = self.width / 2 - l.CW / 2 x = self.width / 2 - l.CW / 2
@ -512,7 +535,8 @@ class GreatWall(AbstractFlowerGame):
elif l == 4: elif l == 4:
text = _("Filled") text = _("Filled")
else: else:
text = str(l) + (_("st"), _("nd"), _("rd"), _("th"))[l - 1] + _(" Deck") text = str(l) + (_("st"), _("nd"), _("rd"), _("th"))[l - 1] \
+ _(" Deck")
stack.texts.misc.config(text=text) stack.texts.misc.config(text=text)
# #
@ -537,13 +561,12 @@ class GreatWall(AbstractFlowerGame):
if stack1 in self.s.foundations: if stack1 in self.s.foundations:
return (card1.rank == card2.rank return (card1.rank == card2.rank
and ((((card1.suit + 1) % 12) == card2.suit) and ((((card1.suit + 1) % 12) == card2.suit)
or (((card1.suit - 1) % 12) == card2.suit))) or (((card1.suit - 1) % 12) == card2.suit)))
else: else:
return (card1.rank + 1 == card2.rank return (card1.rank + 1 == card2.rank
or card1.rank - 1 == card2.rank) or card1.rank - 1 == card2.rank)
# ************************************************************************ # ************************************************************************
# * Four Winds # * Four Winds
# ************************************************************************ # ************************************************************************
@ -574,7 +597,8 @@ class FourWinds(AbstractFlowerGame):
x0 = x + (xoffset[i] * l.XS) x0 = x + (xoffset[i] * l.XS)
y0 = y + (yoffset[i] * l.YS) y0 = y + (yoffset[i] * l.YS)
stack = FourWinds_Foundation(x0, y0, self, -1, stack = FourWinds_Foundation(x0, y0, self, -1,
max_cards=12, max_accept=1, base_rank=i) max_cards=12, max_accept=1,
base_rank=i)
s.foundations.append(stack) s.foundations.append(stack)
t = MfxCanvasText(self.canvas, x0 + l.CW / 2, y0 + l.YS + 5, t = MfxCanvasText(self.canvas, x0 + l.CW / 2, y0 + l.YS + 5,
anchor="center", font=font, anchor="center", font=font,
@ -595,7 +619,8 @@ class FourWinds(AbstractFlowerGame):
anchor="center", font=font, anchor="center", font=font,
text=TEXTS[i+4]) text=TEXTS[i+4])
stack.texts.misc = t stack.texts.misc = t
self.setRegion(s.rows, (x + l.XS, y + l.YS * 0.65, x + l.XS * 4 + 5, y + l.YS * 3 + 5)) self.setRegion(s.rows, (x + l.XS, y + l.YS * 0.65, x + l.XS * 4 + 5,
y + l.YS * 3 + 5))
# Create talon # Create talon
x = x + 2 * l.XS x = x + 2 * l.XS
@ -624,7 +649,6 @@ class FourWinds(AbstractFlowerGame):
self.dealCards() self.dealCards()
# ************************************************************************ # ************************************************************************
# * Sumo # * Sumo
# ************************************************************************ # ************************************************************************
@ -649,10 +673,13 @@ class Sumo(AbstractFlowerGame):
# Create stacks # Create stacks
s.talon = self.Talon_Class(l.s.talon.x, l.s.talon.y, self) s.talon = self.Talon_Class(l.s.talon.x, l.s.talon.y, self)
for r in l.s.foundations: for r in l.s.foundations:
s.foundations.append(self.Foundation_Class(r.x, r.y, self, s.foundations.append(
suit=r.suit, base_rank=3)) self.Foundation_Class(
r.x, r.y, self,
suit=r.suit, base_rank=3))
for r in l.s.rows: for r in l.s.rows:
s.rows.append(self.RowStack_Class(r.x, r.y, self, yoffset=l.YOFFSET)) s.rows.append(
self.RowStack_Class(r.x, r.y, self, yoffset=l.YOFFSET))
for r in l.s.reserves: for r in l.s.reserves:
s.reserves.append(ReserveStack(r.x, r.y, self)) s.reserves.append(ReserveStack(r.x, r.y, self))
l.defaultAll() l.defaultAll()
@ -670,7 +697,6 @@ class Sumo(AbstractFlowerGame):
self.s.talon.dealCards() self.s.talon.dealCards()
# ************************************************************************ # ************************************************************************
# * Big Sumo # * Big Sumo
# ************************************************************************ # ************************************************************************
@ -694,10 +720,12 @@ class BigSumo(AbstractFlowerGame):
# Create stacks # Create stacks
s.talon = self.Talon_Class(l.s.talon.x, l.s.talon.y, self) s.talon = self.Talon_Class(l.s.talon.x, l.s.talon.y, self)
for r in l.s.foundations: for r in l.s.foundations:
s.foundations.append(self.Foundation_Class(r.x, r.y, self, s.foundations.append(
suit=r.suit, base_rank=3)) self.Foundation_Class(r.x, r.y, self,
suit=r.suit, base_rank=3))
for r in l.s.rows: for r in l.s.rows:
s.rows.append(self.RowStack_Class(r.x, r.y, self, yoffset=l.YOFFSET)) s.rows.append(
self.RowStack_Class(r.x, r.y, self, yoffset=l.YOFFSET))
for r in l.s.reserves: for r in l.s.reserves:
s.reserves.append(ReserveStack(r.x, r.y, self)) s.reserves.append(ReserveStack(r.x, r.y, self))
l.defaultAll() l.defaultAll()
@ -715,7 +743,6 @@ class BigSumo(AbstractFlowerGame):
self.s.talon.dealCards() self.s.talon.dealCards()
# ************************************************************************ # ************************************************************************
# * Samuri # * Samuri
# ************************************************************************ # ************************************************************************
@ -739,22 +766,22 @@ class Samuri(AbstractFlowerGame):
# Create stacks # Create stacks
s.talon = self.Talon_Class(l.s.talon.x, l.s.talon.y, self, s.talon = self.Talon_Class(l.s.talon.x, l.s.talon.y, self,
max_rounds=max_rounds, num_deal=num_deal) max_rounds=max_rounds, num_deal=num_deal)
s.waste = WasteStack(l.s.waste.x, l.s.waste.y, self) s.waste = WasteStack(l.s.waste.x, l.s.waste.y, self)
# Create foundations # Create foundations
for r in l.s.foundations: for r in l.s.foundations:
s.foundations.append(self.Foundation_Class(r.x, r.y, self, s.foundations.append(self.Foundation_Class(r.x, r.y, self,
suit=r.suit, base_rank=3)) suit=r.suit, base_rank=3))
# Create row stacks # Create row stacks
for r in l.s.rows: for r in l.s.rows:
s.rows.append(self.RowStack_Class(r.x, r.y, self, yoffset=l.YOFFSET)) s.rows.append(
self.RowStack_Class(r.x, r.y, self, yoffset=l.YOFFSET))
# Define stack groups # Define stack groups
l.defaultAll() l.defaultAll()
# #
# Game over rides # Game over rides
# #
@ -766,7 +793,8 @@ class Samuri(AbstractFlowerGame):
self.s.talon.dealRow(flip=0, frames=0) self.s.talon.dealRow(flip=0, frames=0)
max_row = len(self.s.rows) max_row = len(self.s.rows)
for i in range(max_row): for i in range(max_row):
self.s.talon.dealRow(rows=self.s.rows[i:max_row-i], flip=0, frames=0) self.s.talon.dealRow(
rows=self.s.rows[i:max_row-i], flip=0, frames=0)
self.startDealSample() self.startDealSample()
self.s.talon.dealRow() self.s.talon.dealRow()
self.s.talon.dealCards() self.s.talon.dealCards()
@ -777,7 +805,6 @@ class Samuri(AbstractFlowerGame):
self.dealCards() self.dealCards()
# ************************************************************************ # ************************************************************************
# * Double Samuri # * Double Samuri
# ***********************************************************************/ # ***********************************************************************/
@ -786,7 +813,6 @@ class DoubleSamuri(Samuri):
Rows = 11 Rows = 11
# ************************************************************************ # ************************************************************************
# * Super Samuri # * Super Samuri
# ***********************************************************************/ # ***********************************************************************/
@ -795,7 +821,6 @@ class SuperSamuri(DoubleSamuri):
pass pass
# ************************************************************************ # ************************************************************************
# * Little Easy # * Little Easy
# ************************************************************************ # ************************************************************************
@ -814,19 +839,21 @@ class LittleEasy(AbstractFlowerGame):
def createGame(self, max_rounds=-1, num_deal=3, **layout): def createGame(self, max_rounds=-1, num_deal=3, **layout):
l, s = Layout(self), self.s l, s = Layout(self), self.s
kwdefault(layout, rows=self.Rows, waste=1, texts=1, playcards=self.PlayCards) kwdefault(layout, rows=self.Rows, waste=1, texts=1,
playcards=self.PlayCards)
self.Layout_Method(l, **layout) self.Layout_Method(l, **layout)
self.setSize(l.size[0], l.size[1]) self.setSize(l.size[0], l.size[1])
# Create stacks # Create stacks
s.talon = self.Talon_Class(l.s.talon.x, l.s.talon.y, self, s.talon = self.Talon_Class(l.s.talon.x, l.s.talon.y, self,
max_rounds=max_rounds, num_deal=num_deal) max_rounds=max_rounds, num_deal=num_deal)
s.waste = WasteStack(l.s.waste.x, l.s.waste.y, self) s.waste = WasteStack(l.s.waste.x, l.s.waste.y, self)
for r in l.s.foundations: for r in l.s.foundations:
s.foundations.append(self.Foundation_Class(r.x, r.y, self, s.foundations.append(self.Foundation_Class(r.x, r.y, self,
suit=ANY_SUIT, base_rank=r.suit)) suit=ANY_SUIT, base_rank=r.suit))
for r in l.s.rows: for r in l.s.rows:
s.rows.append(self.RowStack_Class(r.x, r.y, self, yoffset=l.YOFFSET)) s.rows.append(
self.RowStack_Class(r.x, r.y, self, yoffset=l.YOFFSET))
l.defaultAll() l.defaultAll()
# #
@ -846,7 +873,6 @@ class LittleEasy(AbstractFlowerGame):
self.dealCards() self.dealCards()
# ************************************************************************ # ************************************************************************
# * Easy x One # * Easy x One
# ************************************************************************ # ************************************************************************
@ -857,7 +883,6 @@ class EasyX1(LittleEasy):
LittleEasy.createGame(self, max_rounds=2, num_deal=1) LittleEasy.createGame(self, max_rounds=2, num_deal=1)
# ************************************************************************ # ************************************************************************
# * Relax # * Relax
# ************************************************************************ # ************************************************************************
@ -866,7 +891,6 @@ class Relax(EasyX1):
RowStack_Class = Oonsoo_SequenceStack RowStack_Class = Oonsoo_SequenceStack
# ************************************************************************ # ************************************************************************
# * Big Easy # * Big Easy
# ************************************************************************ # ************************************************************************
@ -875,7 +899,6 @@ class BigEasy(LittleEasy):
Rows = 11 Rows = 11
# ************************************************************************ # ************************************************************************
# * Easy Supreme # * Easy Supreme
# ************************************************************************ # ************************************************************************
@ -885,7 +908,6 @@ class EasySupreme(LittleEasy):
PlayCards = 14 PlayCards = 14
# ************************************************************************ # ************************************************************************
# * Just For Fun # * Just For Fun
# ************************************************************************ # ************************************************************************
@ -905,7 +927,8 @@ class JustForFun(AbstractFlowerGame):
def createGame(self, **layout): def createGame(self, **layout):
l, s = Layout(self), self.s l, s = Layout(self), self.s
kwdefault(layout, rows=self.Rows, reserves=self.Reserves, texts=0, playcards=22) kwdefault(layout, rows=self.Rows, reserves=self.Reserves, texts=0,
playcards=22)
self.Layout_Method(l, **layout) self.Layout_Method(l, **layout)
self.setSize(l.size[0], l.size[1]) self.setSize(l.size[0], l.size[1])
@ -913,10 +936,10 @@ class JustForFun(AbstractFlowerGame):
s.talon = self.Talon_Class(l.s.talon.x, l.s.talon.y, self) s.talon = self.Talon_Class(l.s.talon.x, l.s.talon.y, self)
for r in l.s.foundations: for r in l.s.foundations:
s.foundations.append(self.Foundation_Class(r.x, r.y, self, s.foundations.append(self.Foundation_Class(r.x, r.y, self,
suit=ANY_SUIT, base_rank=r.suit)) suit=ANY_SUIT, base_rank=r.suit))
for r in l.s.rows: for r in l.s.rows:
s.rows.append(self.RowStack_Class(r.x, r.y, self, s.rows.append(self.RowStack_Class(r.x, r.y, self,
base_rank=self.BaseRank, yoffset=l.YOFFSET)) base_rank=self.BaseRank, yoffset=l.YOFFSET))
for r in l.s.reserves: for r in l.s.reserves:
s.reserves.append(ReserveStack(r.x, r.y, self)) s.reserves.append(ReserveStack(r.x, r.y, self))
l.defaultAll() l.defaultAll()
@ -935,7 +958,6 @@ class JustForFun(AbstractFlowerGame):
self.s.talon.dealCards() self.s.talon.dealCards()
# ************************************************************************ # ************************************************************************
# * Double Your Fun # * Double Your Fun
# ************************************************************************ # ************************************************************************
@ -945,7 +967,6 @@ class DoubleYourFun(JustForFun):
Reserves = 4 Reserves = 4
# ************************************************************************ # ************************************************************************
# * Firecracker # * Firecracker
# ************************************************************************ # ************************************************************************
@ -956,7 +977,6 @@ class Firecracker(JustForFun):
BaseRank = ANY_RANK BaseRank = ANY_RANK
# ************************************************************************ # ************************************************************************
# * Cherry Bomb # * Cherry Bomb
# ************************************************************************ # ************************************************************************
@ -965,7 +985,6 @@ class CherryBomb(Firecracker):
Rows = 18 Rows = 18
# ************************************************************************ # ************************************************************************
# * Paulownia # * Paulownia
# ************************************************************************ # ************************************************************************
@ -988,18 +1007,19 @@ class Paulownia(AbstractFlowerGame):
# Create talon # Create talon
s.talon = self.Talon_Class(l.s.talon.x, l.s.talon.y, self, s.talon = self.Talon_Class(l.s.talon.x, l.s.talon.y, self,
max_rounds=max_rounds, num_deal=num_deal) max_rounds=max_rounds, num_deal=num_deal)
s.waste = WasteStack(l.s.waste.x, l.s.waste.y, self) s.waste = WasteStack(l.s.waste.x, l.s.waste.y, self)
# Create foundations # Create foundations
for r in l.s.foundations: for r in l.s.foundations:
s.foundations.append(self.Foundation_Class(r.x, r.y, self, s.foundations.append(self.Foundation_Class(r.x, r.y, self,
suit=r.suit, base_rank=3)) suit=r.suit,
base_rank=3))
# Create row stacks # Create row stacks
for r in l.s.rows: for r in l.s.rows:
s.rows.append(self.RowStack_Class(r.x, r.y, self, s.rows.append(self.RowStack_Class(r.x, r.y, self,
base_rank = 0, yoffset=l.YOFFSET)) base_rank=0, yoffset=l.YOFFSET))
# Define stack groups # Define stack groups
l.defaultAll() l.defaultAll()
@ -1017,7 +1037,6 @@ class Paulownia(AbstractFlowerGame):
self.s.talon.dealCards() self.s.talon.dealCards()
# ************************************************************************ # ************************************************************************
# * Register the games # * Register the games
# ************************************************************************ # ************************************************************************
@ -1029,15 +1048,20 @@ def r(id, gameclass, name, game_type, decks, redeals, skill_level):
registerGame(gi) registerGame(gi)
return gi return gi
r(12345, Oonsoo, "Oonsoo", GI.GT_HANAFUDA, 1, 0, GI.SL_MOSTLY_SKILL) r(12345, Oonsoo, "Oonsoo", GI.GT_HANAFUDA, 1, 0, GI.SL_MOSTLY_SKILL)
r(12346, MatsuKiri, "MatsuKiri", GI.GT_HANAFUDA | GI.GT_OPEN, 1, 0, GI.SL_MOSTLY_SKILL) r(12346, MatsuKiri, "MatsuKiri", GI.GT_HANAFUDA | GI.GT_OPEN, 1, 0,
r(12372, MatsuKiriStrict, 'MatsuKiri Strict', GI.GT_HANAFUDA | GI.GT_OPEN, 1, 0, GI.SL_MOSTLY_SKILL) GI.SL_MOSTLY_SKILL)
r(12372, MatsuKiriStrict, 'MatsuKiri Strict', GI.GT_HANAFUDA | GI.GT_OPEN, 1,
0, GI.SL_MOSTLY_SKILL)
r(12347, Gaji, "Gaji", GI.GT_HANAFUDA | GI.GT_OPEN, 1, 0, GI.SL_MOSTLY_SKILL) r(12347, Gaji, "Gaji", GI.GT_HANAFUDA | GI.GT_OPEN, 1, 0, GI.SL_MOSTLY_SKILL)
r(12348, FlowerClock, "Flower Clock", GI.GT_HANAFUDA | GI.GT_OPEN, 1, 0, GI.SL_MOSTLY_SKILL) r(12348, FlowerClock, "Flower Clock", GI.GT_HANAFUDA | GI.GT_OPEN, 1, 0,
GI.SL_MOSTLY_SKILL)
r(12349, Pagoda, "Pagoda", GI.GT_HANAFUDA, 2, 0, GI.SL_BALANCED) r(12349, Pagoda, "Pagoda", GI.GT_HANAFUDA, 2, 0, GI.SL_BALANCED)
r(12350, Samuri, "Samuri", GI.GT_HANAFUDA, 1, 0, GI.SL_BALANCED) r(12350, Samuri, "Samuri", GI.GT_HANAFUDA, 1, 0, GI.SL_BALANCED)
r(12351, GreatWall, "Great Wall", GI.GT_HANAFUDA, 4, 0, GI.SL_MOSTLY_SKILL) r(12351, GreatWall, "Great Wall", GI.GT_HANAFUDA, 4, 0, GI.SL_MOSTLY_SKILL)
r(12352, FourWinds, "Hanafuda Four Winds", GI.GT_HANAFUDA, 1, 1, GI.SL_MOSTLY_SKILL) r(12352, FourWinds, "Hanafuda Four Winds", GI.GT_HANAFUDA, 1, 1,
GI.SL_MOSTLY_SKILL)
r(12353, Sumo, "Sumo", GI.GT_HANAFUDA, 1, 0, GI.SL_MOSTLY_SKILL) r(12353, Sumo, "Sumo", GI.GT_HANAFUDA, 1, 0, GI.SL_MOSTLY_SKILL)
r(12354, BigSumo, "Big Sumo", GI.GT_HANAFUDA, 2, 0, GI.SL_MOSTLY_SKILL) r(12354, BigSumo, "Big Sumo", GI.GT_HANAFUDA, 2, 0, GI.SL_MOSTLY_SKILL)
r(12355, LittleEasy, "Little Easy", GI.GT_HANAFUDA, 1, -1, GI.SL_BALANCED) r(12355, LittleEasy, "Little Easy", GI.GT_HANAFUDA, 1, -1, GI.SL_BALANCED)
@ -1049,11 +1073,14 @@ r(12360, EasyX1, "Easy x One", GI.GT_HANAFUDA, 1, 1, GI.SL_BALANCED)
r(12361, Relax, "Relax", GI.GT_HANAFUDA, 1, 1, GI.SL_BALANCED) r(12361, Relax, "Relax", GI.GT_HANAFUDA, 1, 1, GI.SL_BALANCED)
r(12362, DoubleSamuri, "Double Samuri", GI.GT_HANAFUDA, 2, 0, GI.SL_BALANCED) r(12362, DoubleSamuri, "Double Samuri", GI.GT_HANAFUDA, 2, 0, GI.SL_BALANCED)
r(12363, SuperSamuri, "Super Samuri", GI.GT_HANAFUDA, 4, 0, GI.SL_BALANCED) r(12363, SuperSamuri, "Super Samuri", GI.GT_HANAFUDA, 4, 0, GI.SL_BALANCED)
r(12364, DoubleYourFun, "Double Your Fun", GI.GT_HANAFUDA, 2, 0, GI.SL_MOSTLY_SKILL) r(12364, DoubleYourFun, "Double Your Fun", GI.GT_HANAFUDA, 2, 0,
GI.SL_MOSTLY_SKILL)
r(12365, CherryBomb, "Cherry Bomb", GI.GT_HANAFUDA, 2, 0, GI.SL_BALANCED) r(12365, CherryBomb, "Cherry Bomb", GI.GT_HANAFUDA, 2, 0, GI.SL_BALANCED)
r(12366, OonsooToo, "Oonsoo Too", GI.GT_HANAFUDA, 1, 0, GI.SL_MOSTLY_SKILL) r(12366, OonsooToo, "Oonsoo Too", GI.GT_HANAFUDA, 1, 0, GI.SL_MOSTLY_SKILL)
r(12367, OonsooStrict, "Oonsoo Strict", GI.GT_HANAFUDA, 1, 0, GI.SL_MOSTLY_SKILL) r(12367, OonsooStrict, "Oonsoo Strict", GI.GT_HANAFUDA, 1, 0,
GI.SL_MOSTLY_SKILL)
r(12368, OonsooOpen, "Oonsoo Open", GI.GT_HANAFUDA, 1, 0, GI.SL_MOSTLY_SKILL) r(12368, OonsooOpen, "Oonsoo Open", GI.GT_HANAFUDA, 1, 0, GI.SL_MOSTLY_SKILL)
r(12379, OonsooTimesTwo, "Oonsoo Times Two", GI.GT_HANAFUDA, 2, 0, GI.SL_MOSTLY_SKILL) r(12379, OonsooTimesTwo, "Oonsoo Times Two", GI.GT_HANAFUDA, 2, 0,
GI.SL_MOSTLY_SKILL)
del r del r

View file

@ -23,26 +23,48 @@
__all__ = [] __all__ = []
import sys
# PySol imports # PySol imports
from pysollib.mygettext import _, n_ from pysollib.mygettext import _
from pysollib.gamedb import registerGame, GameInfo, GI from pysollib.gamedb import registerGame, GameInfo, GI
from pysollib.util import *
from pysollib.mfxutil import kwdefault from pysollib.mfxutil import kwdefault
from pysollib.stack import *
from pysollib.game import Game from pysollib.game import Game
from pysollib.layout import Layout from pysollib.layout import Layout
from pysollib.hint import AbstractHint, DefaultHint, CautiousDefaultHint from pysollib.hint import AbstractHint, CautiousDefaultHint
from pysollib.pysoltk import MfxCanvasText from pysollib.pysoltk import MfxCanvasText
from hanafuda_common import * from hanafuda_common import \
Flower_OpenStack, \
FlowerClock_RowStack, \
HanafudaRK_RowStack, \
Hanafuda_SS_FoundationStack, \
Hanafuda_SequenceStack, \
JapaneseGarden_RowStack, \
Queue_BraidStack, \
Queue_Foundation, \
Queue_Hint, \
Queue_ReserveStack, \
Queue_RowStack, \
Samuri_RowStack, \
AbstractFlowerGame
from pysollib.util import ANY_RANK, ANY_SUIT, NO_RANK
from pysollib.stack import \
BasicRowStack, \
DealRowTalonStack, \
InitialDealTalonStack, \
OpenStack, \
ReserveStack, \
StackWrapper, \
WasteStack, \
WasteTalonStack
# ************************************************************************ # ************************************************************************
# * Paulownia # * Paulownia
# ************************************************************************ # ************************************************************************
class Paulownia(AbstractFlowerGame): class Paulownia(AbstractFlowerGame):
Layout_Method = Layout.klondikeLayout Layout_Method = Layout.klondikeLayout
Talon_Class = WasteTalonStack Talon_Class = WasteTalonStack
@ -64,18 +86,19 @@ class Paulownia(AbstractFlowerGame):
# Create talon # Create talon
s.talon = self.Talon_Class(l.s.talon.x, l.s.talon.y, self, s.talon = self.Talon_Class(l.s.talon.x, l.s.talon.y, self,
max_rounds=self.MaxRounds, num_deal=self.NumDeal) max_rounds=self.MaxRounds,
num_deal=self.NumDeal)
s.waste = WasteStack(l.s.waste.x, l.s.waste.y, self) s.waste = WasteStack(l.s.waste.x, l.s.waste.y, self)
# Create foundations # Create foundations
for r in l.s.foundations: for r in l.s.foundations:
s.foundations.append(self.Foundation_Class(r.x, r.y, self, s.foundations.append(self.Foundation_Class(r.x, r.y, self,
suit=r.suit, base_rank=3)) suit=r.suit, base_rank=3))
# Create row stacks # Create row stacks
for r in l.s.rows: for r in l.s.rows:
s.rows.append(self.RowStack_Class(r.x, r.y, self, s.rows.append(self.RowStack_Class(r.x, r.y, self,
base_rank=self.BaseRank, yoffset=l.YOFFSET)) base_rank=self.BaseRank, yoffset=l.YOFFSET))
# Define stack groups # Define stack groups
l.defaultAll() l.defaultAll()
@ -93,7 +116,6 @@ class Paulownia(AbstractFlowerGame):
self.s.talon.dealCards() self.s.talon.dealCards()
class Pine(Paulownia): class Pine(Paulownia):
MaxRounds = 1 MaxRounds = 1
NumDeal = 3 NumDeal = 3
@ -111,7 +133,6 @@ class Iris(Peony):
MaxRounds = 1 MaxRounds = 1
# ************************************************************************ # ************************************************************************
# * Queue # * Queue
# ************************************************************************ # ************************************************************************
@ -139,13 +160,14 @@ class LesserQueue(AbstractFlowerGame):
self.base_card = None self.base_card = None
# Create rows, reserves # Create rows, reserves
s.addattr(braid = None) s.addattr(braid=None)
x, x0 = l.XM + l.XS * 2, (decks - 1.5) % 2.5 x, x0 = l.XM + l.XS * 2, (decks - 1.5) % 2.5
for j in range(decks / 2): for j in range(decks / 2):
y = l.YM y = l.YM
for i in range(2): for i in range(2):
s.rows.append(Queue_RowStack(x + l.XS * (x0 + j), y, self)) s.rows.append(Queue_RowStack(x + l.XS * (x0 + j), y, self))
s.rows.append(Queue_RowStack(x + l.XS * (4 + x0 + j + .5), y, self)) s.rows.append(Queue_RowStack(x + l.XS * (4 + x0 + j + .5), y,
self))
y = y + l.YS * (3 + (decks > 2)) y = y + l.YS * (3 + (decks > 2))
y = l.YM + l.YS y = l.YM + l.YS
for i in range(2): for i in range(2):
@ -166,10 +188,11 @@ class LesserQueue(AbstractFlowerGame):
x, y = l.XM, h-l.YS x, y = l.XM, h-l.YS
s.talon = WasteTalonStack(x, y, self, max_rounds=3) s.talon = WasteTalonStack(x, y, self, max_rounds=3)
l.createText(s.talon, "n") l.createText(s.talon, "n")
s.talon.texts.rounds = MfxCanvasText(self.canvas, s.talon.texts.rounds = MfxCanvasText(
self.width/2, h-2*l.TEXT_MARGIN, self.canvas,
anchor="center", self.width/2, h-2*l.TEXT_MARGIN,
font=self.app.getFont("canvas_default")) anchor="center",
font=self.app.getFont("canvas_default"))
x = x + l.XS x = x + l.XS
s.waste = WasteStack(x, y, self) s.waste = WasteStack(x, y, self)
l.createText(s.waste, "n") l.createText(s.waste, "n")
@ -179,23 +202,27 @@ class LesserQueue(AbstractFlowerGame):
for j in range(decks / 2): for j in range(decks / 2):
y = l.YM y = l.YM
for i in range(4): for i in range(4):
s.foundations.append(Queue_Foundation(x, y, self, -1, mod=12, s.foundations.append(Queue_Foundation(
max_cards=12, base_suit=ANY_SUIT, base_rank=i, rank=i)) x, y, self, -1, mod=12,
s.foundations.append(Queue_Foundation(x + l.XS * (9.5 - j * 2), y, self, -1, mod=12, max_cards=12, base_suit=ANY_SUIT, base_rank=i, rank=i))
max_cards=12, base_suit=ANY_SUIT, base_rank=i, rank=i)) s.foundations.append(
Queue_Foundation(
x + l.XS * (9.5 - j * 2),
y, self, -1, mod=12,
max_cards=12, base_suit=ANY_SUIT, base_rank=i, rank=i))
y = y + l.YS y = y + l.YS
x = x + l.XS x = x + l.XS
self.texts.info = MfxCanvasText(self.canvas, self.texts.info = MfxCanvasText(
self.width/2, h-l.TEXT_MARGIN, self.canvas,
anchor="center", self.width/2, h-l.TEXT_MARGIN,
font=self.app.getFont("canvas_default")) anchor="center",
font=self.app.getFont("canvas_default"))
# define stack-groups # define stack-groups
self.sg.talonstacks = [s.talon] + [s.waste] self.sg.talonstacks = [s.talon] + [s.waste]
self.sg.openstacks = s.foundations + s.rows + s.reserves self.sg.openstacks = s.foundations + s.rows + s.reserves
self.sg.dropstacks = [s.braid] + s.rows + [s.waste] + s.reserves self.sg.dropstacks = [s.braid] + s.rows + [s.waste] + s.reserves
# #
# game overrides # game overrides
# #
@ -206,7 +233,7 @@ class LesserQueue(AbstractFlowerGame):
self.base_card = None self.base_card = None
self.updateText() self.updateText()
for i in range(self.BRAID_CARDS): for i in range(self.BRAID_CARDS):
self.s.talon.dealRow(rows = [self.s.braid]) self.s.talon.dealRow(rows=[self.s.braid])
self.s.talon.dealRow() self.s.talon.dealRow()
# deal base_card to foundations, update cap.base_rank # deal base_card to foundations, update cap.base_rank
self.base_card = self.s.talon.getCard() self.base_card = self.s.talon.getCard()
@ -221,7 +248,8 @@ class LesserQueue(AbstractFlowerGame):
def shallHighlightMatch(self, stack1, card1, stack2, card2): def shallHighlightMatch(self, stack1, card1, stack2, card2):
return (card1.rank == card2.rank and return (card1.rank == card2.rank and
((card1.suit + 1) % 12 == card2.suit or (card2.suit + 1) % 12 == card1.suit)) ((card1.suit + 1) % 12 == card2.suit or
(card2.suit + 1) % 12 == card1.suit))
def getHighlightPilesStacks(self): def getHighlightPilesStacks(self):
return () return ()
@ -238,7 +266,6 @@ class LesserQueue(AbstractFlowerGame):
def _saveGameHook(self, p): def _saveGameHook(self, p):
p.dump(self.base_card.id) p.dump(self.base_card.id)
# #
# game extras # game extras
# #
@ -255,7 +282,7 @@ class LesserQueue(AbstractFlowerGame):
t = t + _(" Ascending") t = t + _(" Ascending")
elif dir == 11: elif dir == 11:
t = t + _(" Descending") t = t + _(" Descending")
self.texts.info.config(text = t) self.texts.info.config(text=t)
def getFoundationDir(self): def getFoundationDir(self):
for s in self.s.foundations: for s in self.s.foundations:
@ -264,14 +291,12 @@ class LesserQueue(AbstractFlowerGame):
return 0 return 0
class GreaterQueue(LesserQueue): class GreaterQueue(LesserQueue):
Hint_Class = Queue_Hint Hint_Class = Queue_Hint
BRAID_CARDS = 40 BRAID_CARDS = 40
BRAID_OFFSET = .5 BRAID_OFFSET = .5
# ************************************************************************ # ************************************************************************
# * Japanese Garden # * Japanese Garden
# ************************************************************************ # ************************************************************************
@ -297,7 +322,6 @@ class JapaneseGarden(AbstractFlowerGame):
def createGame(self): def createGame(self):
l, s = Layout(self), self.s l, s = Layout(self), self.s
font = self.app.getFont("canvas_card")
# Set window size # Set window size
self.setSize(l.XM + l.XS * self.WIDTH, l.YM * 3 + l.YS * self.HEIGHT) self.setSize(l.XM + l.XS * self.WIDTH, l.YM * 3 + l.YS * self.HEIGHT)
@ -307,8 +331,10 @@ class JapaneseGarden(AbstractFlowerGame):
y = l.YM y = l.YM
for j in range(2): for j in range(2):
for i in range(6): for i in range(6):
s.foundations.append(Hanafuda_SS_FoundationStack(x, y, self, i + (j * 6), s.foundations.append(
max_cards=4, max_accept=1, base_rank=3)) Hanafuda_SS_FoundationStack(
x, y, self, i + (j * 6),
max_cards=4, max_accept=1, base_rank=3))
x = x + l.XS x = x + l.XS
x = self.width / 2 + l.XM / 2 - l.XS * 3 x = self.width / 2 + l.XM / 2 - l.XS * 3
y = y + l.YS y = y + l.YS
@ -318,8 +344,10 @@ class JapaneseGarden(AbstractFlowerGame):
y = l.YM * 2 + l.YS * 2 y = l.YM * 2 + l.YS * 2
for j in range(self.YROWS): for j in range(self.YROWS):
for i in range(self.XROWS): for i in range(self.XROWS):
row = self.RowStack_Class(x, y, self, yoffset=0, max_accept=self.MAX_MOVE, row = self.RowStack_Class(
max_move=self.MAX_MOVE, max_cards=self.MAX_CARDS, base_rank=0) x, y, self, yoffset=0, max_accept=self.MAX_MOVE,
max_move=self.MAX_MOVE, max_cards=self.MAX_CARDS,
base_rank=0)
row.CARD_XOFFSET = l.CW / 2 row.CARD_XOFFSET = l.CW / 2
s.rows.append(row) s.rows.append(row)
x = x + self.width / self.XROWS x = x + self.width / self.XROWS
@ -331,12 +359,14 @@ class JapaneseGarden(AbstractFlowerGame):
x = self.width / 2 + l.XM / 2 - (l.XS * self.XRESERVES) / 2 x = self.width / 2 + l.XM / 2 - (l.XS * self.XRESERVES) / 2
for j in range(self.YRESERVES): for j in range(self.YRESERVES):
for i in range(self.XRESERVES): for i in range(self.XRESERVES):
s.reserves.append(ReserveStack(x, y, self, max_accept=self.MAX_RESERVE)) s.reserves.append(
ReserveStack(x, y, self, max_accept=self.MAX_RESERVE))
x = x + l.XS x = x + l.XS
x = self.width / 2 + l.XM / 2 - l.XS * (self.XRESERVES / 2) x = self.width / 2 + l.XM / 2 - l.XS * (self.XRESERVES / 2)
y = y + l.YS y = y + l.YS
if s.reserves: if s.reserves:
self.setRegion(s.reserves, (l.XM, l.YS * (2 + self.YROWS), 999999, 999999)) self.setRegion(
s.reserves, (l.XM, l.YS * (2 + self.YROWS), 999999, 999999))
# Create talon # Create talon
s.talon = InitialDealTalonStack(l.XM, l.YM, self) s.talon = InitialDealTalonStack(l.XM, l.YM, self)
@ -358,12 +388,10 @@ class JapaneseGarden(AbstractFlowerGame):
self.s.talon.dealCards() self.s.talon.dealCards()
class JapaneseGardenII(JapaneseGarden): class JapaneseGardenII(JapaneseGarden):
RowStack_Class = JapaneseGarden_RowStack RowStack_Class = JapaneseGarden_RowStack
class JapaneseGardenIII(JapaneseGardenII): class JapaneseGardenIII(JapaneseGardenII):
XROWS = 2 XROWS = 2
YROWS = 4 YROWS = 4
@ -393,7 +421,6 @@ class SixTengus(SixSages):
YRESERVES = 0 YRESERVES = 0
# ************************************************************************ # ************************************************************************
# * Hanafuda Four Seasons # * Hanafuda Four Seasons
# ************************************************************************ # ************************************************************************
@ -406,7 +433,6 @@ class HanafudaFourSeasons(AbstractFlowerGame):
def createGame(self): def createGame(self):
l, s = Layout(self), self.s l, s = Layout(self), self.s
font = self.app.getFont("canvas_card")
# Set window size # Set window size
self.setSize(l.XM + l.XS * 7, l.YM + l.YS * 5) self.setSize(l.XM + l.XS * 7, l.YM + l.YS * 5)
@ -415,12 +441,12 @@ class HanafudaFourSeasons(AbstractFlowerGame):
x, y, offset = l.XM, l.YM, self.app.images.CARD_YOFFSET x, y, offset = l.XM, l.YM, self.app.images.CARD_YOFFSET
for i in range(6): for i in range(6):
s.rows.append(Samuri_RowStack(x, y, self, offset, max_cards=8, s.rows.append(Samuri_RowStack(x, y, self, offset, max_cards=8,
max_accept=8, base_rank=0)) max_accept=8, base_rank=0))
x = x + l.XS + l.XM + (l.XM * (i == 2)) x = x + l.XS + l.XM + (l.XM * (i == 2))
x, y = l.XM, y + l.YS * 2.5 x, y = l.XM, y + l.YS * 2.5
for i in range(6): for i in range(6):
s.rows.append(Samuri_RowStack(x, y, self, offset, max_cards=8, s.rows.append(Samuri_RowStack(x, y, self, offset, max_cards=8,
max_accept=8, base_rank=0)) max_accept=8, base_rank=0))
x = x + l.XS + l.XM + (l.XM * (i == 2)) x = x + l.XS + l.XM + (l.XM * (i == 2))
self.setRegion(s.rows, (0, 0, 999999, 999999)) self.setRegion(s.rows, (0, 0, 999999, 999999))
@ -440,7 +466,6 @@ class HanafudaFourSeasons(AbstractFlowerGame):
for i in range(4): for i in range(4):
self.s.talon.dealRow(flip=1) self.s.talon.dealRow(flip=1)
# #
# Game extras # Game extras
# #
@ -456,7 +481,6 @@ class HanafudaFourSeasons(AbstractFlowerGame):
return 1 return 1
# ************************************************************************ # ************************************************************************
# * Wisteria # * Wisteria
# ************************************************************************ # ************************************************************************
@ -479,10 +503,14 @@ class Wisteria(AbstractFlowerGame):
x, y = self.width / 2 - l.XS * 3, l.YM x, y = self.width / 2 - l.XS * 3, l.YM
for i in range(2): for i in range(2):
for suit in range(6): for suit in range(6):
s.foundations.append(Hanafuda_SS_FoundationStack(x, y, self, suit=suit + (6 * i))) s.foundations.append(
Hanafuda_SS_FoundationStack(
x, y, self, suit=suit + (6 * i)))
x = x + l.XS x = x + l.XS
x, y = self.width / 2 - l.XS * 3, y + l.YS x, y = self.width / 2 - l.XS * 3, y + l.YS
self.setRegion(self.s.foundations, (-999, -999, 999999, l.YM + l.YS * 2), priority=1) self.setRegion(
self.s.foundations, (-999, -999, 999999, l.YM + l.YS * 2),
priority=1)
x, y = l.XM, l.YM + l.YS * 2 x, y = l.XM, l.YM + l.YS * 2
for i in range(rows): for i in range(rows):
stack = self.RowStack_Class(x, y, self, yoffset=l.YOFFSET) stack = self.RowStack_Class(x, y, self, yoffset=l.YOFFSET)
@ -507,7 +535,6 @@ class Wisteria(AbstractFlowerGame):
self.s.talon.dealRow(rows=[self.s.rows[i]], frames=4) self.s.talon.dealRow(rows=[self.s.rows[i]], frames=4)
# ************************************************************************ # ************************************************************************
# * Flower Arrangement Hint # * Flower Arrangement Hint
# ************************************************************************ # ************************************************************************
@ -582,7 +609,8 @@ class FlowerArrangement_Hint(AbstractHint):
class FlowerArrangement_TableauStack(Flower_OpenStack): class FlowerArrangement_TableauStack(Flower_OpenStack):
def __init__(self, x, y, game, yoffset, **cap): def __init__(self, x, y, game, yoffset, **cap):
kwdefault(cap, dir=-1, max_move=1, max_cards=4, max_accept=1, base_rank=3) kwdefault(cap, dir=-1, max_move=1, max_cards=4, max_accept=1,
base_rank=3)
OpenStack.__init__(self, x, y, game, **cap) OpenStack.__init__(self, x, y, game, **cap)
self.CARD_YOFFSET = yoffset self.CARD_YOFFSET = yoffset
@ -592,7 +620,7 @@ class FlowerArrangement_TableauStack(Flower_OpenStack):
# check that the base card is correct # check that the base card is correct
suits = range(self.cap.mod, (self.cap.mod + 4)) suits = range(self.cap.mod, (self.cap.mod + 4))
if self.cards and (self.cards[0].rank == 3 if self.cards and (self.cards[0].rank == 3
and self.cards[-1].suit in suits): and self.cards[-1].suit in suits):
return self.isHanafudaSequence([self.cards[-1], cards[0]]) return self.isHanafudaSequence([self.cards[-1], cards[0]])
return not self.cards and cards[0].rank == 3 and cards[0].suit in suits return not self.cards and cards[0].rank == 3 and cards[0].suit in suits
@ -641,7 +669,9 @@ class FlowerArrangement(Game):
for i in range(3): for i in range(3):
x = l.XM x = l.XM
for j in range(8): for j in range(8):
s.tableaux.append(FlowerArrangement_TableauStack(x, y, self, TABLEAU_YOFFSET, mod=i * 4)) s.tableaux.append(
FlowerArrangement_TableauStack(
x, y, self, TABLEAU_YOFFSET, mod=i * 4))
x = x + l.XS x = x + l.XS
y = y + th y = y + th
x, y = l.XM, y + l.YM x, y = l.XM, y + l.YM
@ -697,20 +727,28 @@ def r(id, gameclass, name, game_type, decks, redeals, skill_level):
registerGame(gi) registerGame(gi)
return gi return gi
r(12369, Paulownia, 'Paulownia', GI.GT_HANAFUDA, 1, -1, GI.SL_BALANCED) r(12369, Paulownia, 'Paulownia', GI.GT_HANAFUDA, 1, -1, GI.SL_BALANCED)
r(12370, LesserQueue, 'Lesser Queue', GI.GT_HANAFUDA, 2, 2, GI.SL_BALANCED) r(12370, LesserQueue, 'Lesser Queue', GI.GT_HANAFUDA, 2, 2, GI.SL_BALANCED)
r(12371, GreaterQueue, 'Greater Queue', GI.GT_HANAFUDA, 4, 2, GI.SL_BALANCED) r(12371, GreaterQueue, 'Greater Queue', GI.GT_HANAFUDA, 4, 2, GI.SL_BALANCED)
r(12373, JapaneseGarden, 'Japanese Garden', GI.GT_HANAFUDA | GI.GT_OPEN, 1, 0, GI.SL_MOSTLY_SKILL) r(12373, JapaneseGarden, 'Japanese Garden', GI.GT_HANAFUDA | GI.GT_OPEN, 1, 0,
r(12374, JapaneseGardenII, 'Japanese Garden II', GI.GT_HANAFUDA | GI.GT_OPEN, 1, 0, GI.SL_MOSTLY_SKILL) GI.SL_MOSTLY_SKILL)
r(12375, SixSages, 'Six Sages', GI.GT_HANAFUDA | GI.GT_OPEN, 1, 0, GI.SL_MOSTLY_SKILL) r(12374, JapaneseGardenII, 'Japanese Garden II', GI.GT_HANAFUDA | GI.GT_OPEN,
r(12376, SixTengus, 'Six Tengus', GI.GT_HANAFUDA | GI.GT_OPEN, 1, 0, GI.SL_MOSTLY_SKILL) 1, 0, GI.SL_MOSTLY_SKILL)
r(12377, JapaneseGardenIII, 'Japanese Garden III', GI.GT_HANAFUDA | GI.GT_OPEN, 1, 0, GI.SL_MOSTLY_SKILL) r(12375, SixSages, 'Six Sages', GI.GT_HANAFUDA | GI.GT_OPEN, 1, 0,
r(12378, HanafudaFourSeasons, 'Hanafuda Four Seasons', GI.GT_HANAFUDA | GI.GT_OPEN, 1, 0, GI.SL_MOSTLY_SKILL) GI.SL_MOSTLY_SKILL)
r(12376, SixTengus, 'Six Tengus', GI.GT_HANAFUDA | GI.GT_OPEN, 1, 0,
GI.SL_MOSTLY_SKILL)
r(12377, JapaneseGardenIII, 'Japanese Garden III', GI.GT_HANAFUDA | GI.GT_OPEN,
1, 0, GI.SL_MOSTLY_SKILL)
r(12378, HanafudaFourSeasons, 'Hanafuda Four Seasons',
GI.GT_HANAFUDA | GI.GT_OPEN, 1, 0, GI.SL_MOSTLY_SKILL)
r(12380, Eularia, 'Eularia', GI.GT_HANAFUDA, 1, -1, GI.SL_BALANCED) r(12380, Eularia, 'Eularia', GI.GT_HANAFUDA, 1, -1, GI.SL_BALANCED)
r(12381, Peony, 'Peony', GI.GT_HANAFUDA, 1, -1, GI.SL_BALANCED) r(12381, Peony, 'Peony', GI.GT_HANAFUDA, 1, -1, GI.SL_BALANCED)
r(12382, Iris, 'Iris', GI.GT_HANAFUDA, 1, 0, GI.SL_BALANCED) r(12382, Iris, 'Iris', GI.GT_HANAFUDA, 1, 0, GI.SL_BALANCED)
r(12383, Pine, 'Pine', GI.GT_HANAFUDA, 1, 0, GI.SL_BALANCED) r(12383, Pine, 'Pine', GI.GT_HANAFUDA, 1, 0, GI.SL_BALANCED)
r(12384, Wisteria, 'Wisteria', GI.GT_HANAFUDA, 1, 0, GI.SL_MOSTLY_SKILL) r(12384, Wisteria, 'Wisteria', GI.GT_HANAFUDA, 1, 0, GI.SL_MOSTLY_SKILL)
r(12385, FlowerArrangement, 'Flower Arrangement', GI.GT_HANAFUDA, 2, 0, GI.SL_BALANCED) r(12385, FlowerArrangement, 'Flower Arrangement', GI.GT_HANAFUDA, 2, 0,
GI.SL_BALANCED)
del r del r

View file

@ -50,43 +50,52 @@ __all__ = [
] ]
import sys, math import math
from pysollib.mygettext import _, n_ from pysollib.mygettext import _
from pysollib.util import *
from pysollib.mfxutil import kwdefault from pysollib.mfxutil import kwdefault
from pysollib.stack import *
from pysollib.game import Game from pysollib.game import Game
from pysollib.layout import Layout from pysollib.hint import DefaultHint
from pysollib.hint import AbstractHint, DefaultHint, CautiousDefaultHint
from pysollib.util import ANY_RANK, ANY_SUIT
from pysollib.stack import \
AbstractFoundationStack, \
OpenStack, \
ReserveStack, \
isRankSequence, \
cardsFaceUp
# ************************************************************************ # ************************************************************************
# * # *
# ***********************************************************************/ # ***********************************************************************/
class AbstractFlowerGame(Game): class AbstractFlowerGame(Game):
SUITS = (_("Pine"), _("Plum"), _("Cherry"), _("Wisteria"), SUITS = (_("Pine"), _("Plum"), _("Cherry"), _("Wisteria"),
_("Iris"), _("Peony"), _("Bush Clover"), _("Eularia"), _("Iris"), _("Peony"), _("Bush Clover"), _("Eularia"),
_("Chrysanthemum"), _("Maple"), _("Willow"), _("Paulownia")) _("Chrysanthemum"), _("Maple"), _("Willow"), _("Paulownia"))
def shallHighlightMatch(self, stack1, card1, stack2, card2): def shallHighlightMatch(self, stack1, card1, stack2, card2):
return ((card1.suit == card2.suit) return ((card1.suit == card2.suit)
and ((card1.rank + 1 == card2.rank) and ((card1.rank + 1 == card2.rank)
or (card1.rank - 1 == card2.rank))) or (card1.rank - 1 == card2.rank)))
class Queue_Hint(DefaultHint): class Queue_Hint(DefaultHint):
pass pass
# ************************************************************************ # ************************************************************************
# * Flower Foundation Stacks # * Flower Foundation Stacks
# ***********************************************************************/ # ***********************************************************************/
class Flower_FoundationStack(AbstractFoundationStack): class Flower_FoundationStack(AbstractFoundationStack):
def __init__(self, x, y, game, suit, **cap): def __init__(self, x, y, game, suit, **cap):
kwdefault(cap, max_cards=12, max_move=0, base_rank=ANY_RANK, base_suit=ANY_SUIT) kwdefault(cap, max_cards=12, max_move=0, base_rank=ANY_RANK,
base_suit=ANY_SUIT)
AbstractFoundationStack.__init__(self, x, y, game, suit, **cap) AbstractFoundationStack.__init__(self, x, y, game, suit, **cap)
def updateText(self): def updateText(self):
@ -115,6 +124,7 @@ class Flower_FoundationStack(AbstractFoundationStack):
def getBaseCard(self): def getBaseCard(self):
return '' # FIXME return '' # FIXME
def getHelp(self): def getHelp(self):
return '' # FIXME return '' # FIXME
@ -149,7 +159,8 @@ class FlowerClock_Foundation(Flower_FoundationStack):
class Gaji_Foundation(Flower_FoundationStack): class Gaji_Foundation(Flower_FoundationStack):
def __init__(self, x, y, game, suit, **cap): def __init__(self, x, y, game, suit, **cap):
kwdefault(cap, max_move=1, min_cards=1, max_accept=1, base_suit=ANY_SUIT) kwdefault(cap, max_move=1, min_cards=1, max_accept=1,
base_suit=ANY_SUIT)
Flower_FoundationStack.__init__(self, x, y, game, suit, **cap) Flower_FoundationStack.__init__(self, x, y, game, suit, **cap)
self.CARD_YOFFSET = self.game.app.images.CARD_YOFFSET self.CARD_YOFFSET = self.game.app.images.CARD_YOFFSET
@ -158,7 +169,7 @@ class Gaji_Foundation(Flower_FoundationStack):
return 0 return 0
stackcards = self.cards stackcards = self.cards
return ((((stackcards[-1].suit + 1) % 12) == cards[0].suit) return ((((stackcards[-1].suit + 1) % 12) == cards[0].suit)
and (stackcards[-1].rank == cards[0].rank)) and (stackcards[-1].rank == cards[0].rank))
def getBottomImage(self): def getBottomImage(self):
return self.game.app.images.getLetter(self.cap.base_rank) return self.game.app.images.getLetter(self.cap.base_rank)
@ -201,8 +212,8 @@ class MatsuKiri_Foundation(Flower_FoundationStack):
return cards[0].suit == 0 return cards[0].suit == 0
return stackcards[-1].suit + 1 == cards[0].suit return stackcards[-1].suit + 1 == cards[0].suit
## def getBottomImage(self): # def getBottomImage(self):
## return self.game.app.images.getBraidBottom() # return self.game.app.images.getBraidBottom()
class GreatWall_FoundationStack(Flower_FoundationStack): class GreatWall_FoundationStack(Flower_FoundationStack):
@ -239,8 +250,8 @@ class FourWinds_Foundation(Flower_FoundationStack):
else: else:
return (cards[0].suit == stackcards[-1].suit + 1) return (cards[0].suit == stackcards[-1].suit + 1)
## def getBottomImage(self): # def getBottomImage(self):
## return self.game.app.images.getLetter(self.cap.base_rank) # return self.game.app.images.getLetter(self.cap.base_rank)
class Queue_Foundation(AbstractFoundationStack): class Queue_Foundation(AbstractFoundationStack):
@ -264,8 +275,6 @@ class Queue_Foundation(AbstractFoundationStack):
return self.game.app.images.getLetter(self.cap.base_rank) return self.game.app.images.getLetter(self.cap.base_rank)
# ************************************************************************ # ************************************************************************
# * Flower Row Stacks # * Flower Row Stacks
# ***********************************************************************/ # ***********************************************************************/
@ -273,7 +282,8 @@ class Queue_Foundation(AbstractFoundationStack):
class Flower_OpenStack(OpenStack): class Flower_OpenStack(OpenStack):
def __init__(self, x, y, game, yoffset, **cap): def __init__(self, x, y, game, yoffset, **cap):
kwdefault(cap, max_move=99, max_cards=99, max_accept=99, base_rank=0, dir=1) kwdefault(cap, max_move=99, max_cards=99, max_accept=99, base_rank=0,
dir=1)
OpenStack.__init__(self, x, y, game, **cap) OpenStack.__init__(self, x, y, game, **cap)
self.CARD_YOFFSET = yoffset self.CARD_YOFFSET = yoffset
@ -303,8 +313,8 @@ class Flower_OpenStack(OpenStack):
class Hanafuda_SequenceStack(Flower_OpenStack): class Hanafuda_SequenceStack(Flower_OpenStack):
def acceptsCards(self, from_stack, cards): def acceptsCards(self, from_stack, cards):
if (not self.basicAcceptsCards(from_stack, cards) if not self.basicAcceptsCards(from_stack, cards) \
or not self.isHanafudaSequence(cards)): or not self.isHanafudaSequence(cards):
return 0 return 0
stackcards = self.cards stackcards = self.cards
if not len(stackcards): if not len(stackcards):
@ -315,8 +325,8 @@ class Hanafuda_SequenceStack(Flower_OpenStack):
class Oonsoo_SequenceStack(Flower_OpenStack): class Oonsoo_SequenceStack(Flower_OpenStack):
def acceptsCards(self, from_stack, cards): def acceptsCards(self, from_stack, cards):
if (not self.basicAcceptsCards(from_stack, cards) if not self.basicAcceptsCards(from_stack, cards) \
or not self.isHanafudaSequence(cards, 0)): or not self.isHanafudaSequence(cards, 0):
return 0 return 0
stackcards = self.cards stackcards = self.cards
if not len(stackcards): if not len(stackcards):
@ -376,7 +386,8 @@ class Matsukiri_RowStack(Flower_OpenStack):
suit = 0 suit = 0
else: else:
suit = f.cards[-1].suit + 1 suit = f.cards[-1].suit + 1
if not pile[-1].suit == suit or not self.isHanafudaSequence(pile[-4:], 0): if not pile[-1].suit == suit or \
not self.isHanafudaSequence(pile[-4:], 0):
return (None, 0) return (None, 0)
return (f, 4) return (f, 4)
@ -389,7 +400,8 @@ class Samuri_RowStack(Flower_OpenStack):
stackcards = self.cards stackcards = self.cards
if not stackcards: if not stackcards:
return cards[0].rank == 0 return cards[0].rank == 0
return stackcards[-1].suit == cards[0].suit and stackcards[-1].rank + 1 == cards[0].rank return stackcards[-1].suit == cards[0].suit and \
stackcards[-1].rank + 1 == cards[0].rank
class GreatWall_RowStack(Flower_OpenStack): class GreatWall_RowStack(Flower_OpenStack):
@ -416,7 +428,8 @@ class FourWinds_RowStack(Flower_OpenStack):
return 0 return 0
if not stackcards: if not stackcards:
return 1 return 1
return ((cards[0].rank == stackcards[-1].rank) and (cards[0].suit == stackcards[-1].suit - 1)) return ((cards[0].rank == stackcards[-1].rank) and
(cards[0].suit == stackcards[-1].suit - 1))
def getBottomImage(self): def getBottomImage(self):
return self.game.app.images.getReserveBottom() return self.game.app.images.getReserveBottom()
@ -426,7 +439,6 @@ class Queue_BraidStack(OpenStack):
def __init__(self, x, y, game, yoffset): def __init__(self, x, y, game, yoffset):
OpenStack.__init__(self, x, y, game) OpenStack.__init__(self, x, y, game)
CW = self.game.app.images.CARDW
self.CARD_YOFFSET = int(self.game.app.images.CARD_YOFFSET * yoffset) self.CARD_YOFFSET = int(self.game.app.images.CARD_YOFFSET * yoffset)
# use a sine wave for the x offsets # use a sine wave for the x offsets
# compensate for card width # compensate for card width
@ -463,7 +475,7 @@ class JapaneseGarden_RowStack(Flower_OpenStack):
def acceptsCards(self, from_stack, cards): def acceptsCards(self, from_stack, cards):
if (not self.basicAcceptsCards(from_stack, cards) if (not self.basicAcceptsCards(from_stack, cards)
or not from_stack in self.game.s.rows): or from_stack not in self.game.s.rows):
return 0 return 0
stackcards = self.cards stackcards = self.cards
if not len(stackcards): if not len(stackcards):
@ -481,9 +493,3 @@ class HanafudaRK_RowStack(Flower_OpenStack):
if not len(stackcards): if not len(stackcards):
return 1 return 1
return stackcards[-1].rank + 1 == cards[0].rank return stackcards[-1].rank + 1 == cards[0].rank

View file

@ -24,19 +24,31 @@
__all__ = [] __all__ = []
# Imports # Imports
import sys, math import math
# PySol imports # PySol imports
from pysollib.mygettext import _, n_ from pysollib.mygettext import _
from pysollib.gamedb import registerGame, GameInfo, GI from pysollib.gamedb import registerGame, GameInfo, GI
from pysollib.util import *
from pysollib.mfxutil import kwdefault from pysollib.mfxutil import kwdefault
from pysollib.stack import *
from pysollib.game import Game from pysollib.game import Game
from pysollib.layout import Layout from pysollib.layout import Layout
from pysollib.hint import AbstractHint, DefaultHint, CautiousDefaultHint from pysollib.hint import DefaultHint, CautiousDefaultHint
from pysollib.pysoltk import MfxCanvasText from pysollib.pysoltk import MfxCanvasText
from pysollib.util import ANY_RANK, ANY_SUIT, NO_RANK, UNLIMITED_ACCEPTS, \
UNLIMITED_MOVES
from pysollib.stack import \
AC_RowStack, \
AbstractFoundationStack, \
InitialDealTalonStack, \
ReserveStack, \
SS_FoundationStack, \
StackWrapper, \
WasteStack, \
WasteTalonStack, \
OpenStack
# ************************************************************************ # ************************************************************************
# * Hex A Deck Foundation Stacks # * Hex A Deck Foundation Stacks
@ -73,7 +85,8 @@ class Merlins_Foundation(AbstractFoundationStack):
card_dir = (cards[0].rank - self.cards[-1].rank) % self.cap.mod card_dir = (cards[0].rank - self.cards[-1].rank) % self.cap.mod
return card_dir in (1, 15) return card_dir in (1, 15)
else: else:
return (self.cards[-1].rank + stack_dir) % self.cap.mod == cards[0].rank return (self.cards[-1].rank + stack_dir) % self.cap.mod \
== cards[0].rank
# ************************************************************************ # ************************************************************************
@ -83,7 +96,8 @@ class Merlins_Foundation(AbstractFoundationStack):
class HexADeck_OpenStack(OpenStack): class HexADeck_OpenStack(OpenStack):
def __init__(self, x, y, game, yoffset, **cap): def __init__(self, x, y, game, yoffset, **cap):
kwdefault(cap, max_move=UNLIMITED_MOVES, max_accept=UNLIMITED_ACCEPTS, dir=-1) kwdefault(cap, max_move=UNLIMITED_MOVES, max_accept=UNLIMITED_ACCEPTS,
dir=-1)
OpenStack.__init__(self, x, y, game, **cap) OpenStack.__init__(self, x, y, game, **cap)
self.CARD_YOFFSET = yoffset self.CARD_YOFFSET = yoffset
@ -179,7 +193,7 @@ class Bits_RowStack(ReserveStack):
if not r.cards: if not r.cards:
return 0 return 0
return ((self.game.s.foundations[i].cards[-1].rank + 1 return ((self.game.s.foundations[i].cards[-1].rank + 1
>> (self.id % 4)) % 2 == (cards[0].rank + 1) % 2) >> (self.id % 4)) % 2 == (cards[0].rank + 1) % 2)
class Bytes_RowStack(ReserveStack): class Bytes_RowStack(ReserveStack):
@ -233,7 +247,6 @@ class Familiar_ReserveStack(ReserveStack):
class Merlins_BraidStack(OpenStack): class Merlins_BraidStack(OpenStack):
def __init__(self, x, y, game): def __init__(self, x, y, game):
OpenStack.__init__(self, x, y, game) OpenStack.__init__(self, x, y, game)
CW = self.game.app.images.CARDW
self.CARD_YOFFSET = self.game.app.images.CARD_YOFFSET self.CARD_YOFFSET = self.game.app.images.CARD_YOFFSET
# use a sine wave for the x offsets # use a sine wave for the x offsets
self.CARD_XOFFSET = [] self.CARD_XOFFSET = []
@ -302,7 +315,7 @@ class BitsNBytes(Game):
base_suit=j, max_move=0) base_suit=j, max_move=0)
s.rows.append(stack) s.rows.append(stack)
stack.texts.misc = MfxCanvasText(self.canvas, stack.texts.misc = MfxCanvasText(self.canvas,
x + l.CW / 2 , y + l.CH / 2, x + l.CW / 2, y + l.CH / 2,
anchor="center", font=font) anchor="center", font=font)
x = x - l.XS x = x - l.XS
y = y + l.YS y = y + l.YS
@ -312,8 +325,10 @@ class BitsNBytes(Game):
for j in range(4): for j in range(4):
x = l.XM * 3 + l.XS * 3 x = l.XM * 3 + l.XS * 3
for i in range(2): for i in range(2):
s.rows.append(Bytes_RowStack(x, y, self, max_cards=1, s.rows.append(
max_accept=1, base_suit=ANY_SUIT, max_move=0)) Bytes_RowStack(
x, y, self, max_cards=1,
max_accept=1, base_suit=ANY_SUIT, max_move=0))
x = x - l.XS x = x - l.XS
y = y + l.YS y = y + l.YS
@ -321,8 +336,10 @@ class BitsNBytes(Game):
x = l.XM * 2 + l.XS x = l.XM * 2 + l.XS
y = l.YM y = l.YM
for i in range(4): for i in range(4):
s.foundations.append(SS_FoundationStack(x, y, self, i, mod=1, s.foundations.append(
max_move=0, max_cards=1)) SS_FoundationStack(
x, y, self, i, mod=1,
max_move=0, max_cards=1))
y = y + l.YS y = y + l.YS
self.setRegion(s.rows, (0, 0, 999999, 999999)) self.setRegion(s.rows, (0, 0, 999999, 999999))
@ -351,7 +368,7 @@ class BitsNBytes(Game):
s = self.s.foundations[j].cards[-1].rank + 1 s = self.s.foundations[j].cards[-1].rank + 1
for i in range(4): for i in range(4):
stack = self.s.rows[i + j * 4] stack = self.s.rows[i + j * 4]
stack.texts.misc.config(text = str(s % 2)) stack.texts.misc.config(text=str(s % 2))
s = int(s / 2) s = int(s / 2)
def _shuffleHook(self, cards): def _shuffleHook(self, cards):
@ -409,22 +426,29 @@ class HexAKlon(Game):
self.setSize(l.size[0], l.size[1]) self.setSize(l.size[0], l.size[1])
# Create talon # Create talon
s.talon = self.Talon_Class(l.s.talon.x, l.s.talon.y, self, s.talon = self.Talon_Class(
max_rounds=max_rounds, num_deal=num_deal) l.s.talon.x, l.s.talon.y, self,
max_rounds=max_rounds, num_deal=num_deal)
s.waste = WasteStack(l.s.waste.x, l.s.waste.y, self) s.waste = WasteStack(l.s.waste.x, l.s.waste.y, self)
# Create foundations # Create foundations
for r in l.s.foundations[:4]: for r in l.s.foundations[:4]:
s.foundations.append(self.Foundation_Class(r.x, r.y, self, s.foundations.append(
r.suit, mod=16, max_cards=16, max_move=1)) self.Foundation_Class(
r.x, r.y, self,
r.suit, mod=16, max_cards=16, max_move=1))
r = l.s.foundations[4] r = l.s.foundations[4]
s.foundations.append(HexATrump_Foundation(r.x, r.y, self, 4, mod=4, s.foundations.append(
max_move=0, max_cards=4, base_rank=ANY_RANK)) HexATrump_Foundation(
r.x, r.y, self, 4, mod=4,
max_move=0, max_cards=4, base_rank=ANY_RANK))
# Create rows # Create rows
for r in l.s.rows: for r in l.s.rows:
s.rows.append(self.RowStack_Class(r.x, r.y, self, s.rows.append(
suit=ANY_SUIT, base_rank=ANY_RANK)) self.RowStack_Class(
r.x, r.y, self,
suit=ANY_SUIT, base_rank=ANY_RANK))
# Define stack groups # Define stack groups
l.defaultAll() l.defaultAll()
@ -468,22 +492,29 @@ class HexAKlonByThrees(Game):
self.setSize(l.size[0], l.size[1]) self.setSize(l.size[0], l.size[1])
# Create talon # Create talon
s.talon = self.Talon_Class(l.s.talon.x, l.s.talon.y, self, s.talon = self.Talon_Class(
max_rounds=max_rounds, num_deal=num_deal) l.s.talon.x, l.s.talon.y, self,
max_rounds=max_rounds, num_deal=num_deal)
s.waste = WasteStack(l.s.waste.x, l.s.waste.y, self) s.waste = WasteStack(l.s.waste.x, l.s.waste.y, self)
# Create foundations # Create foundations
for r in l.s.foundations[:4]: for r in l.s.foundations[:4]:
s.foundations.append(self.Foundation_Class(r.x, r.y, self, s.foundations.append(
r.suit, mod=16, max_cards=16, max_move=1)) self.Foundation_Class(
r.x, r.y, self,
r.suit, mod=16, max_cards=16, max_move=1))
r = l.s.foundations[4] r = l.s.foundations[4]
s.foundations.append(HexATrump_Foundation(r.x, r.y, self, 4, mod=4, s.foundations.append(
max_move=0, max_cards=4, base_rank=ANY_RANK)) HexATrump_Foundation(
r.x, r.y, self, 4, mod=4,
max_move=0, max_cards=4, base_rank=ANY_RANK))
# Create rows # Create rows
for r in l.s.rows: for r in l.s.rows:
s.rows.append(self.RowStack_Class(r.x, r.y, self, s.rows.append(
suit=ANY_SUIT, base_rank=ANY_RANK)) self.RowStack_Class(
r.x, r.y, self,
suit=ANY_SUIT, base_rank=ANY_RANK))
# Define stack groups # Define stack groups
l.defaultAll() l.defaultAll()
@ -528,21 +559,25 @@ class KingOnlyHexAKlon(Game):
# Create talon # Create talon
s.talon = self.Talon_Class(l.s.talon.x, l.s.talon.y, self, s.talon = self.Talon_Class(l.s.talon.x, l.s.talon.y, self,
max_rounds=max_rounds, num_deal=num_deal) max_rounds=max_rounds, num_deal=num_deal)
s.waste = WasteStack(l.s.waste.x, l.s.waste.y, self) s.waste = WasteStack(l.s.waste.x, l.s.waste.y, self)
# Create foundations # Create foundations
for r in l.s.foundations[:4]: for r in l.s.foundations[:4]:
s.foundations.append(self.Foundation_Class(r.x, r.y, self, s.foundations.append(
r.suit, mod=16, max_cards=16, max_move=1)) self.Foundation_Class(
r.x, r.y, self,
r.suit, mod=16, max_cards=16, max_move=1))
r = l.s.foundations[4] r = l.s.foundations[4]
s.foundations.append(HexATrump_Foundation(r.x, r.y, self, 4, mod=4, s.foundations.append(
max_move=0, max_cards=4, base_rank=ANY_RANK)) HexATrump_Foundation(
r.x, r.y, self, 4, mod=4,
max_move=0, max_cards=4, base_rank=ANY_RANK))
# Create rows # Create rows
for r in l.s.rows: for r in l.s.rows:
s.rows.append(self.RowStack_Class(r.x, r.y, self, s.rows.append(self.RowStack_Class(r.x, r.y, self,
suit=ANY_SUIT, base_rank=15)) suit=ANY_SUIT, base_rank=15))
# Define stack groups # Define stack groups
l.defaultAll() l.defaultAll()
@ -563,7 +598,7 @@ class KingOnlyHexAKlon(Game):
basecard = [None] basecard = [None]
for c in cards[:]: for c in cards[:]:
if c.suit == 4: if c.suit == 4:
if basecard[0] == None: if basecard[0] is None:
basecard[0] = c basecard[0] = c
cards.remove(c) cards.remove(c)
cards = basecard + cards cards = basecard + cards
@ -598,18 +633,20 @@ class KlondikePlus16(Game):
# Create talon # Create talon
s.talon = self.Talon_Class(l.s.talon.x, l.s.talon.y, self, s.talon = self.Talon_Class(l.s.talon.x, l.s.talon.y, self,
max_rounds=max_rounds, num_deal=num_deal) max_rounds=max_rounds, num_deal=num_deal)
s.waste = WasteStack(l.s.waste.x, l.s.waste.y, self) s.waste = WasteStack(l.s.waste.x, l.s.waste.y, self)
# Create foundations # Create foundations
for r in l.s.foundations: for r in l.s.foundations:
s.foundations.append(self.Foundation_Class(r.x, r.y, self, s.foundations.append(
r.suit, mod=16, max_cards=16, max_move=1)) self.Foundation_Class(
r.x, r.y, self,
r.suit, mod=16, max_cards=16, max_move=1))
# Create rows # Create rows
for r in l.s.rows: for r in l.s.rows:
s.rows.append(self.RowStack_Class(r.x, r.y, self, s.rows.append(self.RowStack_Class(r.x, r.y, self,
suit=ANY_SUIT, base_rank=15)) suit=ANY_SUIT, base_rank=15))
# Define stack groups # Define stack groups
l.defaultAll() l.defaultAll()
@ -654,23 +691,26 @@ class TheFamiliar(Game):
# Create talon # Create talon
s.talon = self.Talon_Class(l.s.talon.x, l.s.talon.y, self, s.talon = self.Talon_Class(l.s.talon.x, l.s.talon.y, self,
max_rounds=max_rounds, num_deal=num_deal) max_rounds=max_rounds, num_deal=num_deal)
s.waste = WasteStack(l.s.waste.x, l.s.waste.y, self) s.waste = WasteStack(l.s.waste.x, l.s.waste.y, self)
# Create foundations # Create foundations
for r in l.s.foundations: for r in l.s.foundations:
s.foundations.append(self.Foundation_Class(r.x, r.y, self, s.foundations.append(
r.suit, mod=16, max_cards=16, max_move=1)) self.Foundation_Class(
r.x, r.y, self,
r.suit, mod=16, max_cards=16, max_move=1))
# Create rows # Create rows
for r in l.s.rows: for r in l.s.rows:
s.rows.append(self.RowStack_Class(r.x, r.y, self, s.rows.append(self.RowStack_Class(r.x, r.y, self,
suit=ANY_SUIT, base_rank=15)) suit=ANY_SUIT, base_rank=15))
# Create reserve # Create reserve
x, y = l.XM, self.height - l.YS x, y = l.XM, self.height - l.YS
s.reserves.append(Familiar_ReserveStack(x, y, self, max_cards=3)) s.reserves.append(Familiar_ReserveStack(x, y, self, max_cards=3))
self.setRegion(s.reserves, (-999, y - l.YM, x + l.XS, 999999), priority=1) self.setRegion(
s.reserves, (-999, y - l.YM, x + l.XS, 999999), priority=1)
l.createText(s.reserves[0], "se") l.createText(s.reserves[0], "se")
# Define stack groups # Define stack groups
@ -716,23 +756,26 @@ class TwoFamiliars(Game):
# Create talon # Create talon
s.talon = self.Talon_Class(l.s.talon.x, l.s.talon.y, self, s.talon = self.Talon_Class(l.s.talon.x, l.s.talon.y, self,
max_rounds=max_rounds, num_deal=num_deal) max_rounds=max_rounds, num_deal=num_deal)
s.waste = WasteStack(l.s.waste.x, l.s.waste.y, self) s.waste = WasteStack(l.s.waste.x, l.s.waste.y, self)
# Create foundations # Create foundations
for r in l.s.foundations: for r in l.s.foundations:
s.foundations.append(self.Foundation_Class(r.x, r.y, self, s.foundations.append(
r.suit, mod=16, max_cards=16, max_move=1)) self.Foundation_Class(
r.x, r.y, self,
r.suit, mod=16, max_cards=16, max_move=1))
# Create rows # Create rows
for r in l.s.rows: for r in l.s.rows:
s.rows.append(self.RowStack_Class(r.x, r.y, self, s.rows.append(self.RowStack_Class(r.x, r.y, self,
suit=ANY_SUIT, base_rank=15)) suit=ANY_SUIT, base_rank=15))
# Create reserve # Create reserve
x, y = l.XM, self.height - l.YS x, y = l.XM, self.height - l.YS
s.reserves.append(Familiar_ReserveStack(x, y, self, max_cards=3)) s.reserves.append(Familiar_ReserveStack(x, y, self, max_cards=3))
self.setRegion(s.reserves, (-999, y - l.YM, x + l.XS, 999999), priority=1) self.setRegion(
s.reserves, (-999, y - l.YM, x + l.XS, 999999), priority=1)
l.createText(s.reserves[0], "se") l.createText(s.reserves[0], "se")
# Define stack groups # Define stack groups
@ -778,18 +821,21 @@ class TenByEight(Game):
# Create talon # Create talon
s.talon = self.Talon_Class(l.s.talon.x, l.s.talon.y, self, s.talon = self.Talon_Class(l.s.talon.x, l.s.talon.y, self,
max_rounds=max_rounds, num_deal=num_deal) max_rounds=max_rounds, num_deal=num_deal)
s.waste = WasteStack(l.s.waste.x, l.s.waste.y, self) s.waste = WasteStack(l.s.waste.x, l.s.waste.y, self)
# Create foundations # Create foundations
for r in l.s.foundations: for r in l.s.foundations:
s.foundations.append(self.Foundation_Class(r.x, r.y, self, s.foundations.append(
r.suit, mod=16, max_cards=16, max_move=1)) self.Foundation_Class(
r.x, r.y, self,
r.suit, mod=16, max_cards=16, max_move=1))
# Create rows # Create rows
for r in l.s.rows: for r in l.s.rows:
s.rows.append(self.RowStack_Class(r.x, r.y, self, s.rows.append(self.RowStack_Class(r.x, r.y, self,
suit=ANY_SUIT, base_rank=ANY_RANK)) suit=ANY_SUIT,
base_rank=ANY_RANK))
# Define stack groups # Define stack groups
l.defaultAll() l.defaultAll()
@ -836,18 +882,21 @@ class Drawbridge(Game):
# Create talon # Create talon
s.talon = self.Talon_Class(l.s.talon.x, l.s.talon.y, self, s.talon = self.Talon_Class(l.s.talon.x, l.s.talon.y, self,
max_rounds=max_rounds, num_deal=num_deal) max_rounds=max_rounds, num_deal=num_deal)
s.waste = WasteStack(l.s.waste.x, l.s.waste.y, self) s.waste = WasteStack(l.s.waste.x, l.s.waste.y, self)
# Create foundations # Create foundations
for r in l.s.foundations: for r in l.s.foundations:
s.foundations.append(self.Foundation_Class(r.x, r.y, self, s.foundations.append(
r.suit, mod=16, max_cards=16, max_move=1)) self.Foundation_Class(
r.x, r.y, self,
r.suit, mod=16, max_cards=16, max_move=1))
# Create rows # Create rows
for r in l.s.rows: for r in l.s.rows:
s.rows.append(self.RowStack_Class(r.x, r.y, self, s.rows.append(self.RowStack_Class(r.x, r.y, self,
suit=ANY_SUIT, base_rank=ANY_RANK)) suit=ANY_SUIT,
base_rank=ANY_RANK))
# Define stack groups # Define stack groups
l.defaultAll() l.defaultAll()
@ -892,18 +941,22 @@ class DoubleDrawbridge(Game):
# Create talon # Create talon
s.talon = self.Talon_Class(l.s.talon.x, l.s.talon.y, self, s.talon = self.Talon_Class(l.s.talon.x, l.s.talon.y, self,
max_rounds=max_rounds, num_deal=num_deal) max_rounds=max_rounds, num_deal=num_deal)
s.waste = WasteStack(l.s.waste.x, l.s.waste.y, self) s.waste = WasteStack(l.s.waste.x, l.s.waste.y, self)
# Create foundations # Create foundations
for r in l.s.foundations: for r in l.s.foundations:
s.foundations.append(self.Foundation_Class(r.x, r.y, self, s.foundations.append(
r.suit, mod=16, max_cards=16, max_move=1)) self.Foundation_Class(
r.x, r.y, self,
r.suit, mod=16, max_cards=16, max_move=1))
# Create rows # Create rows
for r in l.s.rows: for r in l.s.rows:
s.rows.append(self.RowStack_Class(r.x, r.y, self, s.rows.append(
suit=ANY_SUIT, base_rank=ANY_RANK)) self.RowStack_Class(
r.x, r.y, self,
suit=ANY_SUIT, base_rank=ANY_RANK))
# Define stack groups # Define stack groups
l.defaultAll() l.defaultAll()
@ -948,21 +1001,26 @@ class HiddenPassages(Game):
# Create talon # Create talon
s.talon = self.Talon_Class(l.s.talon.x, l.s.talon.y, self, s.talon = self.Talon_Class(l.s.talon.x, l.s.talon.y, self,
max_rounds=max_rounds, num_deal=num_deal) max_rounds=max_rounds, num_deal=num_deal)
s.waste = WasteStack(l.s.waste.x, l.s.waste.y, self) s.waste = WasteStack(l.s.waste.x, l.s.waste.y, self)
# Create foundations # Create foundations
for r in l.s.foundations[:4]: for r in l.s.foundations[:4]:
s.foundations.append(self.Foundation_Class(r.x, r.y, self, s.foundations.append(
r.suit, mod=16, max_cards=16, max_move=1)) self.Foundation_Class(
r.x, r.y, self,
r.suit, mod=16, max_cards=16, max_move=1))
r = l.s.foundations[4] r = l.s.foundations[4]
s.foundations.append(HexATrump_Foundation(r.x, r.y, self, 4, mod=4, s.foundations.append(
max_move=0, max_cards=4, base_rank=ANY_RANK)) HexATrump_Foundation(
r.x, r.y, self, 4, mod=4,
max_move=0, max_cards=4, base_rank=ANY_RANK))
# Create rows # Create rows
for r in l.s.rows: for r in l.s.rows:
s.rows.append(self.RowStack_Class(r.x, r.y, self, s.rows.append(self.RowStack_Class(r.x, r.y, self,
suit=ANY_SUIT, base_rank=ANY_RANK)) suit=ANY_SUIT,
base_rank=ANY_RANK))
# Define stack groups # Define stack groups
l.defaultAll() l.defaultAll()
@ -1017,21 +1075,26 @@ class CluitjarsLair(Game):
# Create talon # Create talon
s.talon = self.Talon_Class(l.s.talon.x, l.s.talon.y, self, s.talon = self.Talon_Class(l.s.talon.x, l.s.talon.y, self,
max_rounds=max_rounds, num_deal=num_deal) max_rounds=max_rounds, num_deal=num_deal)
s.waste = WasteStack(l.s.waste.x, l.s.waste.y, self) s.waste = WasteStack(l.s.waste.x, l.s.waste.y, self)
# Create foundations # Create foundations
for r in l.s.foundations[:4]: for r in l.s.foundations[:4]:
s.foundations.append(self.Foundation_Class(r.x, r.y, self, s.foundations.append(
r.suit, mod=16, max_cards=16, max_move=1)) self.Foundation_Class(
r.x, r.y, self,
r.suit, mod=16, max_cards=16, max_move=1))
r = l.s.foundations[4] r = l.s.foundations[4]
s.foundations.append(HexATrump_Foundation(r.x, r.y, self, 4, mod=4, s.foundations.append(
max_move=0, max_cards=4, base_rank=ANY_RANK)) HexATrump_Foundation(
r.x, r.y, self, 4, mod=4,
max_move=0, max_cards=4, base_rank=ANY_RANK))
# Create rows # Create rows
for r in l.s.rows: for r in l.s.rows:
s.rows.append(self.RowStack_Class(r.x, r.y, self, s.rows.append(self.RowStack_Class(r.x, r.y, self,
suit=ANY_SUIT, base_rank=ANY_RANK)) suit=ANY_SUIT,
base_rank=ANY_RANK))
# Define stack groups # Define stack groups
l.defaultAll() l.defaultAll()
@ -1082,7 +1145,8 @@ class MerlinsMeander(AbstractHexADeckGame):
for i in range(2): for i in range(2):
s.rows.append(Merlins_RowStack(x + l.XS * 0.5, y, self)) s.rows.append(Merlins_RowStack(x + l.XS * 0.5, y, self))
s.rows.append(Merlins_RowStack(x + l.XS * 4.5, y, self)) s.rows.append(Merlins_RowStack(x + l.XS * 4.5, y, self))
s.reserves.append(Familiar_ReserveStack(x + l.XS * 6.5, y, self, max_cards=3)) s.reserves.append(
Familiar_ReserveStack(x + l.XS * 6.5, y, self, max_cards=3))
y = y + l.YS * 3 y = y + l.YS * 3
y = l.YM + l.YS y = l.YM + l.YS
for i in range(2): for i in range(2):
@ -1100,33 +1164,38 @@ class MerlinsMeander(AbstractHexADeckGame):
x, y = l.XM + l.XS * 7, l.YM + l.YS * 1.5 x, y = l.XM + l.XS * 7, l.YM + l.YS * 1.5
s.talon = WasteTalonStack(x, y, self, max_rounds=3) s.talon = WasteTalonStack(x, y, self, max_rounds=3)
l.createText(s.talon, "s") l.createText(s.talon, "s")
s.talon.texts.rounds = MfxCanvasText(self.canvas, s.talon.texts.rounds = MfxCanvasText(
x + l.CW / 2, y - l.YM, self.canvas,
anchor="s", x + l.CW / 2, y - l.YM,
font=self.app.getFont("canvas_default")) anchor="s",
x = x - l.XS font=self.app.getFont("canvas_default"))
x -= l.XS
s.waste = WasteStack(x, y, self) s.waste = WasteStack(x, y, self)
l.createText(s.waste, "s") l.createText(s.waste, "s")
# Create foundations # Create foundations
x, y = l.XM + l.XS * 8, l.YM x, y = l.XM + l.XS * 8, l.YM
for i in range(4): for i in range(4):
s.foundations.append(Merlins_Foundation(x, y, self, i, mod=16, s.foundations.append(
max_cards=16, base_rank=ANY_RANK)) Merlins_Foundation(
s.foundations.append(Merlins_Foundation(x + l.XS, y, self, i, mod=16, x, y, self, i, mod=16,
max_cards=16, base_rank=ANY_RANK)) max_cards=16, base_rank=ANY_RANK))
s.foundations.append(
Merlins_Foundation(
x + l.XS, y, self, i, mod=16,
max_cards=16, base_rank=ANY_RANK))
y = y + l.YS y = y + l.YS
self.texts.info = MfxCanvasText(self.canvas, self.texts.info = MfxCanvasText(
x + l.CW + l.XM / 2, y, self.canvas,
anchor="n", x + l.CW + l.XM / 2, y,
font=self.app.getFont("canvas_default")) anchor="n",
font=self.app.getFont("canvas_default"))
# define stack-groups # define stack-groups
self.sg.talonstacks = [s.talon] + [s.waste] self.sg.talonstacks = [s.talon] + [s.waste]
self.sg.openstacks = s.foundations + s.rows + s.reserves self.sg.openstacks = s.foundations + s.rows + s.reserves
self.sg.dropstacks = [s.braid] + s.rows + [s.waste] + s.reserves self.sg.dropstacks = [s.braid] + s.rows + [s.waste] + s.reserves
# #
# game overrides # game overrides
# #
@ -1156,7 +1225,8 @@ class MerlinsMeander(AbstractHexADeckGame):
def shallHighlightMatch(self, stack1, card1, stack2, card2): def shallHighlightMatch(self, stack1, card1, stack2, card2):
return (card1.suit == card2.suit and return (card1.suit == card2.suit and
((card1.rank + 1) % 16 == card2.rank or (card2.rank + 1) % 16 == card1.rank)) ((card1.rank + 1) % 16 == card2.rank or
(card2.rank + 1) % 16 == card1.rank))
def getHighlightPilesStacks(self): def getHighlightPilesStacks(self):
return () return ()
@ -1173,7 +1243,6 @@ class MerlinsMeander(AbstractHexADeckGame):
def _saveGameHook(self, p): def _saveGameHook(self, p):
p.dump(self.base_card.id) p.dump(self.base_card.id)
# #
# game extras # game extras
# #
@ -1224,17 +1293,20 @@ class MagesGame(Game):
# Create talon # Create talon
s.talon = self.Talon_Class(l.s.talon.x, l.s.talon.y, self, s.talon = self.Talon_Class(l.s.talon.x, l.s.talon.y, self,
max_rounds=max_rounds, num_deal=num_deal) max_rounds=max_rounds, num_deal=num_deal)
# Create foundations # Create foundations
for r in l.s.foundations: for r in l.s.foundations:
s.foundations.append(self.Foundation_Class(r.x, r.y, self, s.foundations.append(
r.suit, mod=16, max_cards=16, max_move=1)) self.Foundation_Class(
r.x, r.y, self,
r.suit, mod=16, max_cards=16, max_move=1))
# Create rows # Create rows
for r in l.s.rows: for r in l.s.rows:
s.rows.append(self.RowStack_Class(r.x, r.y, self, s.rows.append(self.RowStack_Class(r.x, r.y, self,
suit=ANY_SUIT, base_rank=ANY_RANK)) suit=ANY_SUIT,
base_rank=ANY_RANK))
# Define stack groups # Define stack groups
l.defaultAll() l.defaultAll()
@ -1257,7 +1329,6 @@ class MagesGame(Game):
(card1.rank + 1 == card2.rank or card2.rank + 1 == card1.rank)) (card1.rank + 1 == card2.rank or card2.rank + 1 == card1.rank))
# ************************************************************************ # ************************************************************************
# * # *
# ************************************************************************ # ************************************************************************
@ -1303,12 +1374,14 @@ class Convolution(AbstractHexADeckGame):
x, y = l.XM + maxrows * l.XS, l.YM x, y = l.XM + maxrows * l.XS, l.YM
for i in range(2): for i in range(2):
for suit in range(5): for suit in range(5):
s.foundations.append(SS_FoundationStack(x, y, self, suit=suit, max_cards=16)) s.foundations.append(
SS_FoundationStack(x, y, self, suit=suit, max_cards=16))
y = y + l.YS y = y + l.YS
x, y = x + l.XS, l.YM x, y = x + l.XS, l.YM
self.setRegion(self.s.foundations, (x - l.XS * 2, -999, 999999, self.setRegion(self.s.foundations, (x - l.XS * 2, -999, 999999,
self.height - (l.YS + l.YM)), priority=1) self.height - (l.YS + l.YM)), priority=1)
s.talon = InitialDealTalonStack(self.width - 3 * l.XS / 2, self.height - l.YS, self) s.talon = InitialDealTalonStack(
self.width - 3 * l.XS / 2, self.height - l.YS, self)
# define stack-groups # define stack-groups
l.defaultStackGroups() l.defaultStackGroups()
@ -1331,7 +1404,8 @@ class Convolution(AbstractHexADeckGame):
closest, cdist = None, 999999999 closest, cdist = None, 999999999
for stack in stacks: for stack in stacks:
if stack.cards and stack is not dragstack: if stack.cards and stack is not dragstack:
dist = (stack.cards[-1].x - cx)**2 + (stack.cards[-1].y - cy)**2 dist = (stack.cards[-1].x - cx)**2 + \
(stack.cards[-1].y - cy)**2
else: else:
dist = (stack.x - cx)**2 + (stack.y - cy)**2 dist = (stack.x - cx)**2 + (stack.y - cy)**2
if dist < cdist: if dist < cdist:
@ -1357,7 +1431,6 @@ class Labyrinth(Convolution):
return (sequence([card1, card2]) or sequence([card2, card1])) return (sequence([card1, card2]) or sequence([card2, card1]))
# ************************************************************************ # ************************************************************************
# * # *
# ************************************************************************ # ************************************************************************
@ -1371,7 +1444,6 @@ class Snakestone(Convolution):
return (sequence([card1, card2]) or sequence([card2, card1])) return (sequence([card1, card2]) or sequence([card2, card1]))
# ************************************************************************ # ************************************************************************
# * # *
# ************************************************************************ # ************************************************************************
@ -1386,17 +1458,24 @@ def r(id, gameclass, name, game_type, decks, redeals, skill_level):
r(165, BitsNBytes, 'Bits n Bytes', GI.GT_HEXADECK, 1, 1, GI.SL_BALANCED) r(165, BitsNBytes, 'Bits n Bytes', GI.GT_HEXADECK, 1, 1, GI.SL_BALANCED)
r(166, HexAKlon, 'Hex A Klon', GI.GT_HEXADECK, 1, -1, GI.SL_BALANCED) r(166, HexAKlon, 'Hex A Klon', GI.GT_HEXADECK, 1, -1, GI.SL_BALANCED)
r(16666, KlondikePlus16, 'Klondike Plus 16', GI.GT_HEXADECK, 1, 1, GI.SL_BALANCED) r(16666, KlondikePlus16, 'Klondike Plus 16', GI.GT_HEXADECK, 1, 1,
r(16667, HexAKlonByThrees, 'Hex A Klon by Threes', GI.GT_HEXADECK, 1, -1, GI.SL_BALANCED) GI.SL_BALANCED)
r(16668, KingOnlyHexAKlon, 'King Only Hex A Klon', GI.GT_HEXADECK, 1, -1, GI.SL_BALANCED) r(16667, HexAKlonByThrees, 'Hex A Klon by Threes', GI.GT_HEXADECK, 1, -1,
GI.SL_BALANCED)
r(16668, KingOnlyHexAKlon, 'King Only Hex A Klon', GI.GT_HEXADECK, 1, -1,
GI.SL_BALANCED)
r(16669, TheFamiliar, 'The Familiar', GI.GT_HEXADECK, 1, 1, GI.SL_BALANCED) r(16669, TheFamiliar, 'The Familiar', GI.GT_HEXADECK, 1, 1, GI.SL_BALANCED)
r(16670, TwoFamiliars, 'Two Familiars', GI.GT_HEXADECK, 2, 1, GI.SL_BALANCED) r(16670, TwoFamiliars, 'Two Familiars', GI.GT_HEXADECK, 2, 1, GI.SL_BALANCED)
r(16671, TenByEight, '10 x 8', GI.GT_HEXADECK, 2, -1, GI.SL_BALANCED) r(16671, TenByEight, '10 x 8', GI.GT_HEXADECK, 2, -1, GI.SL_BALANCED)
r(16672, Drawbridge, 'Drawbridge', GI.GT_HEXADECK, 1, 1, GI.SL_BALANCED) r(16672, Drawbridge, 'Drawbridge', GI.GT_HEXADECK, 1, 1, GI.SL_BALANCED)
r(16673, DoubleDrawbridge, 'Double Drawbridge', GI.GT_HEXADECK, 2, 1, GI.SL_BALANCED) r(16673, DoubleDrawbridge, 'Double Drawbridge', GI.GT_HEXADECK, 2, 1,
r(16674, HiddenPassages, 'Hidden Passages', GI.GT_HEXADECK, 1, 1, GI.SL_MOSTLY_LUCK) GI.SL_BALANCED)
r(16675, CluitjarsLair, 'Cluitjar\'s Lair', GI.GT_HEXADECK, 1, 0, GI.SL_BALANCED) r(16674, HiddenPassages, 'Hidden Passages', GI.GT_HEXADECK, 1, 1,
r(16676, MerlinsMeander, 'Merlin\'s Meander', GI.GT_HEXADECK, 2, 2, GI.SL_BALANCED) GI.SL_MOSTLY_LUCK)
r(16675, CluitjarsLair, 'Cluitjar\'s Lair', GI.GT_HEXADECK, 1, 0,
GI.SL_BALANCED)
r(16676, MerlinsMeander, 'Merlin\'s Meander', GI.GT_HEXADECK, 2, 2,
GI.SL_BALANCED)
r(16677, MagesGame, 'Mage\'s Game', GI.GT_HEXADECK, 1, 0, GI.SL_BALANCED) r(16677, MagesGame, 'Mage\'s Game', GI.GT_HEXADECK, 1, 0, GI.SL_BALANCED)
r(16678, Convolution, 'Convolution', GI.GT_HEXADECK, 2, 0, GI.SL_MOSTLY_SKILL) r(16678, Convolution, 'Convolution', GI.GT_HEXADECK, 2, 0, GI.SL_MOSTLY_SKILL)
r(16679, Labyrinth, 'Hex Labyrinth', GI.GT_HEXADECK, 2, 0, GI.SL_MOSTLY_SKILL) r(16679, Labyrinth, 'Hex Labyrinth', GI.GT_HEXADECK, 2, 0, GI.SL_MOSTLY_SKILL)

View file

@ -27,19 +27,17 @@ __all__ = []
# PySol imports # PySol imports
from pysollib.gamedb import registerGame, GameInfo, GI from pysollib.gamedb import registerGame, GameInfo, GI
from pysollib.util import * from pysollib.games.larasgame import LarasGame_Talon, LarasGame, \
from pysollib.stack import * LarasGame_Reserve
from pysollib.game import Game
from pysollib.layout import Layout
from pysollib.hint import AbstractHint, DefaultHint, CautiousDefaultHint
from pysollib.games.larasgame import LarasGame_Talon, LarasGame, LarasGame_Reserve
from pysollib.stack import \
OpenStack
# ************************************************************************ # ************************************************************************
# * # *
# ************************************************************************ # ************************************************************************
class DojoujisGame_Talon(LarasGame_Talon): class DojoujisGame_Talon(LarasGame_Talon):
def getActiveRow(self): def getActiveRow(self):
card = self.getCard() card = self.getCard()
@ -280,41 +278,40 @@ class DoubleDojoujisGame(DojoujisGame):
return 16 return 16
# register the game # register the game
registerGame(GameInfo(13001, KatrinasGame, "Katrina's Game", registerGame(GameInfo(13001, KatrinasGame, "Katrina's Game",
GI.GT_TAROCK, 2, 1, GI.SL_BALANCED, GI.GT_TAROCK, 2, 1, GI.SL_BALANCED,
ranks = range(14), trumps = range(22))) ranks=range(14), trumps=range(22)))
registerGame(GameInfo(13002, BridgetsGame, "Bridget's Game", registerGame(GameInfo(13002, BridgetsGame, "Bridget's Game",
GI.GT_HEXADECK, 2, 1, GI.SL_BALANCED, GI.GT_HEXADECK, 2, 1, GI.SL_BALANCED,
ranks = range(16), trumps = range(4))) ranks=range(16), trumps=range(4)))
registerGame(GameInfo(13003, FatimehsGame, "Fatimeh's Game", registerGame(GameInfo(13003, FatimehsGame, "Fatimeh's Game",
GI.GT_MUGHAL_GANJIFA, 1, 2, GI.SL_BALANCED, GI.GT_MUGHAL_GANJIFA, 1, 2, GI.SL_BALANCED,
suits = range(8), ranks = range(12))) suits=range(8), ranks=range(12)))
registerGame(GameInfo(13004, KalisGame, "Kali's Game", registerGame(GameInfo(13004, KalisGame, "Kali's Game",
GI.GT_DASHAVATARA_GANJIFA, 1, 2, GI.SL_BALANCED, GI.GT_DASHAVATARA_GANJIFA, 1, 2, GI.SL_BALANCED,
suits = range(10), ranks = range(12))) suits=range(10), ranks=range(12)))
registerGame(GameInfo(13005, DojoujisGame, "Dojouji's Game", registerGame(GameInfo(13005, DojoujisGame, "Dojouji's Game",
GI.GT_HANAFUDA, 2, 0, GI.SL_BALANCED, GI.GT_HANAFUDA, 2, 0, GI.SL_BALANCED,
suits = range(12), ranks = range(4))) suits=range(12), ranks=range(4)))
registerGame(GameInfo(13008, RelaxedKatrinasGame, "Katrina's Game Relaxed", registerGame(GameInfo(13008, RelaxedKatrinasGame, "Katrina's Game Relaxed",
GI.GT_TAROCK, 2, 1, GI.SL_BALANCED, GI.GT_TAROCK, 2, 1, GI.SL_BALANCED,
ranks = range(14), trumps = range(22))) ranks=range(14), trumps=range(22)))
registerGame(GameInfo(13009, DoubleKatrinasGame, "Katrina's Game Doubled", registerGame(GameInfo(13009, DoubleKatrinasGame, "Katrina's Game Doubled",
GI.GT_TAROCK, 4, 2, GI.SL_BALANCED, GI.GT_TAROCK, 4, 2, GI.SL_BALANCED,
ranks = range(14), trumps = range(22))) ranks=range(14), trumps=range(22)))
registerGame(GameInfo(13010, DoubleBridgetsGame, "Bridget's Game Doubled", registerGame(GameInfo(13010, DoubleBridgetsGame, "Bridget's Game Doubled",
GI.GT_HEXADECK, 4, 2, GI.SL_BALANCED, GI.GT_HEXADECK, 4, 2, GI.SL_BALANCED,
ranks = range(16), trumps = range(4))) ranks=range(16), trumps=range(4)))
registerGame(GameInfo(13011, RelaxedKalisGame, "Kali's Game Relaxed", registerGame(GameInfo(13011, RelaxedKalisGame, "Kali's Game Relaxed",
GI.GT_DASHAVATARA_GANJIFA, 1, 2, GI.SL_BALANCED, GI.GT_DASHAVATARA_GANJIFA, 1, 2, GI.SL_BALANCED,
suits = range(10), ranks = range(12))) suits=range(10), ranks=range(12)))
registerGame(GameInfo(13012, DoubleKalisGame, "Kali's Game Doubled", registerGame(GameInfo(13012, DoubleKalisGame, "Kali's Game Doubled",
GI.GT_DASHAVATARA_GANJIFA, 2, 3, GI.SL_BALANCED, GI.GT_DASHAVATARA_GANJIFA, 2, 3, GI.SL_BALANCED,
suits = range(10), ranks = range(12))) suits=range(10), ranks=range(12)))
registerGame(GameInfo(13013, RelaxedFatimehsGame, "Fatimeh's Game Relaxed", registerGame(GameInfo(13013, RelaxedFatimehsGame, "Fatimeh's Game Relaxed",
GI.GT_MUGHAL_GANJIFA, 1, 2, GI.SL_BALANCED, GI.GT_MUGHAL_GANJIFA, 1, 2, GI.SL_BALANCED,
suits = range(8), ranks = range(12))) suits=range(8), ranks=range(12)))
registerGame(GameInfo(13014, DoubleDojoujisGame, "Dojouji's Game Doubled", registerGame(GameInfo(13014, DoubleDojoujisGame, "Dojouji's Game Doubled",
GI.GT_HANAFUDA, 4, 0, GI.SL_BALANCED, GI.GT_HANAFUDA, 4, 0, GI.SL_BALANCED,
suits = range(12), ranks = range(4))) suits=range(12), ranks=range(4)))

View file

@ -24,28 +24,31 @@
__all__ = [] __all__ = []
# Imports # Imports
import sys, math import math
# PySol imports # PySol imports
from pysollib.gamedb import registerGame, GameInfo, GI from pysollib.gamedb import registerGame, GameInfo, GI
from pysollib.util import *
from pysollib.mfxutil import kwdefault from pysollib.mfxutil import kwdefault
from pysollib.stack import *
from pysollib.game import Game from pysollib.game import Game
from pysollib.layout import Layout from pysollib.layout import Layout
from pysollib.hint import AbstractHint, DefaultHint, CautiousDefaultHint
from pysollib.pysoltk import bind from pysollib.pysoltk import bind
from pysollib.util import ANY_RANK
from pysollib.stack import \
InitialDealTalonStack, \
OpenStack
# ************************************************************************ # ************************************************************************
# * Matrix Row Stack # * Matrix Row Stack
# ************************************************************************ # ************************************************************************
class Matrix_RowStack(OpenStack): class Matrix_RowStack(OpenStack):
def __init__(self, x, y, game, **cap): def __init__(self, x, y, game, **cap):
kwdefault(cap, max_move=1, max_accept=1, max_cards=1, kwdefault(cap, max_move=1, max_accept=1, max_cards=1,
base_rank=ANY_RANK) base_rank=ANY_RANK)
OpenStack.__init__(self, x, y, game, **cap) OpenStack.__init__(self, x, y, game, **cap)
def canFlipCard(self): def canFlipCard(self):
@ -108,8 +111,9 @@ class Matrix_RowStack(OpenStack):
self._stopDrag() self._stopDrag()
step = 1 step = 1
from_stack = row[stack_map[j][i + dir]] from_stack = row[stack_map[j][i + dir]]
while not from_stack is self: while from_stack is not self:
from_stack.playMoveMove(1, to_stack, frames=0, sound=False) from_stack.playMoveMove(
1, to_stack, frames=0, sound=False)
to_stack = from_stack to_stack = from_stack
step = step + 1 step = step + 1
from_stack = row[stack_map[j][i + dir * step]] from_stack = row[stack_map[j][i + dir * step]]
@ -169,7 +173,7 @@ class Matrix3(Game):
if cards[i].rank > cards[j].rank: if cards[i].rank > cards[j].rank:
n += 1 n += 1
cards.reverse() cards.reverse()
if n%2: if n % 2:
cards[0], cards[1] = cards[1], cards[0] cards[0], cards[1] = cards[1], cards[0]
return [c]+cards return [c]+cards
@ -199,7 +203,6 @@ class Matrix3(Game):
or (card1.rank - 1 == card2.rank)) or (card1.rank - 1 == card2.rank))
# ************************************************************************ # ************************************************************************
# * Size variations # * Size variations
# ************************************************************************ # ************************************************************************
@ -207,24 +210,31 @@ class Matrix3(Game):
class Matrix4(Matrix3): class Matrix4(Matrix3):
pass pass
class Matrix5(Matrix3): class Matrix5(Matrix3):
pass pass
class Matrix6(Matrix3): class Matrix6(Matrix3):
pass pass
class Matrix7(Matrix3): class Matrix7(Matrix3):
pass pass
class Matrix8(Matrix3): class Matrix8(Matrix3):
pass pass
class Matrix9(Matrix3): class Matrix9(Matrix3):
pass pass
class Matrix10(Matrix3): class Matrix10(Matrix3):
pass pass
class Matrix20(Matrix3): class Matrix20(Matrix3):
pass pass
@ -236,16 +246,18 @@ class Matrix20(Matrix3):
def r(id, gameclass, short_name): def r(id, gameclass, short_name):
name = short_name name = short_name
ncards = int(name[:2]) * int(name[:2]) ncards = int(name[:2]) * int(name[:2])
gi = GameInfo(id, gameclass, name, gi = GameInfo(
GI.GT_MATRIX, 1, 0, GI.SL_SKILL, id, gameclass, name,
category=GI.GC_TRUMP_ONLY, short_name=short_name, GI.GT_MATRIX, 1, 0, GI.SL_SKILL,
suits=(), ranks=(), trumps=range(ncards), category=GI.GC_TRUMP_ONLY, short_name=short_name,
si = {"decks": 1, "ncards": ncards}) suits=(), ranks=(), trumps=range(ncards),
si={"decks": 1, "ncards": ncards})
gi.ncards = ncards gi.ncards = ncards
gi.rules_filename = "matrix.html" gi.rules_filename = "matrix.html"
registerGame(gi) registerGame(gi)
return gi return gi
r(22223, Matrix3, " 3x3 Matrix") r(22223, Matrix3, " 3x3 Matrix")
r(22224, Matrix4, " 4x4 Matrix") r(22224, Matrix4, " 4x4 Matrix")
r(22225, Matrix5, " 5x5 Matrix") r(22225, Matrix5, " 5x5 Matrix")
@ -254,7 +266,6 @@ r(22227, Matrix7, " 7x7 Matrix")
r(22228, Matrix8, " 8x8 Matrix") r(22228, Matrix8, " 8x8 Matrix")
r(22229, Matrix9, " 9x9 Matrix") r(22229, Matrix9, " 9x9 Matrix")
r(22230, Matrix10, "10x10 Matrix") r(22230, Matrix10, "10x10 Matrix")
#r(22240, Matrix20, "20x20 Matrix") # r(22240, Matrix20, "20x20 Matrix")
del r del r

View file

@ -24,24 +24,41 @@
__all__ = [] __all__ = []
# Imports # Imports
import sys, math import math
# PySol imports # PySol imports
from pysollib.mygettext import _, n_ from pysollib.mygettext import _
from pysollib.gamedb import registerGame, GameInfo, GI from pysollib.gamedb import registerGame, GameInfo, GI
from pysollib.util import *
from pysollib.mfxutil import kwdefault from pysollib.mfxutil import kwdefault
from pysollib.stack import *
from pysollib.game import Game from pysollib.game import Game
from pysollib.layout import Layout from pysollib.layout import Layout
from pysollib.hint import AbstractHint, DefaultHint, CautiousDefaultHint, FreeCellType_Hint from pysollib.hint import AbstractHint, DefaultHint
from pysollib.pysoltk import MfxCanvasText from pysollib.pysoltk import MfxCanvasText
from pysollib.util import ANY_RANK, ANY_SUIT, NO_RANK, UNLIMITED_ACCEPTS, \
UNLIMITED_CARDS, UNLIMITED_MOVES
from pysollib.stack import \
AC_RowStack, \
AbstractFoundationStack, \
BasicRowStack, \
DealRowTalonStack, \
InitialDealTalonStack, \
RK_RowStack, \
ReserveStack, \
SS_FoundationStack, \
SS_RowStack, \
StackWrapper, \
WasteStack, \
WasteTalonStack, \
isSameSuitSequence, \
OpenStack
# ************************************************************************ # ************************************************************************
# * Mughal Foundation Stacks # * Mughal Foundation Stacks
# ***********************************************************************/ # ***********************************************************************/
class Mughal_FoundationStack(AbstractFoundationStack): class Mughal_FoundationStack(AbstractFoundationStack):
def __init__(self, x, y, game, suit, **cap): def __init__(self, x, y, game, suit, **cap):
@ -70,8 +87,8 @@ class Triumph_Foundation(AbstractFoundationStack):
card_dir = (cards[0].rank - self.cards[-1].rank) % self.cap.mod card_dir = (cards[0].rank - self.cards[-1].rank) % self.cap.mod
return card_dir in (1, 11) return card_dir in (1, 11)
else: else:
return (self.cards[-1].rank + stack_dir) % self.cap.mod == cards[0].rank return (self.cards[-1].rank + stack_dir) % self.cap.mod \
== cards[0].rank
# ************************************************************************ # ************************************************************************
@ -135,7 +152,7 @@ class Mughal_AC_RowStack(Mughal_OpenStack):
def acceptsCards(self, from_stack, cards): def acceptsCards(self, from_stack, cards):
if (not self.basicAcceptsCards(from_stack, cards) if (not self.basicAcceptsCards(from_stack, cards)
or not self.isAlternateColorSequence(cards)): or not self.isAlternateColorSequence(cards)):
return 0 return 0
stackcards = self.cards stackcards = self.cards
if not len(stackcards): if not len(stackcards):
@ -147,7 +164,7 @@ class Mughal_AF_RowStack(Mughal_OpenStack):
def acceptsCards(self, from_stack, cards): def acceptsCards(self, from_stack, cards):
if (not self.basicAcceptsCards(from_stack, cards) if (not self.basicAcceptsCards(from_stack, cards)
or not self.isAlternateForceSequence(cards)): or not self.isAlternateForceSequence(cards)):
return 0 return 0
stackcards = self.cards stackcards = self.cards
if not len(stackcards): if not len(stackcards):
@ -159,7 +176,7 @@ class Mughal_RK_RowStack(Mughal_OpenStack):
def acceptsCards(self, from_stack, cards): def acceptsCards(self, from_stack, cards):
if (not self.basicAcceptsCards(from_stack, cards) if (not self.basicAcceptsCards(from_stack, cards)
or not self.isRankSequence(cards)): or not self.isRankSequence(cards)):
return 0 return 0
stackcards = self.cards stackcards = self.cards
if not len(stackcards): if not len(stackcards):
@ -171,7 +188,7 @@ class Mughal_SS_RowStack(Mughal_OpenStack):
def acceptsCards(self, from_stack, cards): def acceptsCards(self, from_stack, cards):
if (not self.basicAcceptsCards(from_stack, cards) if (not self.basicAcceptsCards(from_stack, cards)
or not self.isSuitSequence(cards)): or not self.isSuitSequence(cards)):
return 0 return 0
stackcards = self.cards stackcards = self.cards
if not len(stackcards): if not len(stackcards):
@ -182,8 +199,9 @@ class Mughal_SS_RowStack(Mughal_OpenStack):
class Circles_RowStack(SS_RowStack): class Circles_RowStack(SS_RowStack):
def __init__(self, x, y, game, base_rank, yoffset): def __init__(self, x, y, game, base_rank, yoffset):
SS_RowStack.__init__(self, x, y, game, base_rank=base_rank, SS_RowStack.__init__(
max_accept=1, max_move=1) self, x, y, game, base_rank=base_rank,
max_accept=1, max_move=1)
self.CARD_YOFFSET = 1 self.CARD_YOFFSET = 1
@ -191,7 +209,6 @@ class Triumph_BraidStack(OpenStack):
def __init__(self, x, y, game, xoffset, yoffset): def __init__(self, x, y, game, xoffset, yoffset):
OpenStack.__init__(self, x, y, game) OpenStack.__init__(self, x, y, game)
CW = self.game.app.images.CARDW
self.CARD_YOFFSET = int(self.game.app.images.CARD_YOFFSET * yoffset) self.CARD_YOFFSET = int(self.game.app.images.CARD_YOFFSET * yoffset)
# use a sine wave for the x offsets # use a sine wave for the x offsets
self.CARD_XOFFSET = [] self.CARD_XOFFSET = []
@ -240,7 +257,6 @@ class Triumph_ReserveStack(ReserveStack):
return self.game.app.images.getTalonBottom() return self.game.app.images.getTalonBottom()
# ************************************************************************ # ************************************************************************
# * # *
# ***********************************************************************/ # ***********************************************************************/
@ -268,7 +284,6 @@ class Triumph_Hint(DefaultHint):
pass pass
# ************************************************************************ # ************************************************************************
# * Mughal Circles # * Mughal Circles
# ***********************************************************************/ # ***********************************************************************/
@ -281,7 +296,6 @@ class MughalCircles(AbstractMughalGame):
def createGame(self): def createGame(self):
l, s = Layout(self), self.s l, s = Layout(self), self.s
font = self.app.getFont("canvas_default")
# Set window size # Set window size
w, h = l.XM + l.XS * 9, l.YM + l.YS * 7 w, h = l.XM + l.XS * 9, l.YM + l.YS * 7
@ -291,15 +305,20 @@ class MughalCircles(AbstractMughalGame):
x = w / 2 - l.CW / 2 x = w / 2 - l.CW / 2
y = h / 2 - l.YS / 2 y = h / 2 - l.YS / 2
x0 = (-1, -.8, 0, .8, 1, .8, 0, -.8, x0 = (-1, -.8, 0, .8, 1, .8, 0, -.8,
-2, -1.9, -1.5, -.8, 0, .8, 1.5, 1.9, 2, 1.9, 1.5, .8, 0, -.8, -1.5, -1.9) -2, -1.9, -1.5, -.8, 0, .8, 1.5, 1.9, 2, 1.9, 1.5, .8,
0, -.8, -1.5, -1.9)
y0 = (0, -.8, -1, -.8, 0, .8, 1, .8, y0 = (0, -.8, -1, -.8, 0, .8, 1, .8,
0, -.8, -1.5, -1.9, -2, -1.9, -1.5, -.8, 0, .8, 1.5, 1.9, 2, 1.9, 1.5, .8) 0, -.8, -1.5, -1.9, -2, -1.9, -1.5, -.8,
0, .8, 1.5, 1.9, 2, 1.9, 1.5, .8)
for i in range(24): for i in range(24):
# FIXME: # FIXME:
_x, _y = x+l.XS*x0[i]+l.XM*x0[i]*2, y+l.YS*y0[i]+l.YM*y0[i]*2 _x, _y = x+l.XS*x0[i]+l.XM*x0[i]*2, y+l.YS*y0[i]+l.YM*y0[i]*2
if _x < 0: _x = 0 if _x < 0:
if _y < 0: _y = 0 _x = 0
s.rows.append(Circles_RowStack(_x, _y, self, base_rank=ANY_RANK, yoffset=0)) if _y < 0:
_y = 0
s.rows.append(
Circles_RowStack(_x, _y, self, base_rank=ANY_RANK, yoffset=0))
# Create reserve stacks # Create reserve stacks
s.reserves.append(ReserveStack(l.XM, h - l.YS, self)) s.reserves.append(ReserveStack(l.XM, h - l.YS, self))
@ -309,20 +328,26 @@ class MughalCircles(AbstractMughalGame):
x = l.XM x = l.XM
y = l.YM y = l.YM
for i in range(4): for i in range(4):
s.foundations.append(SS_FoundationStack(x, y, self, i, mod = 12, s.foundations.append(
max_move = 0, max_cards = 12)) SS_FoundationStack(
x, y, self, i, mod=12,
max_move=0, max_cards=12))
y = y + l.YS y = y + l.YS
x = self.width - l.XS x = self.width - l.XS
y = l.YM y = l.YM
for i in range(4): for i in range(4):
s.foundations.append(SS_FoundationStack(x, y, self, i + 4, mod = 12, s.foundations.append(
max_move = 0, max_cards = 12)) SS_FoundationStack(
x, y, self, i + 4, mod=12,
max_move=0, max_cards=12))
y = y + l.YS y = y + l.YS
# FIXME: # FIXME:
_x1, _x2 = l.XM + l.XS, w - l.XS - l.XM _x1, _x2 = l.XM + l.XS, w - l.XS - l.XM
for i in s.rows: for i in s.rows:
if i.x < _x1: i.x = _x1 if i.x < _x1:
elif i.x > _x2: i.x = _x2 i.x = _x1
elif i.x > _x2:
i.x = _x2
self.setRegion(s.rows, (_x1, 0, _x2, 999999)) self.setRegion(s.rows, (_x1, 0, _x2, 999999))
# Create talon # Create talon
@ -349,7 +374,6 @@ class MughalCircles(AbstractMughalGame):
or (card1.rank - 1 == card2.rank))) or (card1.rank - 1 == card2.rank)))
# ************************************************************************ # ************************************************************************
# * Eight Legions # * Eight Legions
# ***********************************************************************/ # ***********************************************************************/
@ -362,7 +386,6 @@ class EightLegions(AbstractMughalGame):
def createGame(self): def createGame(self):
l, s = Layout(self), self.s l, s = Layout(self), self.s
font = self.app.getFont("canvas_default")
# Set window size # Set window size
self.setSize(l.XM * 3 + l.XS * 9, l.YM + l.YS * 6) self.setSize(l.XM * 3 + l.XS * 9, l.YM + l.YS * 6)
@ -371,8 +394,8 @@ class EightLegions(AbstractMughalGame):
x = l.XM x = l.XM
y = l.YM y = l.YM
for i in range(8): for i in range(8):
s.rows.append(RK_RowStack(x, y, self, base_rank = 11, s.rows.append(RK_RowStack(x, y, self, base_rank=11,
max_move = 12, max_cards = 99)) max_move=12, max_cards=99))
x = x + l.XS x = x + l.XS
# Create reserve stacks # Create reserve stacks
@ -415,7 +438,6 @@ class EightLegions(AbstractMughalGame):
return 1 return 1
# ************************************************************************ # ************************************************************************
# * Shamsher # * Shamsher
# ***********************************************************************/ # ***********************************************************************/
@ -439,8 +461,10 @@ class Shamsher(AbstractMughalGame):
# Create foundations # Create foundations
for r in l.s.foundations: for r in l.s.foundations:
s.foundations.append(self.Foundation_Class(r.x, r.y, self, s.foundations.append(
r.suit, mod=12, max_cards=12)) self.Foundation_Class(
r.x, r.y, self,
r.suit, mod=12, max_cards=12))
# Create reserve stacks # Create reserve stacks
for r in l.s.reserves: for r in l.s.reserves:
@ -448,8 +472,10 @@ class Shamsher(AbstractMughalGame):
# Create row stacks # Create row stacks
for r in l.s.rows: for r in l.s.rows:
s.rows.append(self.RowStack_Class(r.x, r.y, self, max_cards=12, s.rows.append(
suit=ANY_SUIT, base_rank=self.BASE_RANK)) self.RowStack_Class(
r.x, r.y, self, max_cards=12,
suit=ANY_SUIT, base_rank=self.BASE_RANK))
# Create talon # Create talon
s.talon = self.Talon_Class(l.s.talon.x, l.s.talon.y, self) s.talon = self.Talon_Class(l.s.talon.x, l.s.talon.y, self)
@ -470,7 +496,6 @@ class Shamsher(AbstractMughalGame):
self.s.talon.dealCards() self.s.talon.dealCards()
# ************************************************************************ # ************************************************************************
# * Ashrafi # * Ashrafi
# ***********************************************************************/ # ***********************************************************************/
@ -490,7 +515,6 @@ class Ashrafi(Shamsher):
Shamsher.createGame(self) Shamsher.createGame(self)
# ************************************************************************ # ************************************************************************
# * Ghulam # * Ghulam
# ***********************************************************************/ # ***********************************************************************/
@ -515,7 +539,6 @@ class Ghulam(Shamsher):
or (card1.rank - 1 == card2.rank))) or (card1.rank - 1 == card2.rank)))
# ************************************************************************ # ************************************************************************
# * Tipati # * Tipati
# ***********************************************************************/ # ***********************************************************************/
@ -539,19 +562,24 @@ class Tipati(AbstractMughalGame):
self.setSize(l.size[0], l.size[1]) self.setSize(l.size[0], l.size[1])
# Create talon # Create talon
s.talon = self.Talon_Class(l.s.talon.x, l.s.talon.y, self, s.talon = self.Talon_Class(
max_rounds = max_rounds, num_deal = num_deal) l.s.talon.x, l.s.talon.y, self,
max_rounds=max_rounds, num_deal=num_deal)
s.waste = WasteStack(l.s.waste.x, l.s.waste.y, self) s.waste = WasteStack(l.s.waste.x, l.s.waste.y, self)
# Create foundations # Create foundations
for r in l.s.foundations: for r in l.s.foundations:
s.foundations.append(self.Foundation_Class(r.x, r.y, self, s.foundations.append(
r.suit, mod = 12, max_cards = 12, max_move = self.MAX_MOVE)) self.Foundation_Class(
r.x, r.y, self,
r.suit, mod=12, max_cards=12, max_move=self.MAX_MOVE))
# Create row stacks # Create row stacks
for r in l.s.rows: for r in l.s.rows:
s.rows.append(self.RowStack_Class(r.x, r.y, self, s.rows.append(
suit = ANY_SUIT, base_rank = self.BASE_RANK)) self.RowStack_Class(
r.x, r.y, self,
suit=ANY_SUIT, base_rank=self.BASE_RANK))
# Define stack groups # Define stack groups
l.defaultAll() l.defaultAll()
@ -569,8 +597,6 @@ class Tipati(AbstractMughalGame):
self.s.talon.dealCards() self.s.talon.dealCards()
# ************************************************************************ # ************************************************************************
# * Ashwapati # * Ashwapati
# ***********************************************************************/ # ***********************************************************************/
@ -585,7 +611,7 @@ class Ashwapati(Tipati):
# #
def createGame(self, **layout): def createGame(self, **layout):
Tipati.createGame(self, max_rounds = -1, num_deal = 1) Tipati.createGame(self, max_rounds=-1, num_deal=1)
def shallHighlightMatch(self, stack1, card1, stack2, card2): def shallHighlightMatch(self, stack1, card1, stack2, card2):
return ((card1.suit == card2.suit) return ((card1.suit == card2.suit)
@ -593,7 +619,6 @@ class Ashwapati(Tipati):
or (card1.rank - 1 == card2.rank))) or (card1.rank - 1 == card2.rank)))
# ************************************************************************ # ************************************************************************
# * Gajapati # * Gajapati
# ***********************************************************************/ # ***********************************************************************/
@ -616,7 +641,6 @@ class Gajapati(Tipati):
or (card1.rank - 1 == card2.rank))) or (card1.rank - 1 == card2.rank)))
# ************************************************************************ # ************************************************************************
# * Narpati # * Narpati
# ***********************************************************************/ # ***********************************************************************/
@ -633,7 +657,6 @@ class Narpati(Tipati):
Tipati.createGame(self, max_rounds=1, num_deal=1) Tipati.createGame(self, max_rounds=1, num_deal=1)
# ************************************************************************ # ************************************************************************
# * Garhpati # * Garhpati
# ***********************************************************************/ # ***********************************************************************/
@ -649,7 +672,6 @@ class Garhpati(Tipati):
Tipati.createGame(self, max_rounds=-1, num_deal=3) Tipati.createGame(self, max_rounds=-1, num_deal=3)
# ************************************************************************ # ************************************************************************
# * Dhanpati # * Dhanpati
# ***********************************************************************/ # ***********************************************************************/
@ -664,7 +686,6 @@ class Dhanpati(Tipati):
Tipati.createGame(self, max_rounds=2, num_deal=3) Tipati.createGame(self, max_rounds=2, num_deal=3)
# ************************************************************************ # ************************************************************************
# * Akbar's Triumph # * Akbar's Triumph
# ************************************************************************ # ************************************************************************
@ -693,52 +714,60 @@ class AkbarsTriumph(AbstractMughalGame):
self.base_card = None self.base_card = None
# Create foundations, rows, reserves # Create foundations, rows, reserves
s.addattr(braidstrong = None) # register extra stack variable s.addattr(braidstrong=None) # register extra stack variable
s.addattr(braidweak = None) # register extra stack variable s.addattr(braidweak=None) # register extra stack variable
x, y = l.XM, l.YM x, y = l.XM, l.YM
for j in range(4): for j in range(4):
for i in range(decks): for i in range(decks):
s.foundations.append(Triumph_Foundation(x + l.XS * i, y, self, s.foundations.append(
j, mod = 12, max_cards = 12)) Triumph_Foundation(
x + l.XS * i, y, self,
j, mod=12, max_cards=12))
s.rows.append(Triumph_StrongStack(x + l.XS * decks, y, self)) s.rows.append(Triumph_StrongStack(x + l.XS * decks, y, self))
s.rows.append(Triumph_ReserveStack(x + l.XS * (1 + decks), y, self)) s.rows.append(Triumph_ReserveStack(
x + l.XS * (1 + decks), y, self))
y = y + l.YS y = y + l.YS
x, y = x + l.XS * (5 + decks), l.YM x, y = x + l.XS * (5 + decks), l.YM
for j in range(4): for j in range(4):
s.rows.append(Triumph_ReserveStack(x, y, self)) s.rows.append(Triumph_ReserveStack(x, y, self))
s.rows.append(Triumph_WeakStack(x + l.XS, y, self)) s.rows.append(Triumph_WeakStack(x + l.XS, y, self))
for i in range(decks, 0, -1): for i in range(decks, 0, -1):
s.foundations.append(Triumph_Foundation(x + l.XS * (1 + i), y, self, s.foundations.append(Triumph_Foundation(
j + 4, mod = 12, max_cards = 12)) x + l.XS * (1 + i), y, self,
j + 4, mod=12, max_cards=12))
y = y + l.YS y = y + l.YS
self.texts.info = MfxCanvasText(self.canvas, self.texts.info = MfxCanvasText(
self.width / 2, h - l.YM / 2, self.canvas,
anchor = "center", self.width / 2, h - l.YM / 2,
font = self.app.getFont("canvas_default")) anchor="center",
font=self.app.getFont("canvas_default"))
# Create braids # Create braids
x, y = l.XM + l.XS * 2.3 + l.XS * decks, l.YM x, y = l.XM + l.XS * 2.3 + l.XS * decks, l.YM
s.braidstrong = Triumph_BraidStack(x, y, self, xoffset = 12, yoffset = self.BRAID_OFFSET) s.braidstrong = Triumph_BraidStack(
x = x + l.XS * 1.4 x, y, self, xoffset=12, yoffset=self.BRAID_OFFSET)
s.braidweak = Triumph_BraidStack(x, y, self, xoffset = -12, yoffset = self.BRAID_OFFSET) x += l.XS * 1.4
s.braidweak = Triumph_BraidStack(
x, y, self, xoffset=-12, yoffset=self.BRAID_OFFSET)
# Create talon # Create talon
x, y = l.XM + l.XS * 2 + l.XS * decks, h - l.YS - l.YM x, y = l.XM + l.XS * 2 + l.XS * decks, h - l.YS - l.YM
s.talon = WasteTalonStack(x, y, self, max_rounds = 3) s.talon = WasteTalonStack(x, y, self, max_rounds=3)
l.createText(s.talon, "s") l.createText(s.talon, "s")
s.talon.texts.rounds = MfxCanvasText(self.canvas, s.talon.texts.rounds = MfxCanvasText(
self.width / 2, h - l.YM * 2.5, self.canvas,
anchor = "center", self.width / 2, h - l.YM * 2.5,
font=self.app.getFont("canvas_default")) anchor="center",
x = x + l.XS * 2 font=self.app.getFont("canvas_default"))
x += l.XS * 2
s.waste = WasteStack(x, y, self) s.waste = WasteStack(x, y, self)
l.createText(s.waste, "s") l.createText(s.waste, "s")
# define stack-groups # define stack-groups
self.sg.talonstacks = [s.talon] + [s.waste] self.sg.talonstacks = [s.talon] + [s.waste]
self.sg.openstacks = s.foundations + s.rows self.sg.openstacks = s.foundations + s.rows
self.sg.dropstacks = [s.braidstrong] + [s.braidweak] + s.rows + [s.waste] self.sg.dropstacks = [s.braidstrong] + [s.braidweak] + s.rows \
+ [s.waste]
# #
# game overrides # game overrides
@ -749,13 +778,14 @@ class AkbarsTriumph(AbstractMughalGame):
self.base_card = None self.base_card = None
self.updateText() self.updateText()
for i in range(self.BRAID_CARDS): for i in range(self.BRAID_CARDS):
self.s.talon.dealRow(rows = [self.s.braidstrong]) self.s.talon.dealRow(rows=[self.s.braidstrong])
for i in range(self.BRAID_CARDS): for i in range(self.BRAID_CARDS):
self.s.talon.dealRow(rows = [self.s.braidweak]) self.s.talon.dealRow(rows=[self.s.braidweak])
self.s.talon.dealRow() self.s.talon.dealRow()
# deal base_card to foundations, update cap.base_rank # deal base_card to foundations, update cap.base_rank
self.base_card = self.s.talon.getCard() self.base_card = self.s.talon.getCard()
to_stack = self.s.foundations[self.base_card.suit * self.gameinfo.decks] to_stack = self.s.foundations[
self.base_card.suit * self.gameinfo.decks]
self.flipMove(self.s.talon) self.flipMove(self.s.talon)
self.moveMove(1, self.s.talon, to_stack) self.moveMove(1, self.s.talon, to_stack)
self.updateText() self.updateText()
@ -766,7 +796,8 @@ class AkbarsTriumph(AbstractMughalGame):
def shallHighlightMatch(self, stack1, card1, stack2, card2): def shallHighlightMatch(self, stack1, card1, stack2, card2):
return (card1.suit == card2.suit and return (card1.suit == card2.suit and
((card1.rank + 1) % 12 == card2.rank or (card2.rank + 1) % 12 == card1.rank)) ((card1.rank + 1) % 12 == card2.rank or
(card2.rank + 1) % 12 == card1.rank))
def getHighlightPilesStacks(self): def getHighlightPilesStacks(self):
return () return ()
@ -783,7 +814,6 @@ class AkbarsTriumph(AbstractMughalGame):
def _saveGameHook(self, p): def _saveGameHook(self, p):
p.dump(self.base_card.id) p.dump(self.base_card.id)
# #
# game extras # game extras
# #
@ -800,8 +830,7 @@ class AkbarsTriumph(AbstractMughalGame):
t = t + _(" Ascending") t = t + _(" Ascending")
elif dir == 11: elif dir == 11:
t = t + _(" Descending") t = t + _(" Descending")
self.texts.info.config(text = t) self.texts.info.config(text=t)
# ************************************************************************ # ************************************************************************
@ -814,7 +843,6 @@ class AkbarsConquest(AkbarsTriumph):
BRAID_OFFSET = .9 BRAID_OFFSET = .9
# ************************************************************************ # ************************************************************************
# * # *
# ************************************************************************ # ************************************************************************
@ -860,12 +888,14 @@ class Vajra(AbstractMughalGame):
x, y = l.XM + maxrows * l.XS, l.YM x, y = l.XM + maxrows * l.XS, l.YM
for i in range(2): for i in range(2):
for suit in range(4): for suit in range(4):
s.foundations.append(SS_FoundationStack(x, y, self, suit=suit + (4 * i))) s.foundations.append(
SS_FoundationStack(x, y, self, suit=suit+(4 * i)))
y = y + l.YS y = y + l.YS
x, y = x + l.XS, l.YM x, y = x + l.XS, l.YM
self.setRegion(self.s.foundations, (x - l.XS * 2, -999, 999999, self.setRegion(self.s.foundations, (x - l.XS * 2, -999, 999999,
self.height - (l.YS + l.YM)), priority=1) self.height - (l.YS + l.YM)), priority=1)
s.talon = InitialDealTalonStack(self.width - 3 * l.XS / 2, self.height - l.YS, self) s.talon = InitialDealTalonStack(
self.width - 3 * l.XS / 2, self.height - l.YS, self)
# define stack-groups # define stack-groups
l.defaultStackGroups() l.defaultStackGroups()
@ -888,7 +918,8 @@ class Vajra(AbstractMughalGame):
closest, cdist = None, 999999999 closest, cdist = None, 999999999
for stack in stacks: for stack in stacks:
if stack.cards and stack is not dragstack: if stack.cards and stack is not dragstack:
dist = (stack.cards[-1].x - cx)**2 + (stack.cards[-1].y - cy)**2 dist = (stack.cards[-1].x - cx)**2 + \
(stack.cards[-1].y - cy)**2
else: else:
dist = (stack.x - cx)**2 + (stack.y - cy)**2 dist = (stack.x - cx)**2 + (stack.y - cy)**2
if dist < cdist: if dist < cdist:
@ -914,7 +945,6 @@ class Danda(Vajra):
return (sequence([card1, card2]) or sequence([card2, card1])) return (sequence([card1, card2]) or sequence([card2, card1]))
# ************************************************************************ # ************************************************************************
# * # *
# ************************************************************************ # ************************************************************************
@ -928,7 +958,6 @@ class Khadga(Vajra):
return (sequence([card1, card2]) or sequence([card2, card1])) return (sequence([card1, card2]) or sequence([card2, card1]))
# ************************************************************************ # ************************************************************************
# * # *
# ************************************************************************ # ************************************************************************
@ -942,7 +971,6 @@ class Makara(Vajra):
return (sequence([card1, card2]) or sequence([card2, card1])) return (sequence([card1, card2]) or sequence([card2, card1]))
# ************************************************************************ # ************************************************************************
# * Ashta Dikapala Game Stacks # * Ashta Dikapala Game Stacks
# ************************************************************************ # ************************************************************************
@ -950,7 +978,8 @@ class Makara(Vajra):
class Dikapala_TableauStack(Mughal_OpenStack): class Dikapala_TableauStack(Mughal_OpenStack):
def __init__(self, x, y, game, base_rank, yoffset, **cap): def __init__(self, x, y, game, base_rank, yoffset, **cap):
kwdefault(cap, dir=3, max_move=99, max_cards=4, max_accept=1, base_rank=base_rank) kwdefault(cap, dir=3, max_move=99, max_cards=4, max_accept=1,
base_rank=base_rank)
OpenStack.__init__(self, x, y, game, **cap) OpenStack.__init__(self, x, y, game, **cap)
self.CARD_YOFFSET = yoffset self.CARD_YOFFSET = yoffset
@ -1092,7 +1121,9 @@ class AshtaDikapala(Game):
for i in range(3, 0, -1): for i in range(3, 0, -1):
x = l.XM x = l.XM
for j in range(8): for j in range(8):
s.tableaux.append(Dikapala_TableauStack(x, y, self, i - 1, TABLEAU_YOFFSET)) s.tableaux.append(
Dikapala_TableauStack(
x, y, self, i - 1, TABLEAU_YOFFSET))
x = x + l.XS x = x + l.XS
x = x + l.XM x = x + l.XM
s.reserves.append(Dikapala_ReserveStack(x, y, self)) s.reserves.append(Dikapala_ReserveStack(x, y, self))
@ -1146,14 +1177,17 @@ class AshtaDikapala(Game):
def r(id, gameclass, name, game_type, decks, redeals, skill_level): def r(id, gameclass, name, game_type, decks, redeals, skill_level):
game_type = game_type | GI.GT_MUGHAL_GANJIFA game_type = game_type | GI.GT_MUGHAL_GANJIFA
gi = GameInfo(id, gameclass, name, game_type, decks, redeals, skill_level, gi = GameInfo(id, gameclass, name, game_type, decks, redeals, skill_level,
suits=range(8), ranks=range(12)) suits=range(8), ranks=range(12))
registerGame(gi) registerGame(gi)
return gi return gi
r(14401, MughalCircles, 'Mughal Circles', GI.GT_MUGHAL_GANJIFA, 1, 0, GI.SL_MOSTLY_SKILL)
r(14401, MughalCircles, 'Mughal Circles', GI.GT_MUGHAL_GANJIFA, 1, 0,
GI.SL_MOSTLY_SKILL)
r(14402, Ghulam, 'Ghulam', GI.GT_MUGHAL_GANJIFA, 1, 0, GI.SL_MOSTLY_SKILL) r(14402, Ghulam, 'Ghulam', GI.GT_MUGHAL_GANJIFA, 1, 0, GI.SL_MOSTLY_SKILL)
r(14403, Shamsher, 'Shamsher', GI.GT_MUGHAL_GANJIFA, 1, 0, GI.SL_MOSTLY_SKILL) r(14403, Shamsher, 'Shamsher', GI.GT_MUGHAL_GANJIFA, 1, 0, GI.SL_MOSTLY_SKILL)
r(14404, EightLegions, 'Eight Legions', GI.GT_MUGHAL_GANJIFA, 1, 0, GI.SL_MOSTLY_SKILL) r(14404, EightLegions, 'Eight Legions', GI.GT_MUGHAL_GANJIFA, 1, 0,
GI.SL_MOSTLY_SKILL)
r(14405, Ashrafi, 'Ashrafi', GI.GT_MUGHAL_GANJIFA, 1, 0, GI.SL_MOSTLY_SKILL) r(14405, Ashrafi, 'Ashrafi', GI.GT_MUGHAL_GANJIFA, 1, 0, GI.SL_MOSTLY_SKILL)
r(14406, Tipati, 'Tipati', GI.GT_MUGHAL_GANJIFA, 1, 0, GI.SL_BALANCED) r(14406, Tipati, 'Tipati', GI.GT_MUGHAL_GANJIFA, 1, 0, GI.SL_BALANCED)
r(14407, Ashwapati, 'Ashwapati', GI.GT_MUGHAL_GANJIFA, 1, -1, GI.SL_BALANCED) r(14407, Ashwapati, 'Ashwapati', GI.GT_MUGHAL_GANJIFA, 1, -1, GI.SL_BALANCED)
@ -1161,12 +1195,15 @@ r(14408, Gajapati, 'Gajapati', GI.GT_MUGHAL_GANJIFA, 1, -1, GI.SL_BALANCED)
r(14409, Narpati, 'Narpati', GI.GT_MUGHAL_GANJIFA, 1, 0, GI.SL_BALANCED) r(14409, Narpati, 'Narpati', GI.GT_MUGHAL_GANJIFA, 1, 0, GI.SL_BALANCED)
r(14410, Garhpati, 'Garhpati', GI.GT_MUGHAL_GANJIFA, 1, -1, GI.SL_BALANCED) r(14410, Garhpati, 'Garhpati', GI.GT_MUGHAL_GANJIFA, 1, -1, GI.SL_BALANCED)
r(14411, Dhanpati, 'Dhanpati', GI.GT_MUGHAL_GANJIFA, 1, 1, GI.SL_BALANCED) r(14411, Dhanpati, 'Dhanpati', GI.GT_MUGHAL_GANJIFA, 1, 1, GI.SL_BALANCED)
r(14412, AkbarsTriumph, 'Akbar\'s Triumph', GI.GT_MUGHAL_GANJIFA, 1, 2, GI.SL_BALANCED) r(14412, AkbarsTriumph, 'Akbar\'s Triumph', GI.GT_MUGHAL_GANJIFA, 1, 2,
r(14413, AkbarsConquest, 'Akbar\'s Conquest', GI.GT_MUGHAL_GANJIFA, 2, 2, GI.SL_BALANCED) GI.SL_BALANCED)
r(14413, AkbarsConquest, 'Akbar\'s Conquest', GI.GT_MUGHAL_GANJIFA, 2, 2,
GI.SL_BALANCED)
r(16000, Vajra, 'Vajra', GI.GT_MUGHAL_GANJIFA, 1, 0, GI.SL_MOSTLY_SKILL) r(16000, Vajra, 'Vajra', GI.GT_MUGHAL_GANJIFA, 1, 0, GI.SL_MOSTLY_SKILL)
r(16001, Danda, 'Danda', GI.GT_MUGHAL_GANJIFA, 1, 0, GI.SL_MOSTLY_SKILL) r(16001, Danda, 'Danda', GI.GT_MUGHAL_GANJIFA, 1, 0, GI.SL_MOSTLY_SKILL)
r(16002, Khadga, 'Khadga', GI.GT_MUGHAL_GANJIFA, 1, 0, GI.SL_MOSTLY_SKILL) r(16002, Khadga, 'Khadga', GI.GT_MUGHAL_GANJIFA, 1, 0, GI.SL_MOSTLY_SKILL)
r(16003, Makara, 'Makara', GI.GT_MUGHAL_GANJIFA, 1, 0, GI.SL_MOSTLY_SKILL) r(16003, Makara, 'Makara', GI.GT_MUGHAL_GANJIFA, 1, 0, GI.SL_MOSTLY_SKILL)
r(16004, AshtaDikapala, 'Ashta Dikapala', GI.GT_MUGHAL_GANJIFA, 1, 0, GI.SL_BALANCED) r(16004, AshtaDikapala, 'Ashta Dikapala', GI.GT_MUGHAL_GANJIFA, 1, 0,
GI.SL_BALANCED)
del r del r

View file

@ -24,28 +24,35 @@
__all__ = [] __all__ = []
# Imports # Imports
import sys
# Ultrasol imports # Ultrasol imports
from pysollib.gamedb import registerGame, GameInfo, GI from pysollib.gamedb import registerGame, GameInfo, GI
from pysollib.util import *
from pysollib.mfxutil import kwdefault from pysollib.mfxutil import kwdefault
from pysollib.stack import *
from pysollib.game import Game
from pysollib.layout import Layout from pysollib.layout import Layout
from pysollib.games.special.tarock import AbstractTarockGame, Grasshopper from pysollib.games.special.tarock import AbstractTarockGame, Grasshopper
from pysollib.games.threepeaks import ThreePeaksNoScore from pysollib.games.threepeaks import ThreePeaksNoScore
from pysollib.util import ANY_RANK, NO_RANK, UNLIMITED_ACCEPTS, UNLIMITED_MOVES
from pysollib.stack import \
InitialDealTalonStack, \
ReserveStack, \
SS_FoundationStack, \
StackWrapper, \
OpenStack
# ************************************************************************ # ************************************************************************
# * # *
# ************************************************************************ # ************************************************************************
class Tarock_OpenStack(OpenStack): class Tarock_OpenStack(OpenStack):
def __init__(self, x, y, game, yoffset=-1, **cap): def __init__(self, x, y, game, yoffset=-1, **cap):
kwdefault(cap, max_move=UNLIMITED_MOVES, max_accept=UNLIMITED_ACCEPTS, dir=-1) kwdefault(
cap, max_move=UNLIMITED_MOVES,
max_accept=UNLIMITED_ACCEPTS, dir=-1)
OpenStack.__init__(self, x, y, game, **cap) OpenStack.__init__(self, x, y, game, **cap)
if yoffset < 0: if yoffset < 0:
yoffset = game.app.images.CARD_YOFFSET yoffset = game.app.images.CARD_YOFFSET
@ -84,10 +91,12 @@ class Tarock_OpenStack(OpenStack):
return 1 return 1
def isHighRankCard(self, card): def isHighRankCard(self, card):
maxcard = ([self.game.gameinfo.ranks[-1], self.game.gameinfo.trumps[-1]] maxcard = ([self.game.gameinfo.ranks[-1],
[(card.suit == len(self.game.gameinfo.suits))]) self.game.gameinfo.trumps[-1]]
[(card.suit == len(self.game.gameinfo.suits))])
return card.rank == maxcard or self.cap.base_rank == ANY_RANK return card.rank == maxcard or self.cap.base_rank == ANY_RANK
class Tarock_RK_RowStack(Tarock_OpenStack): class Tarock_RK_RowStack(Tarock_OpenStack):
def acceptsCards(self, from_stack, cards): def acceptsCards(self, from_stack, cards):
@ -102,6 +111,7 @@ class Tarock_RK_RowStack(Tarock_OpenStack):
return (self.basicCanMoveCards(cards) return (self.basicCanMoveCards(cards)
and self.isRankSequence(cards)) and self.isRankSequence(cards))
class Tarock_SS_RowStack(Tarock_OpenStack): class Tarock_SS_RowStack(Tarock_OpenStack):
def acceptsCards(self, from_stack, cards): def acceptsCards(self, from_stack, cards):
@ -116,11 +126,12 @@ class Tarock_SS_RowStack(Tarock_OpenStack):
return (self.basicCanMoveCards(cards) return (self.basicCanMoveCards(cards)
and self.isSuitSequence(cards)) and self.isSuitSequence(cards))
class Tarock_AC_RowStack(Tarock_OpenStack): class Tarock_AC_RowStack(Tarock_OpenStack):
def acceptsCards(self, from_stack, cards): def acceptsCards(self, from_stack, cards):
if (not self.basicAcceptsCards(from_stack, cards) if not self.basicAcceptsCards(from_stack, cards) \
or not self.isAlternateColorSequence(cards)): or not self.isAlternateColorSequence(cards):
return 0 return 0
if not self.cards: if not self.cards:
return self.isHighRankCard(cards[0]) return self.isHighRankCard(cards[0])
@ -134,9 +145,11 @@ class Tarock_AC_RowStack(Tarock_OpenStack):
# * # *
# ************************************************************************ # ************************************************************************
class Cockroach(Grasshopper): class Cockroach(Grasshopper):
MAX_ROUNDS = 1 MAX_ROUNDS = 1
class DoubleCockroach(Grasshopper): class DoubleCockroach(Grasshopper):
MAX_ROUNDS = 1 MAX_ROUNDS = 1
@ -144,6 +157,7 @@ class DoubleCockroach(Grasshopper):
# * # *
# ************************************************************************ # ************************************************************************
class Corkscrew(AbstractTarockGame): class Corkscrew(AbstractTarockGame):
RowStack_Class = StackWrapper(Tarock_RK_RowStack, base_rank=NO_RANK) RowStack_Class = StackWrapper(Tarock_RK_RowStack, base_rank=NO_RANK)
@ -185,13 +199,18 @@ class Corkscrew(AbstractTarockGame):
x, y = l.XM + maxrows * l.XS, l.YM x, y = l.XM + maxrows * l.XS, l.YM
for i in range(2): for i in range(2):
for suit in range(5): for suit in range(5):
s.foundations.append(SS_FoundationStack(x, y, self, suit=suit, s.foundations.append(
max_cards=14 + 8 * (suit == 4))) SS_FoundationStack(
x, y, self, suit=suit,
max_cards=14 + 8 * (suit == 4)))
y = y + l.YS y = y + l.YS
x, y = x + l.XS, l.YM x, y = x + l.XS, l.YM
self.setRegion(self.s.foundations, (x - l.XS * 2, -999, 999999, self.setRegion(
self.height - (l.YS + l.YM)), priority=1) self.s.foundations,
s.talon = InitialDealTalonStack(self.width - 3 * l.XS / 2, self.height - l.YS, self) (x - l.XS * 2, -999, 999999,
self.height - (l.YS + l.YM)), priority=1)
s.talon = InitialDealTalonStack(
self.width - 3 * l.XS / 2, self.height - l.YS, self)
# define stack-groups # define stack-groups
l.defaultStackGroups() l.defaultStackGroups()
@ -215,7 +234,8 @@ class Corkscrew(AbstractTarockGame):
closest, cdist = None, 999999999 closest, cdist = None, 999999999
for stack in stacks: for stack in stacks:
if stack.cards and stack is not dragstack: if stack.cards and stack is not dragstack:
dist = (stack.cards[-1].x - cx)**2 + (stack.cards[-1].y - cy)**2 dist = (stack.cards[-1].x - cx)**2 + \
(stack.cards[-1].y - cy)**2
else: else:
dist = (stack.x - cx)**2 + (stack.y - cy)**2 dist = (stack.x - cx)**2 + (stack.y - cy)**2
if dist < cdist: if dist < cdist:
@ -231,6 +251,7 @@ class Corkscrew(AbstractTarockGame):
# * # *
# ************************************************************************ # ************************************************************************
class Serpent(Corkscrew): class Serpent(Corkscrew):
RowStack_Class = StackWrapper(Tarock_AC_RowStack, base_rank=NO_RANK) RowStack_Class = StackWrapper(Tarock_AC_RowStack, base_rank=NO_RANK)
@ -243,6 +264,7 @@ class Serpent(Corkscrew):
# * # *
# ************************************************************************ # ************************************************************************
class Rambling(Corkscrew): class Rambling(Corkscrew):
RowStack_Class = StackWrapper(Tarock_SS_RowStack, base_rank=NO_RANK) RowStack_Class = StackWrapper(Tarock_SS_RowStack, base_rank=NO_RANK)
@ -255,11 +277,11 @@ class Rambling(Corkscrew):
# * Le Grande Teton # * Le Grande Teton
# ************************************************************************ # ************************************************************************
class LeGrandeTeton(ThreePeaksNoScore): class LeGrandeTeton(ThreePeaksNoScore):
pass pass
# ************************************************************************ # ************************************************************************
# * register the games # * register the games
# ************************************************************************ # ************************************************************************
@ -271,11 +293,11 @@ def r(id, gameclass, name, game_type, decks, redeals, skill_level):
registerGame(gi) registerGame(gi)
return gi return gi
r(13163, Cockroach, 'Cockroach', GI.GT_TAROCK, 1, 0, GI.SL_MOSTLY_SKILL) r(13163, Cockroach, 'Cockroach', GI.GT_TAROCK, 1, 0, GI.SL_MOSTLY_SKILL)
r(13164, DoubleCockroach, 'Double Cockroach', GI.GT_TAROCK, 2, 0, GI.SL_MOSTLY_SKILL) r(13164, DoubleCockroach, 'Double Cockroach', GI.GT_TAROCK, 2, 0,
GI.SL_MOSTLY_SKILL)
r(13165, Corkscrew, 'Corkscrew', GI.GT_TAROCK, 2, 0, GI.SL_MOSTLY_SKILL) r(13165, Corkscrew, 'Corkscrew', GI.GT_TAROCK, 2, 0, GI.SL_MOSTLY_SKILL)
r(13166, Serpent, 'Serpent', GI.GT_TAROCK, 2, 0, GI.SL_MOSTLY_SKILL) r(13166, Serpent, 'Serpent', GI.GT_TAROCK, 2, 0, GI.SL_MOSTLY_SKILL)
r(13167, Rambling, 'Rambling', GI.GT_TAROCK, 2, 0, GI.SL_MOSTLY_SKILL) r(13167, Rambling, 'Rambling', GI.GT_TAROCK, 2, 0, GI.SL_MOSTLY_SKILL)
r(22232, LeGrandeTeton, 'Le Grande Teton', GI.GT_TAROCK, 1, 0, GI.SL_BALANCED) r(22232, LeGrandeTeton, 'Le Grande Teton', GI.GT_TAROCK, 1, 0, GI.SL_BALANCED)

View file

@ -13,6 +13,7 @@ my %skip =
map { $_ => 1 } map { $_ => 1 }
qw( qw(
./pysollib/games/__init__.py ./pysollib/games/__init__.py
./pysollib/games/ultra/__init__.py
./pysollib/pysoltk.py ./pysollib/pysoltk.py
./pysollib/tile/ttk.py ./pysollib/tile/ttk.py
) )
@ -20,7 +21,7 @@ my %skip =
# my $cmd = shell_quote( 'flake8', '.' ); # my $cmd = shell_quote( 'flake8', '.' );
my $cmd = shell_quote( 'flake8', my $cmd = shell_quote( 'flake8',
grep { not exists $skip{$_} } glob('./pysollib/*.py ./pysollib/[cmpuw]*/*.py ./pysollib/tile/*.py ./pysollib/ui/tktile/*.py ./pysollib/games/*.py') ); grep { not exists $skip{$_} } glob('./pysollib/*.py ./pysollib/[cmpuw]*/*.py ./pysollib/tile/*.py ./pysollib/ui/tktile/*.py ./pysollib/games/*.py ./pysollib/games/ultra/*.py') );
# TEST # TEST
eq_or_diff( scalar(`$cmd`), '', "flake8 is happy with the code." ); eq_or_diff( scalar(`$cmd`), '', "flake8 is happy with the code." );