hanabiapp.game.agent.(inbug)outer_state_agent

  1from .agent import Agent
  2from ..action import Action
  3
  4class OuterStateAgent(Agent):
  5  def __init__(self, name, player_number):
  6    super().__init__(name, player_number)
  7    self.need_hle_convert= False
  8    self.already_hints = {}
  9
 10  def get_possible(self,knowledge):
 11    """
 12    各カードに対する知識に基づいて、プレイヤーが持っている可能性があるカードのリストを返す。
 13    """
 14    possible = []
 15    for color in self.game.game_const.ALL_COLORS:
 16      for number, count in enumerate(knowledge[color]):
 17        if count > 0:
 18          possible.append((color, number + 1))  # 色と数字のペアを追加
 19    #check_type_and_dtype(possible)
 20    return possible
 21  
 22  def playable(self,possible, board):
 23    #print("playable関数")
 24    for (color,number) in possible:
 25      #print(f"color:{color},number:{number}")      #print(f"{color}色の最大値:{board[color]}")
 26      if board[color] + 1 != number:
 27        #print(f"Playable:{color,number} is False")
 28        return False # possibleのリスト内で、少なくとも1つでもplayableでないタプルが含まれていると、そのリスト全体に対してFalseが返されます
 29    #print(f"Playable:{possible} is True")
 30    return True 
 31  
 32  def discardable(self,possible, board):
 33    for (color,number) in possible:
 34      if board[color] < number: 
 35        return False
 36    #print("Discardable: ",possible)
 37    return True # ボード上のその色のカードよりも小さい数字なら破棄しても問題ない
 38
 39  def act(self, game_ins):
 40    """
 41    プレイヤーの次のアクションを決定するメソッド
 42    valid_actions: 現在のターンでプレイヤーが取ることのできる有効なアクションのリスト
 43    """
 44    #===============================================================================================
 45    # もしプレイヤがプレイ可能カードを持っていれば,それをプレイする
 46    # 破棄可能カードを持っていたら,それを破棄する
 47    possible = []
 48
 49    # 己のknowledgeから,持ちうるカードの(色,数字)をリストアップ(枚数情報除く)
 50    for k in game_ins.knowledge[self.player_number]:
 51      possible.append(self.get_possible(k))
 52      
 53    # for idx, p in enumerate(possible):
 54    #     print("Possible for Card {}: {}".format(idx + 1, p))
 55
 56    playable_cards= []
 57    discardable_cards = []
 58    for i, card in enumerate(possible):
 59      # ボード上のその色のカードが次に必要な数字かどうかを確認
 60      if self.playable(card,game_ins.board):
 61        # possibleの中から,プレイ可能なカードが見つかったら、それを格納
 62        playable_cards.append(i)
 63      if self.discardable(card,game_ins.board):
 64        discardable_cards.append(i)
 65
 66    #print(f"playable_cards:{playable_cards},discardable_cards:{discardable_cards}")
 67    if playable_cards:
 68      print("outer-state:プレイ可能カードを持っていれるので,それをプレイします.")
 69      return Action(game_ins.game_const.PLAY, card_position=game_ins.random.choice(playable_cards))
 70    if discardable_cards:
 71      print("outer-state:破棄可能カードを持っていれるので,それを捨てます.")
 72      return Action(game_ins.game_const.DISCARD, card_position=game_ins.random.choice(discardable_cards))
 73    #===============================================================================================
 74    # もし相手がプレイ可能なカードを持っていれば,プレイヤはそのカードの色か数字に関するヒントを与える
 75    # すでに出したヒントは出さない
 76
 77    opponent_playable_info = [] # (player_number,card_position)のタプルのリスト
 78    ai_player_number = self.player_number
 79
 80    for i,(player_number,opponent_hand) in enumerate(game_ins.hands.items()):
 81      if player_number != ai_player_number:
 82        for card_position,(color,number) in enumerate(opponent_hand):
 83          if game_ins.board[color] + 1 == number:
 84            opponent_playable_info.append((player_number,card_position))
 85    
 86    opponent_playable_info.sort(key=lambda x: x[1]) # card_positionでソート
 87    print(f"opponent_playable_info:{opponent_playable_info}")
 88    
 89    while opponent_playable_info and game_ins.hints > 0:
 90      player_number,card_position = opponent_playable_info[0] # 一個目のプレイ可能な情報を選択
 91
 92      hinttype = [game_ins.game_const.HINT_COLOR, game_ins.game_const.HINT_NUMBER]
 93
 94      if (card_position, player_number) not in self.already_hints:
 95        self.already_hints[(card_position, player_number)] = [] # ヒントを与えたことを記録するための枠を作る
 96
 97      # print(f"self.already_hints:{self.already_hints}")
 98
 99      for h in self.already_hints[(card_position, player_number)]:
100        hinttype.remove(h) # 既に数字,色ヒントを出した状態であれば,それを出さないようにhinttypeから除外する
101      
102      # print(f"hinttype:{hinttype}")
103      t = None
104      if hinttype:
105          t = game_ins.random.choice(hinttype)
106      
107      
108      if t == game_ins.game_const.HINT_NUMBER:
109        self.already_hints[(card_position, player_number)].append(game_ins.game_const.HINT_NUMBER)
110        print("outer-state:相手がプレイ可能なカードを持っているので,半々の確率で色ヒントか数字ヒントを出します.(ただし,すでに出したヒントは出さない)")
111        return Action(t, pnr=player_number, number=game_ins.hands[player_number][card_position][1])
112      elif t == game_ins.game_const.HINT_COLOR:
113        self.already_hints[(card_position, player_number)].append(game_ins.game_const.HINT_COLOR)
114        print("outer-state:相手がプレイ可能なカードを持っているので,半々の確率で色ヒントか数字ヒントを出します.(ただし,すでに出したヒントは出さない)")
115        return Action(t, pnr=player_number, color=game_ins.hands[player_number][card_position][0])
116
117      opponent_playable_info = opponent_playable_info[1:] # 一個目のプレイ可能な情報を削除
118
119    #===============================================================================================
120    # もし相手がプレイ可能なカードを持っておらず,ヒントトークンがある場合は,相手が情報を持っていないカードのうち1枚をランダムに選択してヒントを与える
121    ai_player_number = self.player_number
122    for player in game_ins.players:
123      if player.player_number == ai_player_number:
124        continue
125    
126      cards = list(range(game_ins.hand_size))
127      game_ins.random.shuffle(cards)
128      random_pick_card_position = cards[0]
129
130      (color,number) = game_ins.hands[player.player_number][random_pick_card_position]
131      
132
133      hinttype = [game_ins.game_const.HINT_COLOR, game_ins.game_const.HINT_NUMBER]
134
135      if (random_pick_card_position,player.player_number) not in self.already_hints:
136          self.already_hints[(random_pick_card_position,player.player_number)] = []
137
138      for h in self.already_hints[(random_pick_card_position,player.player_number)]:
139          hinttype.remove(h)
140        
141      print(f"self.already_hints:{self.already_hints}") 
142      print(f"hinttype:{hinttype}") 
143
144      if hinttype and game_ins.hints > 0:
145          if game_ins.random.choice(hinttype) == game_ins.game_const.HINT_COLOR:
146              self.already_hints[(random_pick_card_position,player.player_number)].append(game_ins.game_const.HINT_COLOR)
147              print("outer-state:相手がプレイ可能なカードを持っておらず,ヒントトークンがある場合は,相手カードのうち,情報を持っていないカードをランダムに選択,ヒントを与えます.")
148              return Action(game_ins.game_const.HINT_COLOR, pnr=i, color=color)
149          else:
150              self.already_hints[(random_pick_card_position,player.player_number)].append(game_ins.game_const.HINT_NUMBER)
151              print("outer-state:相手がプレイ可能なカードを持っておらず,ヒントトークンがある場合は,相手カードのうち,情報を持っていないカードをランダムに選択,ヒントを与えます.")
152              return Action(game_ins.game_const.HINT_NUMBER, pnr=i, number=number)
153      
154    #===============================================================================================
155    # もし相手がプレイ可能なカードを持っておらず,ヒントトークンがない場合,自分のカードをランダムに選んで捨てる
156    
157    print("自分のカードをランダムに選んで捨てます.")
158    #print(f"random_pick_card_position:{random_pick_card_position}")
159    return Action(game_ins.game_const.DISCARD, card_position=game_ins.random.choice(range(game_ins.hand_size)))
class OuterStateAgent(hanabiapp.game.agent.agent.Agent):
  5class OuterStateAgent(Agent):
  6  def __init__(self, name, player_number):
  7    super().__init__(name, player_number)
  8    self.need_hle_convert= False
  9    self.already_hints = {}
 10
 11  def get_possible(self,knowledge):
 12    """
 13    各カードに対する知識に基づいて、プレイヤーが持っている可能性があるカードのリストを返す。
 14    """
 15    possible = []
 16    for color in self.game.game_const.ALL_COLORS:
 17      for number, count in enumerate(knowledge[color]):
 18        if count > 0:
 19          possible.append((color, number + 1))  # 色と数字のペアを追加
 20    #check_type_and_dtype(possible)
 21    return possible
 22  
 23  def playable(self,possible, board):
 24    #print("playable関数")
 25    for (color,number) in possible:
 26      #print(f"color:{color},number:{number}")      #print(f"{color}色の最大値:{board[color]}")
 27      if board[color] + 1 != number:
 28        #print(f"Playable:{color,number} is False")
 29        return False # possibleのリスト内で、少なくとも1つでもplayableでないタプルが含まれていると、そのリスト全体に対してFalseが返されます
 30    #print(f"Playable:{possible} is True")
 31    return True 
 32  
 33  def discardable(self,possible, board):
 34    for (color,number) in possible:
 35      if board[color] < number: 
 36        return False
 37    #print("Discardable: ",possible)
 38    return True # ボード上のその色のカードよりも小さい数字なら破棄しても問題ない
 39
 40  def act(self, game_ins):
 41    """
 42    プレイヤーの次のアクションを決定するメソッド
 43    valid_actions: 現在のターンでプレイヤーが取ることのできる有効なアクションのリスト
 44    """
 45    #===============================================================================================
 46    # もしプレイヤがプレイ可能カードを持っていれば,それをプレイする
 47    # 破棄可能カードを持っていたら,それを破棄する
 48    possible = []
 49
 50    # 己のknowledgeから,持ちうるカードの(色,数字)をリストアップ(枚数情報除く)
 51    for k in game_ins.knowledge[self.player_number]:
 52      possible.append(self.get_possible(k))
 53      
 54    # for idx, p in enumerate(possible):
 55    #     print("Possible for Card {}: {}".format(idx + 1, p))
 56
 57    playable_cards= []
 58    discardable_cards = []
 59    for i, card in enumerate(possible):
 60      # ボード上のその色のカードが次に必要な数字かどうかを確認
 61      if self.playable(card,game_ins.board):
 62        # possibleの中から,プレイ可能なカードが見つかったら、それを格納
 63        playable_cards.append(i)
 64      if self.discardable(card,game_ins.board):
 65        discardable_cards.append(i)
 66
 67    #print(f"playable_cards:{playable_cards},discardable_cards:{discardable_cards}")
 68    if playable_cards:
 69      print("outer-state:プレイ可能カードを持っていれるので,それをプレイします.")
 70      return Action(game_ins.game_const.PLAY, card_position=game_ins.random.choice(playable_cards))
 71    if discardable_cards:
 72      print("outer-state:破棄可能カードを持っていれるので,それを捨てます.")
 73      return Action(game_ins.game_const.DISCARD, card_position=game_ins.random.choice(discardable_cards))
 74    #===============================================================================================
 75    # もし相手がプレイ可能なカードを持っていれば,プレイヤはそのカードの色か数字に関するヒントを与える
 76    # すでに出したヒントは出さない
 77
 78    opponent_playable_info = [] # (player_number,card_position)のタプルのリスト
 79    ai_player_number = self.player_number
 80
 81    for i,(player_number,opponent_hand) in enumerate(game_ins.hands.items()):
 82      if player_number != ai_player_number:
 83        for card_position,(color,number) in enumerate(opponent_hand):
 84          if game_ins.board[color] + 1 == number:
 85            opponent_playable_info.append((player_number,card_position))
 86    
 87    opponent_playable_info.sort(key=lambda x: x[1]) # card_positionでソート
 88    print(f"opponent_playable_info:{opponent_playable_info}")
 89    
 90    while opponent_playable_info and game_ins.hints > 0:
 91      player_number,card_position = opponent_playable_info[0] # 一個目のプレイ可能な情報を選択
 92
 93      hinttype = [game_ins.game_const.HINT_COLOR, game_ins.game_const.HINT_NUMBER]
 94
 95      if (card_position, player_number) not in self.already_hints:
 96        self.already_hints[(card_position, player_number)] = [] # ヒントを与えたことを記録するための枠を作る
 97
 98      # print(f"self.already_hints:{self.already_hints}")
 99
