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

flake8 - mahjongg

This commit is contained in:
Shlomi Fish 2017-04-18 14:37:17 +03:00
parent 2ea7cf48ea
commit 2505afdb68
4 changed files with 165 additions and 144 deletions

View file

@ -1,6 +1,6 @@
#!/usr/bin/env python
# -*- mode: python; coding: utf-8; -*-
# ---------------------------------------------------------------------------##
# ---------------------------------------------------------------------------
#
# Copyright (C) 1998-2003 Markus Franz Xaver Johannes Oberhumer
# Copyright (C) 2003 Mt. Hood Playing Card Co.
@ -19,30 +19,40 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
# ---------------------------------------------------------------------------##
# ---------------------------------------------------------------------------
__all__ = []
# Imports
import sys, re
import sys
import re
import time
# from tkFont import Font
from gettext import ungettext
# PySol imports
from pysollib.mygettext import _, n_
from pysollib.mygettext import _
from pysollib.gamedb import registerGame, GameInfo, GI
from pysollib.util import *
from pysollib.mfxutil import kwdefault, Struct, Image
from pysollib.stack import *
from pysollib.game import Game
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.pysoltk import MfxCanvasText, MfxCanvasImage
from pysollib.pysoltk import bind, EVENT_HANDLED, ANCHOR_NW
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):
if x <= 1:
@ -72,7 +82,7 @@ class Mahjongg_Hint(AbstractHint):
for t in stacks[i+1:]:
if game.cardsMatch(r.cards[0], t.cards[0]):
# simple scoring...
##score = 10000 + r.id + t.id
# score = 10000 + r.id + t.id
rb = r.blockmap
tb = t.blockmap
score = \
@ -166,8 +176,9 @@ class Mahjongg_RowStack(OpenStack):
self._dropPairMove(ncards, to_stack, frames=-1, shadow=shadow)
def _dropPairMove(self, n, other_stack, frames=-1, shadow=-1):
##print 'drop:', self.id, other_stack.id
assert n == 1 and self.acceptsCards(other_stack, [other_stack.cards[-1]])
# print 'drop:', self.id, other_stack.id
assert n == 1 and self.acceptsCards(
other_stack, [other_stack.cards[-1]])
if not self.game.demo:
self.game.playSample("droppair", priority=200)
old_state = self.game.enterState(self.game.S_FILL)
@ -213,7 +224,6 @@ class Mahjongg_RowStack(OpenStack):
for s in self.game.s.rows[self.id+1:]:
s.group.tkraise()
# In Mahjongg games type there are a lot of stacks, so we optimize
# and don't create bindings that are not used anyway.
def initBindings(self):
@ -226,8 +236,8 @@ class Mahjongg_RowStack(OpenStack):
bind(group, "<1>", self.__clickEventHandler)
bind(group, "<3>", self.__controlclickEventHandler)
bind(group, "<Control-1>", self.__controlclickEventHandler)
##bind(group, "<Enter>", self._Stack__enterEventHandler)
##bind(group, "<Leave>", self._Stack__leaveEventHandler)
# bind(group, "<Enter>", self._Stack__enterEventHandler)
# bind(group, "<Leave>", self._Stack__leaveEventHandler)
def __defaultClickEventHandler(self, event, handler):
self.game.event_handled = True # for Game.undoHandler
@ -239,7 +249,7 @@ class Mahjongg_RowStack(OpenStack):
return EVENT_HANDLED
def __clickEventHandler(self, event):
##print 'click:', self.id
# print 'click:', self.id
return self.__defaultClickEventHandler(event, self.clickHandler)
def __controlclickEventHandler(self, event):
@ -259,8 +269,8 @@ class Mahjongg_RowStack(OpenStack):
self._stopDrag()
return 1
if self.basicIsBlocked():
### remove selection
##self.game.playSample("nomove")
# remove selection
# self.game.playSample("nomove")
return 1
# possible move
if from_stack:
@ -277,7 +287,8 @@ class Mahjongg_RowStack(OpenStack):
drag.shade_img.delete()
# game.canvas.delete(drag.shade_img)
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:
return 1
img = MfxCanvasImage(game.canvas, self.x, self.y, image=img,
@ -339,7 +350,6 @@ class AbstractMahjonggGame(Game):
# tiles = tuple(tiles)
return tiles, max_tl, max_tx, max_ty
#
# game layout
#
@ -351,8 +361,8 @@ class AbstractMahjonggGame(Game):
l, s = Layout(self), self.s
show_removed = self.app.opt.mahjongg_show_removed
##dx, dy = 2, -2
##dx, dy = 3, -3
# dx, dy = 2, -2
# dx, dy = 3, -3
cs = self.app.cardset
if cs.version >= 6:
dx = l.XOFFSET
@ -403,10 +413,7 @@ class AbstractMahjonggGame(Game):
self.check_dist = l.CW*l.CW + l.CH*l.CH # see _getClosestStack()
# sort tiles (for 3D)
tiles.sort(lambda a, b:
cmp(a[0], b[0]) or
cmp(-a[1]+a[2], -b[1]+b[2])
)
tiles.sort(key=lambda x: (x[0], x[2]-x[1]))
# create a row stack for each tile and compute the tilemap
tilemap = {}
@ -417,7 +424,7 @@ class AbstractMahjonggGame(Game):
x = x0 + (tx * cardw) / 2 + level * dx
y = y0 + (ty * cardh) / 2 + level * dy
stack = self.RowStack_Class(x, y, self)
##stack.G = (level, tx, ty)
# stack.G = (level, tx, ty)
stack.CARD_XOFFSET = dx
stack.CARD_YOFFSET = dy
s.rows.append(stack)
@ -430,7 +437,7 @@ class AbstractMahjonggGame(Game):
# compute blockmap
for stack in s.rows:
level, tx, ty = tiles[stack.id]
above, below, left, right, up, bottom = {}, {}, {}, {}, {}, {}
above, below, left, right = {}, {}, {}, {}
# above blockers
for tl in range(level+1, level+2):
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))] = 1
# up blockers
##up[tilemap.get((level, tx, ty-1))] = 1
##up[tilemap.get((level, tx+1, ty-1))] = 1
# up[tilemap.get((level, tx, ty-1))] = 1
# up[tilemap.get((level, tx+1, ty-1))] = 1
# bottom blockers
##bottom[tilemap.get((level, tx, ty+2))] = 1
##bottom[tilemap.get((level, tx+1, ty+2))] = 1
# bottom[tilemap.get((level, tx, ty+2))] = 1
# bottom[tilemap.get((level, tx+1, ty+2))] = 1
# sanity check - assert that there are no overlapping tiles
assert tilemap.get((level, tx, ty)) is stack
assert tilemap.get((level, tx+1, ty)) is stack
@ -465,8 +472,8 @@ class AbstractMahjonggGame(Game):
below = tuple(filter(None, below.keys()))
left = tuple(filter(None, left.keys()))
right = tuple(filter(None, right.keys()))
##up = tuple(filter(None, up.keys()))
##bottom = tuple(filter(None, bottom.keys()))
# up = tuple(filter(None, up.keys()))
# bottom = tuple(filter(None, bottom.keys()))
# assemble
stack.blockmap = Struct(
@ -474,8 +481,8 @@ class AbstractMahjonggGame(Game):
below=below,
left=left,
right=right,
##up = up,
##bottom = bottom,
# up=up,
# bottom=bottom,
all_left=None,
all_right=None,
)
@ -488,6 +495,7 @@ class AbstractMahjonggGame(Game):
get_all_left(t)
s.blockmap.all_left.update(t.blockmap.all_left)
s.blockmap.all_left[t] = 1
def get_all_right(s):
if s.blockmap.all_right is None:
s.blockmap.all_right = {}
@ -504,7 +512,6 @@ class AbstractMahjonggGame(Game):
r.blockmap.all_left = tuple(r.blockmap.all_left.keys())
r.blockmap.all_right = tuple(r.blockmap.all_right.keys())
# create other stacks
for i in range(4):
for j in range(9):
@ -536,7 +543,6 @@ class AbstractMahjonggGame(Game):
# Define stack groups
l.defaultStackGroups()
#
# game overrides
#
@ -554,7 +560,6 @@ class AbstractMahjonggGame(Game):
return cards
return new_cards
def _shuffleHook1(self, cards):
# old version; it generate a very easy layouts
old_cards = cards[:]
@ -625,10 +630,9 @@ class AbstractMahjonggGame(Game):
if new_cards:
new_cards.reverse()
return new_cards
print 'oops! can\'t create a solvable game'
print('oops! can\'t create a solvable game')
return old_cards
def _shuffleHook2(self, rows, cards):
start_time = time.time()
@ -690,15 +694,16 @@ class AbstractMahjonggGame(Game):
break
# find suitable stacks
## suitable_stacks = []
## for r in rows:
## if nc[r.id] is None and is_suitable(r, nc):
## suitable_stacks.append(r)
# suitable_stacks = []
# for r in rows:
# if nc[r.id] is None and is_suitable(r, nc):
# suitable_stacks.append(r)
suitable_stacks = [r for r in rows
if nc[r.id] is None and is_suitable(r, nc)]
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):
if iters[0] > max_iters:
return None
@ -742,16 +747,16 @@ class AbstractMahjonggGame(Game):
while True:
ret = create_solvable(cards[:], new_cards)
if DEBUG:
print 'create_solvable time:', time.time() - start_time
print('create_solvable time:', time.time() - start_time)
if ret:
ret.reverse()
return ret
if time.time() - start_time > max_time or \
iters[0] <= max_iters:
print 'oops! can\'t create a solvable game'
print('oops! can\'t create a solvable game')
return None
iters = [0]
print 'oops! can\'t create a solvable game'
print('oops! can\'t create a solvable game')
return None
def _mahjonggShuffle(self):
@ -785,13 +790,13 @@ class AbstractMahjonggGame(Game):
new_cards = self._shuffleHook2(rows, cards)
if new_cards is None:
d = MfxMessageDialog(self.top, title=_('Warning'),
MfxMessageDialog(self.top, title=_('Warning'),
text=_('''\
Sorry, I can\'t find
a solvable configuration.'''),
bitmap='warning')
self.leaveState(old_state)
##self.finishMove()
# self.finishMove()
# hack
am = self.moves.current[0]
am.undo(self) # restore random
@ -895,9 +900,9 @@ a solvable configuration.'''),
for s, c1, c2, color in info:
assert c1 is c2
assert c1 in s.cards
tkraise = False
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:
continue
img = MfxCanvasImage(self.canvas, x, y, image=img,
@ -944,7 +949,7 @@ a solvable configuration.'''),
return self.getCardFaceImage(deck, suit, rank)
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:
return None
return Game._createCard(self, id, deck, suit, rank, x, y)
@ -977,7 +982,7 @@ a solvable configuration.'''),
return card1.rank == card2.rank
## mahjongg util
# mahjongg util
def comp_cardset(ncards):
# calc decks, ranks & trumps
assert ncards % 4 == 0
@ -1001,7 +1006,6 @@ def comp_cardset(ncards):
# * register a Mahjongg type game
# ************************************************************************
from new import classobj
def r(id, short_name, name=None, ncards=144, layout=None):
assert layout
@ -1014,7 +1018,7 @@ def r(id, short_name, name=None, ncards=144, layout=None):
gameclass.NCARDS = ncards
decks, ranks, trumps = comp_cardset(ncards)
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,
suits=range(3), ranks=range(ranks), trumps=range(trumps),
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"
registerGame(gi)
return gi

View file

@ -1,6 +1,6 @@
#!/usr/bin/env python
# -*- mode: python; coding: utf-8; -*-
# ---------------------------------------------------------------------------##
# ---------------------------------------------------------------------------
#
# Copyright (C) 1998-2003 Markus Franz Xaver Johannes Oberhumer
# Copyright (C) 2003 Mt. Hood Playing Card Co.
@ -19,7 +19,7 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
# ---------------------------------------------------------------------------##
# ---------------------------------------------------------------------------
__all__ = []
@ -29,26 +29,33 @@ import sys
from gettext import ungettext
# PySol imports
from pysollib.mygettext import _, n_
from pysollib.mygettext import _
from pysollib.gamedb import registerGame, GameInfo, GI
from pysollib.util import *
from pysollib.mfxutil import kwdefault
from pysollib.stack import *
from pysollib.game import Game
from pysollib.layout import Layout
from pysollib.hint import AbstractHint, DefaultHint, CautiousDefaultHint
from pysollib.hint import AbstractHint
from pysollib.pysoltk import MfxCanvasText, MfxCanvasLine
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):
TOP_MATCHING = False
# FIXME: no intelligence whatsoever is implemented here
def computeHints(self):
game = self.game
# get free stacks
@ -159,6 +166,7 @@ class Shisen_RowStack(Mahjongg_RowStack):
return 0
res_path = [None]
def do_accepts(x, y, direct, direct_chng_cnt, path):
# if direct_chng_cnt > 3:
# return
@ -171,7 +179,7 @@ class Shisen_RowStack(Mahjongg_RowStack):
res_path[0] = path
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
p = path[:]
if direct == 1:
@ -180,7 +188,7 @@ class Shisen_RowStack(Mahjongg_RowStack):
dcc = direct_chng_cnt+1
p.append((x, y))
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
p = path[:]
if direct == 2:
@ -189,7 +197,7 @@ class Shisen_RowStack(Mahjongg_RowStack):
dcc = direct_chng_cnt+1
p.append((x, y))
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
p = path[:]
if direct == 3:
@ -198,7 +206,7 @@ class Shisen_RowStack(Mahjongg_RowStack):
dcc = direct_chng_cnt+1
p.append((x, y))
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
p = path[:]
if direct == 4:
@ -220,7 +228,6 @@ class Shisen_RowStack(Mahjongg_RowStack):
# print res_path
return res_path
def fillStack(self):
self.game.fillStack(self)
@ -229,7 +236,8 @@ class Shisen_RowStack(Mahjongg_RowStack):
if to_stack.cards:
self._dropPairMove(ncards, to_stack, frames=-1, shadow=shadow)
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):
game = self.game
@ -248,7 +256,6 @@ class Shisen_RowStack(Mahjongg_RowStack):
game.updateStackMove(game.s.talon, 1 | 16) # for redo
game.leaveState(old_state)
def drawArrow(self, other_stack, sleep):
game = self.game
images = game.app.images
@ -261,7 +268,7 @@ class Shisen_RowStack(Mahjongg_RowStack):
cardw -= cs.SHADOW_XOFFSET
cardh -= cs.SHADOW_YOFFSET
coords = []
dx, dy = game._delta_x, game._delta_y
dx = game._delta_x
xf, yf = images._xfactor, images._yfactor
for x, y in path:
if x == 0:
@ -277,16 +284,16 @@ class Shisen_RowStack(Mahjongg_RowStack):
else:
coords.append(int(round(yf * (y0+cardh/2+cardh*(y-1)))))
# print coords
##s1 = min(cardw/2, cardh/2, 30)
##w = min(s1/3, 7)
##s2 = min(w, 10)
# s1 = min(cardw/2, cardh/2, 30)
# w = min(s1/3, 7)
# s2 = min(w, 10)
w = 7
arrow = MfxCanvasLine(game.canvas,
coords,
{'width': w,
'fill': game.app.opt.colors['hintarrow'],
##'arrow': 'last',
##'arrowshape': (s1, s1, s2)
# 'arrow': 'last',
# 'arrowshape': (s1, s1, s2)
}
)
game.canvas.update_idletasks()
@ -309,7 +316,7 @@ class AbstractShisenGame(AbstractMahjonggGame):
# start layout
l, s = Layout(self), self.s
##dx, dy = 3, -3
# dx, dy = 3, -3
cs = self.app.cardset
if cs.version >= 6:
@ -376,7 +383,8 @@ class AbstractShisenGame(AbstractMahjonggGame):
l.defaultStackGroups()
def fillStack(self, stack):
if not self.GRAVITY: return
if not self.GRAVITY:
return
to_stack = stack
for from_stack in self.cols[stack.coln][stack.rown+1::-1]:
if not from_stack.cards:
@ -421,11 +429,9 @@ class AbstractShisenGame(AbstractMahjonggGame):
t = r1 + r2 + f
self.texts.info.config(text=t)
def drawHintArrow(self, from_stack, to_stack, ncards, sleep):
from_stack.drawArrow(to_stack, sleep)
def _shuffleHook(self, cards):
return cards
@ -436,23 +442,28 @@ class AbstractShisenGame(AbstractMahjonggGame):
class Shisen_18x8(AbstractShisenGame):
L = (18, 8)
class Shisen_14x6(AbstractShisenGame):
L = (14, 6)
NCARDS = 84
class Shisen_24x12(AbstractShisenGame):
L = (24, 12)
NCARDS = 288
class Shisen_18x8_NoGravity(AbstractShisenGame):
L = (18, 8)
GRAVITY = False
class Shisen_14x6_NoGravity(AbstractShisenGame):
L = (14, 6)
NCARDS = 84
GRAVITY = False
class Shisen_24x12_NoGravity(AbstractShisenGame):
L = (24, 12)
NCARDS = 288
@ -479,11 +490,13 @@ class NotShisen_14x6(AbstractShisenGame):
L = (14, 6)
NCARDS = 84
class NotShisen_18x8(AbstractShisenGame):
Hint_Class = NotShisen_Hint
RowStack_Class = NotShisen_RowStack
L = (18, 8)
class NotShisen_24x12(AbstractShisenGame):
Hint_Class = NotShisen_Hint
RowStack_Class = NotShisen_RowStack
@ -507,6 +520,7 @@ def r(id, gameclass, name, rules_filename="shisensho.html"):
registerGame(gi)
return gi
r(11001, Shisen_14x6, "Shisen-Sho 14x6")
r(11002, Shisen_18x8, "Shisen-Sho 18x8")
r(11003, Shisen_24x12, "Shisen-Sho 24x12")

View file

@ -13,6 +13,10 @@ my %skip =
map { $_ => 1 }
qw(
./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/pysoltk.py
./pysollib/tile/ttk.py
@ -21,7 +25,7 @@ my %skip =
# 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
eq_or_diff( scalar(`$cmd`), '', "flake8 is happy with the code." );