"""Get all hexfields to which the Charakter could move.

TODO: Move method into model, as it deals with relationship between units.

# basic optimization: only check a hex-„square“ around the blob.

for x in range(-self.max_move, self.max_move+1):

for y in range(-self.max_move, self.max_move+1):

+ pos = (self.hex_x + x, self.hex_y + y)

dist = 0.5*(abs(x)+abs(y)+abs(z))

if dist <= self.max_move:

- pos = (self.hex_x + x, self.hex_y + y)

# don’t list those places which are already taken.

hexunit = self.hexmap.get(pos, None)

- if hexunit is None or hexunit is self:

+ path = self.path_to(pos)

+ if not path: # no path to target

+ for pos in path[:self.max_move]:

+ # if we can reach the target, add it

+ pos_is_reachable = len(path) < self.max_move

+ def path_to(self, goal):

+ """Find the cheapest path towards the goal hex.

+ TODO: interleaf with movement targets to reduce the cost.

+ :return: the list of hexes to traverse or None (if no path could be found).

+ def twopos2fourhex(pos1, pos2):

+ return pos1[0], pos1[1], pos2[0], pos2[1]

+ def free_neighbor_nodes(pos):

+ return [(h[0] + pos[0], h[1] + pos[1]) for h in hex_vectors[1:] if self.hexmap.get((h[0] + pos[0], h[1] + pos[1]), None) is None]

+ def dist_heuristic(pos1, pos2):

+ """The estimated distance between two nodes."""

+ return hexgrid_distance(*twopos2fourhex(pos1, pos2))

+ #: TODO: replace by weighted distances which allow different terrains to have different real costs between neighboring nodes.

+ def reconstruct(previous, current):

+ if current in previous:

+ p = reconstruct(previous, previous[current])

+ # TODO: implement path planning

+ start = (self.hex_x, self.hex_y)

+ #: node before the current one

+ #: Known shortest distance to each node

+ #: Estimate of the distance between two nodes

+ h[start] = dist(start, goal)

+ f[start] = g[start] + h[start]

+ current = sorted(openset, key=fval)[0]

+ return reconstruct(previous, previous[goal])

+ openset.remove(current)

+ for neighbor in free_neighbor_nodes(current):

+ if neighbor in closed: continue

+ g_tentative = g[current] + dist(current, neighbor)

+ if not neighbor in openset:

+ h[neighbor] = dist_heuristic(neighbor, goal)

+ tentative_is_better = True

+ elif g_tentative < g[neighbor]:

+ tentative_is_better = True

+ tentative_is_better = False

+ if tentative_is_better:

+ previous[neighbor] = current

+ g[neighbor] = g_tentative

+ f[neighbor] = g[neighbor] + h[neighbor]

+ return None # explicit fail

def _guess_damage_against(self, target):

"""Guess the damage we will do against a given target."""

def guess_damage_at(self, hexpos):

"""Guess the damage we can do on the given hexfield."""

- enemies_around =~~ [u for u in~~ self.model.~~unit~~s_around~~_hex(hexpos[0], hexpos[1]) if self.model.are_enemies(self, u)]~~

+ enemies_around = self.model.enemies_around(self)

my_malus = 3*len(enemies_around) - 3