100      for h in self.already_hints[(card_position, player_number)]:
101        hinttype.remove(h) # 既に数字,色ヒントを出した状態であれば,それを出さないようにhinttypeから除外する
102      
103      # print(f"hinttype:{hinttype}")
104      t = None
105      if hinttype:
106          t = game_ins.random.choice(hinttype)
107      
108      
109      if t == game_ins.game_const.HINT_NUMBER:
110        self.already_hints[(card_position, player_number)].append(game_ins.game_const.HINT_NUMBER)
111        print("outer-state:相手がプレイ可能なカードを持っているので,半々の確率で色ヒントか数字ヒントを出します.(ただし,すでに出したヒントは出さない)")
112        return Action(t, pnr=player_number, number=game_ins.hands[player_number][card_position][1])
113      elif t == game_ins.game_const.HINT_COLOR:
114        self.already_hints[(card_position, player_number)].append(game_ins.game_const.HINT_COLOR)
115        print("outer-state:相手がプレイ可能なカードを持っているので,半々の確率で色ヒントか数字ヒントを出します.(ただし,すでに出したヒントは出さない)")
116        return Action(t, pnr=player_number, color=game_ins.hands[player_number][card_position][0])
117
118      opponent_playable_info = opponent_playable_info[1:] # 一個目のプレイ可能な情報を削除
119
120    #===============================================================================================
121    # もし相手がプレイ可能なカードを持っておらず,ヒントトークンがある場合は,相手が情報を持っていないカードのうち1枚をランダムに選択してヒントを与える
122    ai_player_number = self.player_number
123    for player in game_ins.players:
124      if player.player_number == ai_player_number:
125        continue
126    
127      cards = list(range(game_ins.hand_size))
128      game_ins.random.shuffle(cards)
129      random_pick_card_position = cards[0]
130
131      (color,number) = game_ins.hands[player.player_number][random_pick_card_position]
132      
133
134      hinttype = [game_ins.game_const.HINT_COLOR, game_ins.game_const.HINT_NUMBER]
135
136      if (random_pick_card_position,player.player_number) not in self.already_hints:
137          self.already_hints[(random_pick_card_position,player.player_number)] = []
138
139      for h in self.already_hints[(random_pick_card_position,player.player_number)]:
140          hinttype.remove(h)
141        
142      print(f"self.already_hints:{self.already_hints}") 
143      print(f"hinttype:{hinttype}") 
144
145      if hinttype and game_ins.hints > 0:
146          if game_ins.random.choice(hinttype) == game_ins.game_const.HINT_COLOR:
147              self.already_hints[(random_pick_card_position,player.player_number)].append(game_ins.game_const.HINT_COLOR)
148              print("outer-state:相手がプレイ可能なカードを持っておらず,ヒントトークンがある場合は,相手カードのうち,情報を持っていないカードをランダムに選択,ヒントを与えます.")
149              return Action(game_ins.game_const.HINT_COLOR, pnr=i, color=color)
150          else:
151              self.already_hints[(random_pick_card_position,player.player_number)].append(game_ins.game_const.HINT_NUMBER)
152              print("outer-state:相手がプレイ可能なカードを持っておらず,ヒントトークンがある場合は,相手カードのうち,情報を持っていないカードをランダムに選択,ヒントを与えます.")
153              return Action(game_ins.game_const.HINT_NUMBER, pnr=i, number=number)
154      
155    #===============================================================================================
156    # もし相手がプレイ可能なカードを持っておらず,ヒントトークンがない場合,自分のカードをランダムに選んで捨てる
157    
158    print("自分のカードをランダムに選んで捨てます.")
159    #print(f"random_pick_card_position:{random_pick_card_position}")
160    return Action(game_ins.game_const.DISCARD, card_position=game_ins.random.choice(range(game_ins.hand_size)))

