Hide keyboard shortcuts

Hot-keys on this page

r m x p   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

1from copy import copy 

2 

3from game.ai.defence.yaku_analyzer.tanyao import TanyaoAnalyzer 

4from game.ai.defence.yaku_analyzer.yaku_analyzer import YakuAnalyzer 

5from game.ai.helpers.defence import TileDanger 

6from mahjong.tile import TilesConverter 

7from mahjong.utils import plus_dora 

8from utils.decisions_logger import MeldPrint 

9 

10 

11class ToitoiAnalyzer(YakuAnalyzer): 

12 id = "toitoi" 

13 

14 def __init__(self, enemy): 

15 self.enemy = enemy 

16 self.table = enemy.table 

17 

18 # is our bot 

19 self.main_player = self.table.player 

20 

21 def serialize(self): 

22 return {"id": self.id} 

23 

24 def is_yaku_active(self): 

25 if len(self.enemy.melds) < 2: 

26 return False 

27 

28 for meld in self.enemy.melds: 

29 if meld.type == MeldPrint.CHI: 

30 return False 

31 

32 if len(self.enemy.discards) < 10: 

33 return len(self.enemy.melds) >= 3 

34 

35 return True 

36 

37 def melds_han(self): 

38 return 2 

39 

40 def get_safe_tiles_34(self): 

41 safe_tiles_34 = [] 

42 closed_hand_34 = TilesConverter.to_34_array(self.main_player.closed_hand) 

43 for tile_34 in range(0, 34): 

44 number_of_revealed_tiles = self.main_player.number_of_revealed_tiles(tile_34, closed_hand_34) 

45 if number_of_revealed_tiles == 4: 

46 safe_tiles_34.append(tile_34) 

47 

48 return safe_tiles_34 

49 

50 def get_bonus_danger(self, tile_136, number_of_revealed_tiles): 

51 bonus_danger = [] 

52 tile_34 = tile_136 // 4 

53 number_of_yakuhai = self.enemy.valued_honors.count(tile_34) 

54 

55 # shonpai tiles 

56 if number_of_revealed_tiles == 1: 

57 # aka doras don't get additional danger against toitoi, they just get their regular one 

58 dora_count = plus_dora(tile_136, self.enemy.table.dora_indicators) 

59 if dora_count > 0: 

60 danger = copy(TileDanger.TOITOI_SHONPAI_DORA_BONUS_DANGER) 

61 danger["value"] = dora_count * danger["value"] 

62 danger["dora_count"] = dora_count 

63 bonus_danger.append(danger) 

64 

65 if number_of_yakuhai > 0: 

66 bonus_danger.append(TileDanger.TOITOI_SHONPAI_YAKUHAI_BONUS_DANGER) 

67 else: 

68 bonus_danger.append(TileDanger.TOITOI_SHONPAI_NON_YAKUHAI_BONUS_DANGER) 

69 elif number_of_revealed_tiles == 2: 

70 if number_of_yakuhai > 0: 

71 bonus_danger.append(TileDanger.TOITOI_SECOND_YAKUHAI_HONOR_BONUS_DANGER) 

72 elif number_of_revealed_tiles == 3: 

73 # FIXME: we should add negative bonus danger exclusively against toitoi for such tiles 

74 # except for doras and honors maybe 

75 pass 

76 

77 return bonus_danger 

78 

79 def is_absorbed(self, possible_yaku, tile_34=None): 

80 return self._is_absorbed_by(possible_yaku, TanyaoAnalyzer.id, tile_34)