mirror of
https://github.com/shlomif/PySolFC.git
synced 2025-04-05 00:02:29 -04:00
+ 3 new games
* little reorganisation: move all french games to pysollib/games + new command-line option: `--french-only' (undocumented) * misc. improvements git-svn-id: file:///home/shlomif/Backup/svn-dumps/PySolFC/svnsync-repos/pysolfc/PySolFC/trunk@41 efabe8c0-fbe8-4139-b769-b5e6d273206e
This commit is contained in:
parent
c1fb4f75b0
commit
cf72a6794a
28 changed files with 858 additions and 816 deletions
|
@ -195,7 +195,7 @@ class PysolMenubarActions:
|
|||
tkopt.negative_bottom.set(opt.negative_bottom)
|
||||
for w in TOOLBAR_BUTTONS:
|
||||
tkopt.toolbar_vars[w].set(opt.toolbar_vars[w])
|
||||
if game.gameinfo.category == GI.GC_FRENCH:
|
||||
if game.canFindCard():
|
||||
connect_game_find_card_dialog(game)
|
||||
else:
|
||||
destroy_find_card_dialog()
|
||||
|
@ -282,7 +282,7 @@ class PysolMenubarActions:
|
|||
ms.quickplay = 1
|
||||
if opt.highlight_piles and game.getHighlightPilesStacks():
|
||||
ms.highlight_piles = 1
|
||||
if game.gameinfo.category == GI.GC_FRENCH:
|
||||
if game.canFindCard():
|
||||
ms.find_card = 1
|
||||
if game.app.getGameRulesFilename(game.id): # note: this may return ""
|
||||
ms.rules = 1
|
||||
|
|
|
@ -1380,7 +1380,7 @@ Please select a %s type %s.
|
|||
return None
|
||||
config = CardsetConfig()
|
||||
if not self._parseCardsetConfig(config, lines):
|
||||
##print filename, 'invalide config'
|
||||
##print filename, 'invalid config'
|
||||
return None
|
||||
if config.CARDD > self.top.winfo_screendepth():
|
||||
return None
|
||||
|
@ -1444,7 +1444,7 @@ Please select a %s type %s.
|
|||
return 0
|
||||
cs.year = int(m.group(1))
|
||||
if len(cs.ext) < 2 or cs.ext[0] != ".":
|
||||
if _debug: print_err(1, msg='invalide extention')
|
||||
if _debug: print_err(1, msg='invalid extention')
|
||||
return 0
|
||||
# line[1]: identifier/name
|
||||
if not line[1]:
|
||||
|
@ -1453,19 +1453,19 @@ Please select a %s type %s.
|
|||
cs.ident = line[1]
|
||||
m = re.search(r"^(.*;)?([^;]+)$", cs.ident)
|
||||
if not m:
|
||||
if _debug: print_err(2, msg='invalide format')
|
||||
if _debug: print_err(2, msg='invalid format')
|
||||
return 0
|
||||
cs.name = m.group(2).strip()
|
||||
# line[2]: CARDW, CARDH, CARDD
|
||||
m = re.search(r"^(\d+)\s+(\d+)\s+(\d+)", line[2])
|
||||
if not m:
|
||||
if _debug: print_err(3, msg='invalide format')
|
||||
if _debug: print_err(3, msg='invalid format')
|
||||
return 0
|
||||
cs.CARDW, cs.CARDH, cs.CARDD = int(m.group(1)), int(m.group(2)), int(m.group(3))
|
||||
# line[3]: CARD_UP_YOFFSET, CARD_DOWN_YOFFSET, SHADOW_XOFFSET, SHADOW_YOFFSET
|
||||
m = re.search(r"^(\d+)\s+(\d+)\s+(\d+)\s+(\d+)", line[3])
|
||||
if not m:
|
||||
if _debug: print_err(4, msg='invalide format')
|
||||
if _debug: print_err(4, msg='invalid format')
|
||||
return 0
|
||||
cs.CARD_XOFFSET = int(m.group(1))
|
||||
cs.CARD_YOFFSET = int(m.group(2))
|
||||
|
|
|
@ -1590,7 +1590,7 @@ for %d moves.
|
|||
return card1.color != card2.color and abs(card1.rank-card2.rank) == 1
|
||||
|
||||
def _shallHighlightMatch_ACW(self, stack1, card1, stack2, card2):
|
||||
# by alternate color with wrapping (only for france games)
|
||||
# by alternate color with wrapping (only for french games)
|
||||
return (card1.color != card2.color
|
||||
and ((card1.rank + 1) % 13 == card2.rank
|
||||
or (card2.rank + 1) % 13 == card1.rank))
|
||||
|
@ -1600,7 +1600,7 @@ for %d moves.
|
|||
return card1.suit == card2.suit and abs(card1.rank-card2.rank) == 1
|
||||
|
||||
def _shallHighlightMatch_SSW(self, stack1, card1, stack2, card2):
|
||||
# by same suit with wrapping (only for france games)
|
||||
# by same suit with wrapping (only for french games)
|
||||
return (card1.suit == card2.suit
|
||||
and ((card1.rank + 1) % 13 == card2.rank
|
||||
or (card2.rank + 1) % 13 == card1.rank))
|
||||
|
@ -1610,7 +1610,7 @@ for %d moves.
|
|||
return abs(card1.rank-card2.rank) == 1
|
||||
|
||||
def _shallHighlightMatch_RKW(self, stack1, card1, stack2, card2):
|
||||
# by rank with wrapping (only for france games)
|
||||
# by rank with wrapping (only for french games)
|
||||
return ((card1.rank + 1) % 13 == card2.rank
|
||||
or (card2.rank + 1) % 13 == card1.rank)
|
||||
|
||||
|
@ -2640,6 +2640,10 @@ in the current implementation.''' % version
|
|||
sd.delete()
|
||||
self.stackdesc_list = []
|
||||
|
||||
## for find_card_dialog
|
||||
def canFindCard(self):
|
||||
return self.gameinfo.category == GI.GC_FRENCH
|
||||
|
||||
#
|
||||
# subclass hooks
|
||||
#
|
||||
|
|
|
@ -490,16 +490,22 @@ class GameManager:
|
|||
raise GameInfoException, "wrong GameInfo class"
|
||||
gi.plugin = self.loading_plugin
|
||||
if self.__all_games.has_key(gi.id):
|
||||
raise GameInfoException, "duplicate game ID " + str(gi.id)
|
||||
raise GameInfoException, "duplicate game ID %s: %s and %s" % \
|
||||
(gi.id, str(gi.gameclass),
|
||||
str(self.__all_games[gi.id].gameclass))
|
||||
if self.__all_gamenames.has_key(gi.name):
|
||||
raise GameInfoException, "duplicate game name " + str(gi.id) + ": " + gi.name
|
||||
raise GameInfoException, "duplicate game name %s: %s and %s" % \
|
||||
(gi.id, gi.name, str(self.__all_games[gi.id].gameclass))
|
||||
if 1:
|
||||
for id, game in self.__all_games.items():
|
||||
if gi.gameclass is game.gameclass:
|
||||
raise GameInfoException, "duplicate game class " + str(gi.id)
|
||||
raise GameInfoException, \
|
||||
"duplicate game class %s: %s and %s" % \
|
||||
(gi.id, str(gi.gameclass), str(game.gameclass))
|
||||
for n in gi.altnames:
|
||||
if self.__all_gamenames.has_key(n):
|
||||
raise GameInfoException, "duplicate altgame name " + str(gi.id) + ": " + n
|
||||
raise GameInfoException, "duplicate game altname %s: %s" % \
|
||||
(gi.id, n)
|
||||
##if 0 and gi.si.game_flags & GI.GT_XORIGINAL:
|
||||
## return
|
||||
##print gi.id, gi.name
|
||||
|
|
|
@ -30,6 +30,7 @@ import headsandtails
|
|||
import katzenschwanz
|
||||
import klondike
|
||||
import labyrinth
|
||||
import larasgame
|
||||
import matriarchy
|
||||
import montana
|
||||
import montecarlo
|
||||
|
@ -46,6 +47,7 @@ import pushpin
|
|||
import pyramid
|
||||
import royalcotillion
|
||||
import royaleast
|
||||
import sanibel
|
||||
import siebenbisas
|
||||
import simplex
|
||||
import spider
|
||||
|
@ -53,6 +55,7 @@ import sthelena
|
|||
import sultan
|
||||
import takeaway
|
||||
import terrace
|
||||
import threepeaks
|
||||
import tournament
|
||||
import unionsquare
|
||||
import wavemotion
|
||||
|
|
|
@ -128,7 +128,7 @@ class Strata(Game):
|
|||
s.foundations.append(DieRussische_Foundation(x, y, self,
|
||||
suit=i%4, max_cards=8))
|
||||
x = x + l.XS
|
||||
x, y, = l.XM+l.XS, l.YM+l.YS
|
||||
x, y, = l.XM+l.XS/2, l.YM+l.YS
|
||||
for i in range(8):
|
||||
s.rows.append(AC_RowStack(x, y, self, max_move=1, max_accept=1))
|
||||
x = x + l.XS
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
import sanibel
|
|
@ -277,118 +277,6 @@ class Escalator(Elevator):
|
|||
self.s.talon.dealRow()
|
||||
self.s.talon.dealCards() # deal first card to WasteStack
|
||||
|
||||
# /***********************************************************************
|
||||
# // Tri Peaks - Relaxed Golf in a Pyramid layout
|
||||
# ************************************************************************/
|
||||
|
||||
class TriPeaks_RowStack(Elevator_RowStack):
|
||||
STEP = (1, 2, 2, 3+12, 3+12, 3+12,
|
||||
1, 2, 2, 3+ 9, 3+ 9, 3+ 9,
|
||||
1, 2, 2, 3+ 6, 3+ 6, 3+ 6)
|
||||
|
||||
|
||||
class TriPeaks(RelaxedGolf):
|
||||
|
||||
#
|
||||
# game layout
|
||||
#
|
||||
|
||||
def createGame(self):
|
||||
# create layout
|
||||
l, s = Layout(self), self.s
|
||||
|
||||
# set window
|
||||
l.XOFFSET = int(l.XS * 9 / self.gameinfo.ncards)
|
||||
self.setSize(10*l.XS+l.XM, 4*l.YS+l.YM)
|
||||
|
||||
# extra settings
|
||||
self.talon_card_ids = {}
|
||||
|
||||
# create stacks
|
||||
for i in range(3):
|
||||
for d in ((2, 0), (1, 1), (3, 1), (0, 2), (2, 2), (4, 2)):
|
||||
x = l.XM + (6*i+1+d[0]) * l.XS / 2
|
||||
y = l.YM + d[1] * l.YS / 2
|
||||
s.rows.append(TriPeaks_RowStack(x, y, self))
|
||||
x, y = l.XM, 3*l.YS/2
|
||||
for i in range(10):
|
||||
s.rows.append(Golf_RowStack(x, y, self))
|
||||
x = x + l.XS
|
||||
x, y = l.XM, self.height - l.YS
|
||||
s.talon = Golf_Talon(x, y, self, max_rounds=1)
|
||||
l.createText(s.talon, "nn")
|
||||
x = x + l.XS
|
||||
s.waste = self.Waste_Class(x, y, self)
|
||||
s.waste.CARD_XOFFSET = l.XOFFSET
|
||||
l.createText(s.waste, "nn")
|
||||
# the Waste is also our only Foundation in this game
|
||||
s.foundations.append(s.waste)
|
||||
|
||||
self.texts.score = MfxCanvasText(self.canvas,
|
||||
self.width - 8, self.height - 8,
|
||||
anchor="se",
|
||||
font=self.app.getFont("canvas_large"))
|
||||
|
||||
# define stack-groups (non default)
|
||||
self.sg.openstacks = [s.waste]
|
||||
self.sg.talonstacks = [s.talon]
|
||||
self.sg.dropstacks = s.rows
|
||||
|
||||
#
|
||||
# game overrides
|
||||
#
|
||||
|
||||
def startGame(self):
|
||||
self.startDealSample()
|
||||
self.s.talon.dealRow(rows=self.s.rows[:18], flip=0)
|
||||
self.s.talon.dealRow(rows=self.s.rows[18:])
|
||||
# extra settings: remember cards from the talon
|
||||
self.talon_card_ids = {}
|
||||
for c in self.s.talon.cards:
|
||||
self.talon_card_ids[c.id] = 1
|
||||
self.s.talon.dealCards() # deal first card to WasteStack
|
||||
|
||||
def getGameScore(self):
|
||||
v = -24 * 5
|
||||
if not self.s.waste.cards:
|
||||
return v
|
||||
# compute streaks for cards on the waste
|
||||
streak = 0
|
||||
for c in self.s.waste.cards:
|
||||
if self.talon_card_ids.get(c.id):
|
||||
streak = 0
|
||||
else:
|
||||
streak = streak + 1
|
||||
v = v + streak
|
||||
# each cleared peak gains $15 bonus, and all 3 gain extra $30
|
||||
extra = 30
|
||||
for i in (0, 6, 12):
|
||||
if not self.s.rows[i].cards:
|
||||
v = v + 15
|
||||
else:
|
||||
extra = 0
|
||||
return v + extra
|
||||
|
||||
getGameBalance = getGameScore
|
||||
|
||||
def updateText(self):
|
||||
if self.preview > 1:
|
||||
return
|
||||
b1, b2 = self.app.stats.gameid_balance, 0
|
||||
if self.shallUpdateBalance():
|
||||
b2 = self.getGameBalance()
|
||||
t = _("Balance $%4d") % (b1 + b2)
|
||||
self.texts.score.config(text=t)
|
||||
|
||||
def _restoreGameHook(self, game):
|
||||
self.talon_card_ids = game.loadinfo.talon_card_ids
|
||||
|
||||
def _loadGameHook(self, p):
|
||||
self.loadinfo.addattr(talon_card_ids=p.load(types.DictType))
|
||||
|
||||
def _saveGameHook(self, p):
|
||||
p.dump(self.talon_card_ids)
|
||||
|
||||
|
||||
# /***********************************************************************
|
||||
# // Black Hole
|
||||
|
@ -679,8 +567,6 @@ registerGame(GameInfo(260, RelaxedGolf, "Relaxed Golf",
|
|||
registerGame(GameInfo(40, Elevator, "Elevator",
|
||||
GI.GT_GOLF, 1, 0, GI.SL_BALANCED,
|
||||
altnames=("Egyptian Solitaire", "Pyramid Golf") ))
|
||||
registerGame(GameInfo(237, TriPeaks, "Tri Peaks",
|
||||
GI.GT_GOLF | GI.GT_SCORE, 1, 0, GI.SL_MOSTLY_SKILL))
|
||||
registerGame(GameInfo(98, BlackHole, "Black Hole",
|
||||
GI.GT_GOLF | GI.GT_OPEN, 1, 0, GI.SL_MOSTLY_SKILL))
|
||||
registerGame(GameInfo(267, FourLeafClovers, "Four Leaf Clovers",
|
||||
|
|
449
pysollib/games/larasgame.py
Normal file
449
pysollib/games/larasgame.py
Normal file
|
@ -0,0 +1,449 @@
|
|||
##---------------------------------------------------------------------------##
|
||||
##
|
||||
## Ultrasol -- a Python Solitaire game
|
||||
##
|
||||
## Copyright (C) 2000 Markus Franz Xaver Johannes Oberhumer
|
||||
## Copyright (C) 1999 Markus Franz Xaver Johannes Oberhumer
|
||||
## Copyright (C) 1998 Markus Franz Xaver Johannes Oberhumer
|
||||
## Copyright (C) 1999 Matthew Hohlfeld <hohlfeld@cs.ucsd.edu>
|
||||
##
|
||||
## This program is free software; you can redistribute it and/or modify
|
||||
## it under the terms of the GNU General Public License as published by
|
||||
## the Free Software Foundation; either version 2 of the License, or
|
||||
## (at your option) any later version.
|
||||
##
|
||||
## This program is distributed in the hope that it will be useful,
|
||||
## but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
## GNU General Public License for more details.
|
||||
##
|
||||
## You should have received a copy of the GNU General Public License
|
||||
## along with this program; see the file COPYING.
|
||||
## If not, write to the Free Software Foundation, Inc.,
|
||||
## 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
##
|
||||
##---------------------------------------------------------------------------##
|
||||
|
||||
__all__ = []
|
||||
|
||||
# imports
|
||||
|
||||
# PySol imports
|
||||
from pysollib.gamedb import registerGame, GameInfo, GI
|
||||
from pysollib.util import *
|
||||
from pysollib.stack import *
|
||||
from pysollib.game import Game
|
||||
from pysollib.layout import Layout
|
||||
from pysollib.hint import AbstractHint, DefaultHint, CautiousDefaultHint
|
||||
from pysollib.pysoltk import MfxCanvasText
|
||||
|
||||
|
||||
# /***********************************************************************
|
||||
# //
|
||||
# ************************************************************************/
|
||||
|
||||
class LarasGame_Hint(CautiousDefaultHint):
|
||||
pass
|
||||
|
||||
|
||||
# /***********************************************************************
|
||||
# //
|
||||
# ************************************************************************/
|
||||
|
||||
class LarasGame_Talon(WasteTalonStack):
|
||||
# Deal a card to each of the RowStacks. Then deal
|
||||
# cards to the talon. Return number of cards dealt.
|
||||
def dealRow(self, rows=None, flip=1, reverse=0, frames=-1, sound=0):
|
||||
game = self.game
|
||||
if rows is None:
|
||||
rows = game.s.rows
|
||||
old_state = game.enterState(game.S_DEAL)
|
||||
cards = self.dealToStacks(rows[:game.MAX_ROW], flip, reverse, frames)
|
||||
if sound and frames and self.game.app.opt.animations:
|
||||
self.game.startDealSample()
|
||||
for i in range(game.DEAL_TO_TALON):
|
||||
if self.cards:
|
||||
game.moveMove(1, self, game.s.rows[-1], frames=frames)
|
||||
cards = cards + 1
|
||||
game.leaveState(old_state)
|
||||
if sound:
|
||||
self.game.stopSamples()
|
||||
return cards
|
||||
|
||||
def dealToStacks(self, stacks, flip=1, reverse=0, frames=-1):
|
||||
game = self.game
|
||||
i, move = 0, game.moveMove
|
||||
for r in stacks:
|
||||
if not self.cards:
|
||||
return 0
|
||||
assert not self.getCard().face_up
|
||||
assert r is not self
|
||||
if flip:
|
||||
game.flipMove(self)
|
||||
move(1, self, r, frames=frames)
|
||||
# Dealing has extra rules in this game type:
|
||||
# If card rank == card location then add one card to talon
|
||||
# If card rank == ACE then add two cards to talon
|
||||
# If card rank == JACK, or higher then add one card to talon
|
||||
# After all the rows have been dealt, deal cards to talon in self.dealRow
|
||||
rank = r.getCard().rank
|
||||
if rank == i: # Is the rank == position?
|
||||
if not self.cards:
|
||||
return 0
|
||||
move(1, self, game.s.rows[-1], frames=frames)
|
||||
i = i + 1
|
||||
if rank == 0: # Is this an Ace?
|
||||
for j in range(2):
|
||||
if not self.cards:
|
||||
return 0
|
||||
move(1, self, game.s.rows[-1], frames=frames)
|
||||
if rank >= 10: # Is it a Jack or better?
|
||||
if not self.cards:
|
||||
return 0
|
||||
move(1, self, game.s.rows[-1], frames=frames)
|
||||
return len(stacks)
|
||||
|
||||
def dealCards(self, sound=0):
|
||||
game = self.game
|
||||
if sound and self.game.app.opt.animations:
|
||||
self.game.startDealSample()
|
||||
for r in game.s.reserves[:20]:
|
||||
while r.cards:
|
||||
game.moveMove(1, r, game.s.rows[game.active_row], frames=3, shadow=0)
|
||||
if self.cards:
|
||||
game.active_row = self.getActiveRow()
|
||||
game.flipMove(self)
|
||||
game.moveMove(1, self, game.s.reserves[0], frames=4, shadow=0)
|
||||
ncards = len(game.s.rows[game.active_row].cards)
|
||||
if ncards >= 20:
|
||||
# We have encountered an extreme situation.
|
||||
# In some game type variations it's possible
|
||||
# to have up to 28 cards on a row stack.
|
||||
# We'll have to double up on some of the reserves.
|
||||
for i in range(ncards - 19):
|
||||
game.moveMove(1, game.s.rows[game.active_row],
|
||||
game.s.reserves[19 - i], frames=4, shadow=0)
|
||||
ncards = len(game.s.rows[game.active_row].cards)
|
||||
assert ncards <= 19
|
||||
for i in range(ncards):
|
||||
game.moveMove(1, game.s.rows[game.active_row],
|
||||
game.s.reserves[ncards - i], frames=4, shadow=0)
|
||||
num_cards = len(self.cards) or self.canDealCards()
|
||||
else: # not self.cards
|
||||
if self.round < self.max_rounds:
|
||||
ncards = 0
|
||||
rows = list(game.s.rows)[:game.MAX_ROW]
|
||||
rows.reverse()
|
||||
for r in rows:
|
||||
while r.cards:
|
||||
ncards += 1
|
||||
if r.cards[-1].face_up:
|
||||
game.flipMove(r)
|
||||
game.moveMove(1, r, self, frames=0)
|
||||
assert len(self.cards) == ncards
|
||||
if ncards != 0:
|
||||
game.nextRoundMove(self)
|
||||
game.dealToRows()
|
||||
num_cards = len(self.cards)
|
||||
if sound:
|
||||
game.stopSamples()
|
||||
return num_cards
|
||||
|
||||
def canDealCards(self):
|
||||
if self.game.demo and self.game.moves.index >= 400:
|
||||
return 0
|
||||
return (self.cards or (self.round < self.max_rounds and not self.game.isGameWon()))
|
||||
|
||||
def updateText(self):
|
||||
if self.game.preview > 1:
|
||||
return
|
||||
WasteTalonStack.updateText(self, update_rounds=0)
|
||||
if not self.max_rounds - 1:
|
||||
return
|
||||
t = _("Round %d") % self.round
|
||||
self.texts.rounds.config(text=t)
|
||||
|
||||
def getActiveRow(self):
|
||||
return self.getCard().rank
|
||||
|
||||
|
||||
class LarasGame_RowStack(OpenStack):
|
||||
def __init__(self, x, y, game, yoffset = 1, **cap):
|
||||
apply(OpenStack.__init__, (self, x, y, game), cap)
|
||||
self.CARD_YOFFSET = yoffset
|
||||
|
||||
|
||||
class LarasGame_ReserveStack(OpenStack):
|
||||
pass
|
||||
|
||||
|
||||
class LarasGame_Reserve(OpenStack):
|
||||
|
||||
def acceptsCards(self, from_stack, cards):
|
||||
if not OpenStack.acceptsCards(self, from_stack, cards):
|
||||
return 0
|
||||
return from_stack in self.game.s.rows
|
||||
|
||||
def getBottomImage(self):
|
||||
return self.game.app.images.getReserveBottom()
|
||||
|
||||
|
||||
# /***********************************************************************
|
||||
# // Lara's Game
|
||||
# ************************************************************************/
|
||||
|
||||
class LarasGame(Game):
|
||||
Hint_Class = LarasGame_Hint
|
||||
Talon_Class = LarasGame_Talon
|
||||
Reserve_Class = None
|
||||
DEAL_TO_TALON = 2
|
||||
MAX_ROUNDS = 1
|
||||
ROW_LENGTH = 4
|
||||
MAX_ROW = 13
|
||||
DIR = (-1, 1)
|
||||
|
||||
#
|
||||
# game layout
|
||||
#
|
||||
|
||||
def createGame(self):
|
||||
# create layout
|
||||
l, s = Layout(self), self.s
|
||||
ROW_LENGTH = self.ROW_LENGTH
|
||||
|
||||
# set window
|
||||
w, h = l.XM + l.XS * (ROW_LENGTH + 5), l.YM + l.YS * (ROW_LENGTH + (ROW_LENGTH != 6))
|
||||
self.setSize(w, h)
|
||||
|
||||
# extra settings
|
||||
self.active_row = None
|
||||
|
||||
# Create foundations
|
||||
x, y = l.XM, l.YM
|
||||
for j in range(2):
|
||||
for i in range(ROW_LENGTH):
|
||||
s.foundations.append(SS_FoundationStack(x, y, self, self.Base_Suit(i, j),
|
||||
max_cards = self.Max_Cards(i), mod = self.Mod(i),
|
||||
dir = self.DIR[j], base_rank = self.Base_Rank(i, j)))
|
||||
y = y + l.YS * (not j)
|
||||
x = x + l.XS * j
|
||||
x, y = x + l.XS * 2, l.YM
|
||||
|
||||
# Create rows
|
||||
x, y = l.XM + l.XS, y + l.YS
|
||||
for i in range(self.MAX_ROW):
|
||||
s.rows.append(LarasGame_RowStack(x, y, self))
|
||||
x = x + l.XS
|
||||
if i == ROW_LENGTH or i == ROW_LENGTH * 2 + 1 or i == ROW_LENGTH * 3 + 2:
|
||||
x, y = l.XM + l.XS, y + l.YS
|
||||
|
||||
# Create reserves
|
||||
x, y = l.XM + l.XS * (ROW_LENGTH == 6), l.YM + l.YS * (ROW_LENGTH - (ROW_LENGTH == 6))
|
||||
for i in range(20):
|
||||
s.reserves.append(LarasGame_ReserveStack(x, y, self, max_cards=2))
|
||||
x = x + l.XS * (i < (ROW_LENGTH + 4)) - l.XS * (i == (ROW_LENGTH + 9))
|
||||
y = y - l.YS * (i > (ROW_LENGTH + 3) and i < (ROW_LENGTH + 9)) + l.YS * (i > (ROW_LENGTH + 9))
|
||||
|
||||
# Create talon
|
||||
x, y = l.XM + l.XS * (ROW_LENGTH + 2), h - l.YM - l.YS * 3
|
||||
s.talon = self.Talon_Class(x, y, self, max_rounds=self.MAX_ROUNDS)
|
||||
l.createText(s.talon, "s")
|
||||
if self.MAX_ROUNDS - 1:
|
||||
tx, ty, ta, tf = l.getTextAttr(s.talon, "nn")
|
||||
s.talon.texts.rounds = MfxCanvasText(self.canvas,
|
||||
tx, ty, anchor=ta,
|
||||
font=self.app.getFont("canvas_default"))
|
||||
y = h - l.YS * 2
|
||||
s.rows.append(LarasGame_RowStack(x, y, self, yoffset=0))
|
||||
|
||||
# Define stack-groups (not default)
|
||||
self.sg.openstacks = s.foundations + s.rows[:self.MAX_ROW]
|
||||
self.sg.talonstacks = [s.talon] + s.rows[-1:]
|
||||
self.sg.dropstacks = s.rows[:self.MAX_ROW] + s.reserves
|
||||
|
||||
# Create relaxed reserve
|
||||
if self.Reserve_Class != None:
|
||||
x, y = l.XM + l.XS * (ROW_LENGTH + 2), l.YM + l.YS * .5
|
||||
s.reserves.append(self.Reserve_Class(x, y, self,
|
||||
max_accept=1, max_cards=self.Reserve_Cards))
|
||||
self.sg.openstacks = self.sg.openstacks + s.reserves[19:]
|
||||
self.sg.dropstacks = self.sg.dropstacks + s.reserves[19:]
|
||||
self.setRegion(s.reserves[19:], (x - l.XM / 2, 0, 99999, 99999))
|
||||
|
||||
#
|
||||
# Game extras
|
||||
#
|
||||
|
||||
def Max_Cards(self, i):
|
||||
return 13
|
||||
|
||||
def Mod(self, i):
|
||||
return 13
|
||||
|
||||
def Base_Rank(self, i, j):
|
||||
return 12 * (not j)
|
||||
|
||||
def Deal_Rows(self, i):
|
||||
return 13
|
||||
|
||||
def Base_Suit(self, i, j):
|
||||
return i
|
||||
|
||||
#
|
||||
# game overrides
|
||||
#
|
||||
|
||||
def startGame(self):
|
||||
assert len(self.s.talon.cards) == self.gameinfo.ncards
|
||||
self.dealToRows()
|
||||
|
||||
def dealToRows(self):
|
||||
frames, ncards = 0, len(self.s.talon.cards)
|
||||
for i in range(8):
|
||||
if not self.s.talon.cards:
|
||||
break
|
||||
if i == 4 or len(self.s.talon.cards) <= ncards / 2:
|
||||
self.startDealSample()
|
||||
frames = 4
|
||||
self.s.talon.dealRow(rows=self.s.rows[:self.Deal_Rows(i)], frames=frames)
|
||||
self.moveMove(len(self.s.rows[-1].cards), self.s.rows[-1], self.s.talon, frames=0)
|
||||
self.active_row = None
|
||||
|
||||
def shallHighlightMatch(self, stack1, card1, stack2, card2):
|
||||
i, j = (stack1 in self.s.foundations), (stack2 in self.s.foundations)
|
||||
if not (i or j): return 0
|
||||
if i: stack = stack1
|
||||
else: stack = stack2
|
||||
i = 0
|
||||
for f in self.s.foundations:
|
||||
if f == stack: break
|
||||
i = i + 1 % self.ROW_LENGTH
|
||||
return (card1.suit == card2.suit and
|
||||
((card1.rank + 1) % self.Mod(i) == card2.rank
|
||||
or (card1.rank - 1) % self.Mod(i) == card2.rank))
|
||||
|
||||
def getHighlightPilesStacks(self):
|
||||
return ()
|
||||
|
||||
# Finish the current move.
|
||||
# Append current active_row to moves.current.
|
||||
# Append moves.current to moves.history.
|
||||
def finishMove(self):
|
||||
moves, stats = self.moves, self.stats
|
||||
if not moves.current:
|
||||
return 0
|
||||
# invalidate hints
|
||||
self.hints.list = None
|
||||
# resize (i.e. possibly shorten list from previous undos)
|
||||
if not moves.index == 0:
|
||||
m = moves.history[len(moves.history) - 1]
|
||||
del moves.history[moves.index : ]
|
||||
# update stats
|
||||
if self.demo:
|
||||
stats.demo_moves = stats.demo_moves + 1
|
||||
if moves.index == 0:
|
||||
stats.player_moves = 0 # clear all player moves
|
||||
else:
|
||||
stats.player_moves = stats.player_moves + 1
|
||||
if moves.index == 0:
|
||||
stats.demo_moves = 0 # clear all demo moves
|
||||
stats.total_moves = stats.total_moves + 1
|
||||
# add current move to history (which is a list of lists)
|
||||
moves.current.append(self.active_row)
|
||||
moves.history.append(moves.current)
|
||||
moves.index = moves.index + 1
|
||||
assert moves.index == len(moves.history)
|
||||
moves.current = []
|
||||
self.updateText()
|
||||
self.updateStatus(moves=(moves.index, self.stats.total_moves))
|
||||
self.updateMenus()
|
||||
return 1
|
||||
|
||||
def undo(self):
|
||||
assert self.canUndo()
|
||||
assert self.moves.state == self.S_PLAY and self.moves.current == []
|
||||
assert 0 <= self.moves.index <= len(self.moves.history)
|
||||
if self.moves.index == 0:
|
||||
return
|
||||
self.moves.index = self.moves.index - 1
|
||||
m = self.moves.history[self.moves.index]
|
||||
m = m[:len(m) - 1]
|
||||
m.reverse()
|
||||
self.moves.state = self.S_UNDO
|
||||
for atomic_move in m:
|
||||
atomic_move.undo(self)
|
||||
self.moves.state = self.S_PLAY
|
||||
m = self.moves.history[max(0, self.moves.index - 1)]
|
||||
self.active_row = m[len(m) - 1]
|
||||
self.stats.undo_moves = self.stats.undo_moves + 1
|
||||
self.stats.total_moves = self.stats.total_moves + 1
|
||||
self.hints.list = None
|
||||
self.updateText()
|
||||
self.updateStatus(moves=(self.moves.index, self.stats.total_moves))
|
||||
self.updateMenus()
|
||||
|
||||
def redo(self):
|
||||
assert self.canRedo()
|
||||
assert self.moves.state == self.S_PLAY and self.moves.current == []
|
||||
assert 0 <= self.moves.index <= len(self.moves.history)
|
||||
if self.moves.index == len(self.moves.history):
|
||||
return
|
||||
m = self.moves.history[self.moves.index]
|
||||
self.moves.index = self.moves.index + 1
|
||||
self.active_row = m[len(m) - 1]
|
||||
m = m[:len(m) - 1]
|
||||
self.moves.state = self.S_REDO
|
||||
for atomic_move in m:
|
||||
atomic_move.redo(self)
|
||||
self.moves.state = self.S_PLAY
|
||||
self.stats.redo_moves = self.stats.redo_moves + 1
|
||||
self.stats.total_moves = self.stats.total_moves + 1
|
||||
self.hints.list = None
|
||||
self.updateText()
|
||||
self.updateStatus(moves=(self.moves.index, self.stats.total_moves))
|
||||
self.updateMenus()
|
||||
|
||||
def _restoreGameHook(self, game):
|
||||
self.active_row = game.loadinfo.active_row
|
||||
|
||||
def _loadGameHook(self, p):
|
||||
self.loadinfo.addattr(active_row=0) # register extra load var.
|
||||
self.loadinfo.active_row = p.load()
|
||||
|
||||
def _saveGameHook(self, p):
|
||||
p.dump(self.active_row)
|
||||
|
||||
|
||||
|
||||
# /***********************************************************************
|
||||
# // Relaxed Lara's Game
|
||||
# ************************************************************************/
|
||||
|
||||
class RelaxedLarasGame(LarasGame):
|
||||
Reserve_Class = LarasGame_Reserve
|
||||
Reserve_Cards = 1
|
||||
DEAL_TO_TALON = 3
|
||||
MAX_ROUNDS = 2
|
||||
|
||||
|
||||
# /***********************************************************************
|
||||
# // Double Lara's Game
|
||||
# ************************************************************************/
|
||||
|
||||
class DoubleLarasGame(RelaxedLarasGame):
|
||||
Reserve_Cards = 2
|
||||
MAX_ROUNDS = 3
|
||||
def Max_Cards(self, i):
|
||||
return 26
|
||||
|
||||
|
||||
# register the game
|
||||
|
||||
registerGame(GameInfo(37, LarasGame, "Lara's Game",
|
||||
GI.GT_2DECK_TYPE, 2, 0, GI.SL_BALANCED))
|
||||
registerGame(GameInfo(13006, RelaxedLarasGame, "Lara's Game Relaxed",
|
||||
GI.GT_2DECK_TYPE, 2, 1, GI.SL_BALANCED))
|
||||
registerGame(GameInfo(13007, DoubleLarasGame, "Lara's Game Doubled",
|
||||
GI.GT_2DECK_TYPE, 4, 2, GI.SL_BALANCED))
|
||||
|
||||
|
|
@ -767,8 +767,8 @@ class CircleNine(Game):
|
|||
stack.CARD_YOFFSET = 0
|
||||
|
||||
x, y = l.XM+3.5*l.XS, l.YM+l.YS
|
||||
stack = RK_FoundationStack(x, y, self, suit=ANY_SUIT,
|
||||
max_cards=52, max_move=0, mod=13)
|
||||
stack = RK_FoundationStack(x, y, self, suit=ANY_SUIT, max_cards=52,
|
||||
max_move=0, mod=13, base_rank=ANY_RANK)
|
||||
s.foundations.append(stack)
|
||||
l.createText(stack, 'ne')
|
||||
x, y = l.XM, l.YM
|
||||
|
@ -794,6 +794,44 @@ class CircleNine(Game):
|
|||
self.leaveState(old_state)
|
||||
|
||||
|
||||
class Measure(CircleNine):
|
||||
|
||||
Foundation_Class = StackWrapper(RK_FoundationStack, max_cards=52)
|
||||
|
||||
def createGame(self, rows=8):
|
||||
l, s = Layout(self), self.s
|
||||
self.setSize(l.XM+rows*l.XS, l.YM+2*l.YS+10*l.YOFFSET)
|
||||
|
||||
x, y = l.XM, l.YM
|
||||
s.talon = Strategerie_Talon(x, y, self)
|
||||
l.createText(s.talon, 'ne')
|
||||
x = self.width-l.XS
|
||||
stack = self.Foundation_Class(x, y, self, suit=ANY_SUIT, max_cards=52,
|
||||
max_move=0, mod=13, base_rank=ANY_RANK)
|
||||
s.foundations.append(stack)
|
||||
l.createText(stack, 'nw')
|
||||
|
||||
x, y = l.XM, l.YM+l.YS
|
||||
for i in range(rows):
|
||||
s.rows.append(CircleNine_RowStack(x, y, self, max_accept=1,
|
||||
max_move=1, base_rank=NO_RANK))
|
||||
x += l.XS
|
||||
|
||||
l.defaultStackGroups()
|
||||
self.sg.dropstacks.append(s.talon)
|
||||
|
||||
def startGame(self):
|
||||
self.startDealSample()
|
||||
self.s.talon.dealRow()
|
||||
self.s.talon.fillStack()
|
||||
|
||||
|
||||
class DoubleMeasure(Measure):
|
||||
Foundation_Class = StackWrapper(RK_FoundationStack, max_cards=104)
|
||||
|
||||
def createGame(self, rows=8):
|
||||
Measure.createGame(self, rows=10)
|
||||
|
||||
|
||||
|
||||
# register the game
|
||||
|
@ -833,4 +871,8 @@ registerGame(GameInfo(613, Fanny, "Fanny",
|
|||
GI.GT_NUMERICA, 2, 0, GI.SL_BALANCED))
|
||||
registerGame(GameInfo(641, CircleNine, "Circle Nine",
|
||||
GI.GT_NUMERICA, 1, 0, GI.SL_BALANCED))
|
||||
registerGame(GameInfo(643, Measure, "Measure",
|
||||
GI.GT_NUMERICA | GI.GT_ORIGINAL, 1, 0, GI.SL_MOSTLY_SKILL))
|
||||
registerGame(GameInfo(644, DoubleMeasure, "Double Measure",
|
||||
GI.GT_NUMERICA | GI.GT_ORIGINAL, 2, 0, GI.SL_MOSTLY_SKILL))
|
||||
|
||||
|
|
|
@ -28,7 +28,6 @@
|
|||
__all__ = []
|
||||
|
||||
# Imports
|
||||
import sys, math
|
||||
|
||||
# PySol imports
|
||||
from pysollib.gamedb import registerGame, GameInfo, GI
|
||||
|
@ -40,7 +39,7 @@ from pysollib.layout import Layout
|
|||
from pysollib.hint import AbstractHint, DefaultHint, CautiousDefaultHint
|
||||
from pysollib.pysoltk import MfxCanvasText, MfxCanvasImage, bind, ANCHOR_NW
|
||||
|
||||
from pysollib.games.golf import Golf_Waste, Golf_Hint
|
||||
from golf import Golf_Waste, Golf_Hint
|
||||
|
||||
|
||||
# /***********************************************************************
|
||||
|
@ -77,7 +76,7 @@ class ThreePeaks_TalonStack(WasteTalonStack):
|
|||
class ThreePeaks_RowStack(OpenStack):
|
||||
|
||||
def __init__(self, x, y, game, **cap):
|
||||
kwdefault(cap, max_move=0, max_accept=0, max_cards=1,
|
||||
kwdefault(cap, max_move=1, max_accept=0, max_cards=1,
|
||||
base_rank=ANY_RANK)
|
||||
apply(OpenStack.__init__, (self, x, y, game), cap)
|
||||
|
||||
|
@ -134,9 +133,11 @@ class ThreePeaks(Game):
|
|||
l, s = Layout(self), self.s
|
||||
|
||||
# set window
|
||||
# (compute best XOFFSET - up to 64/72 cards can be in the Waste)
|
||||
decks = self.gameinfo.decks
|
||||
l.XOFFSET = int(l.XS * 9 / self.gameinfo.ncards)
|
||||
# compute best XOFFSET
|
||||
xoffset = int(l.XS * 8 / self.gameinfo.ncards)
|
||||
if xoffset < l.XOFFSET:
|
||||
l.XOFFSET = xoffset
|
||||
|
||||
# Set window size
|
||||
w, h = l.XM + l.XS * 10, l.YM + l.YS * 4
|
||||
|
@ -170,12 +171,12 @@ class ThreePeaks(Game):
|
|||
# Create talon
|
||||
x, y = l.XM, y + l.YM + l.YS
|
||||
s.talon = ThreePeaks_TalonStack(x, y, self, num_deal=1, max_rounds=1)
|
||||
l.createText(s.talon, "ss")
|
||||
l.createText(s.talon, "s")
|
||||
x = x + l.XS
|
||||
s.waste = self.Waste_Class(x, y, self)
|
||||
s.waste.CARD_XOFFSET = l.XOFFSET
|
||||
s.foundations.append(s.waste)
|
||||
l.createText(s.waste, "ss")
|
||||
l.createText(s.waste, "s")
|
||||
|
||||
# Create text for scores
|
||||
if self.preview <= 1:
|
||||
|
@ -279,21 +280,10 @@ class ThreePeaksNoScore(ThreePeaks):
|
|||
return 1
|
||||
|
||||
|
||||
# /***********************************************************************
|
||||
# // Le Grande Teton
|
||||
# ************************************************************************/
|
||||
|
||||
class LeGrandeTeton(ThreePeaksNoScore):
|
||||
pass
|
||||
|
||||
|
||||
|
||||
registerGame(GameInfo(22216, ThreePeaks, "Three Peaks",
|
||||
GI.GT_PAIRING_TYPE, 1, 0, GI.SL_BALANCED))
|
||||
registerGame(GameInfo(22231, ThreePeaksNoScore, "Three Peaks Non-scoring",
|
||||
GI.GT_PAIRING_TYPE, 1, 0, GI.SL_BALANCED))
|
||||
registerGame(GameInfo(22232, LeGrandeTeton, "Le Grande Teton",
|
||||
GI.GT_TAROCK, 1, 0, GI.SL_BALANCED,
|
||||
ranks=range(14), trumps=range(22)))
|
||||
|
||||
|
|
@ -84,7 +84,7 @@ class Tournament(Game):
|
|||
# game layout
|
||||
#
|
||||
|
||||
def createGame(self, **layout):
|
||||
def createGame(self):
|
||||
|
||||
# create layout
|
||||
l, s = Layout(self), self.s
|
||||
|
@ -121,8 +121,9 @@ class Tournament(Game):
|
|||
s.talon = Tournament_Talon(l.XM, l.YM, self, max_rounds=3)
|
||||
l.createText(s.talon, "se")
|
||||
tx, ty, ta, tf = l.getTextAttr(s.talon, "ne")
|
||||
s.talon.texts.rounds = MfxCanvasText(self.canvas, tx, ty, anchor=ta,
|
||||
font=self.app.getFont("canvas_default"))
|
||||
font = self.app.getFont("canvas_default")
|
||||
s.talon.texts.rounds = MfxCanvasText(self.canvas, tx, ty,
|
||||
anchor=ta, font=font)
|
||||
|
||||
# define stack-groups
|
||||
l.defaultStackGroups()
|
||||
|
@ -130,6 +131,7 @@ class Tournament(Game):
|
|||
#
|
||||
# game overrides
|
||||
#
|
||||
|
||||
def _shuffleHook(self, cards):
|
||||
for c in cards[-8:]:
|
||||
if c.rank in (ACE, KING):
|
||||
|
@ -189,7 +191,7 @@ class KingsdownEights(Game):
|
|||
|
||||
Hint_Class = CautiousDefaultHint
|
||||
|
||||
def createGame(self, **layout):
|
||||
def createGame(self):
|
||||
|
||||
# create layout
|
||||
l, s = Layout(self), self.s
|
||||
|
@ -232,6 +234,54 @@ class KingsdownEights(Game):
|
|||
shallHighlightMatch = Game._shallHighlightMatch_AC
|
||||
|
||||
|
||||
# /***********************************************************************
|
||||
# // Saxony
|
||||
# ************************************************************************/
|
||||
|
||||
class Saxony_Reserve(SS_RowStack):
|
||||
def getBottomImage(self):
|
||||
return self.game.app.images.getReserveBottom()
|
||||
def getHelp(self):
|
||||
return _('Reserve. Build down by suit.')
|
||||
|
||||
|
||||
class Saxony(Game):
|
||||
|
||||
def createGame(self):
|
||||
l, s = Layout(self), self.s
|
||||
self.setSize(l.XM+11*l.XS, 2*l.YM+max(2*l.YS+12*l.YOFFSET, 5*l.YS))
|
||||
|
||||
x, y, = l.XM+1.5*l.XS, l.YM
|
||||
for i in range(8):
|
||||
s.foundations.append(SS_FoundationStack(x, y, self, suit=i%4))
|
||||
x = x + l.XS
|
||||
x, y = l.XM+1.5*l.XS, 2*l.YM+l.YS
|
||||
for i in range(8):
|
||||
s.rows.append(BasicRowStack(x, y, self, max_move=1, max_accept=0))
|
||||
x = x + l.XS
|
||||
x, y = l.XM, 2*l.YM+l.YS
|
||||
for i in range(4):
|
||||
stack = Saxony_Reserve(x, y, self, max_move=1)
|
||||
self.s.reserves.append(stack)
|
||||
stack.CARD_YOFFSET = 0
|
||||
y += l.YS
|
||||
x, y = self.width-l.XS, 2*l.YM+l.YS
|
||||
for i in range(4):
|
||||
self.s.reserves.append(ReserveStack(x, y, self))
|
||||
y += l.YS
|
||||
s.talon = DealRowTalonStack(l.XM, l.YM, self)
|
||||
l.createText(s.talon, "ne")
|
||||
|
||||
l.defaultStackGroups()
|
||||
|
||||
|
||||
def startGame(self):
|
||||
self.s.talon.dealRow(rows=self.s.reserves, frames=0)
|
||||
self.startDealSample()
|
||||
self.s.talon.dealRow()
|
||||
|
||||
|
||||
|
||||
# register the game
|
||||
registerGame(GameInfo(303, Tournament, "Tournament",
|
||||
GI.GT_2DECK_TYPE, 2, 2, GI.SL_MOSTLY_LUCK))
|
||||
|
@ -240,6 +290,8 @@ registerGame(GameInfo(304, LaNivernaise, "La Nivernaise",
|
|||
altnames = ("Napoleon's Flank", ),))
|
||||
registerGame(GameInfo(386, KingsdownEights, "Kingsdown Eights",
|
||||
GI.GT_2DECK_TYPE, 2, 0, GI.SL_BALANCED))
|
||||
registerGame(GameInfo(645, Saxony, "Saxony",
|
||||
GI.GT_2DECK_TYPE, 2, 0, GI.SL_MOSTLY_SKILL))
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -6,4 +6,3 @@ import larasgame
|
|||
import matrix
|
||||
import mughal
|
||||
import tarock
|
||||
import threepeaks
|
||||
|
|
|
@ -27,7 +27,6 @@
|
|||
__all__ = []
|
||||
|
||||
# imports
|
||||
import sys, types
|
||||
|
||||
# PySol imports
|
||||
from pysollib.gamedb import registerGame, GameInfo, GI
|
||||
|
@ -38,165 +37,25 @@ from pysollib.layout import Layout
|
|||
from pysollib.hint import AbstractHint, DefaultHint, CautiousDefaultHint
|
||||
from pysollib.pysoltk import MfxCanvasText
|
||||
|
||||
|
||||
# /***********************************************************************
|
||||
# //
|
||||
# ************************************************************************/
|
||||
|
||||
class LarasGame_Hint(CautiousDefaultHint):
|
||||
pass
|
||||
from pysollib.games.larasgame import LarasGame_Talon, LarasGame, LarasGame_Reserve
|
||||
|
||||
|
||||
# /***********************************************************************
|
||||
# //
|
||||
# ************************************************************************/
|
||||
|
||||
class LarasGame_Talon(WasteTalonStack):
|
||||
# Deal a card to each of the RowStacks. Then deal
|
||||
# cards to the talon. Return number of cards dealt.
|
||||
def dealRow(self, rows=None, flip=1, reverse=0, frames=-1, sound=0):
|
||||
game = self.game
|
||||
if rows is None:
|
||||
rows = game.s.rows
|
||||
old_state = game.enterState(game.S_DEAL)
|
||||
cards = self.dealToStacks(rows[:game.MAX_ROW], flip, reverse, frames)
|
||||
if sound and frames and self.game.app.opt.animations:
|
||||
self.game.startDealSample()
|
||||
for i in range(game.DEAL_TO_TALON):
|
||||
if self.cards:
|
||||
game.moveMove(1, self, game.s.rows[-1], frames=frames)
|
||||
cards = cards + 1
|
||||
game.leaveState(old_state)
|
||||
if sound:
|
||||
self.game.stopSamples()
|
||||
return cards
|
||||
|
||||
def dealToStacks(self, stacks, flip=1, reverse=0, frames=-1):
|
||||
game = self.game
|
||||
i, move = 0, game.moveMove
|
||||
for r in stacks:
|
||||
if not self.cards:
|
||||
return 0
|
||||
assert not self.getCard().face_up
|
||||
assert r is not self
|
||||
if flip:
|
||||
game.flipMove(self)
|
||||
move(1, self, r, frames=frames)
|
||||
# Dealing has extra rules in this game type:
|
||||
# If card rank == card location then add one card to talon
|
||||
# If card rank == ACE then add two cards to talon
|
||||
# If card rank == JACK, or higher then add one card to talon
|
||||
# After all the rows have been dealt, deal cards to talon in self.dealRow
|
||||
rank = r.getCard().rank
|
||||
if rank == i: # Is the rank == position?
|
||||
if not self.cards:
|
||||
return 0
|
||||
move(1, self, game.s.rows[-1], frames=frames)
|
||||
i = i + 1
|
||||
if rank == 0: # Is this an Ace?
|
||||
for j in range(2):
|
||||
if not self.cards:
|
||||
return 0
|
||||
move(1, self, game.s.rows[-1], frames=frames)
|
||||
if rank >= 10: # Is it a Jack or better?
|
||||
if not self.cards:
|
||||
return 0
|
||||
move(1, self, game.s.rows[-1], frames=frames)
|
||||
return len(stacks)
|
||||
|
||||
def dealCards(self, sound=0):
|
||||
game = self.game
|
||||
if sound and self.game.app.opt.animations:
|
||||
self.game.startDealSample()
|
||||
for r in game.s.reserves[:20]:
|
||||
while r.cards:
|
||||
game.moveMove(1, r, game.s.rows[game.active_row], frames=3, shadow=0)
|
||||
if self.cards:
|
||||
game.active_row = self.getActiveRow()
|
||||
game.flipMove(self)
|
||||
game.moveMove(1, self, game.s.reserves[0], frames=4, shadow=0)
|
||||
ncards = len(game.s.rows[game.active_row].cards)
|
||||
if ncards >= 20:
|
||||
# We have encountered an extreme situation.
|
||||
# In some game type variations it's possible
|
||||
# to have up to 28 cards on a row stack.
|
||||
# We'll have to double up on some of the reserves.
|
||||
for i in range(ncards - 19):
|
||||
game.moveMove(1, game.s.rows[game.active_row],
|
||||
game.s.reserves[19 - i], frames=4, shadow=0)
|
||||
ncards = len(game.s.rows[game.active_row].cards)
|
||||
assert ncards <= 19
|
||||
for i in range(ncards):
|
||||
game.moveMove(1, game.s.rows[game.active_row],
|
||||
game.s.reserves[ncards - i], frames=4, shadow=0)
|
||||
num_cards = len(self.cards) or self.canDealCards()
|
||||
else: # not self.cards
|
||||
if self.round < self.max_rounds:
|
||||
ncards = 0
|
||||
rows = list(game.s.rows)[:game.MAX_ROW]
|
||||
rows.reverse()
|
||||
for r in rows:
|
||||
while r.cards:
|
||||
ncards += 1
|
||||
if r.cards[-1].face_up:
|
||||
game.flipMove(r)
|
||||
game.moveMove(1, r, self, frames=0)
|
||||
assert len(self.cards) == ncards
|
||||
if ncards != 0:
|
||||
game.nextRoundMove(self)
|
||||
game.dealToRows()
|
||||
num_cards = len(self.cards)
|
||||
if sound:
|
||||
game.stopSamples()
|
||||
return num_cards
|
||||
|
||||
def canDealCards(self):
|
||||
if self.game.demo and self.game.moves.index >= 400:
|
||||
return 0
|
||||
return (self.cards or (self.round < self.max_rounds and not self.game.isGameWon()))
|
||||
|
||||
def updateText(self):
|
||||
if self.game.preview > 1:
|
||||
return
|
||||
WasteTalonStack.updateText(self, update_rounds=0)
|
||||
if not self.max_rounds - 1:
|
||||
return
|
||||
t = _("Round %d") % self.round
|
||||
self.texts.rounds.config(text=t)
|
||||
|
||||
def getActiveRow(self):
|
||||
return self.getCard().rank
|
||||
|
||||
|
||||
|
||||
class DojoujisGame_Talon(LarasGame_Talon):
|
||||
|
||||
def getActiveRow(self):
|
||||
card = self.getCard()
|
||||
return card.rank + card.deck * 4
|
||||
|
||||
|
||||
|
||||
class DoubleKalisGame_Talon(LarasGame_Talon):
|
||||
|
||||
def getActiveRow(self):
|
||||
card = self.getCard()
|
||||
return card.rank + card.deck * 12
|
||||
|
||||
|
||||
|
||||
class LarasGame_RowStack(OpenStack):
|
||||
def __init__(self, x, y, game, yoffset = 1, **cap):
|
||||
apply(OpenStack.__init__, (self, x, y, game), cap)
|
||||
self.CARD_YOFFSET = yoffset
|
||||
|
||||
|
||||
|
||||
class LarasGame_ReserveStack(OpenStack):
|
||||
pass
|
||||
|
||||
|
||||
|
||||
class BridgetsGame_Reserve(OpenStack):
|
||||
|
||||
def acceptsCards(self, from_stack, cards):
|
||||
|
@ -210,270 +69,6 @@ class BridgetsGame_Reserve(OpenStack):
|
|||
return self.game.app.images.getReserveBottom()
|
||||
|
||||
|
||||
|
||||
class LarasGame_Reserve(BridgetsGame_Reserve):
|
||||
|
||||
def acceptsCards(self, from_stack, cards):
|
||||
if not OpenStack.acceptsCards(self, from_stack, cards):
|
||||
return 0
|
||||
return from_stack in self.game.s.rows
|
||||
|
||||
|
||||
|
||||
# /***********************************************************************
|
||||
# // Lara's Game
|
||||
# ************************************************************************/
|
||||
|
||||
class LarasGame(Game):
|
||||
Hint_Class = LarasGame_Hint
|
||||
Talon_Class = LarasGame_Talon
|
||||
Reserve_Class = None
|
||||
DEAL_TO_TALON = 2
|
||||
MAX_ROUNDS = 1
|
||||
ROW_LENGTH = 4
|
||||
MAX_ROW = 13
|
||||
DIR = (-1, 1)
|
||||
|
||||
#
|
||||
# game layout
|
||||
#
|
||||
|
||||
def createGame(self):
|
||||
# create layout
|
||||
l, s = Layout(self), self.s
|
||||
ROW_LENGTH = self.ROW_LENGTH
|
||||
|
||||
# set window
|
||||
w, h = l.XM + l.XS * (ROW_LENGTH + 5), l.YM + l.YS * (ROW_LENGTH + (ROW_LENGTH != 6))
|
||||
self.setSize(w, h)
|
||||
|
||||
# extra settings
|
||||
self.active_row = None
|
||||
|
||||
# Create foundations
|
||||
x, y = l.XM, l.YM
|
||||
for j in range(2):
|
||||
for i in range(ROW_LENGTH):
|
||||
s.foundations.append(SS_FoundationStack(x, y, self, self.Base_Suit(i, j),
|
||||
max_cards = self.Max_Cards(i), mod = self.Mod(i),
|
||||
dir = self.DIR[j], base_rank = self.Base_Rank(i, j)))
|
||||
y = y + l.YS * (not j)
|
||||
x = x + l.XS * j
|
||||
x, y = x + l.XS * 2, l.YM
|
||||
|
||||
# Create rows
|
||||
x, y = l.XM + l.XS, y + l.YS
|
||||
for i in range(self.MAX_ROW):
|
||||
s.rows.append(LarasGame_RowStack(x, y, self))
|
||||
x = x + l.XS
|
||||
if i == ROW_LENGTH or i == ROW_LENGTH * 2 + 1 or i == ROW_LENGTH * 3 + 2:
|
||||
x, y = l.XM + l.XS, y + l.YS
|
||||
|
||||
# Create reserves
|
||||
x, y = l.XM + l.XS * (ROW_LENGTH == 6), l.YM + l.YS * (ROW_LENGTH - (ROW_LENGTH == 6))
|
||||
for i in range(20):
|
||||
s.reserves.append(LarasGame_ReserveStack(x, y, self, max_cards=2))
|
||||
x = x + l.XS * (i < (ROW_LENGTH + 4)) - l.XS * (i == (ROW_LENGTH + 9))
|
||||
y = y - l.YS * (i > (ROW_LENGTH + 3) and i < (ROW_LENGTH + 9)) + l.YS * (i > (ROW_LENGTH + 9))
|
||||
|
||||
# Create talon
|
||||
x, y = l.XM + l.XS * (ROW_LENGTH + 2), h - l.YM - l.YS * 3
|
||||
s.talon = self.Talon_Class(x, y, self, max_rounds=self.MAX_ROUNDS)
|
||||
l.createText(s.talon, "s")
|
||||
if self.MAX_ROUNDS - 1:
|
||||
tx, ty, ta, tf = l.getTextAttr(s.talon, "nn")
|
||||
s.talon.texts.rounds = MfxCanvasText(self.canvas,
|
||||
tx, ty, anchor=ta,
|
||||
font=self.app.getFont("canvas_default"))
|
||||
y = h - l.YS * 2
|
||||
s.rows.append(LarasGame_RowStack(x, y, self, yoffset=0))
|
||||
|
||||
# Define stack-groups (not default)
|
||||
self.sg.openstacks = s.foundations + s.rows[:self.MAX_ROW]
|
||||
self.sg.talonstacks = [s.talon] + s.rows[-1:]
|
||||
self.sg.dropstacks = s.rows[:self.MAX_ROW] + s.reserves
|
||||
|
||||
# Create relaxed reserve
|
||||
if self.Reserve_Class != None:
|
||||
x, y = l.XM + l.XS * (ROW_LENGTH + 2), l.YM + l.YS * .5
|
||||
s.reserves.append(self.Reserve_Class(x, y, self,
|
||||
max_accept=1, max_cards=self.Reserve_Cards))
|
||||
self.sg.openstacks = self.sg.openstacks + s.reserves[19:]
|
||||
self.sg.dropstacks = self.sg.dropstacks + s.reserves[19:]
|
||||
self.setRegion(s.reserves[19:], (x - l.XM / 2, 0, 99999, 99999))
|
||||
|
||||
#
|
||||
# Game extras
|
||||
#
|
||||
|
||||
def Max_Cards(self, i):
|
||||
return 13
|
||||
|
||||
def Mod(self, i):
|
||||
return 13
|
||||
|
||||
def Base_Rank(self, i, j):
|
||||
return 12 * (not j)
|
||||
|
||||
def Deal_Rows(self, i):
|
||||
return 13
|
||||
|
||||
def Base_Suit(self, i, j):
|
||||
return i
|
||||
|
||||
#
|
||||
# game overrides
|
||||
#
|
||||
|
||||
def startGame(self):
|
||||
assert len(self.s.talon.cards) == self.gameinfo.ncards
|
||||
self.dealToRows()
|
||||
|
||||
def dealToRows(self):
|
||||
frames, ncards = 0, len(self.s.talon.cards)
|
||||
for i in range(8):
|
||||
if not self.s.talon.cards:
|
||||
break
|
||||
if i == 4 or len(self.s.talon.cards) <= ncards / 2:
|
||||
self.startDealSample()
|
||||
frames = 4
|
||||
self.s.talon.dealRow(rows=self.s.rows[:self.Deal_Rows(i)], frames=frames)
|
||||
self.moveMove(len(self.s.rows[-1].cards), self.s.rows[-1], self.s.talon, frames=0)
|
||||
self.active_row = None
|
||||
|
||||
def shallHighlightMatch(self, stack1, card1, stack2, card2):
|
||||
i, j = (stack1 in self.s.foundations), (stack2 in self.s.foundations)
|
||||
if not (i or j): return 0
|
||||
if i: stack = stack1
|
||||
else: stack = stack2
|
||||
i = 0
|
||||
for f in self.s.foundations:
|
||||
if f == stack: break
|
||||
i = i + 1 % self.ROW_LENGTH
|
||||
return (card1.suit == card2.suit and
|
||||
((card1.rank + 1) % self.Mod(i) == card2.rank
|
||||
or (card1.rank - 1) % self.Mod(i) == card2.rank))
|
||||
|
||||
def getHighlightPilesStacks(self):
|
||||
return ()
|
||||
|
||||
# Finish the current move.
|
||||
# Append current active_row to moves.current.
|
||||
# Append moves.current to moves.history.
|
||||
def finishMove(self):
|
||||
moves, stats = self.moves, self.stats
|
||||
if not moves.current:
|
||||
return 0
|
||||
# invalidate hints
|
||||
self.hints.list = None
|
||||
# resize (i.e. possibly shorten list from previous undos)
|
||||
if not moves.index == 0:
|
||||
m = moves.history[len(moves.history) - 1]
|
||||
del moves.history[moves.index : ]
|
||||
# update stats
|
||||
if self.demo:
|
||||
stats.demo_moves = stats.demo_moves + 1
|
||||
if moves.index == 0:
|
||||
stats.player_moves = 0 # clear all player moves
|
||||
else:
|
||||
stats.player_moves = stats.player_moves + 1
|
||||
if moves.index == 0:
|
||||
stats.demo_moves = 0 # clear all demo moves
|
||||
stats.total_moves = stats.total_moves + 1
|
||||
# add current move to history (which is a list of lists)
|
||||
moves.current.append(self.active_row)
|
||||
moves.history.append(moves.current)
|
||||
moves.index = moves.index + 1
|
||||
assert moves.index == len(moves.history)
|
||||
moves.current = []
|
||||
self.updateText()
|
||||
self.updateStatus(moves=(moves.index, self.stats.total_moves))
|
||||
self.updateMenus()
|
||||
return 1
|
||||
|
||||
def undo(self):
|
||||
assert self.canUndo()
|
||||
assert self.moves.state == self.S_PLAY and self.moves.current == []
|
||||
assert 0 <= self.moves.index <= len(self.moves.history)
|
||||
if self.moves.index == 0:
|
||||
return
|
||||
self.moves.index = self.moves.index - 1
|
||||
m = self.moves.history[self.moves.index]
|
||||
m = m[:len(m) - 1]
|
||||
m.reverse()
|
||||
self.moves.state = self.S_UNDO
|
||||
for atomic_move in m:
|
||||
atomic_move.undo(self)
|
||||
self.moves.state = self.S_PLAY
|
||||
m = self.moves.history[max(0, self.moves.index - 1)]
|
||||
self.active_row = m[len(m) - 1]
|
||||
self.stats.undo_moves = self.stats.undo_moves + 1
|
||||
self.stats.total_moves = self.stats.total_moves + 1
|
||||
self.hints.list = None
|
||||
self.updateText()
|
||||
self.updateStatus(moves=(self.moves.index, self.stats.total_moves))
|
||||
self.updateMenus()
|
||||
|
||||
def redo(self):
|
||||
assert self.canRedo()
|
||||
assert self.moves.state == self.S_PLAY and self.moves.current == []
|
||||
assert 0 <= self.moves.index <= len(self.moves.history)
|
||||
if self.moves.index == len(self.moves.history):
|
||||
return
|
||||
m = self.moves.history[self.moves.index]
|
||||
self.moves.index = self.moves.index + 1
|
||||
self.active_row = m[len(m) - 1]
|
||||
m = m[:len(m) - 1]
|
||||
self.moves.state = self.S_REDO
|
||||
for atomic_move in m:
|
||||
atomic_move.redo(self)
|
||||
self.moves.state = self.S_PLAY
|
||||
self.stats.redo_moves = self.stats.redo_moves + 1
|
||||
self.stats.total_moves = self.stats.total_moves + 1
|
||||
self.hints.list = None
|
||||
self.updateText()
|
||||
self.updateStatus(moves=(self.moves.index, self.stats.total_moves))
|
||||
self.updateMenus()
|
||||
|
||||
def _restoreGameHook(self, game):
|
||||
self.active_row = game.loadinfo.active_row
|
||||
|
||||
def _loadGameHook(self, p):
|
||||
self.loadinfo.addattr(active_row=0) # register extra load var.
|
||||
self.loadinfo.active_row = p.load()
|
||||
|
||||
def _saveGameHook(self, p):
|
||||
p.dump(self.active_row)
|
||||
|
||||
|
||||
|
||||
# /***********************************************************************
|
||||
# // Relaxed Lara's Game
|
||||
# ************************************************************************/
|
||||
|
||||
class RelaxedLarasGame(LarasGame):
|
||||
Reserve_Class = LarasGame_Reserve
|
||||
Reserve_Cards = 1
|
||||
DEAL_TO_TALON = 3
|
||||
MAX_ROUNDS = 2
|
||||
|
||||
|
||||
# /***********************************************************************
|
||||
# // Double Lara's Game
|
||||
# ************************************************************************/
|
||||
|
||||
class DoubleLarasGame(RelaxedLarasGame):
|
||||
Reserve_Cards = 2
|
||||
MAX_ROUNDS = 3
|
||||
|
||||
#
|
||||
# Game extras
|
||||
#
|
||||
|
||||
def Max_Cards(self, i):
|
||||
return 26
|
||||
|
||||
|
||||
# /***********************************************************************
|
||||
# // Katrina's Game
|
||||
# ************************************************************************/
|
||||
|
@ -528,10 +123,6 @@ class DoubleKatrinasGame(RelaxedKatrinasGame):
|
|||
Reserve_Cards = 3
|
||||
MAX_ROUNDS = 3
|
||||
|
||||
#
|
||||
# Game extras
|
||||
#
|
||||
|
||||
def Max_Cards(self, i):
|
||||
return 28 + 16 * (i == 4)
|
||||
|
||||
|
@ -552,10 +143,6 @@ class BridgetsGame(LarasGame):
|
|||
ROW_LENGTH = 5
|
||||
MAX_ROW = 16
|
||||
|
||||
#
|
||||
# Game extras
|
||||
#
|
||||
|
||||
def Max_Cards(self, i):
|
||||
return 16 - 12 * (i == 4)
|
||||
|
||||
|
@ -580,10 +167,6 @@ class DoubleBridgetsGame(BridgetsGame):
|
|||
Reserve_Cards = 3
|
||||
MAX_ROUNDS = 3
|
||||
|
||||
#
|
||||
# Game extras
|
||||
#
|
||||
|
||||
def Max_Cards(self, i):
|
||||
return 32 - 24 * (i == 4)
|
||||
|
||||
|
@ -598,10 +181,6 @@ class FatimehsGame(LarasGame):
|
|||
MAX_ROW = 12
|
||||
DIR = (1, 1)
|
||||
|
||||
#
|
||||
# Game extras
|
||||
#
|
||||
|
||||
def Max_Cards(self, i):
|
||||
return 12
|
||||
|
||||
|
@ -635,10 +214,6 @@ class KalisGame(FatimehsGame):
|
|||
DEAL_TO_TALON = 6
|
||||
ROW_LENGTH = 5
|
||||
|
||||
#
|
||||
# Game extras
|
||||
#
|
||||
|
||||
def Base_Suit(self, i, j):
|
||||
return i + j * 5
|
||||
|
||||
|
@ -662,10 +237,6 @@ class DoubleKalisGame(RelaxedKalisGame):
|
|||
MAX_ROUNDS = 4
|
||||
MAX_ROW = 24
|
||||
|
||||
#
|
||||
# Game extras
|
||||
#
|
||||
|
||||
def Max_Cards(self, i):
|
||||
return 24
|
||||
|
||||
|
@ -683,10 +254,6 @@ class DojoujisGame(LarasGame):
|
|||
MAX_ROW = 8
|
||||
DIR = (-1, -1)
|
||||
|
||||
#
|
||||
# Game extras
|
||||
#
|
||||
|
||||
def Max_Cards(self, i):
|
||||
return 8
|
||||
|
||||
|
@ -703,7 +270,6 @@ class DojoujisGame(LarasGame):
|
|||
return i + j * 6
|
||||
|
||||
|
||||
|
||||
# /***********************************************************************
|
||||
# // Double Dojouji's Game
|
||||
# ************************************************************************/
|
||||
|
@ -711,10 +277,6 @@ class DojoujisGame(LarasGame):
|
|||
class DoubleDojoujisGame(DojoujisGame):
|
||||
MAX_ROW = 16
|
||||
|
||||
#
|
||||
# Game extras
|
||||
#
|
||||
|
||||
def Max_Cards(self, i):
|
||||
return 16
|
||||
|
||||
|
@ -724,59 +286,39 @@ class DoubleDojoujisGame(DojoujisGame):
|
|||
|
||||
|
||||
# register the game
|
||||
registerGame(GameInfo(37, LarasGame, "Lara's Game",
|
||||
GI.GT_2DECK_TYPE, 2, 0, GI.SL_BALANCED))
|
||||
|
||||
registerGame(GameInfo(13001, KatrinasGame, "Katrina's Game",
|
||||
GI.GT_TAROCK, 2, 1, GI.SL_BALANCED,
|
||||
ranks = range(14), trumps = range(22)))
|
||||
|
||||
registerGame(GameInfo(13002, BridgetsGame, "Bridget's Game",
|
||||
GI.GT_HEXADECK, 2, 1, GI.SL_BALANCED,
|
||||
ranks = range(16), trumps = range(4)))
|
||||
|
||||
registerGame(GameInfo(13003, FatimehsGame, "Fatimeh's Game",
|
||||
GI.GT_MUGHAL_GANJIFA, 1, 2, GI.SL_BALANCED,
|
||||
suits = range(8), ranks = range(12)))
|
||||
|
||||
registerGame(GameInfo(13004, KalisGame, "Kali's Game",
|
||||
GI.GT_DASHAVATARA_GANJIFA, 1, 2, GI.SL_BALANCED,
|
||||
suits = range(10), ranks = range(12)))
|
||||
|
||||
registerGame(GameInfo(13005, DojoujisGame, "Dojouji's Game",
|
||||
GI.GT_HANAFUDA, 2, 0, GI.SL_BALANCED,
|
||||
suits = range(12), ranks = range(4)))
|
||||
|
||||
registerGame(GameInfo(13006, RelaxedLarasGame, "Lara's Game Relaxed",
|
||||
GI.GT_2DECK_TYPE, 2, 1, GI.SL_BALANCED))
|
||||
|
||||
registerGame(GameInfo(13007, DoubleLarasGame, "Lara's Game Doubled",
|
||||
GI.GT_2DECK_TYPE, 4, 2, GI.SL_BALANCED))
|
||||
|
||||
registerGame(GameInfo(13008, RelaxedKatrinasGame, "Katrina's Game Relaxed",
|
||||
GI.GT_TAROCK, 2, 1, GI.SL_BALANCED,
|
||||
ranks = range(14), trumps = range(22)))
|
||||
|
||||
registerGame(GameInfo(13009, DoubleKatrinasGame, "Katrina's Game Doubled",
|
||||
GI.GT_TAROCK, 4, 2, GI.SL_BALANCED,
|
||||
ranks = range(14), trumps = range(22)))
|
||||
|
||||
registerGame(GameInfo(13010, DoubleBridgetsGame, "Bridget's Game Doubled",
|
||||
GI.GT_HEXADECK, 4, 2, GI.SL_BALANCED,
|
||||
ranks = range(16), trumps = range(4)))
|
||||
|
||||
registerGame(GameInfo(13011, RelaxedKalisGame, "Kali's Game Relaxed",
|
||||
GI.GT_DASHAVATARA_GANJIFA, 1, 2, GI.SL_BALANCED,
|
||||
suits = range(10), ranks = range(12)))
|
||||
|
||||
registerGame(GameInfo(13012, DoubleKalisGame, "Kali's Game Doubled",
|
||||
GI.GT_DASHAVATARA_GANJIFA, 2, 3, GI.SL_BALANCED,
|
||||
suits = range(10), ranks = range(12)))
|
||||
|
||||
registerGame(GameInfo(13013, RelaxedFatimehsGame, "Fatimeh's Game Relaxed",
|
||||
GI.GT_MUGHAL_GANJIFA, 1, 2, GI.SL_BALANCED,
|
||||
suits = range(8), ranks = range(12)))
|
||||
|
||||
registerGame(GameInfo(13014, DoubleDojoujisGame, "Dojouji's Game Doubled",
|
||||
GI.GT_HANAFUDA, 4, 0, GI.SL_BALANCED,
|
||||
suits = range(12), ranks = range(4)))
|
||||
|
|
|
@ -39,6 +39,7 @@ from pysollib.layout import Layout
|
|||
#from pysollib.pysoltk import MfxCanvasText
|
||||
|
||||
from pysollib.games.special.tarock import AbstractTarockGame, Grasshopper
|
||||
from pysollib.games.threepeaks import ThreePeaksNoScore
|
||||
|
||||
|
||||
# /***********************************************************************
|
||||
|
@ -254,6 +255,15 @@ class Rambling(Corkscrew):
|
|||
sequence = row.isSuitSequence
|
||||
return (sequence([card1, card2]) or sequence([card2, card1]))
|
||||
|
||||
# /***********************************************************************
|
||||
# // Le Grande Teton
|
||||
# ************************************************************************/
|
||||
|
||||
class LeGrandeTeton(ThreePeaksNoScore):
|
||||
pass
|
||||
|
||||
|
||||
|
||||
# /***********************************************************************
|
||||
# // register the games
|
||||
# ************************************************************************/
|
||||
|
@ -270,5 +280,6 @@ r(13164, DoubleCockroach, 'Double Cockroach', GI.GT_TAROCK, 2, 0, GI.SL_MOSTLY_S
|
|||
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(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)
|
||||
|
||||
|
||||
del r
|
||||
|
|
|
@ -89,6 +89,7 @@ def parse_option(argv):
|
|||
"fg=", "foreground=",
|
||||
"bg=", "background=",
|
||||
"fn=", "font=",
|
||||
"french-only",
|
||||
"noplugins",
|
||||
"nosound",
|
||||
"debug=",
|
||||
|
@ -103,6 +104,7 @@ def parse_option(argv):
|
|||
"fg": None,
|
||||
"bg": None,
|
||||
"fn": None,
|
||||
"french-only": False,
|
||||
"noplugins": False,
|
||||
"nosound": False,
|
||||
"debug": 0,
|
||||
|
@ -120,6 +122,8 @@ def parse_option(argv):
|
|||
opts["bg"] = i[1]
|
||||
elif i[0] in ("--fn", "--font"):
|
||||
opts["fn"] = i[1]
|
||||
elif i[0] == "--french-only":
|
||||
opts["french-only"] = True
|
||||
elif i[0] == "--noplugins":
|
||||
opts["noplugins"] = True
|
||||
elif i[0] == "--nosound":
|
||||
|
@ -146,7 +150,7 @@ def parse_option(argv):
|
|||
return None
|
||||
filename = args and args[0] or None
|
||||
if filename and not os.path.isfile(filename):
|
||||
print _("%s: invalide file name\ntry %s --help for more information") % (prog_name, prog_name)
|
||||
print _("%s: invalid file name\ntry %s --help for more information") % (prog_name, prog_name)
|
||||
return None
|
||||
return opts, filename
|
||||
|
||||
|
@ -190,15 +194,19 @@ def pysol_init(app, args):
|
|||
try:
|
||||
app.commandline.gameid = int(opts['gameid'])
|
||||
except:
|
||||
print >> sys.stderr, 'WARNING: invalide game id:', opts['gameid']
|
||||
app.debug = int(opts['debug'])
|
||||
print >> sys.stderr, 'WARNING: invalid game id:', opts['gameid']
|
||||
try:
|
||||
app.debug = int(opts['debug'])
|
||||
except:
|
||||
print >> sys.stderr, 'invalid argument for debug'
|
||||
|
||||
# init games database
|
||||
import games
|
||||
import games.contrib
|
||||
import games.special
|
||||
import games.ultra
|
||||
import games.mahjongg
|
||||
if not opts['french-only']:
|
||||
#import games.contrib
|
||||
import games.ultra
|
||||
import games.mahjongg
|
||||
import games.special
|
||||
|
||||
# init DataLoader
|
||||
f = os.path.join("html", "license.html")
|
||||
|
@ -322,7 +330,7 @@ def pysol_init(app, args):
|
|||
try:
|
||||
f = Font(top, font)
|
||||
except:
|
||||
print >> sys.stderr, "invalide font name:", font
|
||||
print >> sys.stderr, "invalid font name:", font
|
||||
pass
|
||||
else:
|
||||
if font:
|
||||
|
@ -345,8 +353,7 @@ Main data directory is:
|
|||
%s
|
||||
|
||||
Please check your %s installation.
|
||||
''') % (app.dataloader.dir, PACKAGE),
|
||||
bitmap="error", strings=(_("&Quit"),))
|
||||
''') % (app.dataloader.dir, PACKAGE), bitmap="error", strings=(_("&Quit"),))
|
||||
return 1
|
||||
|
||||
# init cardsets
|
||||
|
|
|
@ -23,7 +23,7 @@ __all__ = ['ColorsDialog']
|
|||
|
||||
# imports
|
||||
import os, sys
|
||||
from Tkinter import *
|
||||
import Tkinter
|
||||
from tkColorChooser import askcolor
|
||||
|
||||
# PySol imports
|
||||
|
@ -44,40 +44,40 @@ class ColorsDialog(MfxDialog):
|
|||
top_frame, bottom_frame = self.createFrames(kw)
|
||||
self.createBitmaps(top_frame, kw)
|
||||
|
||||
frame = Frame(top_frame)
|
||||
frame.pack(expand=YES, fill=BOTH, padx=5, pady=10)
|
||||
frame = Tkinter.Frame(top_frame)
|
||||
frame.pack(expand=True, fill='both', padx=5, pady=10)
|
||||
frame.columnconfigure(0, weight=1)
|
||||
|
||||
self.table_text_color_var = BooleanVar()
|
||||
self.table_text_color_var = Tkinter.BooleanVar()
|
||||
self.table_text_color_var.set(app.opt.table_text_color)
|
||||
self.table_text_color_value_var = StringVar()
|
||||
self.table_text_color_value_var = Tkinter.StringVar()
|
||||
self.table_text_color_value_var.set(app.opt.table_text_color_value)
|
||||
##self.table_color_var = StringVar()
|
||||
##self.table_color_var.set(app.opt.table_color)
|
||||
self.highlight_piles_colors_var = StringVar()
|
||||
self.highlight_piles_colors_var = Tkinter.StringVar()
|
||||
self.highlight_piles_colors_var.set(app.opt.highlight_piles_colors[1])
|
||||
self.highlight_cards_colors_1_var = StringVar()
|
||||
self.highlight_cards_colors_1_var = Tkinter.StringVar()
|
||||
self.highlight_cards_colors_1_var.set(app.opt.highlight_cards_colors[1])
|
||||
self.highlight_cards_colors_2_var = StringVar()
|
||||
self.highlight_cards_colors_2_var = Tkinter.StringVar()
|
||||
self.highlight_cards_colors_2_var.set(app.opt.highlight_cards_colors[3])
|
||||
self.highlight_samerank_colors_1_var = StringVar()
|
||||
self.highlight_samerank_colors_1_var = Tkinter.StringVar()
|
||||
self.highlight_samerank_colors_1_var.set(app.opt.highlight_samerank_colors[1])
|
||||
self.highlight_samerank_colors_2_var = StringVar()
|
||||
self.highlight_samerank_colors_2_var = Tkinter.StringVar()
|
||||
self.highlight_samerank_colors_2_var.set(app.opt.highlight_samerank_colors[3])
|
||||
self.hintarrow_color_var = StringVar()
|
||||
self.hintarrow_color_var = Tkinter.StringVar()
|
||||
self.hintarrow_color_var.set(app.opt.hintarrow_color)
|
||||
self.highlight_not_matching_color_var = StringVar()
|
||||
self.highlight_not_matching_color_var = Tkinter.StringVar()
|
||||
self.highlight_not_matching_color_var.set(app.opt.highlight_not_matching_color)
|
||||
#
|
||||
c = Checkbutton(frame, variable=self.table_text_color_var,
|
||||
text=_("Text foreground:"), anchor=W)
|
||||
c.grid(row=0, column=0, sticky=W+E)
|
||||
l = Label(frame, width=10, height=2,
|
||||
bg=self.table_text_color_value_var.get(),
|
||||
textvariable=self.table_text_color_value_var)
|
||||
c = Tkinter.Checkbutton(frame, variable=self.table_text_color_var,
|
||||
text=_("Text foreground:"), anchor='w')
|
||||
c.grid(row=0, column=0, sticky='we')
|
||||
l = Tkinter.Label(frame, width=10, height=2,
|
||||
bg=self.table_text_color_value_var.get(),
|
||||
textvariable=self.table_text_color_value_var)
|
||||
l.grid(row=0, column=1, padx=5)
|
||||
b = Button(frame, text=_('Change...'), width=10,
|
||||
command=lambda l=l: self.selectColor(l))
|
||||
b = Tkinter.Button(frame, text=_('Change...'), width=10,
|
||||
command=lambda l=l: self.selectColor(l))
|
||||
b.grid(row=0, column=2)
|
||||
row = 1
|
||||
for title, var in (
|
||||
|
@ -90,12 +90,13 @@ class ColorsDialog(MfxDialog):
|
|||
(_('Hint arrow:'), self.hintarrow_color_var),
|
||||
(_('Highlight not matching:'), self.highlight_not_matching_color_var),
|
||||
):
|
||||
Label(frame, text=title, anchor=W).grid(row=row, column=0, sticky=W+E)
|
||||
l = Label(frame, width=10, height=2,
|
||||
bg=var.get(), textvariable=var)
|
||||
Tkinter.Label(frame, text=title, anchor='w'
|
||||
).grid(row=row, column=0, sticky='we')
|
||||
l = Tkinter.Label(frame, width=10, height=2,
|
||||
bg=var.get(), textvariable=var)
|
||||
l.grid(row=row, column=1, padx=5)
|
||||
b = Button(frame, text=_('Change...'), width=10,
|
||||
command=lambda l=l: self.selectColor(l))
|
||||
b = Tkinter.Button(frame, text=_('Change...'), width=10,
|
||||
command=lambda l=l: self.selectColor(l))
|
||||
b.grid(row=row, column=2)
|
||||
row += 1
|
||||
#
|
||||
|
|
|
@ -24,7 +24,7 @@ __all__ = ['FontsDialog']
|
|||
# imports
|
||||
import os, sys
|
||||
import types
|
||||
from Tkinter import *
|
||||
import Tkinter
|
||||
import tkFont
|
||||
|
||||
# PySol imports
|
||||
|
@ -71,38 +71,40 @@ class FontChooserDialog(MfxDialog):
|
|||
else:
|
||||
raise TypeError, 'invalid font style: '+ init_font[3]
|
||||
|
||||
#self.family_var = StringVar()
|
||||
self.weight_var = BooleanVar()
|
||||
self.slant_var = BooleanVar()
|
||||
self.size_var = IntVar()
|
||||
#self.family_var = Tkinter.StringVar()
|
||||
self.weight_var = Tkinter.BooleanVar()
|
||||
self.slant_var = Tkinter.BooleanVar()
|
||||
self.size_var = Tkinter.IntVar()
|
||||
|
||||
frame = Frame(top_frame)
|
||||
frame.pack(expand=YES, fill=BOTH, padx=5, pady=10)
|
||||
frame = Tkinter.Frame(top_frame)
|
||||
frame.pack(expand=True, fill='both', padx=5, pady=10)
|
||||
frame.columnconfigure(0, weight=1)
|
||||
#frame.rowconfigure(1, weight=1)
|
||||
self.entry = Entry(frame, bg='white')
|
||||
self.entry.grid(row=0, column=0, columnspan=2, sticky=W+E+N+S)
|
||||
self.entry.insert(END, _('abcdefghABCDEFGH'))
|
||||
self.list_box = Listbox(frame, width=36, exportselection=False)
|
||||
sb = Scrollbar(frame)
|
||||
self.entry = Tkinter.Entry(frame, bg='white')
|
||||
self.entry.grid(row=0, column=0, columnspan=2, sticky='news')
|
||||
self.entry.insert('end', _('abcdefghABCDEFGH'))
|
||||
self.list_box = Tkinter.Listbox(frame, width=36, exportselection=False)
|
||||
sb = Tkinter.Scrollbar(frame)
|
||||
self.list_box.configure(yscrollcommand=sb.set)
|
||||
sb.configure(command=self.list_box.yview)
|
||||
self.list_box.grid(row=1, column=0, sticky=W+E+N+S) # rowspan=4
|
||||
sb.grid(row=1, column=1, sticky=N+S)
|
||||
self.list_box.grid(row=1, column=0, sticky='news') # rowspan=4
|
||||
sb.grid(row=1, column=1, sticky='ns')
|
||||
bind(self.list_box, '<<ListboxSelect>>', self.fontupdate)
|
||||
##self.list_box.focus()
|
||||
cb1 = Checkbutton(frame, anchor=W, text=_('Bold'),
|
||||
command=self.fontupdate, variable=self.weight_var)
|
||||
cb1.grid(row=2, column=0, columnspan=2, sticky=W+E)
|
||||
cb2 = Checkbutton(frame, anchor=W, text=_('Italic'),
|
||||
command=self.fontupdate, variable=self.slant_var)
|
||||
cb2.grid(row=3, column=0, columnspan=2, sticky=W+E)
|
||||
cb1 = Tkinter.Checkbutton(frame, anchor='w', text=_('Bold'),
|
||||
command=self.fontupdate,
|
||||
variable=self.weight_var)
|
||||
cb1.grid(row=2, column=0, columnspan=2, sticky='we')
|
||||
cb2 = Tkinter.Checkbutton(frame, anchor='w', text=_('Italic'),
|
||||
command=self.fontupdate,
|
||||
variable=self.slant_var)
|
||||
cb2.grid(row=3, column=0, columnspan=2, sticky='we')
|
||||
|
||||
sc = Scale(frame, from_=6, to=40, resolution=1,
|
||||
#label='Size',
|
||||
orient=HORIZONTAL,
|
||||
command=self.fontupdate, variable=self.size_var)
|
||||
sc.grid(row=4, column=0, columnspan=2, sticky=W+E+N+S)
|
||||
sc = Tkinter.Scale(frame, from_=6, to=40, resolution=1,
|
||||
#label='Size',
|
||||
orient='horizontal',
|
||||
command=self.fontupdate, variable=self.size_var)
|
||||
sc.grid(row=4, column=0, columnspan=2, sticky='news')
|
||||
#
|
||||
self.size_var.set(self.font_size)
|
||||
self.weight_var.set(self.font_weight == 'bold')
|
||||
|
@ -111,10 +113,11 @@ class FontChooserDialog(MfxDialog):
|
|||
font_families.sort()
|
||||
selected = -1
|
||||
n = 0
|
||||
self.list_box.insert('end', *font_families)
|
||||
for font in font_families:
|
||||
self.list_box.insert(END, font)
|
||||
if font.lower() == self.font_family.lower():
|
||||
selected = n
|
||||
break
|
||||
n += 1
|
||||
if selected >= 0:
|
||||
self.list_box.select_set(selected)
|
||||
|
@ -155,35 +158,33 @@ class FontsDialog(MfxDialog):
|
|||
top_frame, bottom_frame = self.createFrames(kw)
|
||||
self.createBitmaps(top_frame, kw)
|
||||
|
||||
frame = Frame(top_frame)
|
||||
frame.pack(expand=YES, fill=BOTH, padx=5, pady=10)
|
||||
frame = Tkinter.Frame(top_frame)
|
||||
frame.pack(expand=True, fill='both', padx=5, pady=10)
|
||||
frame.columnconfigure(0, weight=1)
|
||||
|
||||
self.fonts = {}
|
||||
row = 0
|
||||
for fn in (#"default",
|
||||
"sans",
|
||||
"small",
|
||||
"fixed",
|
||||
"canvas_default",
|
||||
#"canvas_card",
|
||||
"canvas_fixed",
|
||||
"canvas_large",
|
||||
"canvas_small",
|
||||
#"tree_small",
|
||||
):
|
||||
for fn, title in (##('default', _('Default')),
|
||||
('sans', _('HTML: ')),
|
||||
('small', _('Small: ')),
|
||||
('fixed', _('Fixed: ')),
|
||||
('canvas_default', _('Tableau default: ')),
|
||||
('canvas_fixed', _('Tableau fixed: ')),
|
||||
('canvas_large', _('Tableau large: ')),
|
||||
('canvas_small', _('Tableau small: ')),
|
||||
):
|
||||
font = app.opt.fonts[fn]
|
||||
self.fonts[fn] = font
|
||||
title = fn.replace("_", " ").capitalize()+": "
|
||||
Label(frame, text=title, anchor=W).grid(row=row, column=0, sticky=W+E)
|
||||
Tkinter.Label(frame, text=title, anchor='w'
|
||||
).grid(row=row, column=0, sticky='we')
|
||||
if font:
|
||||
title = " ".join([str(i) for i in font if not i in ('roman', 'normal')])
|
||||
title = ' '.join([str(i) for i in font if not i in ('roman', 'normal')])
|
||||
elif font is None:
|
||||
title = 'Default'
|
||||
l = Label(frame, font=font, text=title)
|
||||
l = Tkinter.Label(frame, font=font, text=title)
|
||||
l.grid(row=row, column=1)
|
||||
b = Button(frame, text=_('Change...'), width=10,
|
||||
command=lambda l=l, fn=fn: self.selectFont(l, fn))
|
||||
b = Tkinter.Button(frame, text=_('Change...'), width=10,
|
||||
command=lambda l=l, fn=fn: self.selectFont(l, fn))
|
||||
b.grid(row=row, column=2)
|
||||
row += 1
|
||||
#
|
||||
|
@ -192,16 +193,16 @@ class FontsDialog(MfxDialog):
|
|||
|
||||
|
||||
def selectFont(self, label, fn):
|
||||
d = FontChooserDialog(self.top, _("Select font"), self.fonts[fn])
|
||||
d = FontChooserDialog(self.top, _('Select font'), self.fonts[fn])
|
||||
if d.status == 0 and d.button == 0:
|
||||
self.fonts[fn] = d.font
|
||||
title = " ".join([str(i) for i in d.font if not i in ('roman', 'normal')])
|
||||
title = ' '.join([str(i) for i in d.font if not i in ('roman', 'normal')])
|
||||
label.configure(font=d.font, text=title)
|
||||
|
||||
|
||||
def initKw(self, kw):
|
||||
kw = KwStruct(kw,
|
||||
strings=(_("&OK"), _("&Cancel")),
|
||||
strings=(_('&OK'), _('&Cancel')),
|
||||
default=0,
|
||||
)
|
||||
return MfxDialog.initKw(self, kw)
|
||||
|
|
|
@ -24,7 +24,7 @@ __all__ = ['GameInfoDialog']
|
|||
|
||||
# imports
|
||||
import os, sys
|
||||
from Tkinter import *
|
||||
import Tkinter
|
||||
|
||||
# PySol imports
|
||||
from pysollib.mfxutil import KwStruct
|
||||
|
@ -44,8 +44,8 @@ class GameInfoDialog(MfxDialog):
|
|||
top_frame, bottom_frame = self.createFrames(kw)
|
||||
self.createBitmaps(top_frame, kw)
|
||||
|
||||
frame = Frame(top_frame)
|
||||
frame.pack(expand=YES, fill=BOTH, padx=5, pady=10)
|
||||
frame = Tkinter.Frame(top_frame)
|
||||
frame.pack(expand=True, fill='both', padx=5, pady=10)
|
||||
frame.columnconfigure(0, weight=1)
|
||||
|
||||
game = app.game
|
||||
|
@ -108,8 +108,10 @@ class GameInfoDialog(MfxDialog):
|
|||
('Hint:', hint),
|
||||
):
|
||||
if t:
|
||||
Label(frame, text=n, anchor=W).grid(row=row, column=0, sticky=N+W)
|
||||
Label(frame, text=t, anchor=W, justify=LEFT).grid(row=row, column=1, sticky=N+W)
|
||||
Tkinter.Label(frame, text=n, anchor='w'
|
||||
).grid(row=row, column=0, sticky='nw')
|
||||
Tkinter.Label(frame, text=t, anchor='w', justify='left'
|
||||
).grid(row=row, column=1, sticky='nw')
|
||||
row += 1
|
||||
|
||||
if game.s.talon:
|
||||
|
@ -131,9 +133,9 @@ class GameInfoDialog(MfxDialog):
|
|||
focus = self.createButtons(bottom_frame, kw)
|
||||
self.mainloop(focus, kw.timeout)
|
||||
|
||||
|
||||
def showStacks(self, frame, row, title, stacks):
|
||||
Label(frame, text=title, anchor=W).grid(row=row, column=0, sticky=N+W)
|
||||
Tkinter.Label(frame, text=title, anchor='w'
|
||||
).grid(row=row, column=0, sticky='nw')
|
||||
if isinstance(stacks, (list, tuple)):
|
||||
fs = {}
|
||||
for f in stacks:
|
||||
|
@ -145,8 +147,8 @@ class GameInfoDialog(MfxDialog):
|
|||
t = '\n'.join(['%s (%d)' % (i[0], i[1]) for i in fs.items()])
|
||||
else:
|
||||
t = stacks.__class__.__name__
|
||||
Label(frame, text=t, anchor=W, justify=LEFT).grid(row=row, column=1, sticky=N+W)
|
||||
|
||||
Tkinter.Label(frame, text=t, anchor='w', justify='left'
|
||||
).grid(row=row, column=1, sticky='nw')
|
||||
|
||||
def initKw(self, kw):
|
||||
kw = KwStruct(kw,
|
||||
|
|
|
@ -721,14 +721,18 @@ class PysolMenubar(PysolMenubarActions):
|
|||
submenu = self.__menupath[".menubar.file.favoritegames"][2]
|
||||
submenu.delete(0, "last")
|
||||
# insert games
|
||||
g = [self.app.getGameInfo(id) for id in gameids]
|
||||
if len(g) > self.__cb_max*4:
|
||||
g.sort(lambda a, b: cmp(gettext(a.name), gettext(b.name)))
|
||||
self._addSelectAllGameSubMenu(submenu, g,
|
||||
games = []
|
||||
for id in gameids:
|
||||
gi = self.app.getGameInfo(id)
|
||||
if gi:
|
||||
games.append(gi)
|
||||
if len(games) > self.__cb_max*4:
|
||||
games.sort(lambda a, b: cmp(gettext(a.name), gettext(b.name)))
|
||||
self._addSelectAllGameSubMenu(submenu, games,
|
||||
command=self.mSelectGame,
|
||||
variable=self.tkopt.gameid)
|
||||
else:
|
||||
self._addSelectGameSubSubMenu(submenu, g,
|
||||
self._addSelectGameSubSubMenu(submenu, games,
|
||||
command=self.mSelectGame,
|
||||
variable=self.tkopt.gameid)
|
||||
state = self._getEnabledState
|
||||
|
|
|
@ -99,13 +99,14 @@ class SelectGameData(SelectDialogTreeData):
|
|||
self.all_games_gi = map(app.gdb.get, app.gdb.getGamesIdSortedByName())
|
||||
self.no_games = [ SelectGameLeaf(None, None, _("(no games)"), None), ]
|
||||
#
|
||||
s_by_type = s_oriental = s_special = s_original = s_contrib = None
|
||||
s_by_type = s_oriental = s_special = s_original = s_contrib = s_mahjongg = None
|
||||
g = []
|
||||
for data in (GI.SELECT_GAME_BY_TYPE,
|
||||
GI.SELECT_ORIENTAL_GAME_BY_TYPE,
|
||||
GI.SELECT_SPECIAL_GAME_BY_TYPE,
|
||||
GI.SELECT_ORIGINAL_GAME_BY_TYPE,
|
||||
GI.SELECT_CONTRIB_GAME_BY_TYPE):
|
||||
GI.SELECT_CONTRIB_GAME_BY_TYPE,
|
||||
):
|
||||
gg = []
|
||||
for name, select_func in data:
|
||||
if name is None or not filter(select_func, self.all_games_gi):
|
||||
|
@ -114,21 +115,23 @@ class SelectGameData(SelectDialogTreeData):
|
|||
name = name.replace("&", "")
|
||||
gg.append(SelectGameNode(None, name, select_func))
|
||||
g.append(gg)
|
||||
if 1 and g[0]:
|
||||
select_mahjongg_game = lambda gi: gi.si.game_type == GI.GT_MAHJONGG
|
||||
gg = None
|
||||
if filter(select_mahjongg_game, self.all_games_gi):
|
||||
gg = SelectGameNode(None, _("Mahjongg Games"), select_mahjongg_game)
|
||||
g.append(gg)
|
||||
if g[0]:
|
||||
s_by_type = SelectGameNode(None, _("French games"), tuple(g[0]), expanded=1)
|
||||
pass
|
||||
if 1 and g[1]:
|
||||
if g[1]:
|
||||
s_oriental = SelectGameNode(None, _("Oriental Games"), tuple(g[1]))
|
||||
pass
|
||||
if 1 and g[2]:
|
||||
if g[2]:
|
||||
s_special = SelectGameNode(None, _("Special Games"), tuple(g[2]))
|
||||
pass
|
||||
if 1 and g[3]:
|
||||
if g[3]:
|
||||
s_original = SelectGameNode(None, _("Original Games"), tuple(g[3]))
|
||||
pass
|
||||
if 1 and g[4]:
|
||||
##s_contrib = SelectGameNode(None, "Contributed Games", tuple(g[4]))
|
||||
pass
|
||||
## if g[4]:
|
||||
## s_contrib = SelectGameNode(None, "Contributed Games", tuple(g[4]))
|
||||
if g[5]:
|
||||
s_mahjongg = g[5]
|
||||
#
|
||||
s_by_compatibility, gg = None, []
|
||||
for name, games in GI.GAMES_BY_COMPATIBILITY:
|
||||
|
@ -140,16 +143,6 @@ class SelectGameData(SelectDialogTreeData):
|
|||
if 1 and gg:
|
||||
s_by_compatibility = SelectGameNode(None, _("by Compatibility"), tuple(gg))
|
||||
pass
|
||||
## #
|
||||
## s_mahjongg, gg = None, []
|
||||
## for name, games in GI.GAMES_BY_COMPATIBILITY:
|
||||
## select_func = lambda gi, games=games: gi.id in games
|
||||
## if name is None or not filter(select_func, self.all_games_gi):
|
||||
## continue
|
||||
## gg.append(SelectGameNode(None, name, select_func))
|
||||
## if 1 and gg:
|
||||
## s_by_compatibility = SelectGameNode(None, "by Compatibility", tuple(gg))
|
||||
## pass
|
||||
#
|
||||
s_by_pysol_version, gg = None, []
|
||||
for name, games in GI.GAMES_BY_PYSOL_VERSION:
|
||||
|
@ -169,9 +162,7 @@ class SelectGameData(SelectDialogTreeData):
|
|||
SelectGameNode(None, _("All Games"), None, expanded=0),
|
||||
SelectGameNode(None, _("Alternate Names"), ul_alternate_names),
|
||||
SelectGameNode(None, _("Popular Games"), lambda gi: gi.si.game_flags & GI.GT_POPULAR, expanded=0),
|
||||
SelectGameNode(None, _("Mahjongg Games"),
|
||||
lambda gi: gi.si.game_type == GI.GT_MAHJONGG,
|
||||
expanded=0),
|
||||
s_mahjongg,
|
||||
s_oriental,
|
||||
s_special,
|
||||
s_by_type,
|
||||
|
@ -398,7 +389,8 @@ class SelectGameDialogWithPreview(SelectGameDialog):
|
|||
padx=padx, pady=pady, sticky='nsew')
|
||||
right_frame.columnconfigure(1, weight=1)
|
||||
right_frame.rowconfigure(1, weight=1)
|
||||
|
||||
#
|
||||
focus = self.createButtons(bottom_frame, kw)
|
||||
# set the scale factor
|
||||
self.preview.canvas.preview = 2
|
||||
# create a preview of the current game
|
||||
|
@ -406,8 +398,6 @@ class SelectGameDialogWithPreview(SelectGameDialog):
|
|||
self.preview_game = None
|
||||
self.preview_app = None
|
||||
self.updatePreview(gameid, animations=0)
|
||||
#
|
||||
focus = self.createButtons(bottom_frame, kw)
|
||||
##focus = self.tree.frame
|
||||
SelectGameTreeWithPreview.html_viewer = None
|
||||
self.mainloop(focus, kw.timeout)
|
||||
|
@ -532,6 +522,12 @@ class SelectGameDialogWithPreview(SelectGameDialog):
|
|||
self.preview_key = gameid
|
||||
#
|
||||
self.updateInfo(gameid)
|
||||
#
|
||||
rules_button = self.buttons[1]
|
||||
if self.app.getGameRulesFilename(gameid):
|
||||
rules_button.config(state="normal")
|
||||
else:
|
||||
rules_button.config(state="disabled")
|
||||
|
||||
def updateInfo(self, gameid):
|
||||
gi = self.app.gdb.get(gameid)
|
||||
|
|
|
@ -37,7 +37,7 @@ __all__ = ['SoundOptionsDialog']
|
|||
|
||||
# imports
|
||||
import os, sys, string
|
||||
from Tkinter import *
|
||||
import Tkinter
|
||||
import traceback
|
||||
|
||||
# PySol imports
|
||||
|
@ -63,87 +63,88 @@ class SoundOptionsDialog(MfxDialog):
|
|||
self.createBitmaps(top_frame, kw)
|
||||
#
|
||||
self.saved_opt = app.opt.copy()
|
||||
self.sound = BooleanVar()
|
||||
self.sound = Tkinter.BooleanVar()
|
||||
self.sound.set(app.opt.sound != 0)
|
||||
self.sound_mode = BooleanVar()
|
||||
self.sound_mode = Tkinter.BooleanVar()
|
||||
self.sound_mode.set(app.opt.sound_mode != 0)
|
||||
self.sample_volume = IntVar()
|
||||
self.sample_volume = Tkinter.IntVar()
|
||||
self.sample_volume.set(app.opt.sound_sample_volume)
|
||||
self.music_volume = IntVar()
|
||||
self.music_volume = Tkinter.IntVar()
|
||||
self.music_volume.set(app.opt.sound_music_volume)
|
||||
self.samples = [
|
||||
('areyousure', _('Are You Sure'), BooleanVar()),
|
||||
('areyousure', _('Are You Sure'), Tkinter.BooleanVar()),
|
||||
|
||||
('deal', _('Deal'), BooleanVar()),
|
||||
('dealwaste', _('Deal waste'), BooleanVar()),
|
||||
('deal', _('Deal'), Tkinter.BooleanVar()),
|
||||
('dealwaste', _('Deal waste'), Tkinter.BooleanVar()),
|
||||
|
||||
('turnwaste', _('Turn waste'), BooleanVar()),
|
||||
('startdrag', _('Start drag'), BooleanVar()),
|
||||
('turnwaste', _('Turn waste'), Tkinter.BooleanVar()),
|
||||
('startdrag', _('Start drag'), Tkinter.BooleanVar()),
|
||||
|
||||
('drop', _('Drop'), BooleanVar()),
|
||||
('droppair', _('Drop pair'), BooleanVar()),
|
||||
('autodrop', _('Auto drop'), BooleanVar()),
|
||||
('drop', _('Drop'), Tkinter.BooleanVar()),
|
||||
('droppair', _('Drop pair'), Tkinter.BooleanVar()),
|
||||
('autodrop', _('Auto drop'), Tkinter.BooleanVar()),
|
||||
|
||||
('flip', _('Flip'), BooleanVar()),
|
||||
('autoflip', _('Auto flip'), BooleanVar()),
|
||||
('move', _('Move'), BooleanVar()),
|
||||
('nomove', _('No move'), BooleanVar()),
|
||||
('flip', _('Flip'), Tkinter.BooleanVar()),
|
||||
('autoflip', _('Auto flip'), Tkinter.BooleanVar()),
|
||||
('move', _('Move'), Tkinter.BooleanVar()),
|
||||
('nomove', _('No move'), Tkinter.BooleanVar()),
|
||||
|
||||
('undo', _('Undo'), BooleanVar()),
|
||||
('redo', _('Redo'), BooleanVar()),
|
||||
('undo', _('Undo'), Tkinter.BooleanVar()),
|
||||
('redo', _('Redo'), Tkinter.BooleanVar()),
|
||||
|
||||
('autopilotlost', _('Autopilot lost'), BooleanVar()),
|
||||
('autopilotwon', _('Autopilot won'), BooleanVar()),
|
||||
('autopilotlost', _('Autopilot lost'), Tkinter.BooleanVar()),
|
||||
('autopilotwon', _('Autopilot won'), Tkinter.BooleanVar()),
|
||||
|
||||
('gamefinished', _('Game finished'), BooleanVar()),
|
||||
('gamelost', _('Game lost'), BooleanVar()),
|
||||
('gamewon', _('Game won'), BooleanVar()),
|
||||
('gameperfect', _('Perfect game'), BooleanVar()),
|
||||
('gamefinished', _('Game finished'), Tkinter.BooleanVar()),
|
||||
('gamelost', _('Game lost'), Tkinter.BooleanVar()),
|
||||
('gamewon', _('Game won'), Tkinter.BooleanVar()),
|
||||
('gameperfect', _('Perfect game'), Tkinter.BooleanVar()),
|
||||
]
|
||||
|
||||
#
|
||||
frame = Frame(top_frame)
|
||||
frame.pack(expand=1, fill='both', padx=5, pady=5)
|
||||
frame = Tkinter.Frame(top_frame)
|
||||
frame.pack(expand=True, fill='both', padx=5, pady=5)
|
||||
frame.columnconfigure(1, weight=1)
|
||||
#
|
||||
row = 0
|
||||
w = Checkbutton(frame, variable=self.sound,
|
||||
w = Tkinter.Checkbutton(frame, variable=self.sound,
|
||||
text=_("Sound enabled"), anchor='w')
|
||||
w.grid(row=row, column=0, columnspan=2, sticky='ew')
|
||||
#
|
||||
if os.name == "nt" and pysolsoundserver:
|
||||
row += 1
|
||||
w = Checkbutton(frame, variable=self.sound_mode,
|
||||
w = Tkinter.Checkbutton(frame, variable=self.sound_mode,
|
||||
text=_("Use DirectX for sound playing"),
|
||||
command=self.mOptSoundDirectX, anchor='w')
|
||||
w.grid(row=row, column=0, columnspan=2, sticky='ew')
|
||||
#
|
||||
if pysolsoundserver and app.startup_opt.sound_mode > 0:
|
||||
row += 1
|
||||
w = Label(frame, text=_('Sample volume:'))
|
||||
w = Tkinter.Label(frame, text=_('Sample volume:'))
|
||||
w.grid(row=row, column=0, sticky='w')
|
||||
w = Scale(frame, from_=0, to=128, resolution=1,
|
||||
orient='horizontal', takefocus=0,
|
||||
length="3i", #label=_('Sample volume'),
|
||||
variable=self.sample_volume)
|
||||
w = Tkinter.Scale(frame, from_=0, to=128, resolution=1,
|
||||
orient='horizontal', takefocus=0,
|
||||
length="3i", #label=_('Sample volume'),
|
||||
variable=self.sample_volume)
|
||||
w.grid(row=row, column=1, sticky='w', padx=5)
|
||||
row += 1
|
||||
w = Label(frame, text=_('Music volume:'))
|
||||
w = Tkinter.Label(frame, text=_('Music volume:'))
|
||||
w.grid(row=row, column=0, sticky='w', padx=5)
|
||||
w = Scale(frame, from_=0, to=128, resolution=1,
|
||||
orient='horizontal', takefocus=0,
|
||||
length="3i", #label=_('Music volume'),
|
||||
variable=self.music_volume)
|
||||
w = Tkinter.Scale(frame, from_=0, to=128, resolution=1,
|
||||
orient='horizontal', takefocus=0,
|
||||
length="3i", #label=_('Music volume'),
|
||||
variable=self.music_volume)
|
||||
w.grid(row=row, column=1, sticky='w', padx=5)
|
||||
|
||||
else:
|
||||
# remove "Apply" button
|
||||
kw.strings[1] = None
|
||||
#
|
||||
if TkVersion >= 8.4:
|
||||
frame = LabelFrame(top_frame, text=_('Enable samles'), padx=5, pady=5)
|
||||
if Tkinter.TkVersion >= 8.4:
|
||||
frame = Tkinter.LabelFrame(top_frame, text=_('Enable samles'),
|
||||
padx=5, pady=5)
|
||||
else:
|
||||
frame = Frame(top_frame)
|
||||
frame = Tkinter.Frame(top_frame)
|
||||
frame.pack(expand=1, fill='both', padx=5, pady=5)
|
||||
frame.columnconfigure(0, weight=1)
|
||||
frame.columnconfigure(1, weight=1)
|
||||
|
@ -152,7 +153,7 @@ class SoundOptionsDialog(MfxDialog):
|
|||
col = 0
|
||||
for n, t, v in self.samples:
|
||||
v.set(app.opt.sound_samples[n])
|
||||
w = Checkbutton(frame, text=t, anchor='w', variable=v)
|
||||
w = Tkinter.Checkbutton(frame, text=t, anchor='w', variable=v)
|
||||
w.grid(row=row, column=col, sticky='ew')
|
||||
if col == 1:
|
||||
col = 0
|
||||
|
@ -203,7 +204,9 @@ class SoundOptionsDialog(MfxDialog):
|
|||
def mOptSoundDirectX(self, *event):
|
||||
##print self.sound_mode.get()
|
||||
d = MfxMessageDialog(self.top, title=_("Sound preferences info"),
|
||||
text=_("Changing DirectX settings will take effect\nthe next time you restart ")+PACKAGE,
|
||||
text=_("""\
|
||||
Changing DirectX settings will take effect
|
||||
the next time you restart """)+PACKAGE,
|
||||
bitmap="warning",
|
||||
default=0, strings=(_("&OK"),))
|
||||
|
||||
|
|
|
@ -39,6 +39,12 @@ __all__ = ['PysolStatusbar',
|
|||
# imports
|
||||
import os, sys, Tkinter
|
||||
|
||||
if __name__ == '__main__':
|
||||
d = os.path.abspath(os.path.join(sys.path[0], '..', '..'))
|
||||
sys.path.append(d)
|
||||
import gettext
|
||||
gettext.install('pysol', d, unicode=True)
|
||||
|
||||
# PySol imports
|
||||
from pysollib.mfxutil import destruct
|
||||
|
||||
|
@ -61,6 +67,7 @@ class MfxStatusbar:
|
|||
self._columnspan = columnspan
|
||||
#
|
||||
self.padx = 1
|
||||
self.label_relief = 'sunken'
|
||||
self.frame = Tkinter.Frame(self.top, bd=1)
|
||||
self.frame.grid(row=self._row, column=self._column,
|
||||
columnspan=self._columnspan, sticky='ew',
|
||||
|
@ -70,13 +77,28 @@ class MfxStatusbar:
|
|||
if os.name == 'nt':
|
||||
self.frame.config(relief='raised')
|
||||
self.padx = 0
|
||||
if 0:
|
||||
self.frame.config(bd=0)
|
||||
self.label_relief = 'flat'
|
||||
self.padx = 0
|
||||
|
||||
# util
|
||||
def _createLabel(self, name, side='left',
|
||||
fill='none', expand=0, width=0,
|
||||
tooltip=None):
|
||||
label = Tkinter.Label(self.frame, width=width, relief='sunken', bd=1)
|
||||
label.pack(side=side, fill=fill, padx=self.padx, expand=expand)
|
||||
if 0:
|
||||
frame = Tkinter.Frame(self.frame, bd=1, relief=self.label_relief,
|
||||
highlightbackground='#9e9a9e',
|
||||
highlightthickness=1)
|
||||
frame.pack(side=side, fill=fill, padx=self.padx, expand=expand)
|
||||
label = Tkinter.Label(frame, width=width, bd=0)
|
||||
label.pack(expand=True, fill='both')
|
||||
else:
|
||||
label = Tkinter.Label(self.frame, width=width,
|
||||
relief=self.label_relief, bd=1,
|
||||
highlightbackground='black'
|
||||
)
|
||||
label.pack(side=side, fill=fill, padx=self.padx, expand=expand)
|
||||
setattr(self, name + "_label", label)
|
||||
self._widgets.append(label)
|
||||
if tooltip:
|
||||
|
|
|
@ -23,7 +23,7 @@ __all__ = ['TimeoutsDialog']
|
|||
|
||||
# imports
|
||||
import os, sys
|
||||
from Tkinter import *
|
||||
import Tkinter
|
||||
|
||||
# PySol imports
|
||||
from pysollib.mfxutil import destruct, kwdefault, KwStruct, Struct
|
||||
|
@ -43,24 +43,24 @@ class TimeoutsDialog(MfxDialog):
|
|||
top_frame, bottom_frame = self.createFrames(kw)
|
||||
#self.createBitmaps(top_frame, kw)
|
||||
|
||||
frame = Frame(top_frame)
|
||||
frame.pack(expand=YES, fill=BOTH, padx=5, pady=10)
|
||||
frame = Tkinter.Frame(top_frame)
|
||||
frame.pack(expand=True, fill='both', padx=5, pady=10)
|
||||
frame.columnconfigure(0, weight=1)
|
||||
|
||||
self.demo_sleep_var = DoubleVar()
|
||||
self.demo_sleep_var = Tkinter.DoubleVar()
|
||||
self.demo_sleep_var.set(app.opt.demo_sleep)
|
||||
self.hint_sleep_var = DoubleVar()
|
||||
self.hint_sleep_var = Tkinter.DoubleVar()
|
||||
self.hint_sleep_var.set(app.opt.hint_sleep)
|
||||
self.raise_card_sleep_var = DoubleVar()
|
||||
self.raise_card_sleep_var = Tkinter.DoubleVar()
|
||||
self.raise_card_sleep_var.set(app.opt.raise_card_sleep)
|
||||
self.highlight_piles_sleep_var = DoubleVar()
|
||||
self.highlight_piles_sleep_var = Tkinter.DoubleVar()
|
||||
self.highlight_piles_sleep_var.set(app.opt.highlight_piles_sleep)
|
||||
self.highlight_cards_sleep_var = DoubleVar()
|
||||
self.highlight_cards_sleep_var = Tkinter.DoubleVar()
|
||||
self.highlight_cards_sleep_var.set(app.opt.highlight_cards_sleep)
|
||||
self.highlight_samerank_sleep_var = DoubleVar()
|
||||
self.highlight_samerank_sleep_var = Tkinter.DoubleVar()
|
||||
self.highlight_samerank_sleep_var.set(app.opt.highlight_samerank_sleep)
|
||||
#
|
||||
#Label(frame, text='Set delays in seconds').grid(row=0, column=0, columnspan=2)
|
||||
#Tkinter.Label(frame, text='Set delays in seconds').grid(row=0, column=0, columnspan=2)
|
||||
row = 0
|
||||
for title, var in ((_('Demo:'), self.demo_sleep_var),
|
||||
(_('Hint:'), self.hint_sleep_var),
|
||||
|
@ -69,11 +69,11 @@ class TimeoutsDialog(MfxDialog):
|
|||
(_('Highlight cards:'), self.highlight_cards_sleep_var),
|
||||
(_('Highlight same rank:'), self.highlight_samerank_sleep_var),
|
||||
):
|
||||
Label(frame, text=title, anchor=W).grid(row=row, column=0, sticky=W+E)
|
||||
widget = Scale(frame, from_=0.2, to=9.9,
|
||||
resolution=0.1, orient=HORIZONTAL,
|
||||
length="3i",
|
||||
variable=var, takefocus=0)
|
||||
Tkinter.Label(frame, text=title, anchor='w'
|
||||
).grid(row=row, column=0, sticky='we')
|
||||
widget = Tkinter.Scale(frame, from_=0.2, to=9.9,
|
||||
resolution=0.1, orient='horizontal',
|
||||
length="3i", variable=var, takefocus=0)
|
||||
widget.grid(row=row, column=1)
|
||||
row += 1
|
||||
#
|
||||
|
|
|
@ -40,13 +40,19 @@ import os, sys, re, types
|
|||
import htmllib, formatter
|
||||
import Tkinter
|
||||
|
||||
if __name__ == '__main__':
|
||||
d = os.path.abspath(os.path.join(sys.path[0], '..', '..'))
|
||||
sys.path.append(d)
|
||||
import gettext
|
||||
gettext.install('pysol', d, unicode=True)
|
||||
|
||||
# PySol imports
|
||||
from pysollib.mfxutil import Struct, openURL
|
||||
from pysollib.settings import PACKAGE
|
||||
|
||||
# Toolkit imports
|
||||
from tkutil import bind, unbind_destroy, loadImage
|
||||
from tkwidget import MfxDialog
|
||||
from tkwidget import MfxMessageDialog
|
||||
from statusbar import HtmlStatusbar
|
||||
|
||||
|
||||
|
@ -65,9 +71,13 @@ class tkHTMLWriter(formatter.DumbWriter):
|
|||
self.viewer = viewer
|
||||
|
||||
##
|
||||
font = app.getFont("sans")
|
||||
if app:
|
||||
font = app.getFont("sans")
|
||||
fixed = app.getFont("fixed")
|
||||
else:
|
||||
font = ('helvetica', 12)
|
||||
fixed = ('courier', 12)
|
||||
size = font[1]
|
||||
fixed = app.getFont("fixed")
|
||||
sign = 1
|
||||
if size < 0: sign = -1
|
||||
self.fontmap = {
|
||||
|
@ -121,14 +131,21 @@ class tkHTMLWriter(formatter.DumbWriter):
|
|||
if self.anchor:
|
||||
url = self.anchor[0]
|
||||
tag = "href_" + url
|
||||
self.text.tag_add(tag, self.anchor_mark, "insert")
|
||||
anchor_mark = self.anchor_mark
|
||||
if self.text.get(anchor_mark) == ' ': # FIXME
|
||||
try:
|
||||
y, x = anchor_mark.split('.')
|
||||
anchor_mark = y+'.'+str(int(x)+1)
|
||||
except:
|
||||
pass
|
||||
self.text.tag_add(tag, anchor_mark, "insert")
|
||||
self.text.tag_bind(tag, "<1>", self.createCallback(url))
|
||||
self.text.tag_bind(tag, "<Enter>", lambda e: self.anchor_enter(url))
|
||||
self.text.tag_bind(tag, "<Leave>", self.anchor_leave)
|
||||
fg = 'blue'
|
||||
u = self.viewer.normurl(url, with_protocol=False)
|
||||
if u in self.viewer.visited_urls:
|
||||
fg = '#303080'
|
||||
fg = '#660099'
|
||||
self.text.tag_config(tag, foreground=fg, underline=1)
|
||||
self.anchor = None
|
||||
|
||||
|
@ -379,7 +396,7 @@ class tkHTMLViewer:
|
|||
for p in REMOTE_PROTOCOLS:
|
||||
if url.startswith(p):
|
||||
if not openURL(url):
|
||||
self.errorDialog(PACKAGE + _(''' HTML limitation:
|
||||
self.errorDialog(PACKAGE + _('''HTML limitation:
|
||||
The %s protocol is not supported yet.
|
||||
|
||||
Please use your standard web browser
|
||||
|
@ -491,9 +508,9 @@ to open the following URL:
|
|||
self.display(self.home, relpath=0)
|
||||
|
||||
def errorDialog(self, msg):
|
||||
d = MfxDialog(self.parent, title=PACKAGE+" HTML Problem",
|
||||
text=msg, bitmap="warning",
|
||||
strings=(_("&OK"),), default=0)
|
||||
d = MfxMessageDialog(self.parent, title=PACKAGE+" HTML Problem",
|
||||
text=msg, bitmap="warning",
|
||||
strings=(_("&OK"),), default=0)
|
||||
|
||||
def getImage(self, fn):
|
||||
if self.images.has_key(fn):
|
||||
|
@ -526,6 +543,7 @@ def tkhtml_main(args):
|
|||
top = Tkinter.Tk()
|
||||
top.wm_minsize(400, 200)
|
||||
viewer = tkHTMLViewer(top)
|
||||
viewer.app = None
|
||||
viewer.display(url)
|
||||
top.mainloop()
|
||||
return 0
|
||||
|
|
|
@ -70,6 +70,7 @@ class MfxDialog: # ex. _ToplevelDialog
|
|||
self.status = 0
|
||||
self.button = default
|
||||
self.timer = None
|
||||
self.buttons = []
|
||||
self.accel_keys = {}
|
||||
self.top = makeToplevel(parent, title=title)
|
||||
self.top.wm_resizable(resizable, resizable)
|
||||
|
@ -231,6 +232,7 @@ class MfxDialog: # ex. _ToplevelDialog
|
|||
if button == kw.default:
|
||||
focus = b
|
||||
focus.config(default="active")
|
||||
self.buttons.append(b)
|
||||
#
|
||||
b.config(width=button_width)
|
||||
if accel_indx >= 0:
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
import sys, os, re, time
|
||||
from pprint import pprint
|
||||
|
||||
os.environ['LANG'] = 'C'
|
||||
import gettext
|
||||
gettext.install('pysol', 'locale', unicode=True)
|
||||
|
||||
|
@ -15,7 +16,6 @@ rules_dir = os.path.normpath(os.path.join(pysollib_path, 'data/html/rules'))
|
|||
#print rules_dir
|
||||
|
||||
import pysollib.games
|
||||
import pysollib.games.contrib
|
||||
import pysollib.games.special
|
||||
import pysollib.games.ultra
|
||||
import pysollib.games.mahjongg
|
||||
|
@ -138,17 +138,17 @@ def all_games(sort_by='id'):
|
|||
gt = CSI.TYPE_NAME[gi.category]
|
||||
if gt == 'French':
|
||||
gt = 'French (%s)' % GAME_BY_TYPE[gi.si.game_type]
|
||||
name = gi.name.encode('utf-8')
|
||||
altnames = '<br>'.join(gi.altnames).encode('utf-8')
|
||||
if 1 and os.path.exists(os.path.join(rules_dir, rules_fn)):
|
||||
fn = '../data/html/rules/'+rules_fn
|
||||
print '''<tr><td>%s</td><td>
|
||||
<a href="%s" title="Rules for this game">%s</a>
|
||||
</td><td>%s</td><td>%s</td></tr>
|
||||
''' % (id, fn,
|
||||
gi.name.encode('utf-8'), '<br>'.join(gi.altnames).encode('utf-8'), gt)
|
||||
''' % (id, fn, name, altnames, gt)
|
||||
else:
|
||||
print '''<tr><td>%s</td><td>%s</td><td>%s</td><td>%s</td></tr>
|
||||
''' % (id, gi.name.encode('utf-8'),
|
||||
'<br>'.join(gi.altnames).encode('utf-8'), gt)
|
||||
''' % (id, name, altnames, gt)
|
||||
print '</table>'
|
||||
|
||||
def create_html(sort_by):
|
||||
|
@ -219,6 +219,7 @@ def plain_text():
|
|||
for id in get_games_func():
|
||||
gi = GAME_DB.get(id)
|
||||
if gi.category == GI.GC_FRENCH:
|
||||
##print str(gi.gameclass)
|
||||
print gi.name.encode('utf-8')
|
||||
##name = gi.name.lower()
|
||||
##name = re.sub('\W', '', name)
|
||||
|
@ -235,6 +236,8 @@ elif sys.argv[1] == 'gettext':
|
|||
get_text()
|
||||
elif sys.argv[1] == 'text':
|
||||
plain_text()
|
||||
else:
|
||||
sys.exit('invalid argument')
|
||||
|
||||
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue