Esempio n. 1
0
 def __separateBonusMelds(tileString):
     """keep them separate. One meld per bonus tile. Others depend on that."""
     result = []
     if 'f' in tileString or 'y' in tileString:
         for pair in Pairs(tileString.replace(' ', '').replace('R', '')):
             if pair[0] in 'fy':
                 result.append(Meld(pair))
                 tileString = tileString.replace(pair, '', 1)
     return result, tileString
Esempio n. 2
0
 def __computeDragonWindMelds(tileString):
     """returns lists with melds containing all (even single)
     dragons respective winds"""
     dragonMelds = []
     windMelds = []
     for split in tileString.split():
         if split[0] == 'R':
             pairs = Pairs(split[1:])
             for lst, tiles in ((windMelds, elements.wINDS),
                                (dragonMelds, elements.dRAGONS)):
                 for tile in tiles:
                     count = pairs.count(tile)
                     if count:
                         lst.append(Meld([tile] * count))
         elif split[0] in 'dD':
             dragonMelds.append(Meld(split))
         elif split[0] in 'wW':
             windMelds.append(Meld(split))
     return dragonMelds, windMelds
Esempio n. 3
0
    def __init__(self, ruleset, string, computedRules=None, robbedTile=None):
        """evaluate string using ruleset. rules are to be applied in any case.
        ruleset can be Hand, Game or Ruleset."""
        # silence pylint. This method is time critical, so do not split it into smaller methods
        # pylint: disable=R0902,R0914,R0912,R0915
        if isinstance(ruleset, Hand):
            self.ruleset = ruleset.ruleset
            self.player = ruleset.player
            self.computedRules = ruleset.computedRules
        elif isinstance(ruleset, Ruleset):
            self.ruleset = ruleset
            self.player = None
        else:
            self.player = ruleset
            self.ruleset = self.player.game.ruleset
        self.string = string
        self.robbedTile = robbedTile
        if computedRules is not None and not isinstance(computedRules, list):
            computedRules = list([computedRules])
        self.computedRules = computedRules or []
        self.__won = False
        self.mjStr = ''
        self.mjRule = None
        self.ownWind = None
        self.roundWind = None
        tileStrings = []
        mjStrings = []
        haveM = False
        splits = self.string.split()
        for part in splits:
            partId = part[0]
            if partId in 'Mmx':
                haveM = True
                self.ownWind = part[1]
                self.roundWind = part[2]
                mjStrings.append(part)
                self.__won = partId == 'M'
            elif partId == 'L':
                if len(part[1:]) > 8:
                    raise Exception('last tile cannot complete a kang:' +
                                    self.string)
                mjStrings.append(part)
            else:
                tileStrings.append(part)

        if not haveM:
            raise Exception('Hand got string without mMx: %s', self.string)
        self.mjStr = ' '.join(mjStrings)
        self.__lastTile = self.__lastSource = self.__announcements = ''
        self.__lastMeld = 0
        self.__lastMelds = []
        self.hiddenMelds = []
        self.declaredMelds = []
        self.melds = []
        tileString = ' '.join(tileStrings)
        self.bonusMelds, tileString = self.__separateBonusMelds(tileString)
        self.tileNames = Pairs(tileString.replace(' ', '').replace('R', ''))
        self.tileNames.sort()
        self.values = ''.join(x[1] for x in self.tileNames)
        self.suits = set(x[0].lower() for x in self.tileNames)
        self.lenOffset = self.__computeLenOffset(tileString)
        self.dragonMelds, self.windMelds = self.__computeDragonWindMelds(
            tileString)
        self.__separateMelds(tileString)
        self.hiddenMelds = sorted(self.hiddenMelds, key=meldKey)
        self.tileNamesInHand = sum((x.pairs for x in self.hiddenMelds), [])
        self.sortedMeldsContent = meldsContent(self.melds)
        if self.bonusMelds:
            self.sortedMeldsContent += ' ' + meldsContent(self.bonusMelds)

        self.usedRules = []
        self.score = None
        oldWon = self.won
        self.__applyRules()
        if len(self.lastMelds) > 1:
            self.__applyBestLastMeld()
        if self.won != oldWon:
            # if not won after all, this might be a long hand.
            # So we might even have to unapply meld rules and
            # bonus points. Instead just recompute all again.
            # This should only happen with scoring manual games
            # and with scoringtest - normally kajongg would not
            # let you declare an invalid mah jongg
            self.__applyRules()