示例#1
0
 def _rebuild_bot_shanten_cache(self, player):
     isolated_tile_34 = find_isolated_tile_indices(
         TilesConverter.to_34_array(player.closed_hand))[0]
     isolated_tile_136 = isolated_tile_34 * 4
     player.table.revealed_tiles[isolated_tile_34] -= 1
     player.draw_tile(isolated_tile_136)
     player.discard_tile()
示例#2
0
    def calculate_shanten(self,
                          tiles_34,
                          open_sets_34=None,
                          chiitoitsu=True,
                          kokushi=True):
        """
        Return the count of tiles before tempai
        :param tiles_34: 34 tiles format array
        :param open_sets_34: array of array of 34 tiles format
        :param chiitoitsu: bool
        :param kokushi: bool
        :return: int
        """
        # we will modify them later, so we need to use a copy
        tiles_34 = copy.deepcopy(tiles_34)

        self._init(tiles_34)

        count_of_tiles = sum(tiles_34)

        if count_of_tiles > 14:
            return -2

        # With open hand we need to remove open sets from hand and replace them with isolated pon sets
        # it will allow to calculate count of shanten correctly
        if open_sets_34:
            isolated_tiles = find_isolated_tile_indices(tiles_34)
            for meld in open_sets_34:
                if not isolated_tiles:
                    break

                isolated_tile = isolated_tiles.pop()

                tiles_34[meld[0]] -= 1
                tiles_34[meld[1]] -= 1
                tiles_34[meld[2]] -= 1
                tiles_34[isolated_tile] = 3

        if not open_sets_34:
            self.min_shanten = self._scan_chiitoitsu_and_kokushi(
                chiitoitsu, kokushi)

        self._remove_character_tiles(count_of_tiles)

        init_mentsu = math.floor((14 - count_of_tiles) / 3)
        self._scan(init_mentsu)

        return self.min_shanten
示例#3
0
    def is_agari(self, tiles_34, open_sets_34=None):
        """
        Determine was it win or not
        :param tiles_34: 34 tiles format array
        :param open_sets_34: array of array of 34 tiles format
        :return: boolean
        """
        # we will modify them later, so we need to use a copy
        tiles = tiles_34[:]

        # With open hand we need to remove open sets from hand and replace them with isolated pon sets
        # it will allow to determine agari state correctly
        if open_sets_34:
            isolated_tiles = find_isolated_tile_indices(tiles)
            for meld in open_sets_34:
                if not isolated_tiles:
                    break

                isolated_tile = isolated_tiles.pop()

                tiles[meld[0]] -= 1
                tiles[meld[1]] -= 1
                tiles[meld[2]] -= 1
                # kan
                if len(meld) > 3:
                    tiles[meld[3]] -= 1
                tiles[isolated_tile] = 3

        j = ((1 << tiles[27])
             | (1 << tiles[28])
             | (1 << tiles[29])
             | (1 << tiles[30])
             | (1 << tiles[31])
             | (1 << tiles[32])
             | (1 << tiles[33]))

        if j >= 0x10:
            return False

        # 13 orphans
        if ((j & 3) == 2) and (tiles[0] * tiles[8] * tiles[9] * tiles[17] *
                               tiles[18] * tiles[26] * tiles[27] * tiles[28] *
                               tiles[29] * tiles[30] * tiles[31] * tiles[32] *
                               tiles[33] == 2):
            return True

        # seven pairs
        if not (j & 10) and sum([tiles[i] == 2 for i in range(0, 34)]) == 7:
            return True

        if j & 2:
            return False

        n00 = tiles[0] + tiles[3] + tiles[6]
        n01 = tiles[1] + tiles[4] + tiles[7]
        n02 = tiles[2] + tiles[5] + tiles[8]

        n10 = tiles[9] + tiles[12] + tiles[15]
        n11 = tiles[10] + tiles[13] + tiles[16]
        n12 = tiles[11] + tiles[14] + tiles[17]

        n20 = tiles[18] + tiles[21] + tiles[24]
        n21 = tiles[19] + tiles[22] + tiles[25]
        n22 = tiles[20] + tiles[23] + tiles[26]

        n0 = (n00 + n01 + n02) % 3
        if n0 == 1:
            return False

        n1 = (n10 + n11 + n12) % 3
        if n1 == 1:
            return False

        n2 = (n20 + n21 + n22) % 3
        if n2 == 1:
            return False

        if (n0 == 2) + (n1 == 2) + (n2 == 2) + (tiles[27] == 2) + (
                tiles[28] == 2) + (tiles[29] == 2) + (tiles[30] == 2) + (
                    tiles[31] == 2) + (tiles[32] == 2) + (tiles[33] == 2) != 1:
            return False

        nn0 = (n00 * 1 + n01 * 2) % 3
        m0 = self._to_meld(tiles, 0)
        nn1 = (n10 * 1 + n11 * 2) % 3
        m1 = self._to_meld(tiles, 9)
        nn2 = (n20 * 1 + n21 * 2) % 3
        m2 = self._to_meld(tiles, 18)

        if j & 4:
            return (not (n0 | nn0 | n1 | nn1 | n2 | nn2)
                    and self._is_mentsu(m0) and self._is_mentsu(m1)
                    and self._is_mentsu(m2))

        if n0 == 2:
            return (not (n1 | nn1 | n2 | nn2) and self._is_mentsu(m1)
                    and self._is_mentsu(m2) and self._is_atama_mentsu(nn0, m0))

        if n1 == 2:
            return (not (n2 | nn2 | n0 | nn0) and self._is_mentsu(m2)
                    and self._is_mentsu(m0) and self._is_atama_mentsu(nn1, m1))

        if n2 == 2:
            return (not (n0 | nn0 | n1 | nn1) and self._is_mentsu(m0)
                    and self._is_mentsu(m1) and self._is_atama_mentsu(nn2, m2))

        return False
