func abs(x)
  if x < 0
    return -x
  else
    return x
  endif
endfunc

func make_pos(x, y)
  local pos
  pos[X] = x
  pos[Y] = y
  return pos
endfunc

func max(x, y)
  if x < y
    return y
  else
    return x
  endif
endfunc

func min(x, y)
  if x < y
    return x
  else
    return y
  endif
endfunc

func includes(array, item)
  local i
  i = 0
  while i < $array
    if array[i] == item
      return TRUE
    endif
    i = i + 1
  endwhile
  return FALSE
endfunc

func copy_array(array)
  local i ret
  i = 0
  while i < $array
    ret[i] = array[i]
    i = i + 1
  endwhile
  return ret
endfunc

func get_opposite_gate(gate)
  if gate % 2
    return gate - 1
  else
    return gate + 1
  endif
endfunc

func get_transition_gate(gate)
  if gate < 4
    if gate < 2
      if gate == 0
        return 4
      else
        return 6
      endif
    else
      if gate == 2
        return 5
      else
        return 7
      endif
    endif
  else
    if gate < 6
      if gate == 4
        return 0
      else
        return 2
      endif
    else
      if gate == 6
        return 1
      else
        return 3
      endif
    endif
  endif
endfunc

func get_dir_to_enter_gate(gate)
  if gate < 4
    if gate % 2
      # bottom
      return 3
    else
      # top
      return 0
    endif
  else
    if gate % 2
      # right
      return 2
    else
      # left
      return 5
    endif
  endif
endfunc

func get_distance(from, to)
  direct_dist = get_distance_ignoring_gates(from, to)
  gate_and_dist = get_gate_on_shortest_path(from, to)
  return min(direct_dist, gate_and_dist[1])
endfunc

# Among paths using a gate, search the best one
# Returns: [gate, dist]
#   gate: the gate used on the shortest path
#   dist: distance between from and to using the gate
func get_gate_on_shortest_path(from, to)
  local g min_dist gate_of_min_dist ret opposite_gate dist2 transition_gate
  i = 0
  gate_of_min_dist = -1
  min_dist = 999
  while i < $not_blocked_gates
    g = not_blocked_gates[i]
    i = i + 1
    opposite_gate = get_opposite_gate(g)
    dist = get_distance_ignoring_gates(from, gate_positions[g]) + 1 + get_distance_ignoring_gates(gate_positions[opposite_gate], to)
    if dist < min_dist
      gate_of_min_dist = g
      min_dist = dist
    endif
    transition_gate = get_transition_gate(opposite_gate)
    if includes(not_blocked_gates, transition_gate)
      dist2 = get_distance_ignoring_gates(from, gate_positions[g]) + 1 + get_distance_ignoring_gates(gate_positions[opposite_gate], gate_positions[transition_gate]) + 1 + get_distance_ignoring_gates(gate_positions[get_opposite_gate(transition_gate)], to)
      if dist2 < min_dist
        gate_of_min_dist = g
        min_dist = dist2
      endif
    endif
  endwhile
  ret[0] = gate_of_min_dist
  ret[1] = min_dist
  return ret
endfunc

# Get distance between from and to, not using any gate
# Args:
#   from: [x, y]
#   to: [x, y]
# Returns: distance
func get_distance_ignoring_gates(from, to)
  local x_diff y_diff
  x_diff = abs(to[X] - from[X])
  y_diff = abs(to[Y] - from[Y])
  return max(x_diff + y_diff / 2, y_diff)
endfunc

# Returns:
#   TRUE iff p is out of field
func out_of_field(p)
  local x y
  x = p[X]
  y = p[Y]
  if x < 0
    return TRUE
  elif x >= field_width
    return TRUE
  elif x >= field_width - 1
    if (y & 1) == 0
      return TRUE
    endif
  endif
  if y < 0
    return TRUE
  elif y >= field_height
    return TRUE
  endif
  return FALSE
endfunc

# Get direction, avoiding obstacles
# Args:
#   from, to: [x, y]
#   agent_type: 0 .. 3
# Returns:
#   direction -1 .. 5
func get_safety_dir(agent_type, from, to)
  local ideal_dir dir_priorities tmp_dir tmp_to i
  ideal_dir = get_greedy_dir(from, to)
  if ideal_dir == -1
    return ideal_dir
  endif
  dir_priorities = get_dir_priorities(ideal_dir)
  print 'dir_priorities:', dir_priorities
  i = 0
  while i < $dir_priorities
    tmp_dir = dir_priorities[i]
    tmp_to = neighbor(from, tmp_dir)
    print 'tmp_dir:', tmp_dir
    print 'tmp_to:', tmp_to
    i = i + 1
    if out_of_field(tmp_to)
      print 'out of field'
      continue
    endif
    if get_blocker(tmp_to) != NULL
      print 'destination is blocked by other agent'
      continue
    endif
    if get_last_agent_status(our_team, agent_type)
      print get_last_frozen_agent_move(agent_type)
      if tmp_dir == get_last_frozen_agent_move(agent_type)
        print 'this direction will probably lead to freezing again'
        continue
      endif
    endif
    return tmp_dir
  endwhile
  return -1
endfunc

func normalize_dir(dir)
  if dir < 0
    return dir + 6
  elif dir > 5
    return dir - 6
  else
    return dir
  endif
endfunc

# Prioritize directions
func get_dir_priorities(dir)
  local ret
  ret[0] = dir
  ret[1] = normalize_dir(dir - 1)
  ret[2] = normalize_dir(dir + 1)
  ret[3] = normalize_dir(dir - 2)
  ret[4] = normalize_dir(dir + 2)
  ret[5] = normalize_dir(dir - 3)
  return ret
endfunc

func neighbor(p, k)
  local x y g ret offset
  if k == -1
    # Pass
    return p
  endif
  x = p[X]
  y = p[Y]
  # Entering a gate
  g = 0
  while g < GATE_NUM
    if are_same_positions(p, gate_positions[g])
      if k == get_dir_to_enter_gate(g)
        return gate_positions[get_opposite_gate(g)]
      endif
    endif
    g = g + 1
  endwhile
  if k < 3
    if k == 0
      ret[0] = x - y % 2
      ret[1] = y - 1
    elif k == 1
      ret[0] = x + 1 - y % 2
      ret[1] = y - 1
    elif k == 2
      ret[0] = x + 1
      ret[1] = y
    endif
  else
    if k == 3
      ret[0] = x + 1 - y % 2
      ret[1] = y + 1
    elif k == 4
      ret[0] = x - y % 2
      ret[1] = y + 1
    elif k == 5
      ret[0] = x - 1
      ret[1] = y
    endif
  endif
  return ret