エージェントを表現する抽象クラス.

ゲームのプレイヤーとして動作するエージェントの基底クラスであり, すべてのエージェントが共通して持つべきインターフェースを定義する.

Attributes:
  • game_const (GameConst): ゲームの定数
  • name (str): エージェントの名前
  • player_number (int): エージェントの番号
  • need_hle_convert (bool): HLE形式の変換が必要かどうか
  • game (Game): ゲームのインスタンス(後で設定される)
  • is_cui (bool): CUIモードかどうか
OuterStateAgent(name, player_number)
6  def __init__(self, name, player_number):
7    super().__init__(name, player_number)
8    self.need_hle_convert= False
9    self.already_hints = {}

エージェントの初期化.

Arguments:
  • name (str): エージェントの名前
  • player_number (int): エージェントの番号
  • need_hle_convert (bool, optional): HLE形式の変換が必要かどうか(デフォルトはTrue)
need_hle_convert
already_hints
def get_possible(self, knowledge):
11  def get_possible(self,knowledge):
12    """
13    各カードに対する知識に基づいて、プレイヤーが持っている可能性があるカードのリストを返す。
14    """
15    possible = []
16    for color in self.game.game_const.ALL_COLORS:
17      for number, count in enumerate(knowledge[color]):
18        if count > 0:
19          possible.append((color, number + 1))  # 色と数字のペアを追加
20    #check_type_and_dtype(possible)
21    return possible

各カードに対する知識に基づいて、プレイヤーが持っている可能性があるカードのリストを返す。

def playable(self, possible, board):
23  def playable(self,possible, board):
24    #print("playable関数")
25    for (color,number) in possible:
26      #print(f"color:{color},number:{number}")      #print(f"{color}色の最大値:{board[color]}")
27      if board[color] + 1 != number:
28        #print(f"Playable:{color,number} is False")
29        return False # possibleのリスト内で、少なくとも1つでもplayableでないタプルが含まれていると、そのリスト全体に対してFalseが返されます
30    #print(f"Playable:{possible} is True")
31    return True 
def discardable(self, possible, board):
33  def discardable(self,possible, board):
34    for (color,number) in possible:
35      if board[color] < number: 
36        return False
37    #print("Discardable: ",possible)
38    return True # ボード上のその色のカードよりも小さい数字なら破棄しても問題ない
def act(self, game_ins):
 40  def act(self, game_ins):
 41    """
 42    プレイヤーの次のアクションを決定するメソッド
 43    valid_actions: 現在のターンでプレイヤーが取ることのできる有効なアクションのリスト
 44    """
 45    #===============================================================================================
 46    # もしプレイヤがプレイ可能カードを持っていれば,それをプレイする
 47    # 破棄可能カードを持っていたら,それを破棄する
 48    possible = []
 49
 50    # 己のknowledgeから,持ちうるカードの(色,数字)をリストアップ(枚数情報除く)
 51    for k in game_ins.knowledge[self.player_number]:
 52      possible.append(self.get_possible(k))
 53      
 54    # for idx, p in enumerate(possible):
 55    #     print("Possible for Card {}: {}".format(idx + 1, p))
 56
 57    playable_cards= []
 58    discardable_cards = []
 59    for i, card in enumerate(possible):
 60      # ボード上のその色のカードが次に必要な数字かどうかを確認
 61      if self.playable(card,game_ins.board):
 62        # possibleの中から,プレイ可能なカードが見つかったら、それを格納
 63        playable_cards.append(i)
 64      if self.discardable(card,game_ins.board):
 65        discardable_cards.append(i)
 66
 67    #print(f"playable_cards:{playable_cards},discardable_cards:{discardable_cards}")
 68    if playable_cards:
 69      print("outer-state:プレイ可能カードを持っていれるので,それをプレイします.")
 70      return Action(game_ins.game_const.PLAY, card_position=game_ins.random.choice(playable_cards))
 71    if discardable_cards:
 72      print("outer-state:破棄可能カードを持っていれるので,それを捨てます.")
 73      return Action(game_ins.game_const.DISCARD, card_position=game_ins.random.choice(discardable_cards))
 74    #===============================================================================================
 75    # もし相手がプレイ可能なカードを持っていれば,プレイヤはそのカードの色か数字に関するヒントを与える
 76    # すでに出したヒントは出さない
 77
 78    opponent_playable_info = [] # (player_number,card_position)のタプルのリスト
 79    ai_player_number = self.player_number
 80
 81    for i,(player_number,opponent_hand) in enumerate(game_ins.hands.items()):
 82      if player_number != ai_player_number:
 83        for card_position,(color,number) in enumerate(opponent_hand):
 84          if game_ins.board[color] + 1 == number:
 85            opponent_playable_info.append((player_number,card_position))
 86    
 87    opponent_playable_info.sort(key=lambda x: x[1]) # card_positionでソート
 88    print(f"opponent_playable_info:{opponent_playable_info}")
 89    
 90    while opponent_playable_info and game_ins.hints > 0:
 91      player_number,card_position = opponent_playable_info[0] # 一個目のプレイ可能な情報を選択
 92
 93      hinttype = [game_ins.game_const.HINT_COLOR, game_ins.game_const.HINT_NUMBER]
 94
 95      if (card_position, player_number) not in self.already_hints:
 96        self.already_hints[(card_position, player_number)] = [] # ヒントを与えたことを記録するための枠を作る
 97
 98      # print(f"self.already_hints:{self.already_hints}")
 99
