class_docstr: Controller.`
  Keep Track of each ship and shipyard
class_docstr_tok: ["Controller.","`","Keep","Track","of","each","ship","and","shipyard"]
docstr: Take action for ships
  Args:
      board : environment
      method : sampling action or greedy action, either sample or predict
code: def take_ship_action(self, board, method="sample"):
      """Take action for ships
      Args:
          board : environment
          method : sampling action or greedy action, either sample or predict
      """
  
      me = board.current_player
  
      # determine a ship and turn it into a base if we do not have a shipyard
      if len(me.shipyards) == 0:
          convert = False
  
          for ship in me.ships:
              if ship.halite >= 70:
                  self.ship_states[ship.id]["rule"] = True
  
                  self.ship_states[ship.id]["act"] = "convert"
  
                  convert = True
  
                  break
  
          # if there is no ships we can turn into shipyard
          # then we utilize the defined rules to mine the halite
          if not convert:
              ship = me.ships[0]
  
              self.ship_states[ship.id]["rule"] = True
  
              self.ship_states[ship.id]["act"] = "mine"
  
      # set rule agent
      for ship in me.ships:
          # current time step
          step = board.step
  
          if not self.ship_states[ship.id]["rule"]:
              shipyard_pos = nearest_shipyard_position(board, ship)
  
              if board.cells[shipyard_pos].shipyard_id:
                  dis = step + mahattan_distance(
                      shipyard_pos, ship.position
                  )
  
                  # already obtained K halite or this episode almostly ends,
                  # we force these ships to return to the base
                  if (
                      dis <= 299 and dis >= 294
                  ) or ship.halite >= halite:
                      self.ship_states[ship.id]["rule"] = True
  
                      self.ship_states[ship.id][
                          "act"
                      ] = "return_to_base"
  
                      return_to_base_policy(board, ship)
  
          else:
              # take action for these rule ships
              if self.ship_states[ship.id]["act"] == "convert":
                  convert_policy(board, ship)
  
              if self.ship_states[ship.id]["act"] == "mine":
                  mine_policy(board, ship)
  
              if self.ship_states[ship.id]["act"] == "return_to_base":
                  return_to_base_policy(board, ship)
  
      # take actions for those non-rule agent by ppo model
      ready_ship_id = self.get_ship_id()
  
      # obtain the states of these non-rule agent
      state = np.zeros(
          (
              len(ready_ship_id),
              config["ship_obs_dim"] + config["world_dim"],
          )
      )
  
      if len(ready_ship_id):
          for ind, ship_id in enumerate(ready_ship_id):
              ship_index = me.ship_ids.index(ship_id)
  
              ship = me.ships[ship_index]
  
              self.ship_states[ship_id]["obs"].append(
                  get_ship_feature(board, ship)
              )
  
              state[ind] = self.ship_states[ship_id]["obs"][-1]
  
          # take action
          if method == "sample":
              actions = self.ship_actor.sample(state)
          else:
              actions = self.ship_actor.predict(state)
  
      # action for those ships who are ready
      for ind, ship_id in enumerate(ready_ship_id):
          ship_index = me.ship_ids.index(ship_id)
  
          ship = me.ships[ship_index]
  
          ship_policies[actions[ind]](board, ship)
  
          # set act
          self.ship_states[ship_id]["act"].append(actions[ind])
  
      return me.next_actions
  
imports: import pickle
  import base64
  import random
  import numpy
  import torch
  import torch.nn
  import torch.nn.functional
  from torch.distributions import Categorical
  from zerosum_env.envs.halite.helpers import *
  from zerosum_env import make, evaluate
  from collections import deque
  import os
label_desc: Use image node_id 8 for calling the Controller obj's underlying member method code with example usage: obj.take_ship_action(board, method) and returns: me