[prev in list] [next in list] [prev in thread] [next in thread]
List: kde-commits
Subject: [kajongg/sid] src: move __maySay* and sayable from Client to Player
From: Wolfgang Rohdewald <wolfgang () rohdewald ! de>
Date: 2013-10-31 21:21:03
Message-ID: E1Vbzfr-0002lj-Tl () scm ! kde ! org
[Download RAW message or body]
Git commit 779e90c69bd1ff00b3cad7ee44861bbdda1358bd by Wolfgang Rohdewald.
Committed on 29/10/2013 at 07:51.
Pushed by wrohdewald into branch 'sid'.
move __maySay* and sayable from Client to Player
M +1 -81 src/client.py
M +4 -4 src/humanclient.py
M +2 -2 src/intelligence.py
M +6 -6 src/message.py
M +79 -0 src/player.py
http://commits.kde.org/kajongg/779e90c69bd1ff00b3cad7ee44861bbdda1358bd
diff --git a/src/client.py b/src/client.py
index dc09704..9215547 100644
--- a/src/client.py
+++ b/src/client.py
@@ -128,7 +128,6 @@ class Client(object, pb.Referenceable):
self.tables = []
self.table = None
self.tableList = None
- self.sayable = {} # recompute for each move, use as cache
def delete(self):
"""for better garbage collection"""
@@ -322,7 +321,7 @@ class Client(object, pb.Referenceable):
sends answer and one parameter to server"""
delay = 0.0
delayStep = 0.1
- self._computeSayable(move, answers)
+ self.game.myself.computeSayable(move, answers)
result = self.intelligence.selectAnswer(answers)
if result[0] == Message.Chow:
# self.game.debug('%s waits to see if somebody says Pung or Kong before saying chow' %
@@ -467,82 +466,3 @@ class Client(object, pb.Referenceable):
move.exposedMeld = move.player.exposeMeld(move.source)
if not self.thatWasMe(move.player):
self.ask(move, [Message.OK])
-
- def __maySayChow(self):
- """returns answer arguments for the server if calling chow is possible.
- returns the meld to be completed"""
- if self.game.myself == self.game.nextPlayer():
- return self.game.myself.possibleChows()
-
- def __maySayPung(self):
- """returns answer arguments for the server if calling pung is possible.
- returns the meld to be completed"""
- if self.game.lastDiscard:
- lastDiscard = self.game.lastDiscard
- assert lastDiscard[0].isupper(), lastDiscard
- if self.game.myself.concealedTileNames.count(lastDiscard) >= 2:
- return [lastDiscard] * 3
-
- def __maySayKong(self):
- """returns answer arguments for the server if calling or declaring kong is possible.
- returns the meld to be completed or to be declared"""
- return self.game.myself.possibleKongs()
-
- def __maySayMahjongg(self, move):
- """returns answer arguments for the server if calling or declaring Mah Jongg is possible"""
- game = self.game
- myself = game.myself
- robbableTile = withDiscard = None
- if move.message == Message.DeclaredKong:
- withDiscard = move.tiles[0].upper()
- if move.player != myself:
- robbableTile = move.exposedMeld[1] # we want it capitalized for a hidden Kong
- elif move.message == Message.AskForClaims:
- withDiscard = game.lastDiscard
- hand = myself.computeHand(withTile=withDiscard, robbedTile=robbableTile, asWinner=True)
- if hand.won:
- if Debug.robbingKong:
- if move.message == Message.DeclaredKong:
- game.debug('%s may rob the kong from %s/%s' % \
- (myself, move.player, move.exposedMeld.joined))
- if Debug.mahJongg:
- game.debug('%s may say MJ:%s, active=%s' % (
- myself, list(x for x in game.players), game.activePlayer))
- return (meldsContent(hand.hiddenMelds), withDiscard, hand.lastMeld)
-
- def __maySayOriginalCall(self):
- """returns True if Original Call is possible"""
- myself = self.game.myself
- for tileName in set(myself.concealedTileNames):
- if (myself.hand - tileName).callingHands():
- if Debug.originalCall:
- self.game.debug('%s may say Original Call' % myself)
- return True
-
- def _computeSayable(self, move, answers):
- """find out what the player can legally say with this hand"""
- self.sayable = {}
- for message in Message.defined.values():
- self.sayable[message] = True
- if Message.Pung in answers:
- self.sayable[Message.Pung] = self.__maySayPung()
- if Message.Chow in answers:
- self.sayable[Message.Chow] = self.__maySayChow()
- if Message.Kong in answers:
- self.sayable[Message.Kong] = self.__maySayKong()
- if Message.MahJongg in answers:
- self.sayable[Message.MahJongg] = self.__maySayMahjongg(move)
- if Message.OriginalCall in answers:
- self.sayable[Message.OriginalCall] = self.__maySayOriginalCall()
-
- def maybeDangerous(self, msg):
- """could answering with msg lead to dangerous game?
- If so return a list of resulting melds
- where a meld is represented by a list of 2char strings"""
- result = []
- if msg in (Message.Chow, Message.Pung, Message.Kong):
- possibleMelds = self.sayable[msg]
- if isinstance(possibleMelds[0], basestring):
- possibleMelds = [possibleMelds]
- result = [x for x in possibleMelds if self.game.myself.mustPlayDangerous(x)]
- return result
diff --git a/src/humanclient.py b/src/humanclient.py
index e1e87d8..81a48ec 100644
--- a/src/humanclient.py
+++ b/src/humanclient.py
@@ -185,7 +185,7 @@ class ClientDialog(QDialog):
def __declareButton(self, message):
"""define a button"""
- maySay = self.client.sayable[message]
+ maySay = self.client.game.myself.sayable[message]
if Preferences.showOnlyPossibleActions and not maySay:
return
btn = DlgButton(message, self)
@@ -323,7 +323,7 @@ class ClientDialog(QDialog):
answer = button
else:
answer = button.message
- if not self.client.sayable[answer]:
+ if not self.client.game.myself.sayable[answer]:
Sorry(m18n('You cannot say %1', answer.i18nName))
return
Internal.field.clientDialog = None
@@ -607,7 +607,7 @@ class HumanClient(Client):
the default answer being the first in the list."""
if not Internal.field:
return Client.ask(self, move, answers)
- self._computeSayable(move, answers)
+ self.game.myself.computeSayable(move, answers)
deferred = Deferred()
deferred.addCallback(self.__askAnswered)
deferred.addErrback(self.__answerError, move, answers)
@@ -668,7 +668,7 @@ class HumanClient(Client):
# including us that it has been discarded. Only then we will remove it.
myself.handBoard.setEnabled(False)
return answer, myself.handBoard.focusTile.tile
- args = self.sayable[answer]
+ args = self.game.myself.sayable[answer]
assert args
if answer == Message.Chow:
return self.__selectChow(args)
diff --git a/src/intelligence.py b/src/intelligence.py
index 8f7b106..a59d2aa 100644
--- a/src/intelligence.py
+++ b/src/intelligence.py
@@ -230,7 +230,7 @@ class AIDefault(object):
for func in self.client.game.ruleset.filterFunctions('claimness'):
claimness += func.claimness(hand, discard)
for tryAnswer in tryAnswers:
- parameter = self.client.sayable[tryAnswer]
+ parameter = self.client.game.myself.sayable[tryAnswer]
if not parameter:
continue
if claimness[tryAnswer] < 0:
@@ -241,7 +241,7 @@ class AIDefault(object):
parameter = self.selectDiscard(hand)
elif tryAnswer in [Message.Pung, Message.Chow, Message.Kong] and self.respectOriginalCall():
continue
- elif tryAnswer == Message.Pung and self.client.maybeDangerous(tryAnswer):
+ elif tryAnswer == Message.Pung and self.client.game.myself.maybeDangerous(tryAnswer):
continue
elif tryAnswer == Message.Chow:
parameter = self.selectChow(parameter)
diff --git a/src/message.py b/src/message.py
index 13b3007..7f485e6 100644
--- a/src/message.py
+++ b/src/message.py
@@ -164,19 +164,19 @@ class PungChowMessage(NotifyAtOnceMessage):
def toolTip(self, button, dummyTile):
"""decorate the action button which will send this message"""
- maySay = button.client.sayable[self]
+ myself = button.client.game.myself
+ maySay = myself.sayable[self]
if not maySay:
return '', False, ''
- myself = button.client.game.myself
txt = []
warn = False
if myself.originalCall and myself.mayWin:
warn = True
txt.append(m18n('saying %1 violates Original Call',
self.i18nName))
- dangerousMelds = button.client.maybeDangerous(self)
+ dangerousMelds = myself.maybeDangerous(self)
if dangerousMelds:
- lastDiscard = button.client.game.lastDiscard
+ lastDiscard = myself.game.lastDiscard
warn = True
if Debug.dangerousGame and len(dangerousMelds) != len(maySay):
button.client.game.debug('only some claimable melds are dangerous: %s' % dangerousMelds)
@@ -220,10 +220,10 @@ class MessageKong(NotifyAtOnceMessage, ServerMessage):
table.declareKong(msg.player, msg.args[0])
def toolTip(self, button, dummyTile):
"""decorate the action button which will send this message"""
- maySay = button.client.sayable[self]
+ myself = button.client.game.myself
+ maySay = myself.sayable[self]
if not maySay:
return '', False, ''
- myself = button.client.game.myself
txt = []
warn = False
if myself.originalCall and myself.mayWin:
diff --git a/src/player.py b/src/player.py
index 29ddbbc..496c380 100644
--- a/src/player.py
+++ b/src/player.py
@@ -26,6 +26,7 @@ from common import WINDS, Internal, IntDict, Debug
from query import Transaction, Query
from tile import Tile, elements
from meld import Meld, CONCEALED, PUNG, hasChows, meldsContent
+from message import Message
from hand import Hand
class Players(list):
@@ -428,6 +429,7 @@ class PlayingPlayer(Player):
# pylint: disable=too-many-public-methods
# too many public methods
def __init__(self, game):
+ self.sayable = {} # recompute for each move, use as cache
Player.__init__(self, game)
def popupMsg(self, msg):
@@ -514,6 +516,83 @@ class PlayingPlayer(Player):
assert isinstance(kong[0], Tile)
return kongs
+ def __maySayChow(self):
+ """returns answer arguments for the server if calling chow is possible.
+ returns the meld to be completed"""
+ if self == self.game.nextPlayer():
+ return self.possibleChows()
+
+ def __maySayPung(self):
+ """returns answer arguments for the server if calling pung is possible.
+ returns the meld to be completed"""
+ lastDiscard = self.game.lastDiscard
+ if self.game.lastDiscard:
+ assert lastDiscard[0].isupper(), lastDiscard
+ if self.concealedTileNames.count(lastDiscard) >= 2:
+ return [lastDiscard] * 3
+
+ def __maySayKong(self):
+ """returns answer arguments for the server if calling or declaring kong is possible.
+ returns the meld to be completed or to be declared"""
+ return self.possibleKongs()
+
+ def __maySayMahjongg(self, move):
+ """returns answer arguments for the server if calling or declaring Mah Jongg is possible"""
+ game = self.game
+ robbableTile = withDiscard = None
+ if move.message == Message.DeclaredKong:
+ withDiscard = move.tiles[0].upper()
+ if move.player != self:
+ robbableTile = move.exposedMeld[1] # we want it capitalized for a hidden Kong
+ elif move.message == Message.AskForClaims:
+ withDiscard = game.lastDiscard
+ hand = self.computeHand(withTile=withDiscard, robbedTile=robbableTile, asWinner=True)
+ if hand.won:
+ if Debug.robbingKong:
+ if move.message == Message.DeclaredKong:
+ game.debug('%s may rob the kong from %s/%s' % \
+ (self, move.player, move.exposedMeld.joined))
+ if Debug.mahJongg:
+ game.debug('%s may say MJ:%s, active=%s' % (
+ self, list(x for x in game.players), game.activePlayer))
+ return (meldsContent(hand.hiddenMelds), withDiscard, hand.lastMeld)
+
+ def __maySayOriginalCall(self):
+ """returns True if Original Call is possible"""
+ for tileName in set(self.concealedTileNames):
+ if (self.hand - tileName).callingHands():
+ if Debug.originalCall:
+ self.game.debug('%s may say Original Call' % self)
+ return True
+
+ def computeSayable(self, move, answers):
+ """find out what the player can legally say with this hand"""
+ self.sayable = {}
+ for message in Message.defined.values():
+ self.sayable[message] = True
+ if Message.Pung in answers:
+ self.sayable[Message.Pung] = self.__maySayPung()
+ if Message.Chow in answers:
+ self.sayable[Message.Chow] = self.__maySayChow()
+ if Message.Kong in answers:
+ self.sayable[Message.Kong] = self.__maySayKong()
+ if Message.MahJongg in answers:
+ self.sayable[Message.MahJongg] = self.__maySayMahjongg(move)
+ if Message.OriginalCall in answers:
+ self.sayable[Message.OriginalCall] = self.__maySayOriginalCall()
+
+ def maybeDangerous(self, msg):
+ """could answering with msg lead to dangerous game?
+ If so return a list of resulting melds
+ where a meld is represented by a list of 2char strings"""
+ result = []
+ if msg in (Message.Chow, Message.Pung, Message.Kong):
+ possibleMelds = self.sayable[msg]
+ if isinstance(possibleMelds[0], basestring):
+ possibleMelds = [possibleMelds]
+ result = [x for x in possibleMelds if self.mustPlayDangerous(x)]
+ return result
+
def hasConcealedTiles(self, tiles, within=None):
"""do I have those concealed tiles?"""
if within is None:
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic