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

* refactored menubar and toolbar imports

* refactored pysolrandom.py; added WHRandom generator
* bugfixes


git-svn-id: https://pysolfc.svn.sourceforge.net/svnroot/pysolfc/PySolFC/trunk@215 39dd0a4e-7c14-0410-91b3-c4f2d318f732
This commit is contained in:
skomoroh 2007-12-28 08:38:51 +00:00
parent 41449f9c3a
commit 1a2ebe7884
16 changed files with 165 additions and 213 deletions

View file

@ -65,6 +65,7 @@ from pysoltk import FontsDialog
from pysoltk import EditTextDialog from pysoltk import EditTextDialog
from pysoltk import create_find_card_dialog from pysoltk import create_find_card_dialog
from pysoltk import create_solver_dialog from pysoltk import create_solver_dialog
from pysoltk import PysolMenubarTk, PysolToolbarTk
from help import help_about, help_html from help import help_about, help_html
@ -72,8 +73,8 @@ from help import help_about, help_html
# // menubar # // menubar
# ************************************************************************/ # ************************************************************************/
class PysolMenubarActions: class PysolMenubar(PysolMenubarTk):
def __init__(self, app, top): def __init__(self, app, top, progress=None):
self.app = app self.app = app
self.top = top self.top = top
self.game = None self.game = None
@ -99,21 +100,7 @@ class PysolMenubarActions:
pause = 0, pause = 0,
custom_game = 0, custom_game = 0,
) )
PysolMenubarTk.__init__(self, app, top, progress)
def connectGame(self, game):
self.game = game
# will get called after connectGame()
def updateRecentGamesMenu(self, gameids):
pass
def updateBookmarkMenuState(self):
pass
# will get called after a new cardset has been loaded
def updateBackgroundImagesMenu(self):
pass
# #
# delegation to Game # delegation to Game
@ -138,12 +125,6 @@ class PysolMenubarActions:
# menu updates # menu updates
# #
def setMenuState(self, state, path):
raise SubclassResponsibility
def setToolbarState(self, state, path):
raise SubclassResponsibility
def _clearMenuState(self): def _clearMenuState(self):
ms = self.menustate ms = self.menustate
for k, v in ms.__dict__.items(): for k, v in ms.__dict__.items():
@ -819,27 +800,22 @@ class PysolMenubarActions:
# // toolbar # // toolbar
# ************************************************************************/ # ************************************************************************/
class PysolToolbarActions: class PysolToolbar(PysolToolbarTk):
def __init__(self): def __init__(self, *args, **kwargs):
self.game = None self.game = None
self.menubar = None PysolToolbarTk.__init__(self, *args, **kwargs)
# #
# public methods # public methods
# #
def connectGame(self, game, menubar): def connectGame(self, game):
self.game = game self.game = game
self.menubar = menubar
# #
# button event handlers - delegate to menubar # button event handlers - delegate to menubar
# #
def _busy(self):
raise SubclassResponsibility
def mNewGame(self, *args): def mNewGame(self, *args):
if not self._busy(): if not self._busy():
self.menubar.mNewGame() self.menubar.mNewGame()

View file

@ -61,15 +61,16 @@ from winsystems import TkSettings
from pysoltk import wm_withdraw, loadImage from pysoltk import wm_withdraw, loadImage
from pysoltk import MfxDialog, MfxMessageDialog, MfxExceptionDialog from pysoltk import MfxDialog, MfxMessageDialog, MfxExceptionDialog
from pysoltk import TclError, MfxScrolledCanvas from pysoltk import TclError, MfxScrolledCanvas
from pysoltk import PysolMenubar
from pysoltk import PysolProgressBar from pysoltk import PysolProgressBar
from pysoltk import PysolToolbar
from pysoltk import PysolStatusbar, HelpStatusbar from pysoltk import PysolStatusbar, HelpStatusbar
from pysoltk import SelectCardsetDialogWithPreview from pysoltk import SelectCardsetDialogWithPreview
from pysoltk import SelectDialogTreeData from pysoltk import SelectDialogTreeData
from pysoltk import HTMLViewer from pysoltk import HTMLViewer
from pysoltk import destroy_find_card_dialog from pysoltk import destroy_find_card_dialog
from pysoltk import destroy_solver_dialog from pysoltk import destroy_solver_dialog
from actions import PysolMenubar
from actions import PysolToolbar
from help import help_about, destroy_help_html from help import help_about, destroy_help_html
@ -508,7 +509,7 @@ class Application:
self.setTile(self.tabletile_index, force=True) self.setTile(self.tabletile_index, force=True)
# create the toolbar # create the toolbar
dir = self.getToolbarImagesDir() dir = self.getToolbarImagesDir()
self.toolbar = PysolToolbar(self.top, dir=dir, self.toolbar = PysolToolbar(self.top, self.menubar, dir=dir,
size=self.opt.toolbar_size, size=self.opt.toolbar_size,
relief=self.opt.toolbar_relief, relief=self.opt.toolbar_relief,
compound=self.opt.toolbar_compound) compound=self.opt.toolbar_compound)
@ -615,7 +616,7 @@ class Application:
# connect with game # connect with game
self.menubar.connectGame(self.game) self.menubar.connectGame(self.game)
if self.toolbar: ##~ if self.toolbar: ##~
self.toolbar.connectGame(self.game, self.menubar) self.toolbar.connectGame(self.game)
self.game.updateStatus(player=self.opt.player) self.game.updateStatus(player=self.opt.player)
# update "Recent games" menubar entry # update "Recent games" menubar entry
if id in self.opt.recent_gameid: if id in self.opt.recent_gameid:
@ -670,8 +671,8 @@ class Application:
# free game # free game
def freeGame(self): def freeGame(self):
# disconnect from game # disconnect from game
self.toolbar.connectGame(None, None)
self.menubar.connectGame(None) self.menubar.connectGame(None)
self.toolbar.connectGame(None)
# clean up the canvas # clean up the canvas
self.canvas.deleteAllItems() self.canvas.deleteAllItems()
self.canvas.update_idletasks() self.canvas.update_idletasks()