endfunc

func are_same_positions(p, q)
  if p[X] == q[X]
    if p[Y] == q[Y]
      return TRUE
    endif
  endif
  return FALSE
endfunc

# Get direction, not avoiding obstacles
# Args:
#   from, to: [x, y]
# Returns:
#   direction -1 .. 5
func get_dir(from, to)
  local direct_dist gate_and_dist dir
  print 'from:', from
  print 'to:', to
  if are_same_positions(from, to)
    return -1
  endif
  direct_dist = get_distance_ignoring_gates(from, to)
  print 'direct_dist:', direct_dist
  gate_and_dist = get_gate_on_shortest_path(from, to)
  print 'gate_and_dist:', gate_and_dist
  if direct_dist <= gate_and_dist[1]
    # Approach the destination directly
    print 'Approach the destination directly'
    dir = get_dir_ignoring_gates(from, to)
  elif are_same_positions(from, gate_positions[gate_and_dist[0]])
    # Enter the gate
    print 'Enter the gate'
    dir = get_dir_to_enter_gate(gate_and_dist[0])
  else
    # Approach the gate
    print 'Approach the gate'
    dir = get_dir_ignoring_gates(from, gate_positions[gate_and_dist[0]])
  endif
  print 'dir:', dir
  return dir
endfunc

func get_greedy_dir(from, to)
  local tmp_dir
  tmp_dir = get_dir(from, to)
  if tmp_dir == -1
    return tmp_dir
  endif
  tmp_to = neighbor(from, tmp_dir)
  if territories[tmp_to[X]][tmp_to[Y]] != our_team
    return tmp_dir
  endif
  alternative_dir1 = normalize_dir(tmp_dir - 1)
  alternative_to1 = neighbor(from, alternative_dir1)
  if 1 - out_of_field(alternative_to1)
    if territories[alternative_to1[X]][alternative_to1[Y]] != our_team
      if get_distance(alternative_to1, to) <= get_distance(tmp_to, to)
        return alternative_dir1
      endif
    endif
  endif
  alternative_dir2 = normalize_dir(tmp_dir + 1)
  alternative_to2 = neighbor(from, alternative_dir2)
  if 1 - out_of_field(alternative_to2)
    if territories[alternative_to2[X]][alternative_to2[Y]] != our_team
      if get_distance(alternative_to2, to) <= get_distance(tmp_to, to)
        return alternative_dir2
      endif
    endif
  endif
  return tmp_dir
endfunc

# Get direction, not avoiding obstacles
# Args:
#   from, to: [x, y]
# Returns:
#   direction 0 .. 5
func get_dir_ignoring_gates(from, to)
  local fx tx fy ty 
  fy = from[Y]
  ty = to[Y]
  fx = from[X] - (fy%2)
  tx = to[X] 
  print from, to, fx, ' ', tx
  if fy > ty
    if fx < tx
      return 1 
    else
      return 0 + ((fx == field_width - 2) & (fx == tx - ty % 2) & (fy % 2 == 0))
    endif
  elif fy < ty
    if fx < tx
      return 3  
    else
      return 4 - ((fx == field_width - 2) & (fx == tx - ty % 2) & (fy % 2 == 0))
    endif
  else
    if fx == tx - ty % 2
      return -1
    else
      return 2 + (fx > tx - ty % 2) * 3
    endif
  endif
endfunc

func get_last_frozen_agent_move(agent_type)
  return storage[STORAGE_LAST_FROZEN_AGENT_MOVES_OFFSET + agent_type]
endfunc

func get_last_agent_status(team, agent_type)
  return storage[team * 4 + STORAGE_LAST_AGENT_STATUSES_OFFSET + agent_type]
endfunc

# Returns:
#   [x, y] of given agent in last turn
func get_last_agent_position(team, agent_type)
  local pos offset
  offset = STORAGE_LAST_AGENT_POSITIONS_OFFSET + team * AGENT_TYPE_NUM + agent_type * 2
  pos[X] = storage[offset]
  pos[Y] = storage[offset + 1]
  return pos
endfunc

# Args:
#   p: [x, y]
#   q: [x, y]
# Returns:
#   TRUE iff p is in neighbor of q
# Note:
#   It was less efficient to use tmp variable such as px, py
func in_neighbor(p, q)
  if p[Y] == q[Y]
    return (p[X] <= q[X] + 1) & (p[X] >= q[X] - 1)
  elif (p[Y] == q[Y] + 1) | (p[Y] == q[Y] - 1)
    if q[Y] % 2
      # Odd
      return (p[X] <= q[X]) & (p[X] >= q[X] - 1)
    else
      # Even
      return (p[X] <= q[X] + 1) & (p[X] >= q[X])
    endif
  endif
endfunc

# Args:
#   gate: index of gate
# Returns:
#   TRUE iff gate is blocked by opponent stopped agent
func is_gate_blocked_by_stopped_agent(gate)
  local gate_pos opposite_gate_pos
  gate_pos = gate_positions[gate]
  if get_stopped_blocker(gate_pos) != NULL
    return TRUE
  else
    opposite_gate_pos = gate_positions[get_opposite_gate(gate)]
    return get_stopped_blocker(opposite_gate_pos) != NULL
  endif
endfunc

# Args:
#   pos: [x, y]
# Returns:
#   if blocked, [team, agent_type] of blocker
#   otherwise, NULL
func get_stopped_blocker(pos)
  local i t a ret
  i = 0
  while i < $stopped_agents
    t = stopped_agents[i][0]
    a = stopped_agents[i][1]
    if a == DOG
      if in_neighbor(pos, agent_positions[t][a])
        ret[0] = t
        ret[1] = a
        print 'dog blocker:', agent_positions[t][a]
        return ret
      endif
    else
      if are_same_positions(pos, agent_positions[t][a])
        ret[0] = t
        ret[1] = a
        print 'samurai blocker:', agent_positions[t][a]
        return ret
      endif
    endif
    i = i + 1
  endwhile
  return NULL
