@@ -236,71 +236,83 @@ def should_call_kan(self, tile, open_kan, from_riichi=False):
236236 tiles_34 = TilesConverter .to_34_array (self .player .tiles )
237237
238238 closed_hand_34 = TilesConverter .to_34_array (self .player .closed_hand )
239- pon_melds = [x for x in self .player .meld_34_tiles if is_pon (x )]
240-
241- # let's check can we upgrade opened pon to the kan
242- if pon_melds :
243- for meld in pon_melds :
244- # tile is equal to our already opened pon,
245- # so let's call chankan!
246- if tile_34 in meld :
247- return Meld .CHANKAN
248239
249240 melds_34 = copy .copy (self .player .meld_34_tiles )
250241 tiles = copy .copy (self .player .tiles )
251242 closed_hand_tiles = copy .copy (self .player .closed_hand )
252243
253- # we can try to call closed meld
254- if closed_hand_34 [tile_34 ] == 3 :
244+ new_shanten = 0
245+ previous_shanten = 0
246+ new_waits_count = 0
247+ previous_waits_count = 0
248+
249+ # let's check can we upgrade opened pon to the kan
250+ pon_melds = [x for x in self .player .meld_34_tiles if is_pon (x )]
251+ has_chankan_candidate = False
252+ for meld in pon_melds :
253+ # tile is equal to our already opened pon
254+ if tile_34 in meld :
255+ has_chankan_candidate = True
256+
257+ tiles .append (tile )
258+ closed_hand_tiles .append (tile )
259+
260+ previous_shanten , previous_waits_count = self ._calculate_shanten_for_kan (
261+ tiles ,
262+ closed_hand_tiles ,
263+ self .player .melds
264+ )
265+
266+ tiles_34 = TilesConverter .to_34_array (tiles )
267+ tiles_34 [tile_34 ] -= 1
268+
269+ new_waiting , new_shanten = self .hand_builder .calculate_waits (
270+ tiles_34 ,
271+ self .player .meld_34_tiles
272+ )
273+ new_waits_count = self .hand_builder .count_tiles (new_waiting , tiles_34 )
274+
275+ if not has_chankan_candidate :
276+ # we don't have enough tiles in the hand
277+ if closed_hand_34 [tile_34 ] != 3 :
278+ return None
279+
255280 if open_kan or from_riichi :
256281 # this 4 tiles can only be used in kan, no other options
257282 previous_waiting , previous_shanten = self .hand_builder .calculate_waits (tiles_34 , melds_34 )
258- previous_waits_cnt = self .hand_builder .count_tiles (previous_waiting , closed_hand_34 )
259-
260- # shanten calculator doesn't like working with kans, so we pretend it's a pon
261- melds_34 += [[tile_34 , tile_34 , tile_34 ]]
262- closed_hand_34 [tile_34 ] = 0
263-
264- new_waiting , new_shanten = self .hand_builder .calculate_waits (tiles_34 , melds_34 )
265- new_waits_cnt = self .hand_builder .count_tiles (new_waiting , closed_hand_34 )
283+ previous_waits_count = self .hand_builder .count_tiles (previous_waiting , closed_hand_34 )
266284 else :
267- # if we can use or tile in the hand for the forms other than KAN
268285 tiles .append (tile )
269-
270286 closed_hand_tiles .append (tile )
271- closed_hand_34 [tile_34 ] += 1
272287
273- previous_results , previous_shanten = self .hand_builder . find_discard_options (
288+ previous_shanten , previous_waits_count = self ._calculate_shanten_for_kan (
274289 tiles ,
275290 closed_hand_tiles ,
276291 self .player .melds
277292 )
278293
279- previous_results = [x for x in previous_results if x .shanten == previous_shanten ]
280-
281- # it is possible that we don't have results here
282- # when we are in agari state (but without yaku)
283- if not previous_results :
284- return None
294+ # shanten calculator doesn't like working with kans, so we pretend it's a pon
295+ melds_34 += [[tile_34 , tile_34 , tile_34 ]]
296+ new_waiting , new_shanten = self .hand_builder .calculate_waits (tiles_34 , melds_34 )
285297
286- previous_waits_cnt = sorted (previous_results , key = lambda x : - x .ukeire )[0 ].ukeire
298+ closed_hand_34 [tile_34 ] = 4
299+ new_waits_count = self .hand_builder .count_tiles (new_waiting , closed_hand_34 )
287300
288- # shanten calculator doesn't like working with kans, so we pretend it's a pon
289- closed_hand_34 [tile_34 ] = 0
290- melds_34 += [[tile_34 , tile_34 , tile_34 ]]
301+ # it is possible that we don't have results here
302+ # when we are in agari state (but without yaku)
303+ if previous_shanten is None :
304+ return None
291305
292- new_waiting , new_shanten = self . hand_builder . calculate_waits ( tiles_34 , melds_34 )
293- new_waits_cnt = self . hand_builder . count_tiles ( new_waiting , closed_hand_34 )
306+ # it is not possible to reduce number of shanten by calling a kan
307+ assert new_shanten >= previous_shanten
294308
295- # it is not possible to reduce number of shanten by calling a kan
296- assert new_shanten >= previous_shanten
309+ # if shanten number is the same, we should only call kan if ukeire didn't become worse
310+ if new_shanten == previous_shanten :
311+ # we cannot improve ukeire by calling kan (not considering the tile we drew from the dead wall)
312+ assert new_waits_count <= previous_waits_count
297313
298- # if shanten number is the same, we should only call kan if ukeire didn't become worse
299- if new_shanten == previous_shanten :
300- # we cannot improve ukeire by calling kan (not considering the tile we drew from the dead wall)
301- assert new_waits_cnt <= previous_waits_cnt
302- if new_waits_cnt == previous_waits_cnt :
303- return Meld .KAN
314+ if new_waits_count == previous_waits_count :
315+ return has_chankan_candidate and Meld .CHANKAN or Meld .KAN
304316
305317 return None
306318
@@ -324,3 +336,21 @@ def enemy_players(self):
324336 Return list of players except our bot
325337 """
326338 return self .player .table .players [1 :]
339+
340+ def _calculate_shanten_for_kan (self , tiles , closed_hand_tiles , melds ):
341+ previous_results , previous_shanten = self .hand_builder .find_discard_options (
342+ tiles ,
343+ closed_hand_tiles ,
344+ melds
345+ )
346+
347+ previous_results = [x for x in previous_results if x .shanten == previous_shanten ]
348+
349+ # it is possible that we don't have results here
350+ # when we are in agari state (but without yaku)
351+ if not previous_results :
352+ return None , None
353+
354+ previous_waits_cnt = sorted (previous_results , key = lambda x : - x .ukeire )[0 ].ukeire
355+
356+ return previous_shanten , previous_waits_cnt
0 commit comments