Esempio n. 1
0
File: hand.py Progetto: KDE/kajongg
 def __findAllCallingHands(self):
     """always try to find all of them"""
     result = []
     string = self.string
     if ' x' in string or self.lenOffset:
         return result
     candidates = []
     for rule in self.ruleset.mjRules:
         cand = rule.winningTileCandidates(self)
         if Debug.hand and cand:
             # Py2 and Py3 show sets differently
             candis = ''.join(str(x) for x in sorted(cand)) # pylint: disable=unused-variable
             self.debug(fmt('callingHands found {candis} for {rule}'))
         candidates.extend(x.concealed for x in cand)
     for tile in sorted(set(candidates)):
         if sum(x.exposed == tile.exposed for x in self.tiles) == 4:
             continue
         hand = self + tile
         if hand.won:
             result.append(hand)
     if Debug.hand:
         _hiderules = ', '.join(set(x.mjRule.name for x in result))
         if _hiderules:
             self.debug(fmt('Is calling {_hiderules}'))
     return result
Esempio n. 2
0
File: hand.py Progetto: KDE/kajongg
    def __init__(self, player, string, prevHand=None):
        """evaluate string for player. rules are to be applied in any case"""
        if hasattr(self, 'string'):
            # I am from cache
            return

        # shortcuts for speed:
        self._player = weakref.ref(player)
        self.ruleset = player.game.ruleset
        self.intelligence = player.intelligence if player else AIDefault()
        self.string = string
        self.__robbedTile = Tile.unknown
        self.prevHand = prevHand
        self.__won = None
        self.__score = None
        self.__callingHands = None
        self.__mjRule = None
        self.ruleCache = {}
        self.__lastTile = None
        self.__lastSource = TileSource.Unknown
        self.__announcements = set()
        self.__lastMeld = 0
        self.__lastMelds = MeldList()
        self.tiles = None
        self.melds = MeldList()
        self.bonusMelds = MeldList()
        self.usedRules = []
        self.__rest = TileList()
        self.__arranged = None

        self.__parseString(string)
        self.__won = self.lenOffset == 1 and player.mayWin

        if Debug.hand or (Debug.mahJongg and self.lenOffset == 1):
            self.debug(fmt('{callers}',
                           callers=callers(exclude=['__init__'])))
            Hand.indent += 1
            _hideString = string
            self.debug(fmt('New Hand {_hideString} {self.lenOffset}'))

        try:
            self.__arrange()
            self.__calculate()
            self.__arranged = True
        except Hand.__NotWon as notwon:
            if Debug.mahJongg:
                self.debug(fmt(str(notwon)))
            self.__won = False
            self.__score = Score()
        finally:
            self._fixed = True
            if Debug.hand or (Debug.mahJongg and self.lenOffset == 1):
                _hideSelf = str(self)
                _hideScore = str(self.score)
                self.debug(fmt(
                    'Fixing {_hideSelf} {self.won} {_hideScore}'))
            Hand.indent -= 1
Esempio n. 3
0
File: hand.py Progetto: KDE/kajongg
 def __applyBestLastMeld(self):
     """select the last meld giving the highest score
     (only winning variants)"""
     assert len(self.lastMelds) > 1
     totals = []
     prev = self.lastMeld
     for rule in self.usedRules:
         assert isinstance(rule, UsedRule)
     for lastMeld in self.lastMelds:
         self.__lastMeld = lastMeld
         try:
             self.__applyRules()
             totals.append((self.__totalScore().total(), lastMeld))
         except Hand.__NotWon:
             pass
     if totals:
         totals = sorted(totals)  # sort by totalScore
         maxScore = totals[-1][0]
         totals = list(x[1] for x in totals if x[0] == maxScore)
         # now we have a list of only lastMelds reaching maximum score
         if prev not in totals or self.__lastMeld not in totals:
             if Debug.explain and prev not in totals:
                 if not self.player.game.belongsToRobotPlayer():
                     self.debug(fmt(
                         'replaced last meld {prev} with {totals[0]}'))
             self.__lastMeld = totals[0]
             self.__applyRules()
Esempio n. 4
0
File: hand.py Progetto: KDE/kajongg
 def __checkHasExclusiveRules(self):
     """if we have one, remove all others"""
     exclusive = list(x for x in self.usedRules
                      if 'absolute' in x.rule.options)
     if exclusive:
         self.usedRules = exclusive
         self.__score = self.__totalScore()
         if self.__won and not bool(self.__maybeMahjongg()):
             raise Hand.__NotWon(fmt('exclusive rule {exclusive} does not win'))
Esempio n. 5
0
 def __checkHasExclusiveRules(self):
     """if we have one, remove all others"""
     exclusive = list(x for x in self.usedRules
                      if 'absolute' in x.rule.options)
     if exclusive:
         self.usedRules = exclusive
         self.__score = self.__totalScore()
         if self.__won and not bool(self.__maybeMahjongg()):
             raise Hand.__NotWon(fmt('exclusive rule {exclusive} does not win'))
Esempio n. 6
0
File: hand.py Progetto: KDE/kajongg
 def __maybeMahjongg(self):
     """check if this is a mah jongg hand.
     Return a sorted list of matching MJ rules, highest
     total first. If no rule matches, return None"""
     if self.lenOffset == 1 and self.player.mayWin:
         matchingMJRules = [x for x in self.ruleset.mjRules
                            if x.appliesToHand(self)]
         if matchingMJRules:
             if self.robbedTile and self.robbedTile.isConcealed:
                 # Millington 58: robbing hidden kong is only
                 # allowed for 13 orphans
                 matchingMJRules = [
                     x for x in matchingMJRules
                     if 'mayrobhiddenkong' in x.options]
             result = sorted(matchingMJRules, key=lambda x: -x.score.total())
             if Debug.mahJongg:
                 self.debug(fmt('{callers} Found {matchingMJRules}',
                                callers=callers()))
             return result