100      for h in self.already_hints[(card_position, player_number)]:
101        hinttype.remove(h) # 既に数字,色ヒントを出した状態であれば,それを出さないようにhinttypeから除外する
102      
103      # print(f"hinttype:{hinttype}")
104      t = None
105      if hinttype:
106          t = game_ins.random.choice(hinttype)
107      
108      
109      if t == game_ins.game_const.HINT_NUMBER:
110        self.already_hints[(card_position, player_number)].append(game_ins.game_const.HINT_NUMBER)
111        print("outer-state:相手がプレイ可能なカードを持っているので,半々の確率で色ヒントか数字ヒントを出します.(ただし,すでに出したヒントは出さない)")
112        return Action(t, pnr=player_number, number=game_ins.hands[player_number][card_position][1])
113      elif t == game_ins.game_const.HINT_COLOR:
114        self.already_hints[(card_position, player_number)].append(game_ins.game_const.HINT_COLOR)
115        print("outer-state:相手がプレイ可能なカードを持っているので,半々の確率で色ヒントか数字ヒントを出します.(ただし,すでに出したヒントは出さない)")
116        return Action(t, pnr=player_number, color=game_ins.hands[player_number][card_position][0])
117
118      opponent_playable_info = opponent_playable_info[1:] # 一個目のプレイ可能な情報を削除
119
120    #===============================================================================================
121    # もし相手がプレイ可能なカードを持っておらず,ヒントトークンがある場合は,相手が情報を持っていないカードのうち1枚をランダムに選択してヒントを与える
122    ai_player_number = self.player_number
123    for player in game_ins.players:
124      if player.player_number == ai_player_number:
125        continue
126    
127      cards = list(range(game_ins.hand_size))
128      game_ins.random.shuffle(cards)
129      random_pick_card_position = cards[0]
130
131      (color,number) = game_ins.hands[player.player_number][random_pick_card_position]
132      
133
134      hinttype = [game_ins.game_const.HINT_COLOR, game_ins.game_const.HINT_NUMBER]
135
136      if (random_pick_card_position,player.player_number) not in self.already_hints:
137          self.already_hints[(random_pick_card_position,player.player_number)] = []
138
139      for h in self.already_hints[(random_pick_card_position,player.player_number)]:
140          hinttype.remove(h)
141        
142      print(f"self.already_hints:{self.already_hints}") 
143      print(f"hinttype:{hinttype}") 
144
145      if hinttype and game_ins.hints > 0:
146          if game_ins.random.choice(hinttype) == game_ins.game_const.HINT_COLOR:
147              self.already_hints[(random_pick_card_position,player.player_number)].append(game_ins.game_const.HINT_COLOR)
148              print("outer-state:相手がプレイ可能なカードを持っておらず,ヒントトークンがある場合は,相手カードのうち,情報を持っていないカードをランダムに選択,ヒントを与えます.")
149              return Action(game_ins.game_const.HINT_COLOR, pnr=i, color=color)
150          else:
151              self.already_hints[(random_pick_card_position,player.player_number)].append(game_ins.game_const.HINT_NUMBER)
152              print("outer-state:相手がプレイ可能なカードを持っておらず,ヒントトークンがある場合は,相手カードのうち,情報を持っていないカードをランダムに選択,ヒントを与えます.")
153              return Action(game_ins.game_const.HINT_NUMBER, pnr=i, number=number)
154      
155    #===============================================================================================
156    # もし相手がプレイ可能なカードを持っておらず,ヒントトークンがない場合,自分のカードをランダムに選んで捨てる
157    
158    print("自分のカードをランダムに選んで捨てます.")
159    #print(f"random_pick_card_position:{random_pick_card_position}")
160    return Action(game_ins.game_const.DISCARD, card_position=game_ins.random.choice(range(game_ins.hand_size)))

プレイヤーの次のアクションを決定するメソッド valid_actions: 現在のターンでプレイヤーが取ることのできる有効なアクションのリスト