示例#4
0
    def is_agari(self, tiles, melds=None):
        """
        Determine was it win or not
        :param tiles: 34 tiles format array
        :param melds: array of array of 34 tiles format
        :return: boolean
        """
        # we will modify them later, so we need to use a copy
        #tiles = copy.deepcopy(tiles)

        # TODO: I am not sure whether it's a bug or not. Originally the author
        # only took care of a hand of 14 tiles. However, when the closed hand
        # is consist of kans, there will be 15 or even more tiles. For this
        # reason, I intentionally remove one tile from any kan here. This might
        # be a temporally solution. (joseph)
        if sum(tiles) > 14:
            tiles = [t - 1 if t == 4 else t
                     for t in tiles]  # t==4 means a kan.

        # With open hand we need to remove open sets from hand and replace them with isolated pon sets
        # it will allow to determine agari state correctly
        if melds:
            isolated_tiles = find_isolated_tile_indices(tiles)
            for meld in melds:
                if not isolated_tiles:
                    break

                isolated_tile = isolated_tiles.pop()

                tiles[meld[0]] -= 1
                tiles[meld[1]] -= 1
                tiles[meld[2]] -= 1
                tiles[isolated_tile] = 3

        j = (1 << tiles[27]) | (1 << tiles[28]) | (1 << tiles[29]) | (1 << tiles[30]) | \
            (1 << tiles[31]) | (1 << tiles[32]) | (1 << tiles[33])

        if j >= 0x10:
            return False

        # 13 orphans
        if ((j & 3) == 2) and (tiles[0] * tiles[8] * tiles[9] * tiles[17] *
                               tiles[18] * tiles[26] * tiles[27] * tiles[28] *
                               tiles[29] * tiles[30] * tiles[31] * tiles[32] *
                               tiles[33] == 2):
            return True

        # seven pairs
        if not (j & 10) and sum([tiles[i] == 2 for i in range(0, 34)]) == 7:
            return True

        if j & 2:
            return False

        n00 = tiles[0] + tiles[3] + tiles[6]
        n01 = tiles[1] + tiles[4] + tiles[7]
        n02 = tiles[2] + tiles[5] + tiles[8]

        n10 = tiles[9] + tiles[12] + tiles[15]
        n11 = tiles[10] + tiles[13] + tiles[16]
        n12 = tiles[11] + tiles[14] + tiles[17]

        n20 = tiles[18] + tiles[21] + tiles[24]
        n21 = tiles[19] + tiles[22] + tiles[25]
        n22 = tiles[20] + tiles[23] + tiles[26]

        n0 = (n00 + n01 + n02) % 3
        #print("n0={}".format(n0))
        if n0 == 1:
            return False

        n1 = (n10 + n11 + n12) % 3
        #print("n1={}".format(n1))
        if n1 == 1:
            return False

        n2 = (n20 + n21 + n22) % 3
        #print("n2={}".format(n2))
        if n2 == 1:
            return False

        if ((n0 == 2) + (n1 == 2) + (n2 == 2) + (tiles[27] == 2) +
            (tiles[28] == 2) + (tiles[29] == 2) + (tiles[30] == 2) +
            (tiles[31] == 2) + (tiles[32] == 2) + (tiles[33] == 2) != 1):
            return False

        nn0 = (n00 * 1 + n01 * 2) % 3
        m0 = self._to_meld(tiles, 0)
        nn1 = (n10 * 1 + n11 * 2) % 3
        m1 = self._to_meld(tiles, 9)
        nn2 = (n20 * 1 + n21 * 2) % 3
        m2 = self._to_meld(tiles, 18)

        if j & 4:
            return not (n0 | nn0 | n1 | nn1 | n2 | nn2) and self._is_mentsu(m0) \
                   and self._is_mentsu(m1) and self._is_mentsu(m2)

        if n0 == 2:
            return not (n1 | nn1 | n2 | nn2) and self._is_mentsu(m1) and self._is_mentsu(m2) \
                   and self._is_atama_mentsu(nn0, m0)

        if n1 == 2:
            return not (n2 | nn2 | n0 | nn0) and self._is_mentsu(m2) and self._is_mentsu(m0) \
                   and self._is_atama_mentsu(nn1, m1)

        if n2 == 2:
            return not (n0 | nn0 | n1 | nn1) and self._is_mentsu(m0) and self._is_mentsu(m1) \
                   and self._is_atama_mentsu(nn2, m2)

        return False