endfunc

# Args:
#   pos: [x, y]
# Returns:
#   if blocked, [team, agent_type] of blocker
#   otherwise, NULL
func get_blocker_(pos)
  local t a ret
  t = 0
  while t < TEAM_NUM
    a = 0
    while a < AGENT_TYPE_NUM
      if (a == DOG) & (t != our_team)
        if in_neighbor(pos, agent_positions[t][a])
          ret[0] = t
          ret[1] = a
          print 'dog blocker:', agent_positions[t][a]
          return ret
        endif
      else
        if are_same_positions(pos, agent_positions[t][a])
          ret[0] = t
          ret[1] = a
          print 'samurai blocker:', agent_positions[t][a]
          return ret
        endif
      endif
      a = a + 1
    endwhile
    t = t + 1
  endwhile
  return NULL
endfunc

func get_blocker(pos)
  return blocked_positions[pos[X]][pos[Y]]
endfunc

func get_blocked_positions()
  local t a d ret agent_pos
  t = 0
  while t < TEAM_NUM
    a = 0
    while a < AGENT_TYPE_NUM
      agent_pos = agent_positions[t][a]
      if (a == DOG) & (t != our_team)
        ret[agent_pos[X]][agent_pos[Y]][0] = t
        ret[agent_pos[X]][agent_pos[Y]][1] = a
        d = 0
        while d < 6
          pos = neighbor(agent_positions[t][a], d)
          ret[pos[X]][pos[Y]][0] = t
          ret[pos[X]][pos[Y]][1] = a
          d = d + 1
        endwhile
      else
        ret[agent_pos[X]][agent_pos[Y]][0] = t
        ret[agent_pos[X]][agent_pos[Y]][1] = a
      endif
      a = a + 1
    endwhile
    t = t + 1
  endwhile
  return ret
endfunc

# Args:
#   array: [[x, y]]
# Returns:
#   if element i and j (i < j) are duplicated, [i, j]
#   otherwise, NULL
func find_duplicate_point_pair(array)
  local i j ret
  i = 0
  while i < $array
    j = i + 1
    while j < $array
      if are_same_positions(array[i], array[j])
        ret[0] = i
        ret[1] = j
        return ret
      endif
      j = j + 1
    endwhile
    i = i + 1
  endwhile
  return NULL
endfunc

# Remove confliction among our moves
func remove_confliction()
  local destinations a duplicated_pair
  # Priorities: SAMURAI3>2>1>DOG
  a = 0
  while a < AGENT_TYPE_NUM
    destinations[a] = neighbor(our_agent_positions[a], moves[a])
    a = a + 1
  endwhile
  duplicated_pair = find_duplicate_point_pair(destinations)
  while duplicated_pair != NULL
    print 'confliction removed'
    if duplicated_pair[0] != -1
      a = duplicated_pair[0]
    else
      a = duplicated_pair[1]
    endif
    print a
    moves[a] = -1
    destinations[a] = our_agent_positions[a]
    duplicated_pair = find_duplicate_point_pair(destinations)
  endwhile
endfunc

func get_not_blocked_gates()
  local g ret
  g = 0
  while g < GATE_NUM
    if is_gate_blocked_by_stopped_agent(g) != TRUE
      ret[$ret] = g
      ret[$ret] = g + 1
      print 'gate not blocked'
    else
      print 'gate blocked'
    endif
    g = g + 2
  endwhile
  return ret
endfunc

func get_stopped_agents()
  local t a i ret
  t = 0
  while t < TEAM_NUM
    if t == out_team
      t = t + 1
      continue
    endif
    a = 0
    while a < AGENT_TYPE_NUM
      if are_same_positions(get_last_agent_position(t, a), agent_positions[t][a])
        print 'stopped_agent'
        i = $ret
        ret[i][0] = t
        ret[i][1] = a
      endif
      a = a + 1
    endwhile
    t = t + 1
  endwhile
  return ret
endfunc

func get_territories()
  local y width territories
  y = 0
  while y < field_height
    if y % 2 == 0
      width = field_width - 2
    else
      width = field_width
    endif
    x = 0
    while x < width
      owner = gb_hexel_owner(x, y)
      territories[x][y] = owner
      area_sum[owner] = area_sum[owner] + 1
      x = x + 1
    endwhile
    y = y + 1
  endwhile
  return territories
endfunc


