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

Commit 1704d6b

Browse files
committed
improve atodzuke handling rules #72
1. Fixed ukeire2 calculation with atodzuke. 2. For tanyao now only strictly avoid atodzuke in tempai. 3. Don't consider wait to be atodzuke if there are no live non-suitable tiles.
1 parent d368f3b commit 1704d6b

File tree

4 files changed

+74
-17
lines changed

4 files changed

+74
-17
lines changed

project/game/ai/first_version/hand_builder.py

Lines changed: 26 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -198,11 +198,7 @@ def find_discard_options(self, tiles, closed_hand, melds=None):
198198

199199
def count_tiles(self, waiting, tiles_34):
200200
n = 0
201-
not_suitable_tiles = self.ai.current_strategy and self.ai.current_strategy.not_suitable_tiles or []
202201
for tile_34 in waiting:
203-
if self.player.is_open_hand and tile_34 in not_suitable_tiles:
204-
continue
205-
206202
n += 4 - self.player.total_tiles(tile_34, tiles_34)
207203
return n
208204

@@ -639,23 +635,40 @@ def calculate_second_level_ukeire(self, discard_option):
639635

640636
# let's take best ukeire here
641637
if results:
642-
# TODO: find best one considering atodzuke
643-
best_one = sorted(results, key=lambda x: -x.ukeire)[0]
644-
sum_tiles += best_one.ukeire * live_tiles
645-
646-
has_atodzuke = False
638+
result_has_atodzuke = False
647639
if self.player.is_open_hand:
648-
for wait_34 in best_one.waiting:
649-
if wait_34 in not_suitable_tiles:
650-
has_atodzuke = True
640+
best_one = results[0]
641+
best_ukeire = 0
642+
for result in results:
643+
has_atodzuke = False
644+
ukeire = 0
645+
for wait_34 in result.waiting:
646+
if wait_34 in not_suitable_tiles:
647+
has_atodzuke = True
648+
else:
649+
ukeire += result.wait_to_ukeire[wait_34]
650+
651+
# let's consider atodzuke waits to be worse than non-atodzuke ones
652+
if has_atodzuke:
653+
ukeire /= 2
654+
655+
if (ukeire > best_ukeire) or (ukeire >= best_ukeire and not has_atodzuke):
656+
best_ukeire = ukeire
657+
best_one = result
658+
result_has_atodzuke = has_atodzuke
659+
else:
660+
best_one = sorted(results, key=lambda x: -x.ukeire)[0]
661+
best_ukeire = best_one.ukeire
662+
663+
sum_tiles += best_ukeire * live_tiles
651664

652665
# if we are going to have a tempai (on our second level) - let's also count its cost
653666
if shanten == 0:
654667
next_tile_in_hand = best_one.find_tile_in_hand(self.player.closed_hand)
655668
self.player.tiles.remove(next_tile_in_hand)
656669
cost_x_ukeire, _ = self._estimate_cost_x_ukeire(best_one, call_riichi=call_riichi)
657670
# we reduce tile valuation for atodzuke
658-
if has_atodzuke:
671+
if result_has_atodzuke:
659672
cost_x_ukeire /= 2
660673
sum_cost += cost_x_ukeire
661674
self.player.tiles.append(next_tile_in_hand)

project/game/ai/first_version/strategies/tanyao.py

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -140,9 +140,13 @@ def determine_what_to_discard(self, discard_options, hand, open_melds):
140140
continue
141141

142142
# there is no sense to wait 1-4 if we have open hand
143-
all_waiting_are_fine = all([self.is_tile_suitable(x * 4) for x in item.waiting])
144-
if all_waiting_are_fine:
145-
results.append(item)
143+
# but let's only avoid atodzuke tiles in tempai, the rest will be dealt with in
144+
# generic logic
145+
if item.shanten == 0:
146+
all_waiting_are_fine = all(
147+
[(self.is_tile_suitable(x * 4) or item.wait_to_ukeire[x] == 0) for x in item.waiting])
148+
if all_waiting_are_fine:
149+
results.append(item)
146150

147151
if not_suitable_tiles:
148152
return not_suitable_tiles

project/game/ai/first_version/tests/strategies/tests_chiitoitsu.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ def test_should_activate_strategy(self):
3131
tiles = self._string_to_136_array(sou='234', man='223344', pin='5669')
3232
player.init_hand(tiles)
3333
player.draw_tile(self._string_to_136_tile(pin='5'))
34-
player.ai.shanten = 0
34+
player.discard_tile()
3535
self.assertEqual(strategy.should_activate_strategy(player.tiles), False)
3636

3737
tiles = self._string_to_136_array(sou='234', man='22334455669')

project/game/ai/first_version/tests/strategies/tests_tanyao.py

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,46 @@ def test_choose_correct_waiting(self):
220220
discard = player.discard_tile()
221221
self.assertEqual(self._to_string([discard]), '7s')
222222

223+
def test_choose_balanced_ukeire_in_1_shanten(self):
224+
table = self._make_table()
225+
player = table.player
226+
227+
meld = self._make_meld(Meld.CHI, man='678')
228+
player.add_called_meld(meld)
229+
230+
tiles = self._string_to_136_array(man='22678', sou='234568', pin='45')
231+
player.init_hand(tiles)
232+
player.draw_tile(self._string_to_136_tile(man='2'))
233+
234+
self._assert_tanyao(player)
235+
236+
# there are lost of options to avoid atodzuke and even if it is atodzuke,
237+
# it is still a good one, so let's choose more efficient 8s discard instead of 2s
238+
discard = player.discard_tile()
239+
self.assertEqual(self._to_string([discard]), '8s')
240+
241+
def test_choose_pseudo_atodzuke(self):
242+
table = self._make_table()
243+
table.has_aka_dora = False
244+
player = table.player
245+
246+
# one tile is dora indicator and 3 are out
247+
# so this 1-4 wait is not atodzuke
248+
for _ in range(0, 3):
249+
table.add_discarded_tile(1, self._string_to_136_tile(pin='1'), False)
250+
251+
meld = self._make_meld(Meld.CHI, man='678')
252+
player.add_called_meld(meld)
253+
254+
tiles = self._string_to_136_array(man='222678', sou='23488', pin='35')
255+
player.init_hand(tiles)
256+
player.draw_tile(self._string_to_136_tile(pin='2'))
257+
258+
self._assert_tanyao(player)
259+
260+
discard = player.discard_tile()
261+
self.assertEqual(self._to_string([discard]), '5p')
262+
223263
def test_choose_correct_waiting_and_first_opened_meld(self):
224264
tiles = self._string_to_136_array(man='2337788', sou='222', pin='234')
225265
self.player.init_hand(tiles)

0 commit comments

Comments
 (0)