Skip to content
This repository has been archived by the owner on Jul 8, 2023. It is now read-only.

Commit

Permalink
Don't call a riichi for a pair wait (except chitoitsu)
Browse files Browse the repository at this point in the history
  • Loading branch information
Nihisil committed Mar 17, 2017
1 parent 1870d4d commit c41f3d3
Show file tree
Hide file tree
Showing 4 changed files with 67 additions and 2 deletions.
24 changes: 23 additions & 1 deletion project/mahjong/ai/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ def discard_tile(self):

we_can_call_riichi = shanten == 0 and self.player.can_call_riichi()
# current strategy can affect on our discard options
# and don't use strategy specific choices for calling riichi
# so, don't use strategy specific choices for calling riichi
if self.current_strategy and not we_can_call_riichi:
results = self.current_strategy.determine_what_to_discard(self.player.closed_hand,
results,
Expand Down Expand Up @@ -234,6 +234,28 @@ def estimate_hand_value(self, win_tile):
dora_indicators=self.player.table.dora_indicators)
return result

def should_call_riichi(self):
# empty waiting can be found in some cases
if not self.waiting:
return False

# we have a good wait, let's riichi
if len(self.waiting) > 1:
return True

waiting = self.waiting[0]
tiles_34 = TilesConverter.to_34_array(self.player.closed_hand)
count_of_pairs = len([x for x in range(0, 34) if tiles_34[x] == 2])

# pair wait is really easy to improve,
# so let's not riichi it
# but for chitoitsu we can call a riichi
is_pair_wait = tiles_34[waiting] == 1
if is_pair_wait and count_of_pairs != 6:
return False

return True

@property
def valued_honors(self):
return [CHUN, HAKU, HATSU, self.player.table.round_wind, self.player.player_wind]
36 changes: 36 additions & 0 deletions project/mahjong/ai/tests/tests_riichi.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# -*- coding: utf-8 -*-
import unittest

from mahjong.ai.discard import DiscardOption
from mahjong.ai.main import MainAI
from mahjong.ai.shanten import Shanten
from mahjong.constants import EAST, SOUTH, WEST, NORTH, HAKU, HATSU, CHUN, FIVE_RED_SOU
from mahjong.player import Player
from mahjong.table import Table
from utils.tests import TestMixin


class CallRiichiTestCase(unittest.TestCase, TestMixin):

def test_should_call_riichi_and_tanki_wait(self):
table = Table()
table.count_of_remaining_tiles = 60
player = Player(table, 0, 0, False)
player.scores = 25000

tiles = self._string_to_136_array(sou='123456', pin='12345', man='34')
tile = self._string_to_136_tile(pin='6')
player.init_hand(tiles)
player.draw_tile(tile)
player.discard_tile()

self.assertEqual(player.can_call_riichi(), False)

tiles = self._string_to_136_array(sou='1133557799', pin='113')
tile = self._string_to_136_tile(pin='6')
player.init_hand(tiles)
player.draw_tile(tile)
player.discard_tile()

# for chitoitsu it is ok to have a pair wait
self.assertEqual(player.can_call_riichi(), True)
4 changes: 3 additions & 1 deletion project/mahjong/player.py
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ def discard_tile(self, tile=None):
return tile_to_discard

def can_call_riichi(self):
return all([
result = all([
self.in_tempai,

not self.in_riichi,
Expand All @@ -155,6 +155,8 @@ def can_call_riichi(self):
self.table.count_of_remaining_tiles > 4
])

return result and self.ai.should_call_riichi()

def try_to_call_meld(self, tile, is_kamicha_discard):
return self.ai.try_to_call_meld(tile, is_kamicha_discard)

Expand Down
5 changes: 5 additions & 0 deletions project/mahjong/tests/tests_player.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ def test_can_call_riichi_and_tempai(self):
player.in_riichi = False
player.scores = 2000
player.table.count_of_remaining_tiles = 40
player.ai.waiting = [1, 2]

self.assertEqual(player.can_call_riichi(), False)

Expand All @@ -33,6 +34,7 @@ def test_can_call_riichi_and_already_in_riichi(self):
player.in_riichi = True
player.scores = 2000
player.table.count_of_remaining_tiles = 40
player.ai.waiting = [1, 2]

self.assertEqual(player.can_call_riichi(), False)

Expand All @@ -48,6 +50,7 @@ def test_can_call_riichi_and_scores(self):
player.in_riichi = False
player.scores = 0
player.table.count_of_remaining_tiles = 40
player.ai.waiting = [1, 2]

self.assertEqual(player.can_call_riichi(), False)

Expand All @@ -63,6 +66,7 @@ def test_can_call_riichi_and_remaining_tiles(self):
player.in_riichi = False
player.scores = 2000
player.table.count_of_remaining_tiles = 3
player.ai.waiting = [1, 2]

self.assertEqual(player.can_call_riichi(), False)

Expand All @@ -79,6 +83,7 @@ def test_can_call_riichi_and_open_hand(self):
player.scores = 2000
player.melds = [1]
player.table.count_of_remaining_tiles = 40
player.ai.waiting = [1, 2]

self.assertEqual(player.can_call_riichi(), False)

Expand Down

0 comments on commit c41f3d3

Please sign in to comment.