示例#5
0
    def test_find_isolated_tiles(self):
        hand_34 = TilesConverter.string_to_34_array(sou='1369',
                                                    pin='15678',
                                                    man='25',
                                                    honors='124')
        isolated_tiles = find_isolated_tile_indices(hand_34)

        self.assertEqual(
            self._string_to_34_tile(sou='1') in isolated_tiles, False)
        self.assertEqual(
            self._string_to_34_tile(sou='2') in isolated_tiles, False)
        self.assertEqual(
            self._string_to_34_tile(sou='3') in isolated_tiles, False)
        self.assertEqual(
            self._string_to_34_tile(sou='4') in isolated_tiles, False)
        self.assertEqual(
            self._string_to_34_tile(sou='5') in isolated_tiles, False)
        self.assertEqual(
            self._string_to_34_tile(sou='6') in isolated_tiles, False)
        self.assertEqual(
            self._string_to_34_tile(sou='7') in isolated_tiles, False)
        self.assertEqual(
            self._string_to_34_tile(sou='8') in isolated_tiles, False)
        self.assertEqual(
            self._string_to_34_tile(sou='9') in isolated_tiles, False)
        self.assertEqual(
            self._string_to_34_tile(pin='1') in isolated_tiles, False)
        self.assertEqual(
            self._string_to_34_tile(pin='2') in isolated_tiles, False)
        self.assertEqual(
            self._string_to_34_tile(pin='3') in isolated_tiles, True)
        self.assertEqual(
            self._string_to_34_tile(pin='4') in isolated_tiles, False)
        self.assertEqual(
            self._string_to_34_tile(pin='5') in isolated_tiles, False)
        self.assertEqual(
            self._string_to_34_tile(pin='6') in isolated_tiles, False)
        self.assertEqual(
            self._string_to_34_tile(pin='7') in isolated_tiles, False)
        self.assertEqual(
            self._string_to_34_tile(pin='8') in isolated_tiles, False)
        self.assertEqual(
            self._string_to_34_tile(pin='9') in isolated_tiles, False)
        self.assertEqual(
            self._string_to_34_tile(man='1') in isolated_tiles, False)
        self.assertEqual(
            self._string_to_34_tile(man='2') in isolated_tiles, False)
        self.assertEqual(
            self._string_to_34_tile(man='3') in isolated_tiles, False)
        self.assertEqual(
            self._string_to_34_tile(man='4') in isolated_tiles, False)
        self.assertEqual(
            self._string_to_34_tile(man='5') in isolated_tiles, False)
        self.assertEqual(
            self._string_to_34_tile(man='6') in isolated_tiles, False)
        self.assertEqual(
            self._string_to_34_tile(man='7') in isolated_tiles, True)
        self.assertEqual(
            self._string_to_34_tile(man='8') in isolated_tiles, True)
        self.assertEqual(
            self._string_to_34_tile(man='9') in isolated_tiles, True)
        self.assertEqual(
            self._string_to_34_tile(honors='1') in isolated_tiles, False)
        self.assertEqual(
            self._string_to_34_tile(honors='2') in isolated_tiles, False)
        self.assertEqual(
            self._string_to_34_tile(honors='3') in isolated_tiles, True)
        self.assertEqual(
            self._string_to_34_tile(honors='4') in isolated_tiles, False)
        self.assertEqual(
            self._string_to_34_tile(honors='5') in isolated_tiles, True)
        self.assertEqual(
            self._string_to_34_tile(honors='6') in isolated_tiles, True)
        self.assertEqual(
            self._string_to_34_tile(honors='7') in isolated_tiles, True)