View file

@ -287,6 +287,7 @@ class GI:
("Fred Lunde", (459,)), ("Fred Lunde", (459,)),
("Albert Morehead and Geoffrey Mott-Smith", (25, 42, 48, 173, ("Albert Morehead and Geoffrey Mott-Smith", (25, 42, 48, 173,
303, 547, 738)), 303, 547, 738)),
("Albert Morehead", (362,)),
("David Parlett", (64, 98, 294, 338, 654, 674,)), ("David Parlett", (64, 98, 294, 338, 654, 674,)),
("Captain Jeffrey T. Spaulding", (400,)), ("Captain Jeffrey T. Spaulding", (400,)),
("John Stoneham", (201,)), ("John Stoneham", (201,)),

View file

@ -562,14 +562,14 @@ class Well(Game):
(4,2), (4,2),
(2,4)): (2,4)):
x, y = x0+xx*l.XS, y0+yy*l.YS x, y = x0+xx*l.XS, y0+yy*l.YS
stack = SS_RowStack(x, y, self, dir=1, max_move=1) stack = SS_RowStack(x, y, self, dir=1, mod=13, max_move=1)
stack.getBottomImage = stack._getReserveBottomImage stack.getBottomImage = stack._getReserveBottomImage
stack.CARD_YOFFSET = 0 stack.CARD_YOFFSET = 0
s.rows.append(stack) s.rows.append(stack)
# left stack # left stack
x, y = l.XM, l.YM+l.YS+l.TEXT_HEIGHT x, y = l.XM, l.YM+l.YS+l.TEXT_HEIGHT
stack = SS_RowStack(x, y, self, base_rank=ACE, dir=1, max_move=1) stack = SS_RowStack(x, y, self, base_rank=ACE, dir=1, mod=13, max_move=1)
stack.getBottomImage = stack._getReserveBottomImage stack.getBottomImage = stack._getReserveBottomImage
stack.CARD_YOFFSET = 0 stack.CARD_YOFFSET = 0
s.rows.append(stack) s.rows.append(stack)

View file

