mirror of
https://github.com/shlomif/PySolFC.git
synced 2025-04-05 00:02:29 -04:00
flake8 - mahjongg
This commit is contained in:
parent
2ea7cf48ea
commit
2505afdb68
4 changed files with 165 additions and 144 deletions
|
@ -1,6 +1,6 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
# -*- mode: python; coding: utf-8; -*-
|
# -*- mode: python; coding: utf-8; -*-
|
||||||
# ---------------------------------------------------------------------------##
|
# ---------------------------------------------------------------------------
|
||||||
#
|
#
|
||||||
# Copyright (C) 1998-2003 Markus Franz Xaver Johannes Oberhumer
|
# Copyright (C) 1998-2003 Markus Franz Xaver Johannes Oberhumer
|
||||||
# Copyright (C) 2003 Mt. Hood Playing Card Co.
|
# Copyright (C) 2003 Mt. Hood Playing Card Co.
|
||||||
|
@ -19,30 +19,40 @@
|
||||||
# You should have received a copy of the GNU General Public License
|
# You should have received a copy of the GNU General Public License
|
||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
#
|
#
|
||||||
# ---------------------------------------------------------------------------##
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
__all__ = []
|
__all__ = []
|
||||||
|
|
||||||
# Imports
|
# Imports
|
||||||
import sys, re
|
import sys
|
||||||
|
import re
|
||||||
import time
|
import time
|
||||||
#from tkFont import Font
|
# from tkFont import Font
|
||||||
from gettext import ungettext
|
from gettext import ungettext
|
||||||
|
|
||||||
# PySol imports
|
# PySol imports
|
||||||
from pysollib.mygettext import _, n_
|
from pysollib.mygettext import _
|
||||||
from pysollib.gamedb import registerGame, GameInfo, GI
|
from pysollib.gamedb import registerGame, GameInfo, GI
|
||||||
from pysollib.util import *
|
|
||||||
from pysollib.mfxutil import kwdefault, Struct, Image
|
from pysollib.mfxutil import kwdefault, Struct, Image
|
||||||
from pysollib.stack import *
|
|
||||||
from pysollib.game import Game
|
from pysollib.game import Game
|
||||||
from pysollib.layout import Layout
|
from pysollib.layout import Layout
|
||||||
from pysollib.hint import AbstractHint, DefaultHint, CautiousDefaultHint
|
from pysollib.hint import AbstractHint
|
||||||
from pysollib.settings import TOOLKIT, DEBUG
|
from pysollib.settings import TOOLKIT, DEBUG
|
||||||
from pysollib.pysoltk import MfxCanvasText, MfxCanvasImage
|
from pysollib.pysoltk import MfxCanvasText, MfxCanvasImage
|
||||||
from pysollib.pysoltk import bind, EVENT_HANDLED, ANCHOR_NW
|
from pysollib.pysoltk import bind, EVENT_HANDLED, ANCHOR_NW
|
||||||
from pysollib.pysoltk import MfxMessageDialog
|
from pysollib.pysoltk import MfxMessageDialog
|
||||||
|
|
||||||
|
from pysollib.util import ANY_SUIT, NO_RANK
|
||||||
|
|
||||||
|
from pysollib.stack import \
|
||||||
|
InitialDealTalonStack, \
|
||||||
|
OpenStack
|
||||||
|
|
||||||
|
from new import classobj
|
||||||
|
|
||||||
|
if sys.version_info > (3,):
|
||||||
|
xrange = range
|
||||||
|
|
||||||
|
|
||||||
def factorial(x):
|
def factorial(x):
|
||||||
if x <= 1:
|
if x <= 1:
|
||||||
|
@ -72,14 +82,14 @@ class Mahjongg_Hint(AbstractHint):
|
||||||
for t in stacks[i+1:]:
|
for t in stacks[i+1:]:
|
||||||
if game.cardsMatch(r.cards[0], t.cards[0]):
|
if game.cardsMatch(r.cards[0], t.cards[0]):
|
||||||
# simple scoring...
|
# simple scoring...
|
||||||
##score = 10000 + r.id + t.id
|
# score = 10000 + r.id + t.id
|
||||||
rb = r.blockmap
|
rb = r.blockmap
|
||||||
tb = t.blockmap
|
tb = t.blockmap
|
||||||
score = \
|
score = \
|
||||||
10000 + \
|
10000 + \
|
||||||
1000 * (len(rb.below) + len(tb.below)) + \
|
1000 * (len(rb.below) + len(tb.below)) + \
|
||||||
len(rb.all_left) + len(rb.all_right) + \
|
len(rb.all_left) + len(rb.all_right) + \
|
||||||
len(tb.all_left) + len(tb.all_right)
|
len(tb.all_left) + len(tb.all_right)
|
||||||
self.addHint(score, 1, r, t)
|
self.addHint(score, 1, r, t)
|
||||||
i += 1
|
i += 1
|
||||||
|
|
||||||
|
@ -88,7 +98,7 @@ class Mahjongg_Hint(AbstractHint):
|
||||||
# *
|
# *
|
||||||
# ************************************************************************
|
# ************************************************************************
|
||||||
|
|
||||||
#class Mahjongg_Foundation(AbstractFoundationStack):
|
# class Mahjongg_Foundation(AbstractFoundationStack):
|
||||||
class Mahjongg_Foundation(OpenStack):
|
class Mahjongg_Foundation(OpenStack):
|
||||||
|
|
||||||
def __init__(self, x, y, game, suit=ANY_SUIT, **cap):
|
def __init__(self, x, y, game, suit=ANY_SUIT, **cap):
|
||||||
|
@ -103,11 +113,11 @@ class Mahjongg_Foundation(OpenStack):
|
||||||
def basicIsBlocked(self):
|
def basicIsBlocked(self):
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
#def initBindings(self):
|
# def initBindings(self):
|
||||||
# pass
|
# pass
|
||||||
|
|
||||||
def _position(self, card):
|
def _position(self, card):
|
||||||
#AbstractFoundationStack._position(self, card)
|
# AbstractFoundationStack._position(self, card)
|
||||||
OpenStack._position(self, card)
|
OpenStack._position(self, card)
|
||||||
|
|
||||||
fnds = self.game.s.foundations
|
fnds = self.game.s.foundations
|
||||||
|
@ -166,8 +176,9 @@ class Mahjongg_RowStack(OpenStack):
|
||||||
self._dropPairMove(ncards, to_stack, frames=-1, shadow=shadow)
|
self._dropPairMove(ncards, to_stack, frames=-1, shadow=shadow)
|
||||||
|
|
||||||
def _dropPairMove(self, n, other_stack, frames=-1, shadow=-1):
|
def _dropPairMove(self, n, other_stack, frames=-1, shadow=-1):
|
||||||
##print 'drop:', self.id, other_stack.id
|
# print 'drop:', self.id, other_stack.id
|
||||||
assert n == 1 and self.acceptsCards(other_stack, [other_stack.cards[-1]])
|
assert n == 1 and self.acceptsCards(
|
||||||
|
other_stack, [other_stack.cards[-1]])
|
||||||
if not self.game.demo:
|
if not self.game.demo:
|
||||||
self.game.playSample("droppair", priority=200)
|
self.game.playSample("droppair", priority=200)
|
||||||
old_state = self.game.enterState(self.game.S_FILL)
|
old_state = self.game.enterState(self.game.S_FILL)
|
||||||
|
@ -213,24 +224,23 @@ class Mahjongg_RowStack(OpenStack):
|
||||||
for s in self.game.s.rows[self.id+1:]:
|
for s in self.game.s.rows[self.id+1:]:
|
||||||
s.group.tkraise()
|
s.group.tkraise()
|
||||||
|
|
||||||
|
|
||||||
# In Mahjongg games type there are a lot of stacks, so we optimize
|
# In Mahjongg games type there are a lot of stacks, so we optimize
|
||||||
# and don't create bindings that are not used anyway.
|
# and don't create bindings that are not used anyway.
|
||||||
def initBindings(self):
|
def initBindings(self):
|
||||||
group = self.group
|
group = self.group
|
||||||
# FIXME: dirty hack to access the Stack's private methods
|
# FIXME: dirty hack to access the Stack's private methods
|
||||||
#bind(group, "<1>", self._Stack__clickEventHandler)
|
# bind(group, "<1>", self._Stack__clickEventHandler)
|
||||||
#bind(group, "<3>", self._Stack__controlclickEventHandler)
|
# bind(group, "<3>", self._Stack__controlclickEventHandler)
|
||||||
#bind(group, "<Control-1>", self._Stack__controlclickEventHandler)
|
# bind(group, "<Control-1>", self._Stack__controlclickEventHandler)
|
||||||
#
|
#
|
||||||
bind(group, "<1>", self.__clickEventHandler)
|
bind(group, "<1>", self.__clickEventHandler)
|
||||||
bind(group, "<3>", self.__controlclickEventHandler)
|
bind(group, "<3>", self.__controlclickEventHandler)
|
||||||
bind(group, "<Control-1>", self.__controlclickEventHandler)
|
bind(group, "<Control-1>", self.__controlclickEventHandler)
|
||||||
##bind(group, "<Enter>", self._Stack__enterEventHandler)
|
# bind(group, "<Enter>", self._Stack__enterEventHandler)
|
||||||
##bind(group, "<Leave>", self._Stack__leaveEventHandler)
|
# bind(group, "<Leave>", self._Stack__leaveEventHandler)
|
||||||
|
|
||||||
def __defaultClickEventHandler(self, event, handler):
|
def __defaultClickEventHandler(self, event, handler):
|
||||||
self.game.event_handled = True # for Game.undoHandler
|
self.game.event_handled = True # for Game.undoHandler
|
||||||
if self.game.demo:
|
if self.game.demo:
|
||||||
self.game.stopDemo(event)
|
self.game.stopDemo(event)
|
||||||
if self.game.busy:
|
if self.game.busy:
|
||||||
|
@ -239,7 +249,7 @@ class Mahjongg_RowStack(OpenStack):
|
||||||
return EVENT_HANDLED
|
return EVENT_HANDLED
|
||||||
|
|
||||||
def __clickEventHandler(self, event):
|
def __clickEventHandler(self, event):
|
||||||
##print 'click:', self.id
|
# print 'click:', self.id
|
||||||
return self.__defaultClickEventHandler(event, self.clickHandler)
|
return self.__defaultClickEventHandler(event, self.clickHandler)
|
||||||
|
|
||||||
def __controlclickEventHandler(self, event):
|
def __controlclickEventHandler(self, event):
|
||||||
|
@ -259,8 +269,8 @@ class Mahjongg_RowStack(OpenStack):
|
||||||
self._stopDrag()
|
self._stopDrag()
|
||||||
return 1
|
return 1
|
||||||
if self.basicIsBlocked():
|
if self.basicIsBlocked():
|
||||||
### remove selection
|
# remove selection
|
||||||
##self.game.playSample("nomove")
|
# self.game.playSample("nomove")
|
||||||
return 1
|
return 1
|
||||||
# possible move
|
# possible move
|
||||||
if from_stack:
|
if from_stack:
|
||||||
|
@ -273,11 +283,12 @@ class Mahjongg_RowStack(OpenStack):
|
||||||
self.game.playSample("startdrag")
|
self.game.playSample("startdrag")
|
||||||
# create the shade image (see stack.py, _updateShade)
|
# create the shade image (see stack.py, _updateShade)
|
||||||
if drag.shade_img:
|
if drag.shade_img:
|
||||||
#drag.shade_img.dtag(drag.shade_stack.group)
|
# drag.shade_img.dtag(drag.shade_stack.group)
|
||||||
drag.shade_img.delete()
|
drag.shade_img.delete()
|
||||||
#game.canvas.delete(drag.shade_img)
|
# game.canvas.delete(drag.shade_img)
|
||||||
drag.shade_img = None
|
drag.shade_img = None
|
||||||
img = game.app.images.getHighlightedCard(card.deck, card.suit, card.rank)
|
img = game.app.images.getHighlightedCard(
|
||||||
|
card.deck, card.suit, card.rank)
|
||||||
if img is None:
|
if img is None:
|
||||||
return 1
|
return 1
|
||||||
img = MfxCanvasImage(game.canvas, self.x, self.y, image=img,
|
img = MfxCanvasImage(game.canvas, self.x, self.y, image=img,
|
||||||
|
@ -335,11 +346,10 @@ class AbstractMahjonggGame(Game):
|
||||||
for tl in range(level, level + height):
|
for tl in range(level, level + height):
|
||||||
tiles.append((tl, tx, ty))
|
tiles.append((tl, tx, ty))
|
||||||
assert len(tiles) == self.NCARDS
|
assert len(tiles) == self.NCARDS
|
||||||
#tiles.sort()
|
# tiles.sort()
|
||||||
#tiles = tuple(tiles)
|
# tiles = tuple(tiles)
|
||||||
return tiles, max_tl, max_tx, max_ty
|
return tiles, max_tl, max_tx, max_ty
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# game layout
|
# game layout
|
||||||
#
|
#
|
||||||
|
@ -351,8 +361,8 @@ class AbstractMahjonggGame(Game):
|
||||||
l, s = Layout(self), self.s
|
l, s = Layout(self), self.s
|
||||||
show_removed = self.app.opt.mahjongg_show_removed
|
show_removed = self.app.opt.mahjongg_show_removed
|
||||||
|
|
||||||
##dx, dy = 2, -2
|
# dx, dy = 2, -2
|
||||||
##dx, dy = 3, -3
|
# dx, dy = 3, -3
|
||||||
cs = self.app.cardset
|
cs = self.app.cardset
|
||||||
if cs.version >= 6:
|
if cs.version >= 6:
|
||||||
dx = l.XOFFSET
|
dx = l.XOFFSET
|
||||||
|
@ -369,12 +379,12 @@ class AbstractMahjonggGame(Game):
|
||||||
d_x = 0
|
d_x = 0
|
||||||
d_y = 0
|
d_y = 0
|
||||||
self._delta_x, self._delta_y = 0, 0
|
self._delta_x, self._delta_y = 0, 0
|
||||||
#print dx, dy, d_x, d_y, cs.version
|
# print dx, dy, d_x, d_y, cs.version
|
||||||
|
|
||||||
font = self.app.getFont("canvas_default")
|
font = self.app.getFont("canvas_default")
|
||||||
|
|
||||||
# width of self.texts.info
|
# width of self.texts.info
|
||||||
#ti_width = Font(self.canvas, font).measure(_('Remaining'))
|
# ti_width = Font(self.canvas, font).measure(_('Remaining'))
|
||||||
ti_width = 80
|
ti_width = 80
|
||||||
|
|
||||||
# set window size
|
# set window size
|
||||||
|
@ -403,21 +413,18 @@ class AbstractMahjonggGame(Game):
|
||||||
self.check_dist = l.CW*l.CW + l.CH*l.CH # see _getClosestStack()
|
self.check_dist = l.CW*l.CW + l.CH*l.CH # see _getClosestStack()
|
||||||
|
|
||||||
# sort tiles (for 3D)
|
# sort tiles (for 3D)
|
||||||
tiles.sort(lambda a, b:
|
tiles.sort(key=lambda x: (x[0], x[2]-x[1]))
|
||||||
cmp(a[0], b[0]) or
|
|
||||||
cmp(-a[1]+a[2], -b[1]+b[2])
|
|
||||||
)
|
|
||||||
|
|
||||||
# create a row stack for each tile and compute the tilemap
|
# create a row stack for each tile and compute the tilemap
|
||||||
tilemap = {}
|
tilemap = {}
|
||||||
x0 = left_margin
|
x0 = left_margin
|
||||||
y0 = l.YM + dyy
|
y0 = l.YM + dyy
|
||||||
for level, tx, ty in tiles:
|
for level, tx, ty in tiles:
|
||||||
#print level, tx, ty
|
# print level, tx, ty
|
||||||
x = x0 + (tx * cardw) / 2 + level * dx
|
x = x0 + (tx * cardw) / 2 + level * dx
|
||||||
y = y0 + (ty * cardh) / 2 + level * dy
|
y = y0 + (ty * cardh) / 2 + level * dy
|
||||||
stack = self.RowStack_Class(x, y, self)
|
stack = self.RowStack_Class(x, y, self)
|
||||||
##stack.G = (level, tx, ty)
|
# stack.G = (level, tx, ty)
|
||||||
stack.CARD_XOFFSET = dx
|
stack.CARD_XOFFSET = dx
|
||||||
stack.CARD_YOFFSET = dy
|
stack.CARD_YOFFSET = dy
|
||||||
s.rows.append(stack)
|
s.rows.append(stack)
|
||||||
|
@ -430,7 +437,7 @@ class AbstractMahjonggGame(Game):
|
||||||
# compute blockmap
|
# compute blockmap
|
||||||
for stack in s.rows:
|
for stack in s.rows:
|
||||||
level, tx, ty = tiles[stack.id]
|
level, tx, ty = tiles[stack.id]
|
||||||
above, below, left, right, up, bottom = {}, {}, {}, {}, {}, {}
|
above, below, left, right = {}, {}, {}, {}
|
||||||
# above blockers
|
# above blockers
|
||||||
for tl in range(level+1, level+2):
|
for tl in range(level+1, level+2):
|
||||||
above[tilemap.get((tl, tx, ty))] = 1
|
above[tilemap.get((tl, tx, ty))] = 1
|
||||||
|
@ -450,11 +457,11 @@ class AbstractMahjonggGame(Game):
|
||||||
right[tilemap.get((level, tx+2, ty))] = 1
|
right[tilemap.get((level, tx+2, ty))] = 1
|
||||||
right[tilemap.get((level, tx+2, ty+1))] = 1
|
right[tilemap.get((level, tx+2, ty+1))] = 1
|
||||||
# up blockers
|
# up blockers
|
||||||
##up[tilemap.get((level, tx, ty-1))] = 1
|
# up[tilemap.get((level, tx, ty-1))] = 1
|
||||||
##up[tilemap.get((level, tx+1, ty-1))] = 1
|
# up[tilemap.get((level, tx+1, ty-1))] = 1
|
||||||
# bottom blockers
|
# bottom blockers
|
||||||
##bottom[tilemap.get((level, tx, ty+2))] = 1
|
# bottom[tilemap.get((level, tx, ty+2))] = 1
|
||||||
##bottom[tilemap.get((level, tx+1, ty+2))] = 1
|
# bottom[tilemap.get((level, tx+1, ty+2))] = 1
|
||||||
# sanity check - assert that there are no overlapping tiles
|
# sanity check - assert that there are no overlapping tiles
|
||||||
assert tilemap.get((level, tx, ty)) is stack
|
assert tilemap.get((level, tx, ty)) is stack
|
||||||
assert tilemap.get((level, tx+1, ty)) is stack
|
assert tilemap.get((level, tx+1, ty)) is stack
|
||||||
|
@ -465,19 +472,19 @@ class AbstractMahjonggGame(Game):
|
||||||
below = tuple(filter(None, below.keys()))
|
below = tuple(filter(None, below.keys()))
|
||||||
left = tuple(filter(None, left.keys()))
|
left = tuple(filter(None, left.keys()))
|
||||||
right = tuple(filter(None, right.keys()))
|
right = tuple(filter(None, right.keys()))
|
||||||
##up = tuple(filter(None, up.keys()))
|
# up = tuple(filter(None, up.keys()))
|
||||||
##bottom = tuple(filter(None, bottom.keys()))
|
# bottom = tuple(filter(None, bottom.keys()))
|
||||||
|
|
||||||
# assemble
|
# assemble
|
||||||
stack.blockmap = Struct(
|
stack.blockmap = Struct(
|
||||||
above = above,
|
above=above,
|
||||||
below = below,
|
below=below,
|
||||||
left = left,
|
left=left,
|
||||||
right = right,
|
right=right,
|
||||||
##up = up,
|
# up=up,
|
||||||
##bottom = bottom,
|
# bottom=bottom,
|
||||||
all_left = None,
|
all_left=None,
|
||||||
all_right = None,
|
all_right=None,
|
||||||
)
|
)
|
||||||
|
|
||||||
def get_all_left(s):
|
def get_all_left(s):
|
||||||
|
@ -488,6 +495,7 @@ class AbstractMahjonggGame(Game):
|
||||||
get_all_left(t)
|
get_all_left(t)
|
||||||
s.blockmap.all_left.update(t.blockmap.all_left)
|
s.blockmap.all_left.update(t.blockmap.all_left)
|
||||||
s.blockmap.all_left[t] = 1
|
s.blockmap.all_left[t] = 1
|
||||||
|
|
||||||
def get_all_right(s):
|
def get_all_right(s):
|
||||||
if s.blockmap.all_right is None:
|
if s.blockmap.all_right is None:
|
||||||
s.blockmap.all_right = {}
|
s.blockmap.all_right = {}
|
||||||
|
@ -504,7 +512,6 @@ class AbstractMahjonggGame(Game):
|
||||||
r.blockmap.all_left = tuple(r.blockmap.all_left.keys())
|
r.blockmap.all_left = tuple(r.blockmap.all_left.keys())
|
||||||
r.blockmap.all_right = tuple(r.blockmap.all_right.keys())
|
r.blockmap.all_right = tuple(r.blockmap.all_right.keys())
|
||||||
|
|
||||||
|
|
||||||
# create other stacks
|
# create other stacks
|
||||||
for i in range(4):
|
for i in range(4):
|
||||||
for j in range(9):
|
for j in range(9):
|
||||||
|
@ -517,7 +524,7 @@ class AbstractMahjonggGame(Game):
|
||||||
y = l.YM+dyy
|
y = l.YM+dyy
|
||||||
elif TOOLKIT == 'gtk':
|
elif TOOLKIT == 'gtk':
|
||||||
# FIXME
|
# FIXME
|
||||||
x = self.width -l.XS
|
x = self.width - l.XS
|
||||||
y = self.height - l.YS
|
y = self.height - l.YS
|
||||||
stack = Mahjongg_Foundation(x, y, self)
|
stack = Mahjongg_Foundation(x, y, self)
|
||||||
if show_removed:
|
if show_removed:
|
||||||
|
@ -536,7 +543,6 @@ class AbstractMahjonggGame(Game):
|
||||||
# Define stack groups
|
# Define stack groups
|
||||||
l.defaultStackGroups()
|
l.defaultStackGroups()
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# game overrides
|
# game overrides
|
||||||
#
|
#
|
||||||
|
@ -554,7 +560,6 @@ class AbstractMahjonggGame(Game):
|
||||||
return cards
|
return cards
|
||||||
return new_cards
|
return new_cards
|
||||||
|
|
||||||
|
|
||||||
def _shuffleHook1(self, cards):
|
def _shuffleHook1(self, cards):
|
||||||
# old version; it generate a very easy layouts
|
# old version; it generate a very easy layouts
|
||||||
old_cards = cards[:]
|
old_cards = cards[:]
|
||||||
|
@ -625,10 +630,9 @@ class AbstractMahjonggGame(Game):
|
||||||
if new_cards:
|
if new_cards:
|
||||||
new_cards.reverse()
|
new_cards.reverse()
|
||||||
return new_cards
|
return new_cards
|
||||||
print 'oops! can\'t create a solvable game'
|
print('oops! can\'t create a solvable game')
|
||||||
return old_cards
|
return old_cards
|
||||||
|
|
||||||
|
|
||||||
def _shuffleHook2(self, rows, cards):
|
def _shuffleHook2(self, rows, cards):
|
||||||
|
|
||||||
start_time = time.time()
|
start_time = time.time()
|
||||||
|
@ -690,15 +694,16 @@ class AbstractMahjonggGame(Game):
|
||||||
break
|
break
|
||||||
|
|
||||||
# find suitable stacks
|
# find suitable stacks
|
||||||
## suitable_stacks = []
|
# suitable_stacks = []
|
||||||
## for r in rows:
|
# for r in rows:
|
||||||
## if nc[r.id] is None and is_suitable(r, nc):
|
# if nc[r.id] is None and is_suitable(r, nc):
|
||||||
## suitable_stacks.append(r)
|
# suitable_stacks.append(r)
|
||||||
suitable_stacks = [r for r in rows
|
suitable_stacks = [r for r in rows
|
||||||
if nc[r.id] is None and is_suitable(r, nc)]
|
if nc[r.id] is None and is_suitable(r, nc)]
|
||||||
|
|
||||||
old_pairs = []
|
old_pairs = []
|
||||||
i = factorial(len(suitable_stacks))/2/factorial(len(suitable_stacks)-2)
|
i = factorial(len(suitable_stacks))/2 \
|
||||||
|
/ factorial(len(suitable_stacks)-2)
|
||||||
for j in xrange(i):
|
for j in xrange(i):
|
||||||
if iters[0] > max_iters:
|
if iters[0] > max_iters:
|
||||||
return None
|
return None
|
||||||
|
@ -728,11 +733,11 @@ class AbstractMahjonggGame(Game):
|
||||||
if ret:
|
if ret:
|
||||||
ret = [x for x in ret if x != 1]
|
ret = [x for x in ret if x != 1]
|
||||||
return ret
|
return ret
|
||||||
nc[s1.id] = nc[s2.id] = None # try another way
|
nc[s1.id] = nc[s2.id] = None # try another way
|
||||||
|
|
||||||
return None
|
return None
|
||||||
|
|
||||||
new_cards = [None]*len(self.s.rows) # None - empty stack, 1 - non-used
|
new_cards = [None]*len(self.s.rows) # None - empty stack, 1 - non-used
|
||||||
drows = dict.fromkeys(rows) # optimization
|
drows = dict.fromkeys(rows) # optimization
|
||||||
for r in self.s.rows:
|
for r in self.s.rows:
|
||||||
if r not in drows:
|
if r not in drows:
|
||||||
|
@ -742,16 +747,16 @@ class AbstractMahjonggGame(Game):
|
||||||
while True:
|
while True:
|
||||||
ret = create_solvable(cards[:], new_cards)
|
ret = create_solvable(cards[:], new_cards)
|
||||||
if DEBUG:
|
if DEBUG:
|
||||||
print 'create_solvable time:', time.time() - start_time
|
print('create_solvable time:', time.time() - start_time)
|
||||||
if ret:
|
if ret:
|
||||||
ret.reverse()
|
ret.reverse()
|
||||||
return ret
|
return ret
|
||||||
if time.time() - start_time > max_time or \
|
if time.time() - start_time > max_time or \
|
||||||
iters[0] <= max_iters:
|
iters[0] <= max_iters:
|
||||||
print 'oops! can\'t create a solvable game'
|
print('oops! can\'t create a solvable game')
|
||||||
return None
|
return None
|
||||||
iters = [0]
|
iters = [0]
|
||||||
print 'oops! can\'t create a solvable game'
|
print('oops! can\'t create a solvable game')
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def _mahjonggShuffle(self):
|
def _mahjonggShuffle(self):
|
||||||
|
@ -785,13 +790,13 @@ class AbstractMahjonggGame(Game):
|
||||||
|
|
||||||
new_cards = self._shuffleHook2(rows, cards)
|
new_cards = self._shuffleHook2(rows, cards)
|
||||||
if new_cards is None:
|
if new_cards is None:
|
||||||
d = MfxMessageDialog(self.top, title=_('Warning'),
|
MfxMessageDialog(self.top, title=_('Warning'),
|
||||||
text=_('''\
|
text=_('''\
|
||||||
Sorry, I can\'t find
|
Sorry, I can\'t find
|
||||||
a solvable configuration.'''),
|
a solvable configuration.'''),
|
||||||
bitmap='warning')
|
bitmap='warning')
|
||||||
self.leaveState(old_state)
|
self.leaveState(old_state)
|
||||||
##self.finishMove()
|
# self.finishMove()
|
||||||
# hack
|
# hack
|
||||||
am = self.moves.current[0]
|
am = self.moves.current[0]
|
||||||
am.undo(self) # restore random
|
am.undo(self) # restore random
|
||||||
|
@ -817,7 +822,7 @@ a solvable configuration.'''),
|
||||||
|
|
||||||
def startGame(self):
|
def startGame(self):
|
||||||
assert len(self.s.talon.cards) == self.NCARDS
|
assert len(self.s.talon.cards) == self.NCARDS
|
||||||
#self.s.talon.dealRow(rows = self.s.rows, frames = 0)
|
# self.s.talon.dealRow(rows = self.s.rows, frames = 0)
|
||||||
n = 12
|
n = 12
|
||||||
self.s.talon.dealRow(rows=self.s.rows[:self.NCARDS-n], frames=0)
|
self.s.talon.dealRow(rows=self.s.rows[:self.NCARDS-n], frames=0)
|
||||||
self.startDealSample()
|
self.startDealSample()
|
||||||
|
@ -850,8 +855,8 @@ a solvable configuration.'''),
|
||||||
for t in stacks[i+1:]:
|
for t in stacks[i+1:]:
|
||||||
if self.cardsMatch(r.cards[0], t.cards[0]):
|
if self.cardsMatch(r.cards[0], t.cards[0]):
|
||||||
n += 1
|
n += 1
|
||||||
#if n == 3: n = 1
|
# if n == 3: n = 1
|
||||||
#elif n == 2: n = 0
|
# elif n == 2: n = 0
|
||||||
n = n % 2
|
n = n % 2
|
||||||
f += n
|
f += n
|
||||||
i += 1
|
i += 1
|
||||||
|
@ -881,7 +886,7 @@ a solvable configuration.'''),
|
||||||
# Mahjongg special: highlight all moveable tiles
|
# Mahjongg special: highlight all moveable tiles
|
||||||
return ((self.s.rows, 1),)
|
return ((self.s.rows, 1),)
|
||||||
|
|
||||||
def _highlightCards(self, info, sleep=1.5, delta=(1,1,1,1)):
|
def _highlightCards(self, info, sleep=1.5, delta=(1, 1, 1, 1)):
|
||||||
if not Image:
|
if not Image:
|
||||||
delta = (-self._delta_x, 0, 0, -self._delta_y)
|
delta = (-self._delta_x, 0, 0, -self._delta_y)
|
||||||
return Game._highlightCards(self, info, sleep=sleep, delta=delta)
|
return Game._highlightCards(self, info, sleep=sleep, delta=delta)
|
||||||
|
@ -895,9 +900,9 @@ a solvable configuration.'''),
|
||||||
for s, c1, c2, color in info:
|
for s, c1, c2, color in info:
|
||||||
assert c1 is c2
|
assert c1 is c2
|
||||||
assert c1 in s.cards
|
assert c1 in s.cards
|
||||||
tkraise = False
|
|
||||||
x, y = s.x, s.y
|
x, y = s.x, s.y
|
||||||
img = self.app.images.getHighlightedCard(c1.deck, c1.suit, c1.rank, 'black')
|
img = self.app.images.getHighlightedCard(
|
||||||
|
c1.deck, c1.suit, c1.rank, 'black')
|
||||||
if img is None:
|
if img is None:
|
||||||
continue
|
continue
|
||||||
img = MfxCanvasImage(self.canvas, x, y, image=img,
|
img = MfxCanvasImage(self.canvas, x, y, image=img,
|
||||||
|
@ -944,8 +949,8 @@ a solvable configuration.'''),
|
||||||
return self.getCardFaceImage(deck, suit, rank)
|
return self.getCardFaceImage(deck, suit, rank)
|
||||||
|
|
||||||
def _createCard(self, id, deck, suit, rank, x, y):
|
def _createCard(self, id, deck, suit, rank, x, y):
|
||||||
##if deck >= 1 and suit == 3 and rank >= 4:
|
# if deck >= 1 and suit == 3 and rank >= 4:
|
||||||
if deck%4 and suit == 3 and rank >= 4:
|
if deck % 4 and suit == 3 and rank >= 4:
|
||||||
return None
|
return None
|
||||||
return Game._createCard(self, id, deck, suit, rank, x, y)
|
return Game._createCard(self, id, deck, suit, rank, x, y)
|
||||||
|
|
||||||
|
@ -977,11 +982,11 @@ a solvable configuration.'''),
|
||||||
return card1.rank == card2.rank
|
return card1.rank == card2.rank
|
||||||
|
|
||||||
|
|
||||||
## mahjongg util
|
# mahjongg util
|
||||||
def comp_cardset(ncards):
|
def comp_cardset(ncards):
|
||||||
# calc decks, ranks & trumps
|
# calc decks, ranks & trumps
|
||||||
assert ncards % 4 == 0
|
assert ncards % 4 == 0
|
||||||
assert 0 < ncards <= 288 # ???
|
assert 0 < ncards <= 288 # ???
|
||||||
decks = 1
|
decks = 1
|
||||||
cards = ncards/4
|
cards = ncards/4
|
||||||
if ncards > 144:
|
if ncards > 144:
|
||||||
|
@ -1001,7 +1006,6 @@ def comp_cardset(ncards):
|
||||||
# * register a Mahjongg type game
|
# * register a Mahjongg type game
|
||||||
# ************************************************************************
|
# ************************************************************************
|
||||||
|
|
||||||
from new import classobj
|
|
||||||
|
|
||||||
def r(id, short_name, name=None, ncards=144, layout=None):
|
def r(id, short_name, name=None, ncards=144, layout=None):
|
||||||
assert layout
|
assert layout
|
||||||
|
@ -1014,7 +1018,7 @@ def r(id, short_name, name=None, ncards=144, layout=None):
|
||||||
gameclass.NCARDS = ncards
|
gameclass.NCARDS = ncards
|
||||||
decks, ranks, trumps = comp_cardset(ncards)
|
decks, ranks, trumps = comp_cardset(ncards)
|
||||||
gi = GameInfo(id, gameclass, name,
|
gi = GameInfo(id, gameclass, name,
|
||||||
GI.GT_MAHJONGG, 4*decks, 0, ##GI.SL_MOSTLY_SKILL,
|
GI.GT_MAHJONGG, 4*decks, 0, # GI.SL_MOSTLY_SKILL,
|
||||||
category=GI.GC_MAHJONGG, short_name=short_name,
|
category=GI.GC_MAHJONGG, short_name=short_name,
|
||||||
suits=range(3), ranks=range(ranks), trumps=range(trumps),
|
suits=range(3), ranks=range(ranks), trumps=range(trumps),
|
||||||
si={"decks": decks, "ncards": ncards})
|
si={"decks": decks, "ncards": ncards})
|
||||||
|
@ -1022,4 +1026,3 @@ def r(id, short_name, name=None, ncards=144, layout=None):
|
||||||
gi.rules_filename = "mahjongg.html"
|
gi.rules_filename = "mahjongg.html"
|
||||||
registerGame(gi)
|
registerGame(gi)
|
||||||
return gi
|
return gi
|
||||||
|
|
||||||
|
|
|
@ -24,10 +24,10 @@
|
||||||
from mahjongg import r
|
from mahjongg import r
|
||||||
|
|
||||||
# test
|
# test
|
||||||
#r(5991, "AAA 1", ncards=4, layout="0daa")
|
# r(5991, "AAA 1", ncards=4, layout="0daa")
|
||||||
#r(5992, "AAA 2", ncards=8, layout="0daadca")
|
# r(5992, "AAA 2", ncards=8, layout="0daadca")
|
||||||
#r(5993, "AAA 3", ncards=20, layout="0daaCabdacKbbdcaCcbdcc")
|
# r(5993, "AAA 3", ncards=20, layout="0daaCabdacKbbdcaCcbdcc")
|
||||||
#r(5994, "AAA 4", ncards=20, layout="0daaDabdacdcaDcbdcc")
|
# r(5994, "AAA 4", ncards=20, layout="0daaDabdacdcaDcbdcc")
|
||||||
|
|
||||||
# ************************************************************************
|
# ************************************************************************
|
||||||
# * game definitions
|
# * game definitions
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
# -*- mode: python; coding: utf-8; -*-
|
# -*- mode: python; coding: utf-8; -*-
|
||||||
# ---------------------------------------------------------------------------##
|
# ---------------------------------------------------------------------------
|
||||||
#
|
#
|
||||||
# Copyright (C) 1998-2003 Markus Franz Xaver Johannes Oberhumer
|
# Copyright (C) 1998-2003 Markus Franz Xaver Johannes Oberhumer
|
||||||
# Copyright (C) 2003 Mt. Hood Playing Card Co.
|
# Copyright (C) 2003 Mt. Hood Playing Card Co.
|
||||||
|
@ -19,36 +19,43 @@
|
||||||
# You should have received a copy of the GNU General Public License
|
# You should have received a copy of the GNU General Public License
|
||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
#
|
#
|
||||||
# ---------------------------------------------------------------------------##
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
__all__ = []
|
__all__ = []
|
||||||
|
|
||||||
# Imports
|
# Imports
|
||||||
import sys
|
import sys
|
||||||
#from tkFont import Font
|
# from tkFont import Font
|
||||||
from gettext import ungettext
|
from gettext import ungettext
|
||||||
|
|
||||||
# PySol imports
|
# PySol imports
|
||||||
from pysollib.mygettext import _, n_
|
from pysollib.mygettext import _
|
||||||
from pysollib.gamedb import registerGame, GameInfo, GI
|
from pysollib.gamedb import registerGame, GameInfo, GI
|
||||||
from pysollib.util import *
|
|
||||||
from pysollib.mfxutil import kwdefault
|
from pysollib.mfxutil import kwdefault
|
||||||
from pysollib.stack import *
|
|
||||||
from pysollib.game import Game
|
|
||||||
from pysollib.layout import Layout
|
from pysollib.layout import Layout
|
||||||
from pysollib.hint import AbstractHint, DefaultHint, CautiousDefaultHint
|
from pysollib.hint import AbstractHint
|
||||||
from pysollib.pysoltk import MfxCanvasText, MfxCanvasLine
|
from pysollib.pysoltk import MfxCanvasText, MfxCanvasLine
|
||||||
|
|
||||||
from mahjongg import Mahjongg_RowStack, AbstractMahjonggGame, comp_cardset
|
from mahjongg import Mahjongg_RowStack, AbstractMahjonggGame, comp_cardset
|
||||||
|
|
||||||
|
from pysollib.util import ANY_SUIT
|
||||||
|
|
||||||
|
from pysollib.stack import \
|
||||||
|
AbstractFoundationStack, \
|
||||||
|
InitialDealTalonStack
|
||||||
|
|
||||||
|
if sys.version_info > (3,):
|
||||||
|
xrange = range
|
||||||
|
|
||||||
# ************************************************************************
|
# ************************************************************************
|
||||||
# *
|
# *
|
||||||
# ************************************************************************
|
# ************************************************************************
|
||||||
|
|
||||||
|
|
||||||
class Shisen_Hint(AbstractHint):
|
class Shisen_Hint(AbstractHint):
|
||||||
TOP_MATCHING = False
|
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
|
||||||
# get free stacks
|
# get free stacks
|
||||||
|
@ -60,7 +67,7 @@ class Shisen_Hint(AbstractHint):
|
||||||
i = 0
|
i = 0
|
||||||
for r in stacks:
|
for r in stacks:
|
||||||
for t in stacks[i+1:]:
|
for t in stacks[i+1:]:
|
||||||
#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...
|
||||||
if self.TOP_MATCHING:
|
if self.TOP_MATCHING:
|
||||||
|
@ -122,7 +129,7 @@ class Shisen_RowStack(Mahjongg_RowStack):
|
||||||
if nx < 0 or ny < 0 or nx > cols+1 or ny > rows+1:
|
if nx < 0 or ny < 0 or nx > cols+1 or ny > rows+1:
|
||||||
return 0
|
return 0
|
||||||
if nx in (0, cols+1) or ny in (0, rows+1) \
|
if nx in (0, cols+1) or ny in (0, rows+1) \
|
||||||
or not game_cols[nx-1][ny-1].cards:
|
or not game_cols[nx-1][ny-1].cards:
|
||||||
if direct_chng_cnt == 0:
|
if direct_chng_cnt == 0:
|
||||||
return 1
|
return 1
|
||||||
elif direct_chng_cnt == 1:
|
elif direct_chng_cnt == 1:
|
||||||
|
@ -159,20 +166,21 @@ class Shisen_RowStack(Mahjongg_RowStack):
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
res_path = [None]
|
res_path = [None]
|
||||||
|
|
||||||
def do_accepts(x, y, direct, direct_chng_cnt, path):
|
def do_accepts(x, y, direct, direct_chng_cnt, path):
|
||||||
#if direct_chng_cnt > 3:
|
# if direct_chng_cnt > 3:
|
||||||
# return
|
# return
|
||||||
if a[x][y] < direct_chng_cnt:
|
if a[x][y] < direct_chng_cnt:
|
||||||
return
|
return
|
||||||
#if res_path[0]:
|
# if res_path[0]:
|
||||||
# return
|
# return
|
||||||
a[x][y] = direct_chng_cnt
|
a[x][y] = direct_chng_cnt
|
||||||
if x == x2 and y == y2:
|
if x == x2 and y == y2:
|
||||||
res_path[0] = path
|
res_path[0] = path
|
||||||
return
|
return
|
||||||
|
|
||||||
if can_move(x, y, x, y+1, direct, 1, direct_chng_cnt): #### 1
|
if can_move(x, y, x, y+1, direct, 1, direct_chng_cnt): # 1
|
||||||
#dcc = direct == 1 and direct_chng_cnt or direct_chng_cnt+1
|
# dcc = direct == 1 and direct_chng_cnt or direct_chng_cnt+1
|
||||||
p = path[:]
|
p = path[:]
|
||||||
if direct == 1:
|
if direct == 1:
|
||||||
dcc = direct_chng_cnt
|
dcc = direct_chng_cnt
|
||||||
|
@ -180,8 +188,8 @@ class Shisen_RowStack(Mahjongg_RowStack):
|
||||||
dcc = direct_chng_cnt+1
|
dcc = direct_chng_cnt+1
|
||||||
p.append((x, y))
|
p.append((x, y))
|
||||||
do_accepts(x, y+1, 1, dcc, p)
|
do_accepts(x, y+1, 1, dcc, p)
|
||||||
if can_move(x, y, x, y-1, direct, 2, direct_chng_cnt): #### 2
|
if can_move(x, y, x, y-1, direct, 2, direct_chng_cnt): # 2
|
||||||
#dcc = direct == 2 and direct_chng_cnt or direct_chng_cnt+1
|
# dcc = direct == 2 and direct_chng_cnt or direct_chng_cnt+1
|
||||||
p = path[:]
|
p = path[:]
|
||||||
if direct == 2:
|
if direct == 2:
|
||||||
dcc = direct_chng_cnt
|
dcc = direct_chng_cnt
|
||||||
|
@ -189,8 +197,8 @@ class Shisen_RowStack(Mahjongg_RowStack):
|
||||||
dcc = direct_chng_cnt+1
|
dcc = direct_chng_cnt+1
|
||||||
p.append((x, y))
|
p.append((x, y))
|
||||||
do_accepts(x, y-1, 2, dcc, p)
|
do_accepts(x, y-1, 2, dcc, p)
|
||||||
if can_move(x, y, x+1, y, direct, 3, direct_chng_cnt): #### 3
|
if can_move(x, y, x+1, y, direct, 3, direct_chng_cnt): # 3
|
||||||
#dcc = direct == 3 and direct_chng_cnt or direct_chng_cnt+1
|
# dcc = direct == 3 and direct_chng_cnt or direct_chng_cnt+1
|
||||||
p = path[:]
|
p = path[:]
|
||||||
if direct == 3:
|
if direct == 3:
|
||||||
dcc = direct_chng_cnt
|
dcc = direct_chng_cnt
|
||||||
|
@ -198,8 +206,8 @@ class Shisen_RowStack(Mahjongg_RowStack):
|
||||||
dcc = direct_chng_cnt+1
|
dcc = direct_chng_cnt+1
|
||||||
p.append((x, y))
|
p.append((x, y))
|
||||||
do_accepts(x+1, y, 3, dcc, p)
|
do_accepts(x+1, y, 3, dcc, p)
|
||||||
if can_move(x, y, x-1, y, direct, 4, direct_chng_cnt): #### 4
|
if can_move(x, y, x-1, y, direct, 4, direct_chng_cnt): # 4
|
||||||
#dcc = direct == 4 and direct_chng_cnt or direct_chng_cnt+1
|
# dcc = direct == 4 and direct_chng_cnt or direct_chng_cnt+1
|
||||||
p = path[:]
|
p = path[:]
|
||||||
if direct == 4:
|
if direct == 4:
|
||||||
dcc = direct_chng_cnt
|
dcc = direct_chng_cnt
|
||||||
|
@ -209,18 +217,17 @@ class Shisen_RowStack(Mahjongg_RowStack):
|
||||||
do_accepts(x-1, y, 4, dcc, p)
|
do_accepts(x-1, y, 4, dcc, p)
|
||||||
|
|
||||||
do_accepts(x1, y1, 0, 0, [])
|
do_accepts(x1, y1, 0, 0, [])
|
||||||
#from pprint import pprint
|
# from pprint import pprint
|
||||||
#pprint(a)
|
# pprint(a)
|
||||||
|
|
||||||
if a[x2][y2] > 3:
|
if a[x2][y2] > 3:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
res_path = res_path[0]
|
res_path = res_path[0]
|
||||||
res_path.append((x2, y2))
|
res_path.append((x2, y2))
|
||||||
#print res_path
|
# print res_path
|
||||||
return res_path
|
return res_path
|
||||||
|
|
||||||
|
|
||||||
def fillStack(self):
|
def fillStack(self):
|
||||||
self.game.fillStack(self)
|
self.game.fillStack(self)
|
||||||
|
|
||||||
|
@ -229,13 +236,14 @@ class Shisen_RowStack(Mahjongg_RowStack):
|
||||||
if to_stack.cards:
|
if to_stack.cards:
|
||||||
self._dropPairMove(ncards, to_stack, frames=-1, shadow=shadow)
|
self._dropPairMove(ncards, to_stack, frames=-1, shadow=shadow)
|
||||||
else:
|
else:
|
||||||
Mahjongg_RowStack.moveMove(self, ncards, to_stack, frames=frames, shadow=shadow)
|
Mahjongg_RowStack.moveMove(self, ncards, to_stack, frames=frames,
|
||||||
|
shadow=shadow)
|
||||||
|
|
||||||
def _dropPairMove(self, n, other_stack, frames=-1, shadow=-1):
|
def _dropPairMove(self, n, other_stack, frames=-1, shadow=-1):
|
||||||
game = self.game
|
game = self.game
|
||||||
old_state = game.enterState(game.S_FILL)
|
old_state = game.enterState(game.S_FILL)
|
||||||
f = game.s.foundations[0]
|
f = game.s.foundations[0]
|
||||||
game.updateStackMove(game.s.talon, 2|16) # for undo
|
game.updateStackMove(game.s.talon, 2 | 16) # for undo
|
||||||
if not game.demo:
|
if not game.demo:
|
||||||
if game.app.opt.shisen_show_hint:
|
if game.app.opt.shisen_show_hint:
|
||||||
self.drawArrow(other_stack, game.app.opt.timeouts['hint'])
|
self.drawArrow(other_stack, game.app.opt.timeouts['hint'])
|
||||||
|
@ -245,23 +253,22 @@ class Shisen_RowStack(Mahjongg_RowStack):
|
||||||
game.moveMove(n, other_stack, f, frames=frames, shadow=shadow)
|
game.moveMove(n, other_stack, f, frames=frames, shadow=shadow)
|
||||||
self.fillStack()
|
self.fillStack()
|
||||||
other_stack.fillStack()
|
other_stack.fillStack()
|
||||||
game.updateStackMove(game.s.talon, 1|16) # for redo
|
game.updateStackMove(game.s.talon, 1 | 16) # for redo
|
||||||
game.leaveState(old_state)
|
game.leaveState(old_state)
|
||||||
|
|
||||||
|
|
||||||
def drawArrow(self, other_stack, sleep):
|
def drawArrow(self, other_stack, sleep):
|
||||||
game = self.game
|
game = self.game
|
||||||
images = game.app.images
|
images = game.app.images
|
||||||
cs = game.app.cardset
|
cs = game.app.cardset
|
||||||
path = self.acceptsCards(other_stack, [other_stack.cards[-1]])
|
path = self.acceptsCards(other_stack, [other_stack.cards[-1]])
|
||||||
#print path
|
# print path
|
||||||
x0, y0 = game.XMARGIN, game.YMARGIN
|
x0, y0 = game.XMARGIN, game.YMARGIN
|
||||||
cardw, cardh = images.CARDW, images.CARDH
|
cardw, cardh = images.CARDW, images.CARDH
|
||||||
if cs.version >= 6:
|
if cs.version >= 6:
|
||||||
cardw -= cs.SHADOW_XOFFSET
|
cardw -= cs.SHADOW_XOFFSET
|
||||||
cardh -= cs.SHADOW_YOFFSET
|
cardh -= cs.SHADOW_YOFFSET
|
||||||
coords = []
|
coords = []
|
||||||
dx, dy = game._delta_x, game._delta_y
|
dx = game._delta_x
|
||||||
xf, yf = images._xfactor, images._yfactor
|
xf, yf = images._xfactor, images._yfactor
|
||||||
for x, y in path:
|
for x, y in path:
|
||||||
if x == 0:
|
if x == 0:
|
||||||
|
@ -276,17 +283,17 @@ class Shisen_RowStack(Mahjongg_RowStack):
|
||||||
coords.append(int(round(yf * (y0+cardh*(y-1)+6))))
|
coords.append(int(round(yf * (y0+cardh*(y-1)+6))))
|
||||||
else:
|
else:
|
||||||
coords.append(int(round(yf * (y0+cardh/2+cardh*(y-1)))))
|
coords.append(int(round(yf * (y0+cardh/2+cardh*(y-1)))))
|
||||||
#print coords
|
# print coords
|
||||||
##s1 = min(cardw/2, cardh/2, 30)
|
# s1 = min(cardw/2, cardh/2, 30)
|
||||||
##w = min(s1/3, 7)
|
# w = min(s1/3, 7)
|
||||||
##s2 = min(w, 10)
|
# s2 = min(w, 10)
|
||||||
w = 7
|
w = 7
|
||||||
arrow = MfxCanvasLine(game.canvas,
|
arrow = MfxCanvasLine(game.canvas,
|
||||||
coords,
|
coords,
|
||||||
{'width': w,
|
{'width': w,
|
||||||
'fill': game.app.opt.colors['hintarrow'],
|
'fill': game.app.opt.colors['hintarrow'],
|
||||||
##'arrow': 'last',
|
# 'arrow': 'last',
|
||||||
##'arrowshape': (s1, s1, s2)
|
# 'arrowshape': (s1, s1, s2)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
game.canvas.update_idletasks()
|
game.canvas.update_idletasks()
|
||||||
|
@ -297,10 +304,10 @@ class Shisen_RowStack(Mahjongg_RowStack):
|
||||||
|
|
||||||
|
|
||||||
class AbstractShisenGame(AbstractMahjonggGame):
|
class AbstractShisenGame(AbstractMahjonggGame):
|
||||||
Hint_Class = NotShisen_Hint #Shisen_Hint
|
Hint_Class = NotShisen_Hint # Shisen_Hint
|
||||||
RowStack_Class = Shisen_RowStack
|
RowStack_Class = Shisen_RowStack
|
||||||
|
|
||||||
#NCARDS = 144
|
# NCARDS = 144
|
||||||
GRAVITY = True
|
GRAVITY = True
|
||||||
|
|
||||||
def createGame(self):
|
def createGame(self):
|
||||||
|
@ -309,7 +316,7 @@ class AbstractShisenGame(AbstractMahjonggGame):
|
||||||
|
|
||||||
# start layout
|
# start layout
|
||||||
l, s = Layout(self), self.s
|
l, s = Layout(self), self.s
|
||||||
##dx, dy = 3, -3
|
# dx, dy = 3, -3
|
||||||
|
|
||||||
cs = self.app.cardset
|
cs = self.app.cardset
|
||||||
if cs.version >= 6:
|
if cs.version >= 6:
|
||||||
|
@ -328,7 +335,7 @@ class AbstractShisenGame(AbstractMahjonggGame):
|
||||||
font = self.app.getFont("canvas_default")
|
font = self.app.getFont("canvas_default")
|
||||||
|
|
||||||
# width of self.texts.info
|
# width of self.texts.info
|
||||||
#ti_width = Font(self.canvas, font).measure(_('Remaining'))
|
# ti_width = Font(self.canvas, font).measure(_('Remaining'))
|
||||||
ti_width = 80
|
ti_width = 80
|
||||||
|
|
||||||
# set window size
|
# set window size
|
||||||
|
@ -358,8 +365,8 @@ class AbstractShisenGame(AbstractMahjonggGame):
|
||||||
stack.coln, stack.rown = col, row
|
stack.coln, stack.rown = col, row
|
||||||
s.rows.append(stack)
|
s.rows.append(stack)
|
||||||
self.cols[col].append(stack)
|
self.cols[col].append(stack)
|
||||||
#from pprint import pprint
|
# from pprint import pprint
|
||||||
#pprint(self.cols)
|
# pprint(self.cols)
|
||||||
|
|
||||||
# create other stacks
|
# create other stacks
|
||||||
y = l.YM + dyy
|
y = l.YM + dyy
|
||||||
|
@ -376,7 +383,8 @@ class AbstractShisenGame(AbstractMahjonggGame):
|
||||||
l.defaultStackGroups()
|
l.defaultStackGroups()
|
||||||
|
|
||||||
def fillStack(self, stack):
|
def fillStack(self, stack):
|
||||||
if not self.GRAVITY: return
|
if not self.GRAVITY:
|
||||||
|
return
|
||||||
to_stack = stack
|
to_stack = stack
|
||||||
for from_stack in self.cols[stack.coln][stack.rown+1::-1]:
|
for from_stack in self.cols[stack.coln][stack.rown+1::-1]:
|
||||||
if not from_stack.cards:
|
if not from_stack.cards:
|
||||||
|
@ -419,13 +427,11 @@ class AbstractShisenGame(AbstractMahjonggGame):
|
||||||
self.NCARDS - t) % (self.NCARDS - t)
|
self.NCARDS - t) % (self.NCARDS - t)
|
||||||
|
|
||||||
t = r1 + r2 + f
|
t = r1 + r2 + f
|
||||||
self.texts.info.config(text = t)
|
self.texts.info.config(text=t)
|
||||||
|
|
||||||
|
|
||||||
def drawHintArrow(self, from_stack, to_stack, ncards, sleep):
|
def drawHintArrow(self, from_stack, to_stack, ncards, sleep):
|
||||||
from_stack.drawArrow(to_stack, sleep)
|
from_stack.drawArrow(to_stack, sleep)
|
||||||
|
|
||||||
|
|
||||||
def _shuffleHook(self, cards):
|
def _shuffleHook(self, cards):
|
||||||
return cards
|
return cards
|
||||||
|
|
||||||
|
@ -436,23 +442,28 @@ class AbstractShisenGame(AbstractMahjonggGame):
|
||||||
class Shisen_18x8(AbstractShisenGame):
|
class Shisen_18x8(AbstractShisenGame):
|
||||||
L = (18, 8)
|
L = (18, 8)
|
||||||
|
|
||||||
|
|
||||||
class Shisen_14x6(AbstractShisenGame):
|
class Shisen_14x6(AbstractShisenGame):
|
||||||
L = (14, 6)
|
L = (14, 6)
|
||||||
NCARDS = 84
|
NCARDS = 84
|
||||||
|
|
||||||
|
|
||||||
class Shisen_24x12(AbstractShisenGame):
|
class Shisen_24x12(AbstractShisenGame):
|
||||||
L = (24, 12)
|
L = (24, 12)
|
||||||
NCARDS = 288
|
NCARDS = 288
|
||||||
|
|
||||||
|
|
||||||
class Shisen_18x8_NoGravity(AbstractShisenGame):
|
class Shisen_18x8_NoGravity(AbstractShisenGame):
|
||||||
L = (18, 8)
|
L = (18, 8)
|
||||||
GRAVITY = False
|
GRAVITY = False
|
||||||
|
|
||||||
|
|
||||||
class Shisen_14x6_NoGravity(AbstractShisenGame):
|
class Shisen_14x6_NoGravity(AbstractShisenGame):
|
||||||
L = (14, 6)
|
L = (14, 6)
|
||||||
NCARDS = 84
|
NCARDS = 84
|
||||||
GRAVITY = False
|
GRAVITY = False
|
||||||
|
|
||||||
|
|
||||||
class Shisen_24x12_NoGravity(AbstractShisenGame):
|
class Shisen_24x12_NoGravity(AbstractShisenGame):
|
||||||
L = (24, 12)
|
L = (24, 12)
|
||||||
NCARDS = 288
|
NCARDS = 288
|
||||||
|
@ -479,11 +490,13 @@ class NotShisen_14x6(AbstractShisenGame):
|
||||||
L = (14, 6)
|
L = (14, 6)
|
||||||
NCARDS = 84
|
NCARDS = 84
|
||||||
|
|
||||||
|
|
||||||
class NotShisen_18x8(AbstractShisenGame):
|
class NotShisen_18x8(AbstractShisenGame):
|
||||||
Hint_Class = NotShisen_Hint
|
Hint_Class = NotShisen_Hint
|
||||||
RowStack_Class = NotShisen_RowStack
|
RowStack_Class = NotShisen_RowStack
|
||||||
L = (18, 8)
|
L = (18, 8)
|
||||||
|
|
||||||
|
|
||||||
class NotShisen_24x12(AbstractShisenGame):
|
class NotShisen_24x12(AbstractShisenGame):
|
||||||
Hint_Class = NotShisen_Hint
|
Hint_Class = NotShisen_Hint
|
||||||
RowStack_Class = NotShisen_RowStack
|
RowStack_Class = NotShisen_RowStack
|
||||||
|
@ -507,6 +520,7 @@ def r(id, gameclass, name, rules_filename="shisensho.html"):
|
||||||
registerGame(gi)
|
registerGame(gi)
|
||||||
return gi
|
return gi
|
||||||
|
|
||||||
|
|
||||||
r(11001, Shisen_14x6, "Shisen-Sho 14x6")
|
r(11001, Shisen_14x6, "Shisen-Sho 14x6")
|
||||||
r(11002, Shisen_18x8, "Shisen-Sho 18x8")
|
r(11002, Shisen_18x8, "Shisen-Sho 18x8")
|
||||||
r(11003, Shisen_24x12, "Shisen-Sho 24x12")
|
r(11003, Shisen_24x12, "Shisen-Sho 24x12")
|
||||||
|
|
|
@ -13,6 +13,10 @@ my %skip =
|
||||||
map { $_ => 1 }
|
map { $_ => 1 }
|
||||||
qw(
|
qw(
|
||||||
./pysollib/games/__init__.py
|
./pysollib/games/__init__.py
|
||||||
|
./pysollib/games/mahjongg/__init__.py
|
||||||
|
./pysollib/games/mahjongg/mahjongg1.py
|
||||||
|
./pysollib/games/mahjongg/mahjongg2.py
|
||||||
|
./pysollib/games/mahjongg/mahjongg3.py
|
||||||
./pysollib/games/ultra/__init__.py
|
./pysollib/games/ultra/__init__.py
|
||||||
./pysollib/pysoltk.py
|
./pysollib/pysoltk.py
|
||||||
./pysollib/tile/ttk.py
|
./pysollib/tile/ttk.py
|
||||||
|
@ -21,7 +25,7 @@ my %skip =
|
||||||
|
|
||||||
# my $cmd = shell_quote( 'flake8', '.' );
|
# my $cmd = shell_quote( 'flake8', '.' );
|
||||||
my $cmd = shell_quote( 'flake8',
|
my $cmd = shell_quote( 'flake8',
|
||||||
grep { not exists $skip{$_} } glob('./pysollib/*.py ./pysollib/[cmpuw]*/*.py ./pysollib/tile/*.py ./pysollib/ui/tktile/*.py ./pysollib/games/*.py ./pysollib/games/ultra/*.py') );
|
grep { not exists $skip{$_} } glob('./pysollib/*.py ./pysollib/[cmpuw]*/*.py ./pysollib/tile/*.py ./pysollib/ui/tktile/*.py ./pysollib/games/*.py ./pysollib/games/[mu]*/*.py') );
|
||||||
|
|
||||||
# TEST
|
# TEST
|
||||||
eq_or_diff( scalar(`$cmd`), '', "flake8 is happy with the code." );
|
eq_or_diff( scalar(`$cmd`), '', "flake8 is happy with the code." );
|
||||||
|
|
Loading…
Add table
Reference in a new issue