示例#6
0
    def test_find_isolated_tiles(self):
        hand_34 = TilesConverter.string_to_34_array(sou="1369",
                                                    pin="15678",
                                                    man="25",
                                                    honors="124")
        isolated_tiles = find_isolated_tile_indices(hand_34)

        self.assertEqual(
            self._string_to_34_tile(sou="1") in isolated_tiles, False)
        self.assertEqual(
            self._string_to_34_tile(sou="2") in isolated_tiles, False)
        self.assertEqual(
            self._string_to_34_tile(sou="3") in isolated_tiles, False)
        self.assertEqual(
            self._string_to_34_tile(sou="4") in isolated_tiles, False)
        self.assertEqual(
            self._string_to_34_tile(sou="5") in isolated_tiles, False)
        self.assertEqual(
            self._string_to_34_tile(sou="6") in isolated_tiles, False)
        self.assertEqual(
            self._string_to_34_tile(sou="7") in isolated_tiles, False)
        self.assertEqual(
            self._string_to_34_tile(sou="8") in isolated_tiles, False)
        self.assertEqual(
            self._string_to_34_tile(sou="9") in isolated_tiles, False)
        self.assertEqual(
            self._string_to_34_tile(pin="1") in isolated_tiles, False)
        self.assertEqual(
            self._string_to_34_tile(pin="2") in isolated_tiles, False)
        self.assertEqual(
            self._string_to_34_tile(pin="3") in isolated_tiles, True)
        self.assertEqual(
            self._string_to_34_tile(pin="4") in isolated_tiles, False)
        self.assertEqual(
            self._string_to_34_tile(pin="5") in isolated_tiles, False)
        self.assertEqual(
            self._string_to_34_tile(pin="6") in isolated_tiles, False)
        self.assertEqual(
            self._string_to_34_tile(pin="7") in isolated_tiles, False)
        self.assertEqual(
            self._string_to_34_tile(pin="8") in isolated_tiles, False)
        self.assertEqual(
            self._string_to_34_tile(pin="9") in isolated_tiles, False)
        self.assertEqual(
            self._string_to_34_tile(man="1") in isolated_tiles, False)
        self.assertEqual(
            self._string_to_34_tile(man="2") in isolated_tiles, False)
        self.assertEqual(
            self._string_to_34_tile(man="3") in isolated_tiles, False)
        self.assertEqual(
            self._string_to_34_tile(man="4") in isolated_tiles, False)
        self.assertEqual(
            self._string_to_34_tile(man="5") in isolated_tiles, False)
        self.assertEqual(
            self._string_to_34_tile(man="6") in isolated_tiles, False)
        self.assertEqual(
            self._string_to_34_tile(man="7") in isolated_tiles, True)
        self.assertEqual(
            self._string_to_34_tile(man="8") in isolated_tiles, True)
        self.assertEqual(
            self._string_to_34_tile(man="9") in isolated_tiles, True)
        self.assertEqual(
            self._string_to_34_tile(honors="1") in isolated_tiles, False)
        self.assertEqual(
            self._string_to_34_tile(honors="2") in isolated_tiles, False)
        self.assertEqual(
            self._string_to_34_tile(honors="3") in isolated_tiles, True)
        self.assertEqual(
            self._string_to_34_tile(honors="4") in isolated_tiles, False)
        self.assertEqual(
            self._string_to_34_tile(honors="5") in isolated_tiles, True)
        self.assertEqual(
            self._string_to_34_tile(honors="6") in isolated_tiles, True)
        self.assertEqual(
            self._string_to_34_tile(honors="7") in isolated_tiles, True)