func hex_move(a)
    # Draw hexagons
    hex1 = 3
    hex2 = 5
    hex3 = 7
    hex4 = 9
    hex5 = 11
    hex6 = 13
    if storage[999] == 1
      if our_agent_positions[a][1] > field_height - 7
        if our_agent_positions[a][0] <  7
          #left_down
          storage[1000 + a] = 1
        elif our_agent_positions[a][0] > field_width - 7 
          #right_down
          storage[1000 + a] = 2
        else
          #center_down
          storage[1000 + a] = 3
        endif
      elif our_agent_positions[a][1] <  7
        if our_agent_positions[a][0] <  7
          #left_up
          storage[1000 + a] = 4
        elif our_agent_positions[a][0] > field_width - 7 
          #right_up
          storage[1000 + a] = 5
        else
          #center_up
          storage[1000 + a] = 6
        endif
      else
        if our_agent_positions[a][0] <  7
          #left_middle        
          storage[1000 + a] = 7
        elif our_agent_positions[a][0] > field_width - 7 
          #right_middle
          storage[1000 + a] = 8
        else
          #core
          storage[1000 + a] = 9
        endif
      endif
    endif
    if storage[999] < hex6 + 1
      if storage[1000 + a] == 1
        #left_up
        if storage[999] < hex1
          pos_of_min_dist[0] = our_agent_positions[a][0] - 2 
          pos_of_min_dist[1] = our_agent_positions[a][1] - 2 
        elif storage[999] < hex2
          pos_of_min_dist[0] = our_agent_positions[a][0] + 2 
          pos_of_min_dist[1] = our_agent_positions[a][1] - 2
        elif storage[999] < hex3
          pos_of_min_dist[0] = our_agent_positions[a][0] + 2 
          pos_of_min_dist[1] = our_agent_positions[a][1] 
        elif storage[999] < hex4
          pos_of_min_dist[0] = our_agent_positions[a][0] + 2 
          pos_of_min_dist[1] = our_agent_positions[a][1] + 2
        elif storage[999] < hex5
          pos_of_min_dist[0] = our_agent_positions[a][0] - 2 
          pos_of_min_dist[1] = our_agent_positions[a][1] + 2 
        elif storage[999] < hex6
          pos_of_min_dist[0] = our_agent_positions[a][0] - 2 
          pos_of_min_dist[1] = our_agent_positions[a][1] 
        endif
      elif storage[1000 + a] == 2
        #right_up
        if storage[999] < hex1
          pos_of_min_dist[0] = our_agent_positions[a][0] + 2 
          pos_of_min_dist[1] = our_agent_positions[a][1] - 2 
        elif storage[999] < hex2
          pos_of_min_dist[0] = our_agent_positions[a][0] - 2 
          pos_of_min_dist[1] = our_agent_positions[a][1] - 2
        elif storage[999] < hex3
          pos_of_min_dist[0] = our_agent_positions[a][0] - 2 
          pos_of_min_dist[1] = our_agent_positions[a][1] 
        elif storage[999] < hex4
          pos_of_min_dist[0] = our_agent_positions[a][0] - 2 
          pos_of_min_dist[1] = our_agent_positions[a][1] + 2 
        elif storage[999] < hex5
          pos_of_min_dist[0] = our_agent_positions[a][0] + 2 
          pos_of_min_dist[1] = our_agent_positions[a][1] + 2
        elif storage[999] < hex6
          pos_of_min_dist[0] = our_agent_positions[a][0] + 2 
          pos_of_min_dist[1] = our_agent_positions[a][1] 
        endif
      elif storage[1000 + a] == 3
        if storage[999] < hex1
          pos_of_min_dist[0] = our_agent_positions[a][0] - 2 
          pos_of_min_dist[1] = our_agent_positions[a][1] 
        elif storage[999] < hex2
          pos_of_min_dist[0] = our_agent_positions[a][0] - 2 
          pos_of_min_dist[1] = our_agent_positions[a][1] - 2
        elif storage[999] < hex3
          pos_of_min_dist[0] = our_agent_positions[a][0] + 2 
          pos_of_min_dist[1] = our_agent_positions[a][1] - 2
        elif storage[999] < hex4
          pos_of_min_dist[0] = our_agent_positions[a][0] + 2 
          pos_of_min_dist[1] = our_agent_positions[a][1] 
        elif storage[999] < hex5
          pos_of_min_dist[0] = our_agent_positions[a][0] + 2 
          pos_of_min_dist[1] = our_agent_positions[a][1] + 2
        elif storage[999] < hex6
          pos_of_min_dist[0] = our_agent_positions[a][0] - 2 
          pos_of_min_dist[1] = our_agent_positions[a][1] + 2
        endif
      elif  storage[1000 + a] == 4
        if storage[999] < hex1
          pos_of_min_dist[0] = our_agent_positions[a][0] - 2 
          pos_of_min_dist[1] = our_agent_positions[a][1] + 2
        elif storage[999] < hex2
          pos_of_min_dist[0] = our_agent_positions[a][0] + 2 
          pos_of_min_dist[1] = our_agent_positions[a][1] + 2
        elif storage[999] < hex3
          pos_of_min_dist[0] = our_agent_positions[a][0] + 2 
          pos_of_min_dist[1] = our_agent_positions[a][1] 
        elif storage[999] < hex4
          pos_of_min_dist[0] = our_agent_positions[a][0] + 2 
          pos_of_min_dist[1] = our_agent_positions[a][1] - 2
        elif storage[999] < hex5
          pos_of_min_dist[0] = our_agent_positions[a][0] - 2 
          pos_of_min_dist[1] = our_agent_positions[a][1] - 2
        elif storage[999] < hex6
          pos_of_min_dist[0] = our_agent_positions[a][0] - 2 
          pos_of_min_dist[1] = our_agent_positions[a][1] 
        endif
      elif storage[1000 + a] == 5
        if storage[999] < hex1
          pos_of_min_dist[0] = our_agent_positions[a][0] + 2 
          pos_of_min_dist[1] = our_agent_positions[a][1] + 2
        elif storage[999] < hex2
          pos_of_min_dist[0] = our_agent_positions[a][0] - 2 
          pos_of_min_dist[1] = our_agent_positions[a][1] + 2
        elif storage[999] < hex3
          pos_of_min_dist[0] = our_agent_positions[a][0] - 2 
          pos_of_min_dist[1] = our_agent_positions[a][1]
        elif storage[999] < hex4
          pos_of_min_dist[0] = our_agent_positions[a][0] - 2 
          pos_of_min_dist[1] = our_agent_positions[a][1] - 2
        elif storage[999] < hex5
          pos_of_min_dist[0] = our_agent_positions[a][0] + 2 
          pos_of_min_dist[1] = our_agent_positions[a][1] - 2
        elif storage[999] < hex6
          pos_of_min_dist[0] = our_agent_positions[a][0] + 2 
          pos_of_min_dist[1] = our_agent_positions[a][1]
        endif
      elif storage[1000 + a] == 6
        if storage[999] < hex1
          pos_of_min_dist[0] = our_agent_positions[a][0] + 2 
          pos_of_min_dist[1] = our_agent_positions[a][1]
        elif storage[999] < hex2
          pos_of_min_dist[0] = our_agent_positions[a][0] + 2 
          pos_of_min_dist[1] = our_agent_positions[a][1] + 2
        elif storage[999] < hex3
          pos_of_min_dist[0] = our_agent_positions[a][0] - 2 
          pos_of_min_dist[1] = our_agent_positions[a][1] + 2
        elif storage[999] < hex4
          pos_of_min_dist[0] = our_agent_positions[a][0] - 2 
          pos_of_min_dist[1] = our_agent_positions[a][1] 
        elif storage[999] < hex5
          pos_of_min_dist[0] = our_agent_positions[a][0] - 2 
          pos_of_min_dist[1] = our_agent_positions[a][1] - 2
        elif storage[999] < hex6
          pos_of_min_dist[0] = our_agent_positions[a][0] + 2 
          pos_of_min_dist[1] = our_agent_positions[a][1] - 2
        endif
      elif storage[1000 + a] == 7
        if storage[999] < hex1
          pos_of_min_dist[0] = our_agent_positions[a][0] + 2 
          pos_of_min_dist[1] = our_agent_positions[a][1] - 2
        elif storage[999] < hex2
          pos_of_min_dist[0] = our_agent_positions[a][0] + 2 
          pos_of_min_dist[1] = our_agent_positions[a][1]
        elif storage[999] < hex3
          pos_of_min_dist[0] = our_agent_positions[a][0] + 2 
          pos_of_min_dist[1] = our_agent_positions[a][1] + 2
        elif storage[999] < hex4
          pos_of_min_dist[0] = our_agent_positions[a][0] - 2 
          pos_of_min_dist[1] = our_agent_positions[a][1] + 2
        elif storage[999] < hex5
          pos_of_min_dist[0] = our_agent_positions[a][0] - 2 
          pos_of_min_dist[1] = our_agent_positions[a][1]
        elif storage[999] < hex6
          pos_of_min_dist[0] = our_agent_positions[a][0] - 2 
          pos_of_min_dist[1] = our_agent_positions[a][1] - 2
        endif
      elif storage[1000 + a] == 8
        if storage[999] < hex1
          pos_of_min_dist[0] = our_agent_positions[a][0] - 2 
          pos_of_min_dist[1] = our_agent_positions[a][1] + 2
        elif storage[999] < hex2
          pos_of_min_dist[0] = our_agent_positions[a][0] - 2 
          pos_of_min_dist[1] = our_agent_positions[a][1]
        elif storage[999] < hex3
          pos_of_min_dist[0] = our_agent_positions[a][0] - 2 
          pos_of_min_dist[1] = our_agent_positions[a][1] - 2
        elif storage[999] < hex4
          pos_of_min_dist[0] = our_agent_positions[a][0] + 2 
          pos_of_min_dist[1] = our_agent_positions[a][1] - 2
        elif storage[999] < hex5
          pos_of_min_dist[0] = our_agent_positions[a][0] + 2 
          pos_of_min_dist[1] = our_agent_positions[a][1]
        elif storage[999] < hex6
          pos_of_min_dist[0] = our_agent_positions[a][0] + 2 
          pos_of_min_dist[1] = our_agent_positions[a][1] + 2
        endif
      elif storage[1000 + a] == 9
        if storage[999] < hex1
          pos_of_min_dist[0] = our_agent_positions[a][0] + 2 
          pos_of_min_dist[1] = our_agent_positions[a][1]
        elif storage[999] < hex2
          pos_of_min_dist[0] = our_agent_positions[a][0] + 2 
          pos_of_min_dist[1] = our_agent_positions[a][1] + 2
        elif storage[999] < hex3
          pos_of_min_dist[0] = our_agent_positions[a][0] - 2 
          pos_of_min_dist[1] = our_agent_positions[a][1] + 2
        elif storage[999] < hex4
          pos_of_min_dist[0] = our_agent_positions[a][0] - 2 
          pos_of_min_dist[1] = our_agent_positions[a][1] 
        elif storage[999] < hex5
          pos_of_min_dist[0] = our_agent_positions[a][0] - 2 
          pos_of_min_dist[1] = our_agent_positions[a][1] - 2
        elif storage[999] < hex6
          pos_of_min_dist[0] = our_agent_positions[a][0] + 2 
          pos_of_min_dist[1] = our_agent_positions[a][1] - 2
        endif
      endif
    endif
    return get_safety_dir(a, our_agent_positions[a], pos_of_min_dist)
