mirror of
https://github.com/shlomif/PySolFC.git
synced 2025-04-05 00:02:29 -04:00
+ added config-file option `translate_game_names'
+ added accelerator ctrl-x: `Hold and quit' * fixed games `Matriarchy', `Grandfather', `Bristol', `Chessboard', Twenty, `Q.C.' * improved MfxScrolledCanvas * improved hint * fixed SelectTileDialogWithPreview git-svn-id: file:///home/shlomif/Backup/svn-dumps/PySolFC/svnsync-repos/pysolfc/PySolFC/trunk@194 efabe8c0-fbe8-4139-b769-b5e6d273206e
This commit is contained in:
parent
ebb552c135
commit
46a2191011
21 changed files with 153 additions and 88 deletions
|
@ -550,7 +550,7 @@ class Application:
|
||||||
if self.opt.save_games_geometry and not self.opt.wm_maximized:
|
if self.opt.save_games_geometry and not self.opt.wm_maximized:
|
||||||
w = self.canvas.winfo_width()
|
w = self.canvas.winfo_width()
|
||||||
h = self.canvas.winfo_height()
|
h = self.canvas.winfo_height()
|
||||||
geom = (w-2, h-2) # XXX: subtract canvas borderwidth
|
geom = (w, h)
|
||||||
self.opt.games_geometry[self.game.id] = geom
|
self.opt.games_geometry[self.game.id] = geom
|
||||||
self.freeGame()
|
self.freeGame()
|
||||||
#
|
#
|
||||||
|
@ -1056,7 +1056,10 @@ Please select a %s type %s.
|
||||||
def loadStatistics(self):
|
def loadStatistics(self):
|
||||||
if not os.path.exists(self.fn.stats):
|
if not os.path.exists(self.fn.stats):
|
||||||
return
|
return
|
||||||
|
import time
|
||||||
|
t = time.time()
|
||||||
stats = unpickle(self.fn.stats)
|
stats = unpickle(self.fn.stats)
|
||||||
|
print 'loadStatistics', time.time()-t
|
||||||
if stats:
|
if stats:
|
||||||
##print "loaded:", stats.__dict__
|
##print "loaded:", stats.__dict__
|
||||||
self.stats.__dict__.update(stats.__dict__)
|
self.stats.__dict__.update(stats.__dict__)
|
||||||
|
@ -1082,7 +1085,10 @@ Please select a %s type %s.
|
||||||
self.opt.save(self.fn.opt_cfg)
|
self.opt.save(self.fn.opt_cfg)
|
||||||
|
|
||||||
def saveStatistics(self):
|
def saveStatistics(self):
|
||||||
|
import time
|
||||||
|
t = time.time()
|
||||||
self.__saveObject(self.stats, self.fn.stats)
|
self.__saveObject(self.stats, self.fn.stats)
|
||||||
|
print 'saveStatistics', time.time()-t
|
||||||
|
|
||||||
def saveComments(self):
|
def saveComments(self):
|
||||||
self.__saveObject(self.comments, self.fn.comments)
|
self.__saveObject(self.comments, self.fn.comments)
|
||||||
|
|
|
@ -46,7 +46,7 @@ from mfxutil import Pickler, Unpickler, UnpicklingError
|
||||||
from mfxutil import Image, ImageTk
|
from mfxutil import Image, ImageTk
|
||||||
from mfxutil import destruct, Struct, SubclassResponsibility
|
from mfxutil import destruct, Struct, SubclassResponsibility
|
||||||
from mfxutil import uclock, usleep
|
from mfxutil import uclock, usleep
|
||||||
from mfxutil import format_time
|
from mfxutil import format_time, print_err
|
||||||
from settings import PACKAGE, TITLE, TOOLKIT, TOP_TITLE
|
from settings import PACKAGE, TITLE, TOOLKIT, TOP_TITLE
|
||||||
from settings import VERSION, VERSION_TUPLE
|
from settings import VERSION, VERSION_TUPLE
|
||||||
from settings import DEBUG
|
from settings import DEBUG
|
||||||
|
@ -220,8 +220,9 @@ class Game:
|
||||||
for stack in self.s.foundations:
|
for stack in self.s.foundations:
|
||||||
ncards += stack.cap.max_cards
|
ncards += stack.cap.max_cards
|
||||||
if ncards != self.gameinfo.ncards:
|
if ncards != self.gameinfo.ncards:
|
||||||
print 'WARNING: invalid sum of foundations.max_cards:', \
|
print_err('invalid sum of foundations.max_cards: '
|
||||||
class_name, ncards, self.gameinfo.ncards
|
'%s: %s %s' % (class_name, ncards, self.gameinfo.ncards),
|
||||||
|
2)
|
||||||
if self.s.rows:
|
if self.s.rows:
|
||||||
from stack import AC_RowStack, UD_AC_RowStack, \
|
from stack import AC_RowStack, UD_AC_RowStack, \
|
||||||
SS_RowStack, UD_SS_RowStack, \
|
SS_RowStack, UD_SS_RowStack, \
|
||||||
|
@ -243,20 +244,20 @@ class Game:
|
||||||
self._shallHighlightMatch_RKW)),):
|
self._shallHighlightMatch_RKW)),):
|
||||||
if isinstance(r, c):
|
if isinstance(r, c):
|
||||||
if self.shallHighlightMatch not in f:
|
if self.shallHighlightMatch not in f:
|
||||||
print 'WARNING: shallHighlightMatch is not valid:', \
|
print_err('shallHighlightMatch is not valid: '
|
||||||
class_name, r.__class__
|
' %s, %s' % (class_name, r.__class__), 2)
|
||||||
if r.cap.mod == 13 and self.shallHighlightMatch != f[1]:
|
if r.cap.mod == 13 and self.shallHighlightMatch != f[1]:
|
||||||
print 'WARNING: shallHighlightMatch is not valid (wrap):', \
|
print_err('shallHighlightMatch is not valid (wrap): '
|
||||||
class_name, r.__class__
|
' %s, %s' % (class_name, r.__class__), 2)
|
||||||
break
|
break
|
||||||
if self.s.talon.max_rounds > 1 and \
|
if self.s.talon.max_rounds > 1 and \
|
||||||
self.s.talon.texts.rounds is None:
|
self.s.talon.texts.rounds is None:
|
||||||
print 'WARNING: max_rounds > 1, but talon.texts.rounds is None:', \
|
print_err('max_rounds > 1, but talon.texts.rounds is None: '
|
||||||
class_name
|
'%s' % class_name, 2)
|
||||||
elif self.s.talon.max_rounds <= 1 and \
|
elif self.s.talon.max_rounds <= 1 and \
|
||||||
self.s.talon.texts.rounds is not None:
|
self.s.talon.texts.rounds is not None:
|
||||||
print 'WARNING: max_rounds <= 1, but talon.texts.rounds is not None:', \
|
print_err('max_rounds <= 1, but talon.texts.rounds is not None: '
|
||||||
class_name
|
'%s' % class_name, 2)
|
||||||
|
|
||||||
|
|
||||||
def initBindings(self):
|
def initBindings(self):
|
||||||
|
|
|
@ -38,9 +38,9 @@
|
||||||
import imp
|
import imp
|
||||||
|
|
||||||
# PySol imports
|
# PySol imports
|
||||||
from mfxutil import Struct
|
from mfxutil import Struct, print_err
|
||||||
from resource import CSI
|
from resource import CSI
|
||||||
from settings import CHECK_GAMES
|
import settings
|
||||||
|
|
||||||
|
|
||||||
# /***********************************************************************
|
# /***********************************************************************
|
||||||
|
@ -411,20 +411,33 @@ class GameInfo(Struct):
|
||||||
rules_filename=None,
|
rules_filename=None,
|
||||||
):
|
):
|
||||||
#
|
#
|
||||||
|
def to_unicode(s):
|
||||||
|
if isinstance(s, unicode):
|
||||||
|
return s
|
||||||
|
try:
|
||||||
|
s = unicode(s, 'utf-8')
|
||||||
|
except UnicodeDecodeError, err:
|
||||||
|
print_err(err)
|
||||||
|
s = unicode(s, 'utf-8', 'ignore')
|
||||||
|
return s
|
||||||
ncards = decks * (len(suits) * len(ranks) + len(trumps))
|
ncards = decks * (len(suits) * len(ranks) + len(trumps))
|
||||||
game_flags = game_type & ~1023
|
game_flags = game_type & ~1023
|
||||||
game_type = game_type & 1023
|
game_type = game_type & 1023
|
||||||
|
name = to_unicode(name)
|
||||||
en_name = name # for app.getGameRulesFilename
|
en_name = name # for app.getGameRulesFilename
|
||||||
if not isinstance(name, unicode):
|
if settings.TRANSLATE_GAME_NAMES:
|
||||||
en_name = unicode(name, 'utf-8')
|
name = _(name)
|
||||||
name = _(name)
|
|
||||||
if not short_name:
|
if not short_name:
|
||||||
short_name = name
|
short_name = name
|
||||||
else:
|
else:
|
||||||
short_name = _(short_name)
|
short_name = to_unicode(short_name)
|
||||||
|
if settings.TRANSLATE_GAME_NAMES:
|
||||||
|
short_name = _(short_name)
|
||||||
if isinstance(altnames, basestring):
|
if isinstance(altnames, basestring):
|
||||||
altnames = (altnames,)
|
altnames = (altnames,)
|
||||||
altnames = [_(n) for n in altnames]
|
altnames = [to_unicode(n) for n in altnames]
|
||||||
|
if settings.TRANSLATE_GAME_NAMES:
|
||||||
|
altnames = [_(n) for n in altnames]
|
||||||
#
|
#
|
||||||
if not (1 <= category <= 9):
|
if not (1 <= category <= 9):
|
||||||
if game_type == GI.GT_HANAFUDA:
|
if game_type == GI.GT_HANAFUDA:
|
||||||
|
@ -537,7 +550,7 @@ class GameManager:
|
||||||
##print gi.id, gi.short_name.encode('utf-8')
|
##print gi.id, gi.short_name.encode('utf-8')
|
||||||
if not isinstance(gi, GameInfo):
|
if not isinstance(gi, GameInfo):
|
||||||
raise GameInfoException("wrong GameInfo class")
|
raise GameInfoException("wrong GameInfo class")
|
||||||
if self.check_game and CHECK_GAMES:
|
if self.check_game and settings.CHECK_GAMES:
|
||||||
self._check_game(gi)
|
self._check_game(gi)
|
||||||
##if 0 and gi.si.game_flags & GI.GT_XORIGINAL:
|
##if 0 and gi.si.game_flags & GI.GT_XORIGINAL:
|
||||||
## return
|
## return
|
||||||
|
|
|
@ -96,7 +96,7 @@ class StreetsAndAlleys(Game):
|
||||||
x = x1
|
x = x1
|
||||||
for i in range(4):
|
for i in range(4):
|
||||||
s.foundations.append(self.Foundation_Class(x, y, self, suit=i, max_move=0))
|
s.foundations.append(self.Foundation_Class(x, y, self, suit=i, max_move=0))
|
||||||
y = y + l.YS
|
y += l.YS
|
||||||
if texts:
|
if texts:
|
||||||
tx, ty, ta, tf = l.getTextAttr(None, "ss")
|
tx, ty, ta, tf = l.getTextAttr(None, "ss")
|
||||||
tx, ty = x+tx, y-l.YS+ty
|
tx, ty = x+tx, y-l.YS+ty
|
||||||
|
@ -109,7 +109,7 @@ class StreetsAndAlleys(Game):
|
||||||
stack = self.RowStack_Class(x, y, self)
|
stack = self.RowStack_Class(x, y, self)
|
||||||
stack.CARD_XOFFSET, stack.CARD_YOFFSET = l.XOFFSET, 0
|
stack.CARD_XOFFSET, stack.CARD_YOFFSET = l.XOFFSET, 0
|
||||||
s.rows.append(stack)
|
s.rows.append(stack)
|
||||||
y = y + l.YS
|
y += l.YS
|
||||||
x, y = self.width - l.XS, self.height - l.YS
|
x, y = self.width - l.XS, self.height - l.YS
|
||||||
s.talon = InitialDealTalonStack(x, y, self)
|
s.talon = InitialDealTalonStack(x, y, self)
|
||||||
if reserves:
|
if reserves:
|
||||||
|
@ -384,20 +384,17 @@ class CastlesEnd(Bastion):
|
||||||
|
|
||||||
class Chessboard_Foundation(SS_FoundationStack):
|
class Chessboard_Foundation(SS_FoundationStack):
|
||||||
def __init__(self, x, y, game, suit, **cap):
|
def __init__(self, x, y, game, suit, **cap):
|
||||||
kwdefault(cap, mod=13, min_cards=1, max_move=0)
|
kwdefault(cap, mod=13, min_cards=1, max_move=0, base_rank=ANY_RANK)
|
||||||
SS_FoundationStack.__init__(self, x, y, game, suit, **cap)
|
SS_FoundationStack.__init__(self, x, y, game, suit, **cap)
|
||||||
|
|
||||||
def acceptsCards(self, from_stack, cards):
|
def acceptsCards(self, from_stack, cards):
|
||||||
|
if not SS_FoundationStack.acceptsCards(self, from_stack, cards):
|
||||||
|
return False
|
||||||
if not self.cards:
|
if not self.cards:
|
||||||
if len(cards) != 1 or not cards[0].face_up:
|
|
||||||
return False
|
|
||||||
if cards[0].suit != self.cap.base_suit:
|
|
||||||
return False
|
|
||||||
for s in self.game.s.foundations:
|
for s in self.game.s.foundations:
|
||||||
if s.cards:
|
if s.cards:
|
||||||
return cards[0].rank == s.cards[0].rank
|
return cards[0].rank == s.cards[0].rank
|
||||||
return True
|
return True
|
||||||
return SS_FoundationStack.acceptsCards(self, from_stack, cards)
|
|
||||||
|
|
||||||
|
|
||||||
class Chessboard_RowStack(UD_SS_RowStack):
|
class Chessboard_RowStack(UD_SS_RowStack):
|
||||||
|
|
|
@ -76,14 +76,13 @@ class Bristol_Talon(TalonStack):
|
||||||
|
|
||||||
|
|
||||||
class Bristol(Game):
|
class Bristol(Game):
|
||||||
Layout_Method = Layout.klondikeLayout
|
|
||||||
Hint_Class = Bristol_Hint
|
Hint_Class = Bristol_Hint
|
||||||
|
|
||||||
#
|
#
|
||||||
# game layout
|
# game layout
|
||||||
#
|
#
|
||||||
|
|
||||||
def createGame(self, **layout):
|
def createGame(self):
|
||||||
# create layout
|
# create layout
|
||||||
l, s = Layout(self), self.s
|
l, s = Layout(self), self.s
|
||||||
|
|
||||||
|
@ -94,7 +93,7 @@ class Bristol(Game):
|
||||||
x, y, = l.XM + 3*l.XS, l.YM
|
x, y, = l.XM + 3*l.XS, l.YM
|
||||||
for i in range(4):
|
for i in range(4):
|
||||||
s.foundations.append(RK_FoundationStack(x, y, self, max_move=0))
|
s.foundations.append(RK_FoundationStack(x, y, self, max_move=0))
|
||||||
x = x + l.XS
|
x += l.XS
|
||||||
for i in range(2):
|
for i in range(2):
|
||||||
y = l.YM + (i*2+3)*l.YS/2
|
y = l.YM + (i*2+3)*l.YS/2
|
||||||
for j in range(4):
|
for j in range(4):
|
||||||
|
@ -105,9 +104,12 @@ class Bristol(Game):
|
||||||
x, y, = l.XM + 3*l.XS, l.YM + 4*l.YS
|
x, y, = l.XM + 3*l.XS, l.YM + 4*l.YS
|
||||||
s.talon = Bristol_Talon(x, y, self)
|
s.talon = Bristol_Talon(x, y, self)
|
||||||
l.createText(s.talon, "sw")
|
l.createText(s.talon, "sw")
|
||||||
|
x += l.XS
|
||||||
for i in range(3):
|
for i in range(3):
|
||||||
x = x + l.XS
|
stack = WasteStack(x, y, self)
|
||||||
s.reserves.append(ReserveStack(x, y, self, max_accept=0, max_cards=UNLIMITED_CARDS))
|
l.createText(stack, 'n')
|
||||||
|
s.reserves.append(stack)
|
||||||
|
x += l.XS
|
||||||
|
|
||||||
# define stack-groups
|
# define stack-groups
|
||||||
self.sg.openstacks = s.foundations + s.rows
|
self.sg.openstacks = s.foundations + s.rows
|
||||||
|
@ -125,14 +127,14 @@ class Bristol(Game):
|
||||||
for c in cards[:24]: # search the first 24 cards only
|
for c in cards[:24]: # search the first 24 cards only
|
||||||
if c.rank == KING:
|
if c.rank == KING:
|
||||||
kings.append(i)
|
kings.append(i)
|
||||||
i = i + 1
|
i += 1
|
||||||
for i in kings:
|
for i in kings:
|
||||||
j = i % n # j = card index of rowstack bottom
|
j = i % n # j = card index of rowstack bottom
|
||||||
while j < i:
|
while j < i:
|
||||||
if cards[j].rank != KING:
|
if cards[j].rank != KING:
|
||||||
cards[j], cards[i] = cards[i], cards[j]
|
cards[j], cards[i] = cards[i], cards[j]
|
||||||
break
|
break
|
||||||
j = j + n
|
j += n
|
||||||
cards.reverse()
|
cards.reverse()
|
||||||
return cards
|
return cards
|
||||||
|
|
||||||
|
|
|
@ -884,34 +884,35 @@ class Q_C_(Klondike):
|
||||||
self.s.talon.dealRow(frames=0)
|
self.s.talon.dealRow(frames=0)
|
||||||
self.startDealSample()
|
self.startDealSample()
|
||||||
self.s.talon.dealRow()
|
self.s.talon.dealRow()
|
||||||
self.s.talon.dealCards() # deal first card to WasteStack
|
while self.s.talon.cards:
|
||||||
self.fillAll()
|
self.s.talon.dealCards() # deal first card to WasteStack
|
||||||
|
if not self.fillWaste():
|
||||||
|
break
|
||||||
|
|
||||||
def fillOne(self, stack):
|
def fillWaste(self):
|
||||||
if stack.cards:
|
waste = self.s.waste
|
||||||
c = stack.cards[-1]
|
if waste.cards:
|
||||||
|
c = waste.cards[-1]
|
||||||
for f in self.s.foundations:
|
for f in self.s.foundations:
|
||||||
if f.acceptsCards(stack, [c]):
|
if f.acceptsCards(self.s.waste, [c]):
|
||||||
stack.moveMove(1, f)
|
waste.moveMove(1, f)
|
||||||
return 1
|
return True
|
||||||
return 0
|
return False
|
||||||
|
|
||||||
def fillAll(self):
|
def fillStack(self, stack=None):
|
||||||
# fill
|
waste = self.s.waste
|
||||||
if not self.s.waste.cards and self.s.talon.cards:
|
while True:
|
||||||
self.s.talon.dealCards()
|
if not self.fillWaste():
|
||||||
for stack in self.s.rows:
|
break
|
||||||
if not stack.cards and self.s.waste.cards:
|
if stack in self.s.rows and not stack.cards:
|
||||||
self.s.waste.moveMove(1, stack)
|
if not waste.cards:
|
||||||
# move to foundations
|
while self.s.talon.cards:
|
||||||
if self.fillOne(self.s.waste):
|
self.s.talon.dealCards()
|
||||||
self.fillAll()
|
if not self.fillWaste():
|
||||||
for stack in self.s.rows:
|
break
|
||||||
if self.fillOne(stack):
|
if waste.cards:
|
||||||
self.fillAll()
|
waste.moveMove(1, stack)
|
||||||
|
|
||||||
def fillStack(self, stack):
|
|
||||||
self.fillAll()
|
|
||||||
|
|
||||||
shallHighlightMatch = Game._shallHighlightMatch_SS
|
shallHighlightMatch = Game._shallHighlightMatch_SS
|
||||||
|
|
||||||
|
|
|
@ -94,6 +94,9 @@ class Matriarchy_Talon(WasteTalonStack):
|
||||||
n = 0
|
n = 0
|
||||||
update_flags = 1
|
update_flags = 1
|
||||||
# deal
|
# deal
|
||||||
|
if self.cards:
|
||||||
|
if sound and not self.game.demo:
|
||||||
|
self.game.playSample("dealwaste")
|
||||||
while n < ncards:
|
while n < ncards:
|
||||||
# from self to waste
|
# from self to waste
|
||||||
while n < ncards:
|
while n < ncards:
|
||||||
|
@ -108,6 +111,8 @@ class Matriarchy_Talon(WasteTalonStack):
|
||||||
if n < ncards and len(waste.cards) > 0:
|
if n < ncards and len(waste.cards) > 0:
|
||||||
assert len(self.cards) == 0
|
assert len(self.cards) == 0
|
||||||
assert self.round < self.max_rounds or update_flags == 0
|
assert self.round < self.max_rounds or update_flags == 0
|
||||||
|
if sound:
|
||||||
|
self.game.playSample("turnwaste", priority=20)
|
||||||
self.game.turnStackMove(waste, self)
|
self.game.turnStackMove(waste, self)
|
||||||
if update_flags:
|
if update_flags:
|
||||||
self.game.nextRoundMove(self)
|
self.game.nextRoundMove(self)
|
||||||
|
|
|
@ -564,9 +564,11 @@ class NewBritishConstitution(BritishConstitution):
|
||||||
|
|
||||||
class Twenty_RowStack(BasicRowStack):
|
class Twenty_RowStack(BasicRowStack):
|
||||||
def acceptsCards(self, from_stack, cards):
|
def acceptsCards(self, from_stack, cards):
|
||||||
#if not BasicRowStack.acceptsCards(self, from_stack, cards):
|
if not BasicRowStack.acceptsCards(self, from_stack, cards):
|
||||||
# return False
|
return False
|
||||||
return len(self.cards) == 0
|
return len(self.cards) == 0
|
||||||
|
def getHelp(self):
|
||||||
|
return _('Tableau. Empty piles can be filled with any card.')
|
||||||
|
|
||||||
class Twenty(Game):
|
class Twenty(Game):
|
||||||
def createGame(self):
|
def createGame(self):
|
||||||
|
@ -574,7 +576,7 @@ class Twenty(Game):
|
||||||
l, s = Layout(self), self.s
|
l, s = Layout(self), self.s
|
||||||
|
|
||||||
# set window
|
# set window
|
||||||
self.setSize(l.XM+10*l.XS, l.YM+3*l.XS+10*l.YOFFSET)
|
self.setSize(l.XM+10*l.XS, l.YM+3*l.YS+10*l.YOFFSET)
|
||||||
|
|
||||||
# create stacks
|
# create stacks
|
||||||
x, y = l.XM, l.YM
|
x, y = l.XM, l.YM
|
||||||
|
@ -589,10 +591,11 @@ class Twenty(Game):
|
||||||
base_rank=KING, dir=-1))
|
base_rank=KING, dir=-1))
|
||||||
x += l.XS
|
x += l.XS
|
||||||
|
|
||||||
for y in (l.YM+l.YS, l.YM+2*l.XS+5*l.YOFFSET):
|
for y in (l.YM+l.YS, l.YM+2*l.YS+5*l.YOFFSET):
|
||||||
x = l.XM
|
x = l.XM
|
||||||
for i in range(10):
|
for i in range(10):
|
||||||
s.rows.append(Twenty_RowStack(x, y, self))
|
s.rows.append(Twenty_RowStack(x, y, self,
|
||||||
|
base_rank=ANY_RANK, max_accept=1))
|
||||||
x += l.XS
|
x += l.XS
|
||||||
|
|
||||||
# define stack-groups
|
# define stack-groups
|
||||||
|
|
|
@ -141,8 +141,8 @@ class Odessa(RussianSolitaire):
|
||||||
# ************************************************************************/
|
# ************************************************************************/
|
||||||
|
|
||||||
class Grandfather_Talon(RedealTalonStack):
|
class Grandfather_Talon(RedealTalonStack):
|
||||||
def redealCards(self, sound=False):
|
def dealCards(self, sound=False):
|
||||||
RedealTalonStack.redealCards(self, sound=sound, shuffle=True)
|
self.redealCards(sound=sound, shuffle=True)
|
||||||
|
|
||||||
class Grandfather(RussianSolitaire):
|
class Grandfather(RussianSolitaire):
|
||||||
Talon_Class = StackWrapper(Grandfather_Talon, max_rounds=3)
|
Talon_Class = StackWrapper(Grandfather_Talon, max_rounds=3)
|
||||||
|
@ -152,9 +152,17 @@ class Grandfather(RussianSolitaire):
|
||||||
l.createRoundText(self.s.talon, 'nn')
|
l.createRoundText(self.s.talon, 'nn')
|
||||||
|
|
||||||
def startGame(self):
|
def startGame(self):
|
||||||
|
frames = 0
|
||||||
|
sound = False
|
||||||
for i, j in ((1,7),(1,6),(2,6),(2,5),(3,5),(3,4)):
|
for i, j in ((1,7),(1,6),(2,6),(2,5),(3,5),(3,4)):
|
||||||
self.s.talon.dealRowAvail(rows=self.s.rows[i:j], flip=0, frames=0)
|
if len(self.s.talon.cards) <= j-i:
|
||||||
self.startDealSample()
|
frames = -1
|
||||||
|
sound = True
|
||||||
|
self.startDealSample()
|
||||||
|
self.s.talon.dealRowAvail(rows=self.s.rows[i:j],
|
||||||
|
flip=0, frames=frames)
|
||||||
|
if not sound:
|
||||||
|
self.startDealSample()
|
||||||
self.s.talon.dealRowAvail()
|
self.s.talon.dealRowAvail()
|
||||||
for i in range(4):
|
for i in range(4):
|
||||||
self.s.talon.dealRowAvail(rows=self.s.rows[1:])
|
self.s.talon.dealRowAvail(rows=self.s.rows[1:])
|
||||||
|
|
|
@ -463,11 +463,11 @@ class DefaultHint(AbstractHint):
|
||||||
self.step030(game.s.foundations, game.s.rows, game.sg.dropstacks)
|
self.step030(game.s.foundations, game.s.rows, game.sg.dropstacks)
|
||||||
|
|
||||||
# 4) try if we can move a card from a RowStack to a ReserveStack
|
# 4) try if we can move a card from a RowStack to a ReserveStack
|
||||||
if not self.hints:
|
if not self.hints or self.level == 0:
|
||||||
self.step040(game.s.rows, game.sg.reservestacks)
|
self.step040(game.s.rows, game.sg.reservestacks)
|
||||||
|
|
||||||
# 5) try if we should move a card from a ReserveStack to a RowStack
|
# 5) try if we should move a card from a ReserveStack to a RowStack
|
||||||
if not self.hints:
|
if not self.hints or self.level == 0:
|
||||||
self.step050(game.sg.reservestacks, game.s.rows)
|
self.step050(game.sg.reservestacks, game.s.rows)
|
||||||
|
|
||||||
# Don't be too clever and give up ;-)
|
# Don't be too clever and give up ;-)
|
||||||
|
@ -488,7 +488,7 @@ class DefaultHint(AbstractHint):
|
||||||
score, color = 0, None
|
score, color = 0, None
|
||||||
score, color = self._getDropCardScore(score, color, r, t, ncards)
|
score, color = self._getDropCardScore(score, color, r, t, ncards)
|
||||||
self.addHint(score, ncards, r, t, color)
|
self.addHint(score, ncards, r, t, color)
|
||||||
if score >= 90000:
|
if score >= 90000 and self.level >= 1:
|
||||||
break
|
break
|
||||||
# 1b) try if we can move cards to one of the RowStacks
|
# 1b) try if we can move cards to one of the RowStacks
|
||||||
for pile in self.step010b_getPiles(r):
|
for pile in self.step010b_getPiles(r):
|
||||||
|
|
|
@ -106,6 +106,8 @@ def print_err(s, level=1):
|
||||||
ss = PACKAGE+': ERROR:'
|
ss = PACKAGE+': ERROR:'
|
||||||
elif level == 1:
|
elif level == 1:
|
||||||
ss = PACKAGE+': WARNING:'
|
ss = PACKAGE+': WARNING:'
|
||||||
|
elif level == 2:
|
||||||
|
ss = PACKAGE+': DEBUG WARNING:'
|
||||||
print >> sys.stderr, ss, s.encode(locale.getpreferredencoding())
|
print >> sys.stderr, ss, s.encode(locale.getpreferredencoding())
|
||||||
sys.stderr.flush()
|
sys.stderr.flush()
|
||||||
|
|
||||||
|
@ -165,7 +167,9 @@ def win32_gethomedir():
|
||||||
return hd
|
return hd
|
||||||
hd = os.path.expanduser('~')
|
hd = os.path.expanduser('~')
|
||||||
if hd == '~': # win9x
|
if hd == '~': # win9x
|
||||||
return os.path.abspath('/')
|
hd = os.path.abspath('/windows/Application Data')
|
||||||
|
if not os.path.exists(hd):
|
||||||
|
hd = os.path.abspath('/')
|
||||||
return hd
|
return hd
|
||||||
|
|
||||||
# /***********************************************************************
|
# /***********************************************************************
|
||||||
|
|
|
@ -25,9 +25,9 @@ import traceback
|
||||||
|
|
||||||
# PySol imports
|
# PySol imports
|
||||||
from mfxutil import print_err
|
from mfxutil import print_err
|
||||||
from settings import VERSION_TUPLE, WIN_SYSTEM
|
|
||||||
from resource import CSI
|
from resource import CSI
|
||||||
from configobj import configobj, validate
|
from configobj import configobj, validate
|
||||||
|
import settings
|
||||||
|
|
||||||
# Toolkit imports
|
# Toolkit imports
|
||||||
from pysoltk import TOOLBAR_BUTTONS
|
from pysoltk import TOOLBAR_BUTTONS
|
||||||
|
@ -97,6 +97,7 @@ tabletile_name = string
|
||||||
recent_gameid = int_list
|
recent_gameid = int_list
|
||||||
favorite_gameid = int_list
|
favorite_gameid = int_list
|
||||||
visible_buttons = string_list
|
visible_buttons = string_list
|
||||||
|
translate_game_names = boolean
|
||||||
|
|
||||||
[sound_samples]
|
[sound_samples]
|
||||||
move = boolean
|
move = boolean
|
||||||
|
@ -219,6 +220,7 @@ class Options:
|
||||||
('sound_sample_volume', 'int'),
|
('sound_sample_volume', 'int'),
|
||||||
('sound_music_volume', 'int'),
|
('sound_music_volume', 'int'),
|
||||||
('tabletile_name', 'str'),
|
('tabletile_name', 'str'),
|
||||||
|
('translate_game_names', 'bool'),
|
||||||
#('toolbar_vars', 'list'),
|
#('toolbar_vars', 'list'),
|
||||||
#('recent_gameid', 'list'),
|
#('recent_gameid', 'list'),
|
||||||
#('favorite_gameid', 'list'),
|
#('favorite_gameid', 'list'),
|
||||||
|
@ -229,7 +231,7 @@ class Options:
|
||||||
self._config = None # configobj.ConfigObj instance
|
self._config = None # configobj.ConfigObj instance
|
||||||
self._config_encoding = 'utf-8'
|
self._config_encoding = 'utf-8'
|
||||||
|
|
||||||
self.version_tuple = VERSION_TUPLE # XXX
|
self.version_tuple = settings.VERSION_TUPLE # XXX
|
||||||
self.saved = 0 # XXX
|
self.saved = 0 # XXX
|
||||||
# options menu:
|
# options menu:
|
||||||
self.player = _("Unknown")
|
self.player = _("Unknown")
|
||||||
|
@ -277,6 +279,7 @@ class Options:
|
||||||
self.mouse_type = 'drag-n-drop' # or 'sticky-mouse' or 'point-n-click'
|
self.mouse_type = 'drag-n-drop' # or 'sticky-mouse' or 'point-n-click'
|
||||||
self.mouse_undo = False # use mouse for undo/redo
|
self.mouse_undo = False # use mouse for undo/redo
|
||||||
self.negative_bottom = True
|
self.negative_bottom = True
|
||||||
|
self.translate_game_names = True
|
||||||
# sound
|
# sound
|
||||||
self.sound = True
|
self.sound = True
|
||||||
self.sound_mode = 1
|
self.sound_mode = 1
|
||||||
|
@ -354,6 +357,7 @@ class Options:
|
||||||
self.dragcursor = True
|
self.dragcursor = True
|
||||||
|
|
||||||
def setDefaults(self, top=None):
|
def setDefaults(self, top=None):
|
||||||
|
WIN_SYSTEM = settings.WIN_SYSTEM
|
||||||
# toolbar
|
# toolbar
|
||||||
#if WIN_SYSTEM == 'win32':
|
#if WIN_SYSTEM == 'win32':
|
||||||
# self.toolbar_style = 'crystal'
|
# self.toolbar_style = 'crystal'
|
||||||
|
@ -494,6 +498,7 @@ class Options:
|
||||||
|
|
||||||
def load(self, filename):
|
def load(self, filename):
|
||||||
|
|
||||||
|
# create ConfigObj instance
|
||||||
try:
|
try:
|
||||||
config = configobj.ConfigObj(filename,
|
config = configobj.ConfigObj(filename,
|
||||||
configspec=configspec,
|
configspec=configspec,
|
||||||
|
@ -504,6 +509,7 @@ class Options:
|
||||||
encoding=self._config_encoding)
|
encoding=self._config_encoding)
|
||||||
self._config = config
|
self._config = config
|
||||||
|
|
||||||
|
# create sections
|
||||||
for section in (
|
for section in (
|
||||||
'general',
|
'general',
|
||||||
'sound_samples',
|
'sound_samples',
|
||||||
|
@ -516,6 +522,7 @@ class Options:
|
||||||
if section not in config:
|
if section not in config:
|
||||||
config[section] = {}
|
config[section] = {}
|
||||||
|
|
||||||
|
# add initial comment
|
||||||
if not os.path.exists(filename):
|
if not os.path.exists(filename):
|
||||||
config.initial_comment = ['-*- coding: %s -*-' %
|
config.initial_comment = ['-*- coding: %s -*-' %
|
||||||
self._config_encoding]
|
self._config_encoding]
|
||||||
|
@ -544,6 +551,8 @@ class Options:
|
||||||
elif val is not None:
|
elif val is not None:
|
||||||
setattr(self, key, val)
|
setattr(self, key, val)
|
||||||
|
|
||||||
|
settings.TRANSLATE_GAME_NAMES = self.translate_game_names
|
||||||
|
|
||||||
recent_gameid = self._getOption('general', 'recent_gameid', 'list')
|
recent_gameid = self._getOption('general', 'recent_gameid', 'list')
|
||||||
if recent_gameid is not None:
|
if recent_gameid is not None:
|
||||||
try:
|
try:
|
||||||
|
|
|
@ -72,6 +72,9 @@ TOP_TITLE = n_('Top 10')
|
||||||
# use menu for select game
|
# use menu for select game
|
||||||
SELECT_GAME_MENU = True
|
SELECT_GAME_MENU = True
|
||||||
|
|
||||||
|
# i18n, see also options.py
|
||||||
|
TRANSLATE_GAME_NAMES = True
|
||||||
|
|
||||||
# debug
|
# debug
|
||||||
DEBUG = 0 # must be integer
|
DEBUG = 0 # must be integer
|
||||||
CHECK_GAMES = False # check duplicated names and classes
|
CHECK_GAMES = False # check duplicated names and classes
|
||||||
|
|
|
@ -48,7 +48,8 @@ class FindCardDialog(Tkinter.Toplevel):
|
||||||
|
|
||||||
def __init__(self, parent, game, dir, size='large'):
|
def __init__(self, parent, game, dir, size='large'):
|
||||||
Tkinter.Toplevel.__init__(self)
|
Tkinter.Toplevel.__init__(self)
|
||||||
self.title(_('Find card'))
|
title = TITLE + ' - ' + _('Find card')
|
||||||
|
self.title(title)
|
||||||
self.wm_resizable(False, False)
|
self.wm_resizable(False, False)
|
||||||
#
|
#
|
||||||
##self.images_dir = dir
|
##self.images_dir = dir
|
||||||
|
|
|
@ -368,7 +368,7 @@ class PysolMenubar(PysolMenubarActions):
|
||||||
menu.add_command(label=n_("&Save"), command=self.mSave, accelerator=m+"S")
|
menu.add_command(label=n_("&Save"), command=self.mSave, accelerator=m+"S")
|
||||||
menu.add_command(label=n_("Save &as..."), command=self.mSaveAs)
|
menu.add_command(label=n_("Save &as..."), command=self.mSaveAs)
|
||||||
menu.add_separator()
|
menu.add_separator()
|
||||||
menu.add_command(label=n_("&Hold and quit"), command=self.mHoldAndQuit)
|
menu.add_command(label=n_("&Hold and quit"), command=self.mHoldAndQuit, accelerator=m+"X")
|
||||||
if WIN_SYSTEM != "aqua":
|
if WIN_SYSTEM != "aqua":
|
||||||
menu.add_command(label=n_("&Quit"), command=self.mQuit, accelerator=m+"Q")
|
menu.add_command(label=n_("&Quit"), command=self.mQuit, accelerator=m+"Q")
|
||||||
|
|
||||||
|
@ -532,6 +532,7 @@ class PysolMenubar(PysolMenubarActions):
|
||||||
self._bindKey(ctrl, "n", self.mNewGameWithNextId)
|
self._bindKey(ctrl, "n", self.mNewGameWithNextId)
|
||||||
self._bindKey(ctrl, "o", self.mOpen)
|
self._bindKey(ctrl, "o", self.mOpen)
|
||||||
self._bindKey(ctrl, "s", self.mSave)
|
self._bindKey(ctrl, "s", self.mSave)
|
||||||
|
self._bindKey(ctrl, "x", self.mHoldAndQuit)
|
||||||
self._bindKey(ctrl, "q", self.mQuit)
|
self._bindKey(ctrl, "q", self.mQuit)
|
||||||
self._bindKey("", "z", self.mUndo)
|
self._bindKey("", "z", self.mUndo)
|
||||||
self._bindKey("", "BackSpace", self.mUndo) # undocumented
|
self._bindKey("", "BackSpace", self.mUndo) # undocumented
|
||||||
|
|
|
@ -192,12 +192,11 @@ class SelectTileDialogWithPreview(MfxDialog):
|
||||||
MfxDialog.mDone(self, button)
|
MfxDialog.mDone(self, button)
|
||||||
|
|
||||||
def updatePreview(self, key):
|
def updatePreview(self, key):
|
||||||
##print key
|
|
||||||
if key == self.preview_key:
|
if key == self.preview_key:
|
||||||
return
|
return
|
||||||
canvas = self.preview.canvas
|
canvas = self.preview.canvas
|
||||||
canvas.deleteAllItems()
|
canvas.deleteAllItems()
|
||||||
if isinstance(key, str):
|
if isinstance(key, basestring):
|
||||||
# solid color
|
# solid color
|
||||||
canvas.config(bg=key)
|
canvas.config(bg=key)
|
||||||
canvas.setTile(None)
|
canvas.setTile(None)
|
||||||
|
|
|
@ -560,10 +560,15 @@ class MfxScrolledCanvas:
|
||||||
width = kw.get("width")
|
width = kw.get("width")
|
||||||
height = kw.get("height")
|
height = kw.get("height")
|
||||||
self.frame = Tile.Frame(self.parent, width=width, height=height)
|
self.frame = Tile.Frame(self.parent, width=width, height=height)
|
||||||
|
|
||||||
def createCanvas(self, kw):
|
def createCanvas(self, kw):
|
||||||
self.canvas = MfxCanvas(self.frame, **kw)
|
bd = kw['bd']
|
||||||
self.canvas.grid(row=0, column=0, sticky="news")
|
kw['bd'] = 0
|
||||||
|
relief = kw['relief']
|
||||||
|
del kw['relief']
|
||||||
|
frame = Tkinter.Frame(self.frame, bd=bd, relief=relief)
|
||||||
|
frame.grid(row=0, column=0, sticky="news")
|
||||||
|
self.canvas = MfxCanvas(frame, **kw)
|
||||||
|
self.canvas.pack(expand=True, fill='both')
|
||||||
def createHbar(self):
|
def createHbar(self):
|
||||||
self.hbar = Tile.Scrollbar(self.frame, takefocus=0,
|
self.hbar = Tile.Scrollbar(self.frame, takefocus=0,
|
||||||
orient="horizontal")
|
orient="horizontal")
|
||||||
|
|
|
@ -51,7 +51,8 @@ class FindCardDialog(Tkinter.Toplevel):
|
||||||
|
|
||||||
def __init__(self, parent, game, dir, size='large'):
|
def __init__(self, parent, game, dir, size='large'):
|
||||||
Tkinter.Toplevel.__init__(self)
|
Tkinter.Toplevel.__init__(self)
|
||||||
self.title(_('Find card'))
|
title = TITLE + ' - ' + _('Find card')
|
||||||
|
self.title(title)
|
||||||
self.wm_resizable(False, False)
|
self.wm_resizable(False, False)
|
||||||
#
|
#
|
||||||
##self.images_dir = dir
|
##self.images_dir = dir
|
||||||
|
|
|
@ -365,7 +365,7 @@ class PysolMenubar(PysolMenubarActions):
|
||||||
menu.add_command(label=n_("&Save"), command=self.mSave, accelerator=m+"S")
|
menu.add_command(label=n_("&Save"), command=self.mSave, accelerator=m+"S")
|
||||||
menu.add_command(label=n_("Save &as..."), command=self.mSaveAs)
|
menu.add_command(label=n_("Save &as..."), command=self.mSaveAs)
|
||||||
menu.add_separator()
|
menu.add_separator()
|
||||||
menu.add_command(label=n_("&Hold and quit"), command=self.mHoldAndQuit)
|
menu.add_command(label=n_("&Hold and quit"), command=self.mHoldAndQuit, accelerator=m+"X")
|
||||||
if WIN_SYSTEM != "aqua":
|
if WIN_SYSTEM != "aqua":
|
||||||
menu.add_command(label=n_("&Quit"), command=self.mQuit, accelerator=m+"Q")
|
menu.add_command(label=n_("&Quit"), command=self.mQuit, accelerator=m+"Q")
|
||||||
|
|
||||||
|
@ -536,6 +536,7 @@ class PysolMenubar(PysolMenubarActions):
|
||||||
self._bindKey(ctrl, "n", self.mNewGameWithNextId)
|
self._bindKey(ctrl, "n", self.mNewGameWithNextId)
|
||||||
self._bindKey(ctrl, "o", self.mOpen)
|
self._bindKey(ctrl, "o", self.mOpen)
|
||||||
self._bindKey(ctrl, "s", self.mSave)
|
self._bindKey(ctrl, "s", self.mSave)
|
||||||
|
self._bindKey(ctrl, "x", self.mHoldAndQuit)
|
||||||
self._bindKey(ctrl, "q", self.mQuit)
|
self._bindKey(ctrl, "q", self.mQuit)
|
||||||
self._bindKey("", "z", self.mUndo)
|
self._bindKey("", "z", self.mUndo)
|
||||||
self._bindKey("", "BackSpace", self.mUndo) # undocumented
|
self._bindKey("", "BackSpace", self.mUndo) # undocumented
|
||||||
|
|
|
@ -196,7 +196,7 @@ class SelectTileDialogWithPreview(MfxDialog):
|
||||||
return
|
return
|
||||||
canvas = self.preview.canvas
|
canvas = self.preview.canvas
|
||||||
canvas.deleteAllItems()
|
canvas.deleteAllItems()
|
||||||
if isinstance(key, str):
|
if isinstance(key, basestring):
|
||||||
# solid color
|
# solid color
|
||||||
canvas.config(bg=key)
|
canvas.config(bg=key)
|
||||||
canvas.setTile(None)
|
canvas.setTile(None)
|
||||||
|
|
|
@ -550,10 +550,15 @@ class MfxScrolledCanvas:
|
||||||
width = kw.get("width")
|
width = kw.get("width")
|
||||||
height = kw.get("height")
|
height = kw.get("height")
|
||||||
self.frame = Tkinter.Frame(self.parent, width=width, height=height)
|
self.frame = Tkinter.Frame(self.parent, width=width, height=height)
|
||||||
|
|
||||||
def createCanvas(self, kw):
|
def createCanvas(self, kw):
|
||||||
self.canvas = MfxCanvas(self.frame, **kw)
|
bd = kw['bd']
|
||||||
self.canvas.grid(row=0, column=0, sticky="news")
|
kw['bd'] = 0
|
||||||
|
relief = kw['relief']
|
||||||
|
del kw['relief']
|
||||||
|
frame = Tkinter.Frame(self.frame, bd=bd, relief=relief)
|
||||||
|
frame.grid(row=0, column=0, sticky="news")
|
||||||
|
self.canvas = MfxCanvas(frame, **kw)
|
||||||
|
self.canvas.pack(expand=True, fill='both')
|
||||||
def createHbar(self):
|
def createHbar(self):
|
||||||
self.hbar = Tkinter.Scrollbar(self.frame, takefocus=0,
|
self.hbar = Tkinter.Scrollbar(self.frame, takefocus=0,
|
||||||
orient="horizontal")
|
orient="horizontal")
|
||||||
|
|
Loading…
Add table
Reference in a new issue