[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