endfunc

func get_move_to_make_square(a)
  agent_pos = our_agent_positions[a]
  min_x = field_width / 3 * 2
  min_y = 0
  max_x = field_width - 3
  max_y = field_height - 1
  min_dist = 999
  pos_of_min_dist = NULL
  # diagonal 1
  x = min_x + 1
  y = min_y + 1
  while x < max_x
    tmp_y = y
    while (get_blocker(make_pos(x, tmp_y)) != NULL) & (territories[x][tmp_y] != our_team)
      tmp_y = tmp_y + 1
    endwhile
    if territories[x][tmp_y] != our_team
      pos = make_pos(x, tmp_y)
      dist = get_distance(agent_pos, pos)
      if dist <= 1
        return get_safety_dir(a, agent_pos, pos)
      endif
      if dist < min_dist
        min_dist = dist
        pos_of_min_dist = pos
      endif
    endif
    p[X] = x
    p[Y] = y
    new_p = neighbor(p, 3)
    x = new_p[X]
    y = new_p[Y]
  endwhile
  # diagonal 2
  x = max_x - 1
  y = max_y - 1
  while x > min_x
    tmp_y = y
    while (get_blocker(make_pos(x, tmp_y)) != NULL) & (territories[x][tmp_y] != our_team)
      tmp_y = tmp_y + 1
    endwhile
    if territories[x][tmp_y] != our_team
      pos = make_pos(x, tmp_y)
      dist = get_distance(agent_pos, pos)
      if dist <= 1
        return get_safety_dir(a, agent_pos, pos)
      endif
      if dist < min_dist
        min_dist = dist
        pos_of_min_dist = pos
      endif
    endif
    p[X] = x
    p[Y] = y
    new_p = neighbor(p, 0)
    x = new_p[X]
    y = new_p[Y]
  endwhile
  # diagonal 3
  x = max_x - 1
  y = (field_height - (max_x - min_x) * 2) / 2
  while x > min_x
    tmp_y = y
    while (get_blocker(make_pos(x, tmp_y)) != NULL) & (territories[x][tmp_y] != our_team)
      tmp_y = tmp_y + 1
    endwhile
    if territories[x][tmp_y] != our_team
      pos = make_pos(x, tmp_y)
      dist = get_distance(agent_pos, pos)
      if dist <= 1
        return get_safety_dir(a, agent_pos, pos)
      endif
      if dist < min_dist
        min_dist = dist
        pos_of_min_dist = pos
      endif
    endif
    p[X] = x
    p[Y] = y
    new_p = neighbor(p, 4)
    x = new_p[X]
    y = new_p[Y]
  endwhile
  # top left -> top right
  x = min_x
  y = min_y
  while x < max_x - 1
    tmp_y = y
    while (get_blocker(make_pos(x, tmp_y)) != NULL) & (territories[x][tmp_y] != our_team)
      tmp_y = tmp_y + 1
    endwhile
    if territories[x][tmp_y] != our_team
      pos = make_pos(x, tmp_y)
      dist = get_distance(agent_pos, pos)
      if dist <= 1
        return get_safety_dir(a, agent_pos, pos)
      endif
      if dist < min_dist
        min_dist = dist
        pos_of_min_dist = pos
      endif
    endif
    x = x + 1
  endwhile
  # top right -> bottom right
  x = max_x
  y = y + 1
  while y < max_y - 1
    tmp_x = x
    while (get_blocker(make_pos(tmp_x, y)) != NULL) & (territories[tmp_x][y] != our_team)
      tmp_x = tmp_x + 1
    endwhile
    if territories[tmp_x][y] != our_team
      pos = make_pos(tmp_x, y)
      dist = get_distance(agent_pos, pos)
      if dist <= 1
        return get_safety_dir(a, agent_pos, pos)
      endif
      if dist < min_dist
        min_dist = dist
        pos_of_min_dist = pos
      endif
    endif
    y = y + 1
  endwhile
  # bottom right -> bottom left
  x = max_x - 1
  y = max_y
  while x > min_x
    tmp_y = y
    while (get_blocker(make_pos(x, tmp_y)) != NULL) & (territories[x][tmp_y] != our_team)
      tmp_y = tmp_y - 1
    endwhile
    if territories[x][tmp_y] != our_team
      pos = make_pos(x, tmp_y)
      dist = get_distance(agent_pos, pos)
      if dist <= 1
        return get_safety_dir(a, agent_pos, pos)
      endif
      if dist < min_dist
        min_dist = dist
        pos_of_min_dist = pos
      endif
    endif
    x = x - 1
  endwhile
  # bottom left -> top left
  while y > min_y
    tmp_x = x
    while (get_blocker(make_pos(tmp_x, y)) != NULL) & (territories[tmp_x][y] != our_team)
      tmp_x = tmp_x - 1
    endwhile
    if territories[tmp_x][y] != our_team
      pos = make_pos(tmp_x, y)
      dist = get_distance(agent_pos, pos)
      if dist <= 1
        return get_safety_dir(a, agent_pos, pos)
      endif
      if dist < min_dist
        min_dist = dist
        pos_of_min_dist = pos
      endif
    endif
    y = y - 1
  endwhile
  print 'min_dist:', min_dist
  print 'pos_of_min_dist:', pos_of_min_dist
  return get_safety_dir(a, our_agent_positions[a], pos_of_min_dist)
