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

+ 7 new games

* improved startup; progressbar has been shown before load/register games
* improved gettext; game names has been translated during registration
* updated russian translation



git-svn-id: file:///home/shlomif/Backup/svn-dumps/PySolFC/svnsync-repos/pysolfc/PySolFC/trunk@185 efabe8c0-fbe8-4139-b769-b5e6d273206e
This commit is contained in:
skomoroh 2007-07-20 22:15:07 +00:00
parent 959a14b1eb
commit 6bb2e86dc9
31 changed files with 1877 additions and 1471 deletions

View file

@ -5,7 +5,8 @@
##
include pysol.py setup.py setup.cfg MANIFEST.in Makefile COPYING README
#recursive-include pysollib *.py
include pysollib/*.py pysollib/macosx/*.py pysollib/winsystems/*.py
include pysollib/*.py pysollib/macosx/*.py pysollib/configobj/*.py
include pysollib/winsystems/*.py
include pysollib/tk/*.py pysollib/tile/*.py pysollib/pysolgtk/*.py
include pysollib/games/*.py pysollib/games/special/*.py
include pysollib/games/ultra/*.py pysollib/games/mahjongg/*.py
@ -26,7 +27,7 @@ graft html-src
#graft data/images
recursive-include data/images *.gif *.png *.jpg
graft data/tiles
include data/pysol.xbm data/pysol.xpm data/pysol.ico
include data/pysol.xbm data/pysol.xpm data/pysol.ico data/PySol.icns
##
## data - sound
##

View file

@ -5,7 +5,7 @@
msgid ""
msgstr ""
"Project-Id-Version: PySol 0.0.1\n"
"POT-Creation-Date: Tue Jun 5 04:28:06 2007\n"
"POT-Creation-Date: Fri Jul 20 23:41:28 2007\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@ -360,6 +360,9 @@ msgstr ""
msgid "Bonaparte"
msgstr ""
msgid "Boomerang"
msgstr ""
msgid "Boost"
msgstr ""
@ -720,6 +723,9 @@ msgstr ""
msgid "Der letzte Monarch"
msgstr ""
msgid "Desert Island"
msgstr ""
msgid "Deuces"
msgstr ""
@ -804,6 +810,9 @@ msgstr ""
msgid "Double Fives"
msgstr ""
msgid "Double Footling"
msgstr ""
msgid "Double FreeCell"
msgstr ""
@ -1125,9 +1134,15 @@ msgstr ""
msgid "Flying Dragon"
msgstr ""
msgid "Footling"
msgstr ""
msgid "ForeCell"
msgstr ""
msgid "Forest Glade"
msgstr ""
msgid "Formic"
msgstr ""
@ -1320,6 +1335,9 @@ msgstr ""
msgid "Grand Duchess +"
msgstr ""
msgid "Grandee"
msgstr ""
msgid "Grandfather"
msgstr ""
@ -1776,6 +1794,9 @@ msgstr ""
msgid "Limited"
msgstr ""
msgid "Limpopo"
msgstr ""
msgid "Lion"
msgstr ""
@ -3324,6 +3345,9 @@ msgstr ""
msgid "Spike"
msgstr ""
msgid "Spoilt"
msgstr ""
msgid "Squadron"
msgstr ""
@ -3624,6 +3648,9 @@ msgstr ""
msgid "Trapdoor Spider"
msgstr ""
msgid "Travellers"
msgstr ""
msgid "Treasure Trove"
msgstr ""
@ -3633,6 +3660,9 @@ msgstr ""
msgid "Trefoil"
msgstr ""
msgid "Tri Peaks"
msgstr ""
msgid "Triangle"
msgstr ""
@ -3681,6 +3711,9 @@ msgstr ""
msgid "Trusty Twelve"
msgstr ""
msgid "Turncoats"
msgstr ""
msgid "Tuxedo"
msgstr ""
@ -3774,6 +3807,9 @@ msgstr ""
msgid "Virginia Reel"
msgstr ""
msgid "Voracious"
msgstr ""
msgid "Wake-Robin"
msgstr ""

File diff suppressed because it is too large Load diff

View file

@ -5,7 +5,7 @@
msgid ""
msgstr ""
"Project-Id-Version: PySol 0.0.1\n"
"POT-Creation-Date: Tue Jun 5 04:28:06 2007\n"
"POT-Creation-Date: Fri Jul 20 23:41:28 2007\n"
"PO-Revision-Date: 2007-05-11 17:25+0400\n"
"Last-Translator: Скоморох <skomoroh@gmail.com>\n"
"Language-Team: Russian <ru@li.org>\n"
@ -362,6 +362,9 @@ msgstr "Лодка"
msgid "Bonaparte"
msgstr "Бонапарт"
msgid "Boomerang"
msgstr ""
msgid "Boost"
msgstr "Повышение"
@ -724,6 +727,9 @@ msgstr "Der lange Zopf"
msgid "Der letzte Monarch"
msgstr "Der letzte Monarch"
msgid "Desert Island"
msgstr ""
msgid "Deuces"
msgstr "Двойки"
@ -809,6 +815,10 @@ msgstr "Двойной кузнечик"
msgid "Double Fives"
msgstr "Двойные пятёрки"
#, fuzzy
msgid "Double Footling"
msgstr "Двойной Дельфин"
msgid "Double FreeCell"
msgstr "Двойная свободная ячейка"
@ -1138,10 +1148,17 @@ msgstr "Полёт"
msgid "Flying Dragon"
msgstr "Летящий дракон"
msgid "Footling"
msgstr ""
#, fuzzy
msgid "ForeCell"
msgstr "Свободная ячейка"
#, fuzzy
msgid "Forest Glade"
msgstr "Цветочный сад"
msgid "Formic"
msgstr "Муравьиный"
@ -1339,6 +1356,10 @@ msgstr "Великая Герцогиня"
msgid "Grand Duchess +"
msgstr "Великая Герцогиня +"
#, fuzzy
msgid "Grandee"
msgstr "Гранада"
msgid "Grandfather"
msgstr "Дедушка"
@ -1802,6 +1823,9 @@ msgstr "Лили"
msgid "Limited"
msgstr "Ограниченный"
msgid "Limpopo"
msgstr ""
msgid "Lion"
msgstr "Лев"
@ -3370,6 +3394,9 @@ msgstr "Пауклонд"
msgid "Spike"
msgstr "Шип"
msgid "Spoilt"
msgstr ""
msgid "Squadron"
msgstr "Эскадрон"
@ -3683,6 +3710,10 @@ msgstr "Люк"
msgid "Trapdoor Spider"
msgstr "Люк Паука"
#, fuzzy
msgid "Travellers"
msgstr "Волны"
msgid "Treasure Trove"
msgstr "Клад"
@ -3692,6 +3723,10 @@ msgstr "Древо жизни"
msgid "Trefoil"
msgstr "Клевер"
#, fuzzy
msgid "Tri Peaks"
msgstr "Три вершины"
msgid "Triangle"
msgstr "Треугольник"
@ -3740,6 +3775,10 @@ msgstr "Тройка"
msgid "Trusty Twelve"
msgstr "Верные двенадцать"
#, fuzzy
msgid "Turncoats"
msgstr "Турнир"
msgid "Tuxedo"
msgstr "Смокинг"
@ -3838,6 +3877,9 @@ msgstr "Маджонг Victory Arrow"
msgid "Virginia Reel"
msgstr "Виргинский Рил"
msgid "Voracious"
msgstr ""
#, fuzzy
msgid "Wake-Robin"
msgstr "Робин"

File diff suppressed because it is too large Load diff

View file

@ -591,7 +591,7 @@ class PysolMenubarActions:
else:
player = self.app.opt.player
p0, p1, p2 = player, "", _(" for ") + player
n = _(self.game.gameinfo.short_name)
n = self.game.gameinfo.name
#
if mode == 100:
d = Status_StatsDialog(self.top, game=self.game)

View file

@ -1178,12 +1178,12 @@ Please select a %s type %s.
def getGameTitleName(self, id):
gi = self.gdb.get(id)
if gi is None: return None
return _(gi.name)
return gi.name
def getGameMenuitemName(self, id):
gi = self.gdb.get(id)
if gi is None: return None
return _(gi.short_name)
return gi.short_name
def getGameRulesFilename(self, id):
gi = self.gdb.get(id)

View file

@ -38,6 +38,7 @@
import time
import math
import traceback
from gettext import ungettext
from cStringIO import StringIO
# PySol imports
@ -1676,15 +1677,18 @@ You have reached
self.finished = True
self.playSample("gameperfect", priority=1000)
self.winAnimation(perfect=1)
text = ungettext('''Your playing time is %s\nfor %d move.''',
'''Your playing time is %s\nfor %d moves.''',
self.moves.index)
text = text % (time, self.moves.index)
d = MfxMessageDialog(self.top, title=_("Game won"),
text=_('''
Congratulations, this
was a truly perfect game !
Your playing time is %s
for %d moves.
%s
''') % (time, self.moves.index, top_msg),
%s
''') % (text, top_msg),
strings=(_("&New game"), None, _("&Cancel")),
image=self.app.gimages.logos[5])
elif status == 1:
@ -1693,14 +1697,17 @@ for %d moves.
self.finished = True
self.playSample("gamewon", priority=1000)
self.winAnimation()
text = ungettext('''Your playing time is %s\nfor %d move.''',
'''Your playing time is %s\nfor %d moves.''',
self.moves.index)
text = text % (time, self.moves.index)
d = MfxMessageDialog(self.top, title=_("Game won"),
text=_('''
Congratulations, you did it !
Your playing time is %s
for %d moves.
%s
''') % (time, self.moves.index, top_msg),
%s
''') % (text, top_msg),
strings=(_("&New game"), None, _("&Cancel")),
image=self.app.gimages.logos[4])
elif self.gstats.updated < 0:
@ -2282,9 +2289,12 @@ for %d moves.
self.playSample("autopilotwon", priority=1000)
s = self.app.miscrandom.choice((_("&Great"), _("&Cool"),
_("&Yeah"), _("&Wow")))
text = ungettext('\nGame solved in %d move.\n',
'\nGame solved in %d moves.\n',
self.moves.index)
text = text % self.moves.index
d = MfxMessageDialog(self.top, title=TITLE+_(" Autopilot"),
text=_("\nGame solved in %d moves.\n") %
self.moves.index,
text=text,
image=self.app.gimages.logos[4],
strings=(s,),
separator=True,

View file

@ -281,6 +281,7 @@ class GI:
("Art Cabral", (9,)),
("Charles Jewell", (220, 309,)),
("Robert Harbin", (381,)),
("Robert Hogue", (22216,)),
("Michael Keller", (592,)),
("Fred Lunde", (459,)),
("Albert Morehead and Geoffrey Mott-Smith", (25, 42, 48, 173,
@ -409,21 +410,22 @@ class GameInfo(Struct):
suits=range(4), ranks=range(13), trumps=(),
rules_filename=None,
):
def to_unicode(s):
def gettext_name(s):
if not isinstance(s, unicode):
return unicode(s, 'utf-8')
return s
return _(unicode(s, 'utf-8'))
return _(s)
#
ncards = decks * (len(suits) * len(ranks) + len(trumps))
game_flags = game_type & ~1023
game_type = game_type & 1023
name = to_unicode(name)
name = gettext_name(name)
if not short_name:
short_name = name
short_name = to_unicode(short_name)
else:
short_name = gettext_name(short_name)
if isinstance(altnames, basestring):
altnames = (altnames,)
altnames = [to_unicode(n) for n in altnames]
altnames = [gettext_name(n) for n in altnames]
#
if not (1 <= category <= 9):
if game_type == GI.GT_HANAFUDA:
@ -494,6 +496,11 @@ class GameManager:
self.check_game = True
self.current_filename = None
self.registered_game_types = {}
self.callback = None # update progress-bar (see main.py)
self._num_games = 0 # for callback only
def setCallback(self, func):
self.callback = func
def getSelected(self):
return self.__selected_key
@ -562,6 +569,10 @@ class GameManager:
if self.current_filename is not None:
gi.gameclass.MODULE_FILENAME = self.current_filename
if self.callback and self._num_games % 10 == 0:
self.callback()
self._num_games += 1
#
# access games database - we do not expose hidden games
#
@ -581,20 +592,20 @@ class GameManager:
if self.__games_by_name is None:
l1, l2, l3 = [], [], []
for id, gi in self.__games.items():
name = _(gi.name).lower()
name = gi.name #.lower()
l1.append((name, id))
if gi.name != gi.short_name:
name = _(gi.short_name).lower()
name = gi.short_name #.lower()
l2.append((name, id))
for n in gi.altnames:
name = _(n).lower()
name = n #.lower()
l3.append((name, id, n))
l1.sort()
l2.sort()
l3.sort()
self.__games_by_name = tuple(map(lambda item: item[1], l1))
self.__games_by_short_name = tuple(map(lambda item: item[1], l2))
self.__games_by_altname = tuple(map(lambda item: item[1:], l3))
self.__games_by_name = tuple([i[1] for i in l1])
self.__games_by_short_name = tuple([i[1] for i in l2])
self.__games_by_altname = tuple([i[1:] for i in l3])
return self.__games_by_name
def getGamesIdSortedByShortName(self):

View file

@ -604,6 +604,54 @@ class CanCan(FreeCell):
self.s.talon.dealRowAvail()
# /***********************************************************************
# // Limpopo
# ************************************************************************/
class Limpopo(Game):
def createGame(self):
# create layout
l, s = Layout(self), self.s
# set window
self.setSize(l.XM+10.5*l.XS, l.YM+2*l.YS+20*l.YOFFSET)
# create stacks
x, y = l.XM, l.YM+l.YS/2
for i in (0,1):
stack = ReserveStack(x, y, self, max_cards=4)
s.reserves.append(stack)
stack.CARD_YOFFSET = l.YOFFSET
l.createText(stack, 'n')
x += l.XS
x, y = l.XM+2.5*l.XS, l.YM
for i in range(8):
s.foundations.append(SS_FoundationStack(x, y, self, suit=i/2))
x += l.XS
x, y = l.XM+2.5*l.XS, l.YM+l.YS
for i in range(8):
s.rows.append(AC_RowStack(x, y, self))
x += l.XS
x, y = l.XM, self.height-l.YS
s.talon = InitialDealTalonStack(x, y, self)
# define stack-groups
l.defaultStackGroups()
def startGame(self):
for i in range(12):
self.s.talon.dealRow(frames=0)
self.startDealSample()
self.s.talon.dealRow()
shallHighlightMatch = Game._shallHighlightMatch_AC
# register the game
registerGame(GameInfo(5, RelaxedFreeCell, "Relaxed FreeCell",
@ -652,4 +700,6 @@ registerGame(GameInfo(648, Headquarters, "Headquarters",
GI.GT_FREECELL | GI.GT_OPEN | GI.GT_ORIGINAL, 2, 0, GI.SL_MOSTLY_SKILL))
registerGame(GameInfo(698, CanCan, "Can Can",
GI.GT_RAGLAN | GI.GT_OPEN, 1, 0, GI.SL_MOSTLY_SKILL))
registerGame(GameInfo(746, Limpopo, "Limpopo",
GI.GT_FREECELL | GI.GT_ORIGINAL, 2, 0, GI.SL_MOSTLY_SKILL))

View file

@ -1470,9 +1470,9 @@ registerGame(GameInfo(541, BatsfordAgain, "Batsford Again",
registerGame(GameInfo(572, GoldMine, "Gold Mine",
GI.GT_NUMERICA, 1, 0, GI.SL_MOSTLY_SKILL))
registerGame(GameInfo(585, LuckyThirteen, "Lucky Thirteen",
GI.GT_NUMERICA, 1, 0, GI.SL_MOSTLY_LUCK))
GI.GT_1DECK_TYPE, 1, 0, GI.SL_MOSTLY_LUCK))
registerGame(GameInfo(586, LuckyPiles, "Lucky Piles",
GI.GT_NUMERICA, 1, 0, GI.SL_MOSTLY_SKILL))
GI.GT_FAN_TYPE, 1, 0, GI.SL_MOSTLY_SKILL))
registerGame(GameInfo(601, AmericanCanister, "American Canister",
GI.GT_BELEAGUERED_CASTLE | GI.GT_OPEN, 1, 0, GI.SL_MOSTLY_SKILL))
registerGame(GameInfo(602, BritishCanister, "British Canister",

View file

@ -30,6 +30,7 @@ __all__ = []
import sys, re
import time
#from tkFont import Font
from gettext import ungettext
# PySol imports
from pysollib.gamedb import registerGame, GameInfo, GI
@ -840,8 +841,6 @@ a solvable configuration.'''),
if self.preview > 1 or self.texts.info is None:
return
from gettext import ungettext
# find matching tiles
stacks = []
for r in self.s.rows:

View file

@ -24,6 +24,7 @@ __all__ = []
# Imports
import sys
#from tkFont import Font
from gettext import ungettext
# PySol imports
from pysollib.gamedb import registerGame, GameInfo, GI
@ -381,7 +382,6 @@ class AbstractShisenGame(AbstractMahjonggGame):
if self.preview > 1 or self.texts.info is None:
return
from gettext import ungettext
game = self.app.game
if 0:

View file

@ -224,9 +224,10 @@ class FourByFour_Hint(DefaultHint):
class FourByFour_Foundation(AbstractFoundationStack):
def _getNumSameCards(self):
decks = self.game.gameinfo.decks
rank = self.cards[-1].rank
n = 1
for i in range(2,5):
for i in range(2, 4*decks+1):
if len(self.cards) < i:
break
if self.cards[-i].rank != rank:
@ -235,23 +236,20 @@ class FourByFour_Foundation(AbstractFoundationStack):
return n
def _getDir(self):
if len(self.cards) < 4:
decks = self.game.gameinfo.decks
if len(self.cards) < 4*decks:
return 0
if isRankSequence(self.cards[-4:], dir=0):
if isRankSequence(self.cards[-4*decks:], dir=0):
return 1
return 0
def acceptsCards(self, from_stack, cards):
if not AbstractFoundationStack.acceptsCards(self, from_stack, cards):
return False
if not self.cards:
return True
dir = self._getDir()
return (self.cards[-1].rank+dir) % 13 == cards[0].rank
if len(self.cards) < 4:
return cards[0].rank == self.cards[-1].rank
if isRankSequence(self.cards[-4:], dir=0):
return (cards[0].rank+1) % 13 == self.cards[-1].rank
return cards[0].rank == self.cards[-1].rank
return (self.cards[-1].rank+dir) % self.cap.mod == cards[0].rank
def getHelp(self):
return _('Foundation. Build up regardless of suit.')
@ -271,7 +269,7 @@ class FourByFour(Game):
self.setSize(l.XM+7*l.XS, l.YM+2*l.YS+20*l.YOFFSET)
x, y = l.XM, l.YM
s.talon = WasteTalonStack(y, x, self, max_rounds=1)
s.talon = WasteTalonStack(x, y, self, max_rounds=1)
l.createText(s.talon, 's')
x += l.XS
s.waste = WasteStack(x, y, self)
@ -301,20 +299,26 @@ class FourByFour(Game):
self.s.talon.dealCards()
def updateText(self):
decks = self.gameinfo.decks
if self.preview > 1:
return
f = self.s.foundations[0]
if not f.cards:
return
if len(f.cards) == 52:
if f.cap.base_rank == ANY_RANK:
t = ''
else:
r = RANKS[f.cap.base_rank]
n = 4*decks
t = '%s (%d)' % (r, n)
elif len(f.cards) == 52*decks:
t = ''
else:
n = f._getNumSameCards()
n = 4-n
n = 4*decks - n
r = f.cards[-1].rank
if n == 0:
n = 4
r = (r+1)%13
n = 4*decks
r = (r+1) % f.cap.mod
r = RANKS[r]
t = '%s (%d)' % (r, n)
f.texts.misc.config(text=t)
@ -322,6 +326,65 @@ class FourByFour(Game):
shallHighlightMatch = Game._shallHighlightMatch_RKW
# /***********************************************************************
# // Footling
# ************************************************************************/
class Footling(FourByFour):
Hint_Class = DefaultHint
def createGame(self, rows=8, reserves=4, playcards=15):
decks = self.gameinfo.decks
l, s = Layout(self), self.s
self.setSize(l.XM+rows*l.XS, l.YM+2*l.YS+playcards*l.YOFFSET)
x, y = l.XM, l.YM
for i in range(reserves):
s.reserves.append(ReserveStack(x, y, self))
x += l.XS
x = self.width - 2*l.XS
s.foundations.append(FourByFour_Foundation(x, y, self,
suit=ANY_SUIT, base_rank=ACE, max_cards=52*decks,
max_accept=1, max_move=0))
stack = s.foundations[0]
tx, ty, ta, tf = l.getTextAttr(stack, 'ne')
font = self.app.getFont('canvas_default')
stack.texts.misc = MfxCanvasText(self.canvas, tx, ty,
anchor=ta, font=font)
x, y = l.XM, l.YM+l.YS
for i in range(rows):
s.rows.append(AC_RowStack(x, y, self))
x += l.XS
x, y = l.XM, self.height-l.YS
s.talon = InitialDealTalonStack(x, y, self)
l.defaultStackGroups()
def startGame(self):
for i in range(5):
self.s.talon.dealRow(frames=0)
self.startDealSample()
self.s.talon.dealRow()
self.s.talon.dealRowAvail()
shallHighlightMatch = Game._shallHighlightMatch_AC
class DoubleFootling(Footling):
def createGame(self):
Footling.createGame(self, rows=10, reserves=5, playcards=18)
def startGame(self):
for i in range(9):
self.s.talon.dealRow(frames=0)
self.startDealSample()
self.s.talon.dealRow()
self.s.talon.dealRowAvail()
# register the game
registerGame(GameInfo(41, PileOn, "PileOn",
@ -337,5 +400,9 @@ registerGame(GameInfo(555, Quartets, "Quartets",
GI.GT_1DECK_TYPE | GI.GT_OPEN | GI.GT_ORIGINAL, 1, 0, GI.SL_MOSTLY_SKILL))
registerGame(GameInfo(703, FourByFour, "Four by Four",
GI.GT_1DECK_TYPE, 1, 0, GI.SL_BALANCED))
registerGame(GameInfo(740, Footling, "Footling",
GI.GT_FREECELL | GI.GT_OPEN | GI.GT_ORIGINAL, 1, 0, GI.SL_MOSTLY_SKILL))
registerGame(GameInfo(741, DoubleFootling, "Double Footling",
GI.GT_FREECELL | GI.GT_OPEN | GI.GT_ORIGINAL, 2, 0, GI.SL_MOSTLY_SKILL))

View file

@ -1112,6 +1112,162 @@ class Phalanx(Game):
# /***********************************************************************
# // Grandee
# // Turncoats
# // Voracious
# ************************************************************************/
class Grandee(Game):
Hint_Class = CautiousDefaultHint
Talon_Class = DealRowTalonStack
RowStack_Class = SS_RowStack
def createGame(self, waste=False, rows=14):
# create layout
l, s = Layout(self), self.s
# set window
decks = self.gameinfo.decks
w = max(decks*4, rows/2)
self.setSize(l.XM+w*l.XS, l.YM+5*l.YS)
# create stacks
x, y = l.XM + (w-decks*4)*l.XS/2, l.YM
for i in range(4):
for j in range(decks):
s.foundations.append(SS_FoundationStack(x, y, self, suit=i))
x += l.XS
y = l.YM+1.5*l.YS
for i in range(2):
x = l.XM + (w-rows/2)*l.XS/2
for j in range(rows/2):
stack = self.RowStack_Class(x, y, self, max_move=1)
stack.CARD_YOFFSET = 0
s.rows.append(stack)
x += l.XS
y += l.YS
x, y = self.width-l.XS, self.height-l.YS
s.talon = self.Talon_Class(x, y, self)
if waste:
l.createText(s.talon, 'n')
x -= l.XS
s.waste = WasteStack(x, y, self)
l.createText(s.waste, 'n')
else:
l.createText(s.talon, 'sw')
# define stack-groups
l.defaultStackGroups()
def startGame(self):
self.startDealSample()
self.s.talon.dealRow()
shallHighlightMatch = Game._shallHighlightMatch_SS
class Turncoats(Grandee):
Talon_Class = TalonStack
RowStack_Class = StackWrapper(UD_AC_RowStack, base_rank=NO_RANK)
def createGame(self):
Grandee.createGame(self, rows=12)
def fillStack(self, stack):
if not stack.cards:
if stack in self.s.rows and self.s.talon.cards:
old_state = self.enterState(self.S_FILL)
self.s.talon.flipMove()
self.s.talon.moveMove(1, stack)
self.leaveState(old_state)
shallHighlightMatch = Game._shallHighlightMatch_AC
class Voracious(Grandee):
Talon_Class = StackWrapper(WasteTalonStack, max_rounds=1)
RowStack_Class = StackWrapper(SS_RowStack, base_rank=NO_RANK)
def createGame(self):
Grandee.createGame(self, waste=True, rows=12)
def startGame(self):
self.startDealSample()
self.s.talon.dealRow()
self.s.talon.dealCards()
def fillStack(self, stack):
if not stack.cards:
if stack in self.s.rows:
old_state = self.enterState(self.S_FILL)
if not self.s.waste.cards:
self.s.talon.dealCards()
if self.s.waste.cards:
self.s.waste.moveMove(1, stack)
self.leaveState(old_state)
# /***********************************************************************
# //
# ************************************************************************/
class DesertIsland(Game):
def createGame(self):
# create layout
l, s = Layout(self), self.s
# set window
self.setSize(l.XM+8*l.XS, l.YM+5*l.YS)
# create stacks
x, y = l.XM, l.YM
for i in range(8):
s.foundations.append(SS_FoundationStack(x, y, self,
suit=i/2, max_cards=10))
x += l.XS
y = l.YM+l.YS
for i in range(3):
x = l.XM
for j in range(8):
##stack = SS_RowStack(x, y, self, max_move=1)
stack = ReserveStack(x, y, self)
stack.CARD_YOFFSET = 0
s.rows.append(stack)
x += l.XS
y += l.YS
x, y = self.width-l.XS, self.height-l.YS
s.talon = DealRowTalonStack(x, y, self)
l.createText(s.talon, 'sw')
# define stack-groups
l.defaultStackGroups()
def _shuffleHook(self, cards):
return self._shuffleHookMoveToTop(cards,
lambda c: (c.rank == ACE, c.suit))
def startGame(self):
self.s.talon.dealRow(rows=self.s.foundations, frames=0)
self.startDealSample()
self.s.talon.dealRow()
def isGameWon(self):
for s in self.s.foundations:
if len(s.cards) != 10:
return False
return True
# register the game
registerGame(GameInfo(330, Sultan, "Sultan",
GI.GT_2DECK_TYPE, 2, 2, GI.SL_MOSTLY_LUCK,
@ -1157,3 +1313,11 @@ registerGame(GameInfo(729, TwoRings, "Two Rings",
GI.GT_2DECK_TYPE, 2, 1, GI.SL_MOSTLY_LUCK))
registerGame(GameInfo(730, Phalanx, "Phalanx",
GI.GT_1DECK_TYPE, 1, 0, GI.SL_MOSTLY_LUCK))
registerGame(GameInfo(742, Grandee, "Grandee",
GI.GT_2DECK_TYPE, 2, 0, GI.SL_BALANCED))
registerGame(GameInfo(743, Turncoats, "Turncoats",
GI.GT_1DECK_TYPE, 1, 0, GI.SL_BALANCED))
registerGame(GameInfo(744, Voracious, "Voracious",
GI.GT_2DECK_TYPE, 2, 0, GI.SL_BALANCED))
registerGame(GameInfo(745, DesertIsland, "Desert Island",
GI.GT_2DECK_TYPE | GI.GT_ORIGINAL, 2, 0, GI.SL_BALANCED))

View file

@ -283,7 +283,9 @@ class ThreePeaksNoScore(ThreePeaks):
registerGame(GameInfo(22216, ThreePeaks, "Three Peaks",
GI.GT_PAIRING_TYPE, 1, 0, GI.SL_BALANCED))
GI.GT_PAIRING_TYPE, 1, 0, GI.SL_BALANCED,
altnames=("Tri Peaks",)
))
registerGame(GameInfo(22231, ThreePeaksNoScore, "Three Peaks Non-scoring",
GI.GT_PAIRING_TYPE, 1, 0, GI.SL_BALANCED))

View file

@ -81,12 +81,11 @@ def init():
gettext.bindtextdomain('pysol', locale_dir)
gettext.textdomain('pysol')
import __builtin__
__builtin__.__dict__['_'] = gettext.ugettext # use unicode
__builtin__.__dict__['n_'] = lambda x: x
__builtin__._ = gettext.ugettext # use unicode
__builtin__.n_ = lambda x: x
## debug
if 'PYSOL_CHECK_GAMES' in os.environ or \
'PYSOL_DEBUG' in os.environ:
if 'PYSOL_CHECK_GAMES' in os.environ or 'PYSOL_DEBUG' in os.environ:
settings.CHECK_GAMES = True
print 'PySol debugging: set CHECK_GAMES to True'
if 'PYSOL_DEBUG' in os.environ:

View file

@ -44,6 +44,7 @@ from util import DataLoader
from mfxutil import print_err
from resource import Tile
from app import Application
from gamedb import GAME_DB
from pysolaudio import AbstractAudioClient, PysolSoundServerModuleClient
from pysolaudio import Win32AudioClient, OSSAudioClient, PyGameAudioClient
from settings import TITLE, SOUND_MOD
@ -149,6 +150,22 @@ def parse_option(argv):
# ************************************************************************/
def pysol_init(app, args):
# init commandline options (undocumented)
opts = parse_option(args)
if not opts:
return 1
sys.exit(1)
opts, filename = opts
if filename:
app.commandline.loadgame = filename
app.commandline.game = opts['game']
if opts['gameid'] is not None:
try:
app.commandline.gameid = int(opts['gameid'])
except ValueError:
print_err(_('invalid game id: ') + opts['gameid'])
# try to create the config directory
for d in (
app.dn.config,
@ -166,32 +183,52 @@ def pysol_init(app, args):
traceback.print_exc()
pass
# init commandline options (undocumented)
opts = parse_option(args)
if not opts:
return 1
sys.exit(1)
opts, filename = opts
if filename:
app.commandline.loadgame = filename
app.commandline.game = opts['game']
if opts['gameid'] is not None:
try:
app.commandline.gameid = int(opts['gameid'])
except ValueError:
print_err(_('invalid game id: ') + opts['gameid'])
# load options
try:
app.loadOptions()
except:
traceback.print_exc()
pass
# init DataLoader
f = os.path.join("html", "license.html")
app.dataloader = DataLoader(args[0], f)
# init toolkit 1)
top = MfxRoot(className=TITLE)
app.top = top
app.top_bg = top.cget("bg")
app.top_cursor = top.cget("cursor")
# init toolkit 2)
init_root_window(top, app)
# prepare the progress bar
app.loadImages1()
if not app.progress_images:
app.progress_images = (loadImage(app.gimages.logos[0]),
loadImage(app.gimages.logos[1]))
app.wm_withdraw()
# create the progress bar
title = _("Welcome to %s") % TITLE
color = app.opt.colors['table']
if app.tabletile_index > 0:
color = "#008200"
app.intro.progress = PysolProgressBar(app, top, title=title, color=color,
images=app.progress_images, norm=2.0)
app.intro.progress.update(step=1)
# init games database
def progressCallback(*args):
app.intro.progress.update(step=1)
GAME_DB.setCallback(progressCallback)
import games
if not opts['french-only']:
import games.ultra
import games.mahjongg
import games.special
# init DataLoader
f = os.path.join("html", "license.html")
app.dataloader = DataLoader(args[0], f)
# try to load plugins
if not opts["noplugins"]:
for dir in (os.path.join(app.dataloader.dir, "games"),
@ -201,19 +238,7 @@ def pysol_init(app, args):
app.loadPlugins(dir)
except:
pass
# init toolkit 1)
top = MfxRoot(className=TITLE)
app.top = top
app.top_bg = top.cget("bg")
app.top_cursor = top.cget("cursor")
# load options
try:
app.loadOptions()
except:
traceback.print_exc()
pass
GAME_DB.setCallback(None)
# init audio 1)
app.audio = None
@ -249,12 +274,10 @@ def pysol_init(app, args):
else:
app.opt.sound_mode = 0
# init toolkit 2)
init_root_window(top, app)
# check games
if len(app.gdb.getGamesIdSortedByName()) == 0:
app.wm_withdraw()
app.intro.progress.destroy()
d = MfxMessageDialog(top, title=_("%s installation error") % TITLE,
text=_('''
No games were found !!!
@ -317,21 +340,6 @@ Please check your %s installation.
break
app.audio.playContinuousMusic(app.music_playlist)
# prepare the progress bar
app.loadImages1()
if not app.progress_images:
app.progress_images = (loadImage(app.gimages.logos[0]),
loadImage(app.gimages.logos[1]))
app.wm_withdraw()
# create the progress bar
title = _("Welcome to %s") % TITLE
color = app.opt.colors['table']
if app.tabletile_index > 0:
color = "#008200"
app.intro.progress = PysolProgressBar(app, top, title=title, color=color,
images=app.progress_images, norm=1.4)
# prepare other images
app.loadImages2()
app.loadImages3()

View file

@ -501,7 +501,6 @@ class PysolMenubar(PysolMenubarActions):
label = gi.short_name
else:
label = gi.name
label = _(label)
menu_item = gtk.MenuItem(label)
menu_item.set_data('user_data', gi.id)
menu_item.connect('activate', self.mSelectGame)
@ -523,7 +522,6 @@ class PysolMenubar(PysolMenubarActions):
break
m = min(n+d-1, len(games)-1)
n1, n2 = games[n].name, games[m].name
n1, n2 = _(n1), _(n2)
label = n1[:3]+' - '+n2[:3]
submenu = self._createSubMenu(menu, label=label)
self._addGamesSubMenu(games[n:n+d], submenu)
@ -568,7 +566,7 @@ class PysolMenubar(PysolMenubarActions):
#
games = {}
for gi in mahjongg_games:
c = _(gi.short_name).strip()[0]
c = gi.short_name.strip()[0]
if c in games:
games[c].append(gi)
else:

View file

@ -195,8 +195,6 @@ class SelectGameDialogWithPreview(MfxDialog):
iter = store.append(root_iter)
store.set(iter, 0, root_label, 1, -1)
for label, games in gl:
label = _(label)
label = label.replace("&", "")
self._addGames(store, iter, label, games)
@ -207,7 +205,6 @@ class SelectGameDialogWithPreview(MfxDialog):
store.set(iter, 0, root_label, 1, -1)
for id, name in games:
child_iter = store.append(iter)
name = _(name)
store.set(child_iter, 0, name, 1, id)
@ -292,7 +289,6 @@ class SelectGameDialogWithPreview(MfxDialog):
data = []
for label, vg in GI.GAMES_BY_COMPATIBILITY:
selecter = lambda gi, vg=vg: gi.id in vg
label = _(label)
data.append((label, selecter))
self._addGamesFromData(data, store, root_iter,
_("by Compatibility"), all_games)
@ -473,8 +469,8 @@ class SelectGameDialogWithPreview(MfxDialog):
def updateInfo(self, gameid):
gi = self.app.gdb.get(gameid)
# info
name = _(gi.name)
altnames = '\n'.join([_(n) for n in gi.altnames])
name = gi.name
altnames = '\n'.join(gi.altnames)
category = _(CSI.TYPE[gi.category])
type = ''
if gi.si.game_type in GI.TYPE_NAMES:

View file

@ -86,7 +86,7 @@ class LogFormatter(PysolStatsFormatter):
for result in self.getLogResults(player, prev_games):
iter = self.store.append(None)
self.store.set(iter,
0, _(result[0]),
0, result[0],
1, result[1],
2, result[2],
3, result[3],
@ -229,7 +229,7 @@ class Game_StatsDialog:
current = 0
for id in self.games_id:
gi = self.app.gdb.get(id)
combo.append_text(_(gi.name))
combo.append_text(gi.name)
if id == self.gameid:
current = n
n += 1

View file

@ -702,7 +702,7 @@ class PysolMenubar(PysolMenubarActions):
games = {}
for gi in mahjongg_games:
c = _(gi.short_name).strip()[0]
c = gi.short_name.strip()[0]
if c in games:
games[c].append(gi)
else:
@ -770,7 +770,7 @@ class PysolMenubar(PysolMenubarActions):
if not games[n:n+d]:
break
m = min(n+d-1, len(games)-1)
label = _(games[n].name)[:3]+' - '+_(games[m].name)[:3]
label = games[n].name[:3] + ' - ' + games[m].name[:3]
submenu = MfxMenu(menu, label=label, name=None)
self._addSelectGameSubSubMenu(games[n:n+d], submenu,
command, variable)
@ -787,9 +787,9 @@ class PysolMenubar(PysolMenubarActions):
gi = games[i]
columnbreak = i > 0 and (i % cb) == 0
if short_name:
label = _(gi.short_name)
label = gi.short_name
else:
label = _(gi.name)
label = gi.name
## menu.add_radiobutton(command=command, variable=variable,
## columnbreak=columnbreak,
## value=gi.id, label=label, name=None)
@ -806,7 +806,7 @@ class PysolMenubar(PysolMenubarActions):
if len(games) == 0:
menu.add_radiobutton(label='<none>', name=None, state='disabled')
elif len(games) > self.__cb_max*4:
games.sort(lambda a, b: cmp(_(a.name), _(b.name)))
games.sort(lambda a, b: cmp(a.name, b.name))
self._addSelectAllGameSubMenu(games, menu,
command=self.mSelectGame,
variable=self.tkopt.gameid)

View file

@ -68,7 +68,6 @@ class SelectGameNode(SelectDialogTreeNode):
# key/value pairs
for id, name in self.select_func:
if id and name:
name = _(name) # name of game
node = SelectGameLeaf(self.tree, self, name, key=id)
contents.append(node)
else:
@ -77,12 +76,10 @@ class SelectGameNode(SelectDialogTreeNode):
# All games
##name = '%s (%s)' % (gi.name, CSI.TYPE_NAME[gi.category])
name = gi.name
name = _(name) # name of game
node = SelectGameLeaf(self.tree, self, name, key=gi.id)
contents.append(node)
elif gi and self.select_func(gi):
name = gi.name
name = _(name) # name of game
node = SelectGameLeaf(self.tree, self, name, key=gi.id)
contents.append(node)
return contents or self.tree.data.no_games
@ -110,8 +107,6 @@ class SelectGameData(SelectDialogTreeData):
for name, select_func in data:
if name is None or not filter(select_func, self.all_games_gi):
continue
name = _(name)
name = name.replace("&", "")
gg.append(SelectGameNode(None, name, select_func))
g.append(gg)
select_mahjongg_game = lambda gi: gi.si.game_type == GI.GT_MAHJONGG
@ -142,7 +137,6 @@ class SelectGameData(SelectDialogTreeData):
select_func = lambda gi, games=games: gi.id in games
if name is None or not filter(select_func, self.all_games_gi):
continue
name = _(name)
gg.append(SelectGameNode(None, name, select_func))
if 1 and gg:
s_by_compatibility = SelectGameNode(None, _("by Compatibility"),
@ -553,8 +547,8 @@ class SelectGameDialogWithPreview(SelectGameDialog):
def updateInfo(self, gameid):
gi = self.app.gdb.get(gameid)
# info
name = _(gi.name)
altnames = '\n'.join([_(n) for n in gi.altnames])
name = gi.name
altnames = '\n'.join(gi.altnames)
category = _(CSI.TYPE[gi.category])
type = ''
if gi.si.game_type in GI.TYPE_NAMES:

View file

@ -78,7 +78,6 @@ class SolverDialog(MfxDialog):
gamenames = ['']
for id in games:
name = app.getGameTitleName(id)
name = _(name)
gamenames.append(name)
self.games[name] = id
gamenames.sort()
@ -231,7 +230,6 @@ class SolverDialog(MfxDialog):
def connectGame(self, game):
name = self.app.getGameTitleName(game.id)
name = _(name)
if name in self.gamenames:
self.start_button.config(state='normal')
i = self.gamenames.index(name)

View file

@ -392,7 +392,6 @@ class TreeFormatter(PysolStatsFormatter):
num_rows = 0
for result in self.getLogResults(player, prev_games):
t1, t2, t3, t4, t5, t6 = result
t1 = _(t1) # game name
id = self.tree.insert(None, "end", text=t1, values=(t2, t3, t4))
self.parent_window.tree_items.append(id)
num_rows += 1
@ -861,7 +860,10 @@ class ProgressionFrame(Tile.Frame):
frame.columnconfigure(0, weight=1)
# constants
self.canvas_width, self.canvas_height = 550, 250
w = dialog.tkfont.measure('M') * 42
w = max(w, 500)
w = min(w, 600)
self.canvas_width, self.canvas_height = w, 250
if parent.winfo_screenwidth() < 800 or \
parent.winfo_screenheight() < 600:
self.canvas_width, self.canvas_height = 400, 200

View file

@ -39,6 +39,7 @@ __all__ = ['TclError',
# imports
import Tkinter
TclError = Tkinter.TclError
import Tile
# PySol imports
from tkconst import EVENT_PROPAGATE
@ -52,6 +53,7 @@ from tkconst import EVENT_PROPAGATE
class MfxRoot(Tkinter.Tk):
def __init__(self, **kw):
Tkinter.Tk.__init__(self, **kw)
Tile.initialize(self)
self.app = None
self.wm_protocol('WM_DELETE_WINDOW', self.wmDeleteWindow)
# for interruptible sleep

View file

@ -706,7 +706,7 @@ class PysolMenubar(PysolMenubarActions):
games = {}
for gi in mahjongg_games:
c = _(gi.short_name).strip()[0]
c = gi.short_name.strip()[0]
if c in games:
games[c].append(gi)
else:
@ -774,7 +774,7 @@ class PysolMenubar(PysolMenubarActions):
if not games[n:n+d]:
break
m = min(n+d-1, len(games)-1)
label = _(games[n].name)[:3]+' - '+_(games[m].name)[:3]
label = games[n].name[:3] + ' - ' + games[m].name[:3]
submenu = MfxMenu(menu, label=label, name=None)
self._addSelectGameSubSubMenu(games[n:n+d], submenu,
command, variable)
@ -791,12 +791,9 @@ class PysolMenubar(PysolMenubarActions):
gi = games[i]
columnbreak = i > 0 and (i % cb) == 0
if short_name:
label = _(gi.short_name)
label = gi.short_name
else:
label = _(gi.name)
## menu.add_radiobutton(command=command, variable=variable,
## columnbreak=columnbreak,
## value=gi.id, label=label, name=None)
label = gi.name
# optimized by inlining
menu.tk.call((menu._w, 'add', 'radiobutton') +
menu._options({'command': command,
@ -810,7 +807,7 @@ class PysolMenubar(PysolMenubarActions):
if len(games) == 0:
menu.add_radiobutton(label='<none>', name=None, state='disabled')
elif len(games) > self.__cb_max*4:
games.sort(lambda a, b: cmp(_(a.name), _(b.name)))
games.sort(lambda a, b: cmp(a.name, b.name))
self._addSelectAllGameSubMenu(games, menu,
command=self.mSelectGame,
variable=self.tkopt.gameid)

View file

@ -68,7 +68,6 @@ class SelectGameNode(SelectDialogTreeNode):
# key/value pairs
for id, name in self.select_func:
if id and name:
name = _(name) # name of game
node = SelectGameLeaf(self.tree, self, name, key=id)
contents.append(node)
else:
@ -77,12 +76,10 @@ class SelectGameNode(SelectDialogTreeNode):
# All games
##name = '%s (%s)' % (gi.name, CSI.TYPE_NAME[gi.category])
name = gi.name
name = _(name) # name of game
node = SelectGameLeaf(self.tree, self, name, key=gi.id)
contents.append(node)
elif gi and self.select_func(gi):
name = gi.name
name = _(name) # name of game
node = SelectGameLeaf(self.tree, self, name, key=gi.id)
contents.append(node)
return contents or self.tree.data.no_games
@ -110,8 +107,6 @@ class SelectGameData(SelectDialogTreeData):
for name, select_func in data:
if name is None or not filter(select_func, self.all_games_gi):
continue
name = _(name)
name = name.replace("&", "")
gg.append(SelectGameNode(None, name, select_func))
g.append(gg)
select_mahjongg_game = lambda gi: gi.si.game_type == GI.GT_MAHJONGG
@ -142,7 +137,6 @@ class SelectGameData(SelectDialogTreeData):
select_func = lambda gi, games=games: gi.id in games
if name is None or not filter(select_func, self.all_games_gi):
continue
name = _(name)
gg.append(SelectGameNode(None, name, select_func))
if 1 and gg:
s_by_compatibility = SelectGameNode(None, _("by Compatibility"),
@ -554,8 +548,7 @@ class SelectGameDialogWithPreview(SelectGameDialog):
def updateInfo(self, gameid):
gi = self.app.gdb.get(gameid)
# info
name = _(gi.name)
altnames = '\n'.join([_(n) for n in gi.altnames])
altnames = '\n'.join(gi.altnames)
category = _(CSI.TYPE[gi.category])
type = ''
if gi.si.game_type in GI.TYPE_NAMES:

View file

@ -77,7 +77,6 @@ class SolverDialog(MfxDialog):
gamenames = ['']
for id in games:
name = app.getGameTitleName(id)
name = _(name)
gamenames.append(name)
self.games[name] = id
gamenames.sort()
@ -234,7 +233,6 @@ class SolverDialog(MfxDialog):
def connectGame(self, game):
name = self.app.getGameTitleName(game.id)
name = _(name)
if name in self.gamenames:
self.start_button.config(state='normal')
i = self.gamenames.index(name)

View file

@ -431,7 +431,6 @@ class CanvasFormatter(PysolStatsFormatter):
if not player or not prev_games:
return 0
for result in self.getLogResults(player, prev_games):
result[0] = _(result[0]) # game name
s = "%-25s %-20s %-17s %s" % tuple(result[:4])
id = self.canvas.create_text(1, y, text=s, anchor="nw",
font=self.font, fill=self.fg)

View file

@ -16,6 +16,9 @@ rules_dir = os.path.normpath(os.path.join(pysollib_path, 'data/html/rules'))
#pprint(sys.path)
#print rules_dir
from pysollib.init import fix_gettext
fix_gettext()
import pysollib.games
import pysollib.games.special
import pysollib.games.ultra