Ledenel / auto-white-reimu

a mahjong library aimed to implement mahjong AIs by imitating white reimu -- a excellent mahjong player.
GNU General Public License v3.0
9 stars 1 forks source link

fix 0s 0p representation and check 0s 0p in demo 'Monte Carlo estimation' #14

Closed Ledenel closed 5 years ago

Ledenel commented 5 years ago

Now the demo 1(Monte Carlo estimation) do accept 0m, 0p, 0s as input, but not treated as aka 5m, aka 5p, aka 5s. Instead it is a tile with number zero, which is weird and buggy. (mentioned in Pull Request #5 )

maybe first fix it by add restriction and conversion to normal 5s/5m/5p in demo, then discuss the representation for aka 5m.

Ledenel commented 5 years ago

we could make a new class AkaTile, extends Tile to deal that. AkaTile 0s has different hash from tuple(0, 's'), but __eq__ with 5s and makes no different with 5s.

https://github.com/Ledenel/auto-white-reimu/blob/73deb12922a5ba29063c3f1e985185d742c74f8d/mahjong/tile/definition.py#L34 should be a change point to return aka tiles.

Then we could make tile_from_tenhou return Aka 5s rather than true weird 0s (means weird number zero).

Ledenel commented 5 years ago

further unit test with 0s, 0p, 0m needed.

canuse commented 5 years ago

If we return a AkaTile object like this:

def tile_from_tenhou(index):
    """
    tenhou index is numbered as [1m,1m,1m,1m,2m,2m,...,9m,1p,...,9p,1s,...,9s,1z,...,7z,7z,7z,7z]
    numbered first 5m,5s,5p is considered as aka dora.
    """
    if index == 16:
        return AkaTile(0, 'm')
    elif index == 52:
        return AkaTile(0, 'p')
    elif index == 88:
        return AkaTile(0, 's')
    else:
        color, number, _ = TENHOU_TILE_CATEGORY.category(index)
        return Tile(number + 1, SUIT_ORDER[color])

This implement leads to test failure in test_flush.py:

Expected :{<0m>, <6m>}
Actual   :{<5m>, <6m>}

and the reason is

>>>{tile_from_tenhou(16)}=={tile_from_tenhou(16)}
True
>>>{tile_from_tenhou(16)}=={tile_from_tenhou(17)}
False
>>>tile_from_tenhou(16)==tile_from_tenhou(17)
True
Ledenel commented 5 years ago

Sorry my fault. Same object (defined by __eq__) must have same hash (defined by __hash__). A cleaner solution is making AkaTile a wrapper for Tile, redefine the hash and eq, then remain anything else unchanged.

Ledenel commented 5 years ago

fixed in #21 . Thanks for the contribution!