endfunc

# gates
#   0   2
# 4       5
#
# 6       7
#   1   3

# directions
#   0  1
# 5      2
#   4  3

# Constants for array access
NULL = 0 # Used as invalid value
TRUE = 1 # Used as boolean true
FALSE = 0 # Used as boolean true
X = 0 # Used as index of array
Y = 1 # Used as index of array
DOG = 0
SAMURAI1 = 1
SAMURAI2 = 2
SAMURAI3 = 3
TEAM_NUM = 4
AGENT_TYPE_NUM = 4
GATE_NUM = 8
STORAGE_LAST_AGENT_POSITIONS_OFFSET = 1
STORAGE_LAST_AGENT_STATUSES_OFFSET = 33
STORAGE_LAST_AGENT_MOVES_OFFSET = 49
STORAGE_LAST_FROZEN_AGENT_MOVES_OFFSET = 53

# Collect necessary info
our_team = gb_team_id()
field_size = gb_field_size()
field_width = field_size[X]
field_height = field_size[Y]
agent_positions = gb_agent_positions()
our_agent_positions = agent_positions[our_team]
gate_positions = gb_gate_positions()
territories = get_territories()

print 'field_width:', field_width
print 'field_height:', field_height

storage = gb_storage()

# storage[0] is a current turn
storage[0] = storage[0] + 1

blocked_positions = get_blocked_positions()

stopped_agents = get_stopped_agents()
print 'stopped_agents:', stopped_agents

not_blocked_gates = get_not_blocked_gates()
print 'not_blocked_gates:', not_blocked_gates

if storage[0] == 1
   storage[999] = 999
endif

