import random

class _AI:
  def get_command_letter(self, command):
    if command == 0:
      return "w"
    elif command == 1:
      return "a"
    elif command == 2:
      return "s"
    else:
      return "d"

class RandomAI(_AI):
  def __init__(self):
    self.name = "random_ai"

  def get_next_command(self, available_commands):
    self.current_command = random.randint(0, 3)
    return self.get_command_letter(self.current_command)

class DirectionAI(_AI):
  def __init__(self):
    self.name = "direction_ai"

  def get_next_command(self, available_commands):
    if   available_commands["s"]: # Prefer "down" movements
      return "s"
    elif available_commands["a"]: # Then "left"
      return "a"
    elif available_commands["d"]: # Then "right"
      return "d"
    else:                         # Only move "up" if no others are available
      return "w"

class PairCheckAI(_AI):
  def __init__(self):
    self.name = "pair_check_ai"
    self.direction_points = {"w": 0, "a": 0, "s": 0, "d": 0}

  def get_next_command(self, available_commands):
    
    # Check which direction to move
    # print("calculating points for board:")
    h_points = self.calc_points(self.board)
    rotated_board = self.rotate_board(self.board)
    v_points = self.calc_points(rotated_board)

    # No points, return a random direction
    if h_points == 0 and v_points == 0:
      # print("nothing, random movement")
      return self.get_command_letter(random.randint(0, 3))

    # print("h: " + str(h_points))
    # print("v: " + str(v_points))

    # Up/down and left/right scores are the same
    self.direction_points["w"] = v_points
    self.direction_points["a"] = h_points
    self.direction_points["s"] = v_points
    self.direction_points["d"] = h_points

    dir_letter = max(self.direction_points, key=self.direction_points.get)
    # print("moving: " + dir_letter)

    return dir_letter

  def update_board(self, board):
    self.board = board

  # Calculates the number of points in each row
  def calc_points(self, board):
#    self.print_board(board)

    total_score = 0
    for row in board:
      score = 0
      for n in row:
        if   n == 0:
          pass
        elif score == 0:
          score = n
        elif score != n:
          score = n
        elif score == n:
          # will_score = True
          score *= 2
          total_score += score
          score = 0
    return total_score

  # Rotates the board
  def rotate_board(self, board):
    
    row_size = len(board)
    board_size = row_size ** 2

    rotated = []
    for i in range(0, row_size):
      rotated.append([])

    for i in range(0, board_size):
      rotated[i / row_size].append(board[i % row_size][i / row_size])
    return rotated

  def print_board(self, board):
    for i in board:
      print(i)