@ -451,21 +451,25 @@ class Glacier(Game):
# /*********************************************************************** # /***********************************************************************
# // Eight Packs (ex. Four Packs)
# // Four Packs # // Four Packs
# ************************************************************************/ # ************************************************************************/
class FourPacks(Game): class EightPacks(Game):
def createGame(self): RowStack_Class = SS_RowStack
def createGame(self, max_rounds=3, width=10, playcards=14):
l, s = Layout(self), self.s l, s = Layout(self), self.s
self.setSize(l.XM+10*l.XS, l.YM+2*l.YS+l.TEXT_HEIGHT+14*l.YOFFSET) self.setSize(l.XM+width*l.XS,
l.YM+2*l.YS+l.TEXT_HEIGHT+playcards*l.YOFFSET)
x, y = l.XM, l.YM x, y = l.XM, l.YM
for i in range(10): for i in range(10):
s.rows.append(SS_RowStack(x, y, self, dir=1)) s.rows.append(self.RowStack_Class(x, y, self, dir=1))
x += l.XS x += l.XS
x, y = self.width-l.XS, self.height-l.YS x, y = self.width-l.XS, self.height-l.YS
s.talon = WasteTalonStack(x, y, self, max_rounds=3) s.talon = WasteTalonStack(x, y, self, max_rounds=max_rounds)
l.createText(s.talon, 'n') l.createText(s.talon, 'n')
l.createRoundText(s.talon, 'nnn') l.createRoundText(s.talon, 'nnn')
@ -481,15 +485,41 @@ class FourPacks(Game):
self.s.talon.dealCards() self.s.talon.dealCards()
def isGameWon(self): def isGameWon(self):
if self.s.talon.cards or self.s.waste.cards:
return False
for s in self.s.rows: for s in self.s.rows:
if s.cards: if s.cards:
if len(s.cards) != 13 or not isSameSuitSequence(s.cards, dir=1): if len(s.cards) != 13:
return False return False
return True return True
shallHighlightMatch = Game._shallHighlightMatch_SS shallHighlightMatch = Game._shallHighlightMatch_SS
class FourPacks_RowStack(SS_RowStack):
def canMoveCards(self, cards):
if not self.basicCanMoveCards(cards):
return False
return len(cards) == len(self.cards)
class FourPacks(EightPacks):
RowStack_Class = StackWrapper(FourPacks_RowStack, mod=13)
def createGame(self):
EightPacks.createGame(self, max_rounds=2, width=12, playcards=18)
def isGameWon(self):
if self.s.talon.cards or self.s.waste.cards:
return False
for s in self.s.rows:
if s.cards:
if s.cards[0].rank != ACE:
return False
if len(s.cards) != 26:
return False
return True
# register the game # register the game
registerGame(GameInfo(294, CurdsAndWhey, "Curds and Whey", registerGame(GameInfo(294, CurdsAndWhey, "Curds and Whey",
@ -520,7 +550,9 @@ registerGame(GameInfo(534, Harvestman, "Harvestman",
GI.GT_SPIDER | GI.GT_ORIGINAL, 2, 0, GI.SL_MOSTLY_SKILL)) GI.GT_SPIDER | GI.GT_ORIGINAL, 2, 0, GI.SL_MOSTLY_SKILL))
registerGame(GameInfo(687, Glacier, "Glacier", registerGame(GameInfo(687, Glacier, "Glacier",
GI.GT_2DECK_TYPE, 2, 0, GI.SL_BALANCED)) GI.GT_2DECK_TYPE, 2, 0, GI.SL_BALANCED))
registerGame(GameInfo(724, FourPacks, "Four Packs", registerGame(GameInfo(724, EightPacks, "Eight Packs",
GI.GT_2DECK_TYPE, 2, 2, GI.SL_MOSTLY_SKILL)) GI.GT_2DECK_TYPE | GI.GT_ORIGINAL, 2, 2, GI.SL_MOSTLY_SKILL))
registerGame(GameInfo(762, FourPacks, "Four Packs",
GI.GT_2DECK_TYPE, 2, 1, GI.SL_MOSTLY_SKILL))

View file

@ -44,6 +44,7 @@ from mahjongg import Mahjongg_RowStack, AbstractMahjonggGame, comp_cardset
# ************************************************************************/ # ************************************************************************/
class Shisen_Hint(AbstractHint): class Shisen_Hint(AbstractHint):
TOP_MATCHING = False
# FIXME: no intelligence whatsoever is implemented here # FIXME: no intelligence whatsoever is implemented here
def computeHints(self): def computeHints(self):
game = self.game game = self.game
@ -59,11 +60,18 @@ class Shisen_Hint(AbstractHint):
#if game.cardsMatch(r.cards[0], t.cards[0]): #if game.cardsMatch(r.cards[0], t.cards[0]):
if r.acceptsCards(t, t.cards): if r.acceptsCards(t, t.cards):
# simple scoring... # simple scoring...
score = 1000 + r.rown + t.rown if self.TOP_MATCHING:
score = 2000 - r.rown - t.rown
else:
score = 1000 + r.rown + t.rown
self.addHint(score, 1, r, t) self.addHint(score, 1, r, t)
i += 1 i += 1
class NotShisen_Hint(Shisen_Hint):
TOP_MATCHING = True
# /*********************************************************************** # /***********************************************************************
# // Shisen-Sho # // Shisen-Sho
# ************************************************************************/ # ************************************************************************/
@ -288,7 +296,7 @@ class Shisen_RowStack(Mahjongg_RowStack):
class AbstractShisenGame(AbstractMahjonggGame): class AbstractShisenGame(AbstractMahjonggGame):
Hint_Class = Shisen_Hint Hint_Class = NotShisen_Hint #Shisen_Hint
RowStack_Class = Shisen_RowStack RowStack_Class = Shisen_RowStack
#NCARDS = 144 #NCARDS = 144
@ -379,11 +387,9 @@ class AbstractShisenGame(AbstractMahjonggGame):
if self.preview > 1 or self.texts.info is None: if self.preview > 1 or self.texts.info is None:
return return
game = self.app.game if self.app.opt.shisen_show_matching:
if 0:
# find matching tiles # find matching tiles
stacks = game.s.rows stacks = self.s.rows
f, i = 0, 0 f, i = 0, 0
for r in stacks: for r in stacks:
i = i + 1 i = i + 1
@ -456,27 +462,6 @@ class Shisen_24x12_NoGravity(AbstractShisenGame):
# // Not Shisen-Sho # // Not Shisen-Sho
# ************************************************************************/ # ************************************************************************/
class NotShisen_Hint(AbstractHint):
# FIXME: no intelligence whatsoever is implemented here
def computeHints(self):
game = self.game
# get free stacks
stacks = []
for r in game.s.rows:
if r.cards:
stacks.append(r)
# find matching tiles
i = 0
for r in stacks:
for t in stacks[i+1:]:
#if game.cardsMatch(r.cards[0], t.cards[0]):
if r.acceptsCards(t, t.cards):
# simple scoring...
score = 2000 - r.rown - t.rown
self.addHint(score, 1, r, t)
i += 1
class NotShisen_RowStack(Shisen_RowStack): class NotShisen_RowStack(Shisen_RowStack):
def acceptsCards(self, from_stack, cards): def acceptsCards(self, from_stack, cards):
if not self.game.cardsMatch(self.cards[0], cards[-1]): if not self.game.cardsMatch(self.cards[0], cards[-1]):

View file

@ -1351,7 +1351,8 @@ registerGame(GameInfo(331, SultanPlus, "Sultan +",
registerGame(GameInfo(354, Boudoir, "Boudoir", registerGame(GameInfo(354, Boudoir, "Boudoir",
GI.GT_2DECK_TYPE, 2, 2, GI.SL_MOSTLY_LUCK)) GI.GT_2DECK_TYPE, 2, 2, GI.SL_MOSTLY_LUCK))
registerGame(GameInfo(410, CaptiveQueens, "Captive Queens", registerGame(GameInfo(410, CaptiveQueens, "Captive Queens",
GI.GT_1DECK_TYPE, 1, 2, GI.SL_MOSTLY_LUCK)) GI.GT_1DECK_TYPE, 1, 2, GI.SL_MOSTLY_LUCK,
altnames=("Quadrille",) ))
registerGame(GameInfo(418, Contradance, "Contradance", registerGame(GameInfo(418, Contradance, "Contradance",
GI.GT_2DECK_TYPE, 2, 1, GI.SL_LUCK, GI.GT_2DECK_TYPE, 2, 1, GI.SL_LUCK,
altnames=("Cotillion",) )) altnames=("Cotillion",) ))

View file

@ -54,11 +54,11 @@ Image = ImageTk = ImageOps = None
if TOOLKIT == 'tk': if TOOLKIT == 'tk':
try: # PIL try: # PIL
import Image import Image
except ImportError:
pass
else:
import ImageTk import ImageTk
import ImageOps import ImageOps
except ImportError:
Image = None
else:
# for py2exe # for py2exe
import GifImagePlugin import GifImagePlugin
import PngImagePlugin import PngImagePlugin

View file

@ -58,6 +58,7 @@ highlight_not_matching = boolean
mahjongg_show_removed = boolean mahjongg_show_removed = boolean
mahjongg_create_solvable = integer(0, 2) mahjongg_create_solvable = integer(0, 2)
shisen_show_hint = boolean shisen_show_hint = boolean
shisen_show_matching = boolean
animations = integer(0, 5) animations = integer(0, 5)
redeal_animation = boolean redeal_animation = boolean
win_animation = boolean win_animation = boolean
@ -186,6 +187,7 @@ class Options:
('mahjongg_show_removed', 'bool'), ('mahjongg_show_removed', 'bool'),
('mahjongg_create_solvable', 'int'), ('mahjongg_create_solvable', 'int'),
('shisen_show_hint', 'bool'), ('shisen_show_hint', 'bool'),
('shisen_show_matching', 'bool'),
('animations', 'int'), ('animations', 'int'),
('redeal_animation', 'bool'), ('redeal_animation', 'bool'),
('win_animation', 'bool'), ('win_animation', 'bool'),
@ -256,6 +258,7 @@ class Options:
self.mahjongg_show_removed = False self.mahjongg_show_removed = False
self.mahjongg_create_solvable = 2 # 0 - none, 1 - easy, 2 - hard self.mahjongg_create_solvable = 2 # 0 - none, 1 - easy, 2 - hard
self.shisen_show_hint = True self.shisen_show_hint = True
self.shisen_show_matching = False
self.animations = 2 # default to Fast self.animations = 2 # default to Fast
self.redeal_animation = True self.redeal_animation = True
self.win_animation = True self.win_animation = True

View file

@ -38,7 +38,6 @@ from gtk import gdk
# PySol imports # PySol imports
from pysollib.gamedb import GI from pysollib.gamedb import GI
from pysollib.actions import PysolMenubarActions
from pysollib.settings import TITLE from pysollib.settings import TITLE
# toolkit imports # toolkit imports
@ -61,9 +60,8 @@ def ltk2gtk(s):
# // - menu actions # // - menu actions
# ************************************************************************/ # ************************************************************************/
class PysolMenubar(PysolMenubarActions): class PysolMenubarTk:
def __init__(self, app, top, progress=None): def __init__(self, app, top, progress=None):
PysolMenubarActions.__init__(self, app, top)
self.progress = progress self.progress = progress
self._cb_max = gdk.screen_height()/24 self._cb_max = gdk.screen_height()/24
# create menus # create menus
@ -660,6 +658,10 @@ class PysolMenubar(PysolMenubarActions):
def updateRecentGamesMenu(self, games): def updateRecentGamesMenu(self, games):
self._updateGamesMenu('/menubar/file/recentgames', games) self._updateGamesMenu('/menubar/file/recentgames', games)
def updateBookmarkMenuState(self):
# FIXME
pass
def _updateGamesMenu(self, path, games): def _updateGamesMenu(self, path, games):
item = self.top.ui_manager.get_widget(path) item = self.top.ui_manager.get_widget(path)
item.show() item.show()

View file

@ -36,7 +36,6 @@ import gtk
from gtk import gdk from gtk import gdk
# PySol imports # PySol imports
from pysollib.actions import PysolToolbarActions
@ -44,11 +43,10 @@ from pysollib.actions import PysolToolbarActions
# // # //
# ************************************************************************/ # ************************************************************************/
class PysolToolbar(PysolToolbarActions): class PysolToolbarTk:
def __init__(self, top, dir, size=0, relief=0, compound=None): def __init__(self, top, menubar, dir, size=0, relief=0, compound=None):
PysolToolbarActions.__init__(self)
self.top = top self.top = top
self.menubar = menubar
self.dir = dir self.dir = dir
self.side = -1 self.side = -1

View file

@ -41,10 +41,12 @@ from mfxutil import SubclassResponsibility
# /*********************************************************************** # /***********************************************************************
# // system based random (need python >= 2.3) # // Abstract class for PySol Random number generator.
# //
# // We use a seed of type long in the range [0, MAX_SEED].
# ************************************************************************/ # ************************************************************************/
class SysRandom(random.Random): class BasicRandom:
#MAX_SEED = 0L #MAX_SEED = 0L
#MAX_SEED = 0xffffffffffffffffL # 64 bits #MAX_SEED = 0xffffffffffffffffL # 64 bits
MAX_SEED = 100000000000000000000L # 20 digits MAX_SEED = 100000000000000000000L # 20 digits
@ -55,14 +57,6 @@ class SysRandom(random.Random):
ORIGIN_SELECTED = 3 # manually entered ORIGIN_SELECTED = 3 # manually entered
ORIGIN_NEXT_GAME = 4 # "Next game number" ORIGIN_NEXT_GAME = 4 # "Next game number"
def __init__(self, seed=None):
if seed is None:
seed = self._getRandomSeed()
random.Random.__init__(self, seed)
self.initial_seed = seed
self.initial_state = self.getstate()
self.origin = self.ORIGIN_UNKNOWN
def __str__(self): def __str__(self):
return self.str(self.initial_seed) return self.str(self.initial_seed)
@ -70,7 +64,7 @@ class SysRandom(random.Random):
return '%020d' % seed return '%020d' % seed
def reset(self): def reset(self):
self.setstate(self.initial_state) raise SubclassResponsibility
def copy(self): def copy(self):
random = self.__class__(0L) random = self.__class__(0L)
@ -89,19 +83,48 @@ class SysRandom(random.Random):
# /*********************************************************************** # /***********************************************************************
# // Abstract PySol Random number generator. # // Mersenne Twister random number generator
# // # // uses standart python module `random'
# // We use a seed of type long in the range [0, MAX_SEED].
# ************************************************************************/ # ************************************************************************/
class MFXRandom: class MTRandom(BasicRandom, random.Random):
MAX_SEED = 0L
ORIGIN_UNKNOWN = 0 def __init__(self, seed=None):
ORIGIN_RANDOM = 1 if seed is None:
ORIGIN_PREVIEW = 2 # random from preview seed = self._getRandomSeed()
ORIGIN_SELECTED = 3 # manually entered random.Random.__init__(self, seed)
ORIGIN_NEXT_GAME = 4 # "Next game number" self.initial_seed = seed
self.initial_state = self.getstate()
self.origin = self.ORIGIN_UNKNOWN
def reset(self):
self.setstate(self.initial_state)
# /***********************************************************************
# // Wichman-Hill random number generator
# // uses standart python module `random'
# ************************************************************************/
class WHRandom(BasicRandom, random.WichmannHill):
def __init__(self, seed=None):
if seed is None:
seed = self._getRandomSeed()
random.WichmannHill.__init__(self, seed)
self.initial_seed = seed
self.initial_state = self.getstate()
self.origin = self.ORIGIN_UNKNOWN
def reset(self):
self.setstate(self.initial_state)
# /***********************************************************************
# // Abstract class for LC Random number generators.
# ************************************************************************/
class MFXRandom(BasicRandom):
def __init__(self, seed=None): def __init__(self, seed=None):
if seed is None: if seed is None:
@ -109,9 +132,6 @@ class MFXRandom:
self.initial_seed = self.setSeed(seed) self.initial_seed = self.setSeed(seed)
self.origin = self.ORIGIN_UNKNOWN self.origin = self.ORIGIN_UNKNOWN
def __str__(self):
return self.str(self.initial_seed)
def reset(self): def reset(self):
self.seed = self.initial_seed self.seed = self.initial_seed
@ -119,9 +139,7 @@ class MFXRandom:
return self.seed return self.seed
def setSeed(self, seed): def setSeed(self, seed):
seed = self._convertSeed(seed) seed = long(seed)
if not isinstance(seed, long):
raise TypeError, "seeds must be longs"
if not (0L <= seed <= self.MAX_SEED): if not (0L <= seed <= self.MAX_SEED):
raise ValueError, "seed out of range" raise ValueError, "seed out of range"
self.seed = seed self.seed = seed
@ -133,11 +151,6 @@ class MFXRandom:
def setstate(self, state): def setstate(self, state):
self.seed = state self.seed = state
def copy(self):
random = self.__class__(0L)
random.__dict__.update(self.__dict__)
return random
# #
# implementation # implementation
# #
@ -152,43 +165,12 @@ class MFXRandom:
def randrange(self, a, b): def randrange(self, a, b):
return self.randint(a, b-1) return self.randint(a, b-1)
#
# subclass responsibility
#
# Get the next random number in the range [0.0, 1.0).
def random(self):
raise SubclassResponsibility
#
# subclass overrideable
#
def _convertSeed(self, seed):
return long(seed)
def increaseSeed(self, seed):
if seed < self.MAX_SEED:
return seed + 1L
return 0L
def _getRandomSeed(self):
t = long(time.time() * 256.0)
t = (t ^ (t >> 24)) % (self.MAX_SEED + 1L)
return t
#
# shuffle
# see: Knuth, Vol. 2, Chapter 3.4.2, Algorithm P
# see: FAQ of sci.crypt: "How do I shuffle cards ?"
#
def shuffle(self, seq): def shuffle(self, seq):
n = len(seq) - 1 n = len(seq) - 1
while n > 0: while n > 0:
j = self.randint(0, n) j = self.randint(0, n)
seq[n], seq[j] = seq[j], seq[n] seq[n], seq[j] = seq[j], seq[n]
n = n - 1 n -= 1
# /*********************************************************************** # /***********************************************************************
@ -200,14 +182,6 @@ class MFXRandom:
# ************************************************************************/ # ************************************************************************/
class LCRandom64(MFXRandom): class LCRandom64(MFXRandom):
MAX_SEED = 0xffffffffffffffffL # 64 bits
def str(self, seed):
s = repr(long(seed))
if s[-1:] == "L":
s = s[:-1]
s = "0"*(20-len(s)) + s
return s
def random(self): def random(self):
self.seed = (self.seed*6364136223846793005L + 1L) & self.MAX_SEED self.seed = (self.seed*6364136223846793005L + 1L) & self.MAX_SEED
@ -216,7 +190,8 @@ class LCRandom64(MFXRandom):
# /*********************************************************************** # /***********************************************************************
# // Linear Congruential random generator # // Linear Congruential random generator
# // In PySol this is only used for 0 <= seed <= 32000. # // In PySol this is only used for 0 <= seed <= 32000
# // for Windows FreeCell compatibility
# ************************************************************************/ # ************************************************************************/
class LCRandom31(MFXRandom): class LCRandom31(MFXRandom):
@ -233,12 +208,18 @@ class LCRandom31(MFXRandom):
self.seed = (self.seed*214013L + 2531011L) & self.MAX_SEED self.seed = (self.seed*214013L + 2531011L) & self.MAX_SEED
return a + (int(self.seed >> 16) % (b+1-a)) return a + (int(self.seed >> 16) % (b+1-a))
def shuffle(self, seq):
n = len(seq) - 1
while n > 0:
j = self.randint(0, n)
seq[n], seq[j] = seq[j], seq[n]
n -= 1
# select # select
if sys.version_info >= (2,3): #PysolRandom = LCRandom64
PysolRandom = SysRandom #PysolRandom = WHRandom
else: PysolRandom = MTRandom
PysolRandom = LCRandom64
# /*********************************************************************** # /***********************************************************************
@ -258,7 +239,7 @@ def constructRandom(s):
# test # test
if __name__ == '__main__': if __name__ == '__main__':
_, r = constructRandom('12345') r = constructRandom('12345')
print r.randint(0, 100) print r.randint(0, 100)
print r.random() print r.random()
print type(r) print type(r)

View file

@ -34,7 +34,7 @@
## ##
##---------------------------------------------------------------------------## ##---------------------------------------------------------------------------##
__all__ = ['PysolMenubar'] __all__ = ['PysolMenubarTk']
# imports # imports
import math, os, sys, re, traceback import math, os, sys, re, traceback
@ -51,7 +51,6 @@ from pysollib.settings import SELECT_GAME_MENU
from pysollib.settings import USE_FREECELL_SOLVER from pysollib.settings import USE_FREECELL_SOLVER
from pysollib.settings import DEBUG from pysollib.settings import DEBUG
from pysollib.gamedb import GI from pysollib.gamedb import GI
from pysollib.actions import PysolMenubarActions
# toolkit imports # toolkit imports
from tkconst import EVENT_HANDLED, EVENT_PROPAGATE, CURSOR_WATCH, COMPOUNDS from tkconst import EVENT_HANDLED, EVENT_PROPAGATE, CURSOR_WATCH, COMPOUNDS
@ -178,9 +177,8 @@ class MfxMenu(MfxMenubar):
# // - menu actions # // - menu actions
# ************************************************************************/ # ************************************************************************/
class PysolMenubar(PysolMenubarActions): class PysolMenubarTk:
def __init__(self, app, top, progress=None): def __init__(self, app, top, progress=None):
PysolMenubarActions.__init__(self, app, top)
self._createTkOpt() self._createTkOpt()
self._setOptions() self._setOptions()
# init columnbreak # init columnbreak

View file

@ -33,7 +33,7 @@
## ##
##---------------------------------------------------------------------------## ##---------------------------------------------------------------------------##
__all__ = ['PysolToolbar'] __all__ = ['PysolToolbarTk']
# imports # imports
import os import os
@ -45,7 +45,6 @@ from pysollib.mfxutil import destruct
from pysollib.mfxutil import Image, ImageTk, ImageOps from pysollib.mfxutil import Image, ImageTk, ImageOps
from pysollib.util import IMAGE_EXTENSIONS from pysollib.util import IMAGE_EXTENSIONS
from pysollib.settings import TITLE, WIN_SYSTEM from pysollib.settings import TITLE, WIN_SYSTEM
from pysollib.actions import PysolToolbarActions
from pysollib.winsystems import TkSettings from pysollib.winsystems import TkSettings
# Toolkit imports # Toolkit imports
@ -166,13 +165,12 @@ class ToolbarLabel(Tkinter.Message):
# // Note: Applications should call show/hide after constructor. # // Note: Applications should call show/hide after constructor.
# ************************************************************************/ # ************************************************************************/
class PysolToolbar(PysolToolbarActions): class PysolToolbarTk:
def __init__(self, top, dir, size=0, relief='flat', compound='none'):
PysolToolbarActions.__init__(self)
def __init__(self, top, menubar, dir,
size=0, relief='flat', compound='none'):
self.top = top self.top = top
self.menubar = menubar
self.side = -1 self.side = -1
self._tooltips = [] self._tooltips = []
self._widgets = [] self._widgets = []
@ -210,6 +208,10 @@ class PysolToolbar(PysolToolbarActions):
self._createButton(l, f, check=True, tooltip=t) self._createButton(l, f, check=True, tooltip=t)
else: else:
self._createButton(l, f, tooltip=t) self._createButton(l, f, tooltip=t)
self.pause_button.config(variable=menubar.tkopt.pause)
self.popup = MfxMenu(master=None, label=n_('Toolbar'), tearoff=0)
createToolbarMenu(menubar, self.popup)
position=len(self._widgets) position=len(self._widgets)
self.frame.rowconfigure(position, weight=1) self.frame.rowconfigure(position, weight=1)
@ -219,7 +221,6 @@ class PysolToolbar(PysolToolbarActions):
tooltip=_("Player options")) tooltip=_("Player options"))
# #
self.player_label.bind("<1>",self.mOptPlayerOptions) self.player_label.bind("<1>",self.mOptPlayerOptions)
self.popup = None
self.frame.bind("<3>", self.rightclickHandler) self.frame.bind("<3>", self.rightclickHandler)
# #
self.setCompound(compound, force=True) self.setCompound(compound, force=True)
@ -301,7 +302,6 @@ class PysolToolbar(PysolToolbarActions):
setattr(self, name + "_disabled_image", dis_image) setattr(self, name + "_disabled_image", dis_image)
button.config(image=(image, 'disabled', dis_image)) button.config(image=(image, 'disabled', dis_image))
else: else:
image = self._loadImage(name)
button.config(image=image) button.config(image=image)
def _createButton(self, label, command, check=False, tooltip=None): def _createButton(self, label, command, check=False, tooltip=None):
@ -411,18 +411,6 @@ class PysolToolbar(PysolToolbarActions):
self.frame.config(cursor=cursor) self.frame.config(cursor=cursor)
self.frame.update_idletasks() self.frame.update_idletasks()
def connectGame(self, game, menubar):
PysolToolbarActions.connectGame(self, game, menubar)
if self.popup:
self.popup.destroy()
destruct(self.popup)
self.popup = None
if menubar:
tkopt = menubar.tkopt
self.pause_button.config(variable=tkopt.pause)
self.popup = MfxMenu(master=None, label=n_('Toolbar'), tearoff=0)
createToolbarMenu(menubar, self.popup)
def updateText(self, **kw): def updateText(self, **kw):
for name in kw.keys(): for name in kw.keys():
label = getattr(self, name + "_label") label = getattr(self, name + "_label")

View file

@ -34,7 +34,7 @@
## ##
##---------------------------------------------------------------------------## ##---------------------------------------------------------------------------##
__all__ = ['PysolMenubar'] __all__ = ['PysolMenubarTk']
# imports # imports
import math, os, sys, re import math, os, sys, re
@ -51,7 +51,6 @@ from pysollib.settings import SELECT_GAME_MENU
from pysollib.settings import USE_FREECELL_SOLVER from pysollib.settings import USE_FREECELL_SOLVER
from pysollib.settings import DEBUG from pysollib.settings import DEBUG
from pysollib.gamedb import GI from pysollib.gamedb import GI
from pysollib.actions import PysolMenubarActions
# toolkit imports # toolkit imports
from tkconst import EVENT_HANDLED, EVENT_PROPAGATE, CURSOR_WATCH, COMPOUNDS from tkconst import EVENT_HANDLED, EVENT_PROPAGATE, CURSOR_WATCH, COMPOUNDS
@ -177,9 +176,8 @@ class MfxMenu(MfxMenubar):
# // - menu actions # // - menu actions
# ************************************************************************/ # ************************************************************************/
class PysolMenubar(PysolMenubarActions): class PysolMenubarTk:
def __init__(self, app, top, progress=None): def __init__(self, app, top, progress=None):
PysolMenubarActions.__init__(self, app, top)
self._createTkOpt() self._createTkOpt()
self._setOptions() self._setOptions()
# init columnbreak # init columnbreak

View file

@ -33,7 +33,7 @@
## ##
##---------------------------------------------------------------------------## ##---------------------------------------------------------------------------##
__all__ = ['PysolToolbar'] __all__ = ['PysolToolbarTk']
# imports # imports
import os import os
@ -44,7 +44,6 @@ from pysollib.mfxutil import destruct
from pysollib.mfxutil import Image, ImageTk from pysollib.mfxutil import Image, ImageTk
from pysollib.util import IMAGE_EXTENSIONS from pysollib.util import IMAGE_EXTENSIONS
from pysollib.settings import TITLE from pysollib.settings import TITLE
from pysollib.actions import PysolToolbarActions
from pysollib.winsystems import TkSettings from pysollib.winsystems import TkSettings
# Toolkit imports # Toolkit imports
@ -164,13 +163,12 @@ class ToolbarLabel(Tkinter.Message):
# // Note: Applications should call show/hide after constructor. # // Note: Applications should call show/hide after constructor.
# ************************************************************************/ # ************************************************************************/
class PysolToolbar(PysolToolbarActions): class PysolToolbarTk:
def __init__(self, top, dir, size=0, relief='flat', compound='none'):
PysolToolbarActions.__init__(self)
def __init__(self, top, menubar, dir,
size=0, relief='flat', compound='none'):
self.top = top self.top = top
self.menubar = menubar
#self._setRelief(relief) #self._setRelief(relief)
self.side = -1 self.side = -1
self._tooltips = [] self._tooltips = []
@ -210,6 +208,7 @@ class PysolToolbar(PysolToolbarActions):
self._createButton(l, f, check=True, tooltip=t) self._createButton(l, f, check=True, tooltip=t)
else: else:
self._createButton(l, f, tooltip=t) self._createButton(l, f, tooltip=t)
self.pause_button.config(variable=menubar.tkopt.pause)
sep = self._createFlatSeparator() sep = self._createFlatSeparator()
sep.bind("<1>", self.clickHandler) sep.bind("<1>", self.clickHandler)
@ -219,7 +218,8 @@ class PysolToolbar(PysolToolbarActions):
# #
self.player_label.bind("<1>",self.mOptPlayerOptions) self.player_label.bind("<1>",self.mOptPlayerOptions)
##self.player_label.bind("<3>",self.mOptPlayerOptions) ##self.player_label.bind("<3>",self.mOptPlayerOptions)
self.popup = None self.popup = MfxMenu(master=None, label=n_('Toolbar'), tearoff=0)
createToolbarMenu(menubar, self.popup)
self.frame.bind("<1>", self.clickHandler) self.frame.bind("<1>", self.clickHandler)
self.frame.bind("<3>", self.rightclickHandler) self.frame.bind("<3>", self.rightclickHandler)
# #
@ -419,18 +419,6 @@ class PysolToolbar(PysolToolbarActions):
self.frame.config(cursor=cursor) self.frame.config(cursor=cursor)
self.frame.update_idletasks() self.frame.update_idletasks()
def connectGame(self, game, menubar):
PysolToolbarActions.connectGame(self, game, menubar)
if self.popup:
self.popup.destroy()
destruct(self.popup)
self.popup = None
if menubar:
tkopt = menubar.tkopt
self.pause_button.config(variable=tkopt.pause)
self.popup = MfxMenu(master=None, label=n_('Toolbar'), tearoff=0)
createToolbarMenu(menubar, self.popup)
def updateText(self, **kw): def updateText(self, **kw):
for name in kw.keys(): for name in kw.keys():
label = getattr(self, name + "_label") label = getattr(self, name + "_label")