a = 0
while a < AGENT_TYPE_NUM
  print 'agent:', a
  if gb_agent_status(our_team, a)
    moves[a] = -1
  elif a == DOG
    i = 0
    temp_top = 0
    top_team = -1  
    while i < TEAM_NUM
      if i != our_team
        if temp_top < area_sum[i]
          temp_top = area_sum[i]
          top_team = i
        endif
      endif
      i = i + 1
    endwhile
    j = 1
    temp_top = 999
    samurai_num = 1
    while j < AGENT_TYPE_NUM
      d_s_dist = get_distance(our_agent_positions[DOG], agent_positions[top_team][j])
      print '********',d_s_dist, '********'
      if d_s_dist < temp_top
        temp_top = d_s_dist
        samurai_num = j
      endif
      j = j + 1
      print j
    endwhile
    moves[a] = get_dir(our_agent_positions[DOG], agent_positions[top_team][samurai_num])
  else
    # Draw hexagons
    hex1 = 3
    hex2 = 5
    hex3 = 7
    hex4 = 9
    hex5 = 11
    hex6 = 13
    if storage[0] == 1
      if our_agent_positions[a][1] > field_height - 7
        if our_agent_positions[a][0] <  7
          #left_down
          storage[1000 + a] = 1
        elif our_agent_positions[a][0] > field_width - 7 
          #right_down
          storage[1000 + a] = 2
        else
          #center_down
          storage[1000 + a] = 3
        endif
      elif our_agent_positions[a][1] <  7
        if our_agent_positions[a][0] <  7
          #left_up
          storage[1000 + a] = 4
        elif our_agent_positions[a][0] > field_width - 7 
          #right_up
          storage[1000 + a] = 5
        else
          #center_up
          storage[1000 + a] = 6
        endif
      else
        if our_agent_positions[a][0] <  7
          #left_middle        
          storage[1000 + a] = 7
        elif our_agent_positions[a][0] > field_width - 7 
          #right_middle
          storage[1000 + a] = 8
        else
          #core
          storage[1000 + a] = 9
        endif
      endif
    endif
    if storage[0] < hex6 + 1
      if storage[1000 + a] == 1
        #left_up
        if storage[0] < hex1
          pos_of_min_dist[0] = our_agent_positions[a][0] - 2 
          pos_of_min_dist[1] = our_agent_positions[a][1] - 2 
        elif storage[0] < hex2
          pos_of_min_dist[0] = our_agent_positions[a][0] + 2 
          pos_of_min_dist[1] = our_agent_positions[a][1] - 2
        elif storage[0] < hex3
          pos_of_min_dist[0] = our_agent_positions[a][0] + 2 
          pos_of_min_dist[1] = our_agent_positions[a][1] 
        elif storage[0] < hex4
          pos_of_min_dist[0] = our_agent_positions[a][0] + 2 
          pos_of_min_dist[1] = our_agent_positions[a][1] + 2
        elif storage[0] < hex5
          pos_of_min_dist[0] = our_agent_positions[a][0] - 2 
          pos_of_min_dist[1] = our_agent_positions[a][1] + 2 
        elif storage[0] < hex6
          pos_of_min_dist[0] = our_agent_positions[a][0] - 2 
          pos_of_min_dist[1] = our_agent_positions[a][1] 
        endif
      elif storage[1000 + a] == 2
        #right_up
        if storage[0] < hex1
          pos_of_min_dist[0] = our_agent_positions[a][0] + 2 
          pos_of_min_dist[1] = our_agent_positions[a][1] - 2 
        elif storage[0] < hex2
          pos_of_min_dist[0] = our_agent_positions[a][0] - 2 
          pos_of_min_dist[1] = our_agent_positions[a][1] - 2
        elif storage[0] < hex3
          pos_of_min_dist[0] = our_agent_positions[a][0] - 2 
          pos_of_min_dist[1] = our_agent_positions[a][1] 
        elif storage[0] < hex4
          pos_of_min_dist[0] = our_agent_positions[a][0] - 2 
          pos_of_min_dist[1] = our_agent_positions[a][1] + 2 
        elif storage[0] < hex5
          pos_of_min_dist[0] = our_agent_positions[a][0] + 2 
          pos_of_min_dist[1] = our_agent_positions[a][1] + 2
        elif storage[0] < hex6
          pos_of_min_dist[0] = our_agent_positions[a][0] + 2 
          pos_of_min_dist[1] = our_agent_positions[a][1] 
        endif
      elif storage[1000 + a] == 3
        if storage[0] < hex1
          pos_of_min_dist[0] = our_agent_positions[a][0] - 2 
          pos_of_min_dist[1] = our_agent_positions[a][1] 
        elif storage[0] < hex2
          pos_of_min_dist[0] = our_agent_positions[a][0] - 2 
          pos_of_min_dist[1] = our_agent_positions[a][1] - 2
        elif storage[0] < hex3
          pos_of_min_dist[0] = our_agent_positions[a][0] + 2 
          pos_of_min_dist[1] = our_agent_positions[a][1] - 2
        elif storage[0] < hex4
          pos_of_min_dist[0] = our_agent_positions[a][0] + 2 
          pos_of_min_dist[1] = our_agent_positions[a][1] 
        elif storage[0] < hex5
          pos_of_min_dist[0] = our_agent_positions[a][0] + 2 
          pos_of_min_dist[1] = our_agent_positions[a][1] + 2
        elif storage[0] < hex6
          pos_of_min_dist[0] = our_agent_positions[a][0] - 2 
          pos_of_min_dist[1] = our_agent_positions[a][1] + 2
        endif
      elif  storage[1000 + a] == 4
        if storage[0] < hex1
          pos_of_min_dist[0] = our_agent_positions[a][0] - 2 
          pos_of_min_dist[1] = our_agent_positions[a][1] + 2
        elif storage[0] < hex2
          pos_of_min_dist[0] = our_agent_positions[a][0] + 2 
          pos_of_min_dist[1] = our_agent_positions[a][1] + 2
        elif storage[0] < hex3
          pos_of_min_dist[0] = our_agent_positions[a][0] + 2 
          pos_of_min_dist[1] = our_agent_positions[a][1] 
        elif storage[0] < hex4
          pos_of_min_dist[0] = our_agent_positions[a][0] + 2 
          pos_of_min_dist[1] = our_agent_positions[a][1] - 2
        elif storage[0] < hex5
          pos_of_min_dist[0] = our_agent_positions[a][0] - 2 
          pos_of_min_dist[1] = our_agent_positions[a][1] - 2
        elif storage[0] < hex6
          pos_of_min_dist[0] = our_agent_positions[a][0] - 2 
          pos_of_min_dist[1] = our_agent_positions[a][1] 
        endif
      elif storage[1000 + a] == 5
        if storage[0] < hex1
          pos_of_min_dist[0] = our_agent_positions[a][0] + 2 
          pos_of_min_dist[1] = our_agent_positions[a][1] + 2
        elif storage[0] < hex2
          pos_of_min_dist[0] = our_agent_positions[a][0] - 2 
          pos_of_min_dist[1] = our_agent_positions[a][1] + 2
        elif storage[0] < hex3
          pos_of_min_dist[0] = our_agent_positions[a][0] - 2 
          pos_of_min_dist[1] = our_agent_positions[a][1]
        elif storage[0] < hex4
          pos_of_min_dist[0] = our_agent_positions[a][0] - 2 
          pos_of_min_dist[1] = our_agent_positions[a][1] - 2
        elif storage[0] < hex5
          pos_of_min_dist[0] = our_agent_positions[a][0] + 2 
          pos_of_min_dist[1] = our_agent_positions[a][1] - 2
        elif storage[0] < hex6
          pos_of_min_dist[0] = our_agent_positions[a][0] + 2 
          pos_of_min_dist[1] = our_agent_positions[a][1]
        endif
      elif storage[1000 + a] == 6
        if storage[0] < hex1
          pos_of_min_dist[0] = our_agent_positions[a][0] + 2 
          pos_of_min_dist[1] = our_agent_positions[a][1]
        elif storage[0] < hex2
          pos_of_min_dist[0] = our_agent_positions[a][0] + 2 
          pos_of_min_dist[1] = our_agent_positions[a][1] + 2
        elif storage[0] < hex3
          pos_of_min_dist[0] = our_agent_positions[a][0] - 2 
          pos_of_min_dist[1] = our_agent_positions[a][1] + 2
        elif storage[0] < hex4
          pos_of_min_dist[0] = our_agent_positions[a][0] - 2 
          pos_of_min_dist[1] = our_agent_positions[a][1] 
        elif storage[0] < hex5
          pos_of_min_dist[0] = our_agent_positions[a][0] - 2 
          pos_of_min_dist[1] = our_agent_positions[a][1] - 2
        elif storage[0] < hex6
          pos_of_min_dist[0] = our_agent_positions[a][0] + 2 
          pos_of_min_dist[1] = our_agent_positions[a][1] - 2
        endif
      elif storage[1000 + a] == 7
        if storage[0] < hex1
          pos_of_min_dist[0] = our_agent_positions[a][0] + 2 
          pos_of_min_dist[1] = our_agent_positions[a][1] - 2
        elif storage[0] < hex2
          pos_of_min_dist[0] = our_agent_positions[a][0] + 2 
          pos_of_min_dist[1] = our_agent_positions[a][1]
        elif storage[0] < hex3
          pos_of_min_dist[0] = our_agent_positions[a][0] + 2 
          pos_of_min_dist[1] = our_agent_positions[a][1] + 2
        elif storage[0] < hex4
          pos_of_min_dist[0] = our_agent_positions[a][0] - 2 
          pos_of_min_dist[1] = our_agent_positions[a][1] + 2
        elif storage[0] < hex5
          pos_of_min_dist[0] = our_agent_positions[a][0] - 2 
          pos_of_min_dist[1] = our_agent_positions[a][1]
        elif storage[0] < hex6
          pos_of_min_dist[0] = our_agent_positions[a][0] - 2 
          pos_of_min_dist[1] = our_agent_positions[a][1] - 2
        endif
      elif storage[1000 + a] == 8
        if storage[0] < hex1
          pos_of_min_dist[0] = our_agent_positions[a][0] - 2 
          pos_of_min_dist[1] = our_agent_positions[a][1] + 2
        elif storage[0] < hex2
          pos_of_min_dist[0] = our_agent_positions[a][0] - 2 
          pos_of_min_dist[1] = our_agent_positions[a][1]
        elif storage[0] < hex3
          pos_of_min_dist[0] = our_agent_positions[a][0] - 2 
          pos_of_min_dist[1] = our_agent_positions[a][1] - 2
        elif storage[0] < hex4
          pos_of_min_dist[0] = our_agent_positions[a][0] + 2 
          pos_of_min_dist[1] = our_agent_positions[a][1] - 2
        elif storage[0] < hex5
          pos_of_min_dist[0] = our_agent_positions[a][0] + 2 
          pos_of_min_dist[1] = our_agent_positions[a][1]
        elif storage[0] < hex6
          pos_of_min_dist[0] = our_agent_positions[a][0] + 2 
          pos_of_min_dist[1] = our_agent_positions[a][1] + 2
        endif
      elif storage[1000 + a] == 9
        if storage[0] < hex1
          pos_of_min_dist[0] = our_agent_positions[a][0] + 2 
          pos_of_min_dist[1] = our_agent_positions[a][1]
        elif storage[0] < hex2
          pos_of_min_dist[0] = our_agent_positions[a][0] + 2 
          pos_of_min_dist[1] = our_agent_positions[a][1] + 2
        elif storage[0] < hex3
          pos_of_min_dist[0] = our_agent_positions[a][0] - 2 
          pos_of_min_dist[1] = our_agent_positions[a][1] + 2
        elif storage[0] < hex4
          pos_of_min_dist[0] = our_agent_positions[a][0] - 2 
          pos_of_min_dist[1] = our_agent_positions[a][1] 
        elif storage[0] < hex5
          pos_of_min_dist[0] = our_agent_positions[a][0] - 2 
          pos_of_min_dist[1] = our_agent_positions[a][1] - 2
        elif storage[0] < hex6
          pos_of_min_dist[0] = our_agent_positions[a][0] + 2 
          pos_of_min_dist[1] = our_agent_positions[a][1] - 2
        endif
      endif
      moves[a] = get_safety_dir(a, our_agent_positions[a], pos_of_min_dist)
      #moves[a] = get_dir(our_agent_positions[a], pos_of_min_dist)
    elif storage[999] < 14
      moves[a] = hex_move(a)
      storage[998] = storage[998] + 1
      if storage[998] == 3
        storage[998] = 0
        storage[999] = storage[999] + 1
      endif
    else
      # Make square
      moves[a] = get_move_to_make_square(a)
    endif
  endif
  a = a + 1
