@@ -236,71 +236,83 @@ def should_call_kan(self, tile, open_kan, from_riichi=False):
236
236
tiles_34 = TilesConverter .to_34_array (self .player .tiles )
237
237
238
238
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
248
239
249
240
melds_34 = copy .copy (self .player .meld_34_tiles )
250
241
tiles = copy .copy (self .player .tiles )
251
242
closed_hand_tiles = copy .copy (self .player .closed_hand )
252
243
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_shouminkan_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_shouminkan_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_shouminkan_candidate :
276
+ # we don't have enough tiles in the hand
277
+ if closed_hand_34 [tile_34 ] != 3 :
278
+ return None
279
+
255
280
if open_kan or from_riichi :
256
281
# this 4 tiles can only be used in kan, no other options
257
282
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 )
266
284
else :
267
- # if we can use or tile in the hand for the forms other than KAN
268
285
tiles .append (tile )
269
-
270
286
closed_hand_tiles .append (tile )
271
- closed_hand_34 [tile_34 ] += 1
272
287
273
- previous_results , previous_shanten = self .hand_builder . find_discard_options (
288
+ previous_shanten , previous_waits_count = self ._calculate_shanten_for_kan (
274
289
tiles ,
275
290
closed_hand_tiles ,
276
291
self .player .melds
277
292
)
278
293
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 )
285
297
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 )
287
300
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
291
305
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
294
308
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
297
313
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_shouminkan_candidate and Meld .CHANKAN or Meld .KAN
304
316
305
317
return None
306
318
@@ -324,3 +336,21 @@ def enemy_players(self):
324
336
Return list of players except our bot
325
337
"""
326
338
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