endwhile

print 'tmp moves:', moves

remove_confliction()

print 'final moves', moves

gb_move(moves)

# storage[1-32] are last agent positions
t = 0
while t < TEAM_NUM
  t_offset = t * AGENT_TYPE_NUM + STORAGE_LAST_AGENT_POSITIONS_OFFSET
  a = 0
  while a < AGENT_TYPE_NUM
    pos = agent_positions[t][a]
    storage[t_offset + a * 2] = pos[X]
    storage[t_offset + a * 2 + 1] = pos[Y]
    a = a + 1
  endwhile
  t = t + 1
endwhile

# storage[33-48] are last agent statuses (1 iff frozen)
# storage[53-56] are moves when our agents are frozen
t = 0
while t < TEAM_NUM
  t_offset = t * AGENT_TYPE_NUM + STORAGE_LAST_AGENT_STATUSES_OFFSET
  a = 0
  while a < AGENT_TYPE_NUM
    frozen = gb_agent_status(t, a)
    storage[t_offset + a] = frozen
    if frozen
      storage[STORAGE_LAST_FROZEN_AGENT_MOVES_OFFSET + a] = storage[STORAGE_LAST_AGENT_MOVES_OFFSET + a]
    endif
    a = a + 1
  endwhile
  t = t + 1
endwhile

# storage[49-52] are last moves of our agents
a = 0
while a < AGENT_TYPE_NUM
  storage[STORAGE_LAST_AGENT_MOVES_OFFSET + a] = moves[a]
  a = a + 1
endwhile


