# -*- coding: utf-8 -*-
# This file has been generated, if you wish to
# modify it in a permanent way, please refer
# to the script file : gen/generator_python.rb

from api import *
import random

DEPART =  MAX_TOUR//2 + random.randint(0,MAX_TOUR//2-TAILLE_TERRAIN)

def mamagie(): return magie(moi())
def mabase(): return base_joueur(moi())

def add_pos(p1,p2): return (p2[0]+p1[0],p2[1]+p1[1])
def diff_pos(p1,p2): return (p2[0]-p1[0],p2[1]-p1[1])
def div_pos(p,d): return (p[0]//d,p[1]//d)
def mul_pos(p,m): return (p[0]*m,p[1]*m)
def mul_pospos(p1,p2): return (p1[0]*p2[0],p1[1]*p2[1])
def distance_pos(p1,p2): return (abs(p2[0]-p1[0])+abs(p2[1]-p1[1]))

def acote (pos,portee):
	'''Permet d'iterer sur toutes les cases qui sont dans la portee d'une tour'''
	for y in range(-portee, portee+1):
		for x in range(-portee+abs(y),portee+1-abs(y)):
			if (x is 0 and y is 0): continue
			ret = add_pos(pos,(x,y))
			if ( 0<=ret[0]<TAILLE_TERRAIN and 0<=ret[1]<TAILLE_TERRAIN  ): yield ret

def nb_sorciers_total (pos):
	return max(nb_sorciers(pos,j) for j in adversaires())

def escargot():
	# C'est degueu
	pos = (TAILLE_TERRAIN//2,TAILLE_TERRAIN//2)
	for d in range(1,TAILLE_TERRAIN//2):
		for i in range(2*d+1):
			if i % (2*d) == 0:
				for j in range(1,2*d):
					yield add_pos(pos, (-d+i,-d+j))
			yield add_pos(pos, (-d+i,-d))
			yield add_pos(pos, (-d+i,+d))

def chemin_intelligent (dep, arr):
	'''Dijkstra. Pas tres rapide, mais bon, ca passe...'''
	key = dep
	visited = set()
	tmp = {dep:([],0)}
	while True:
		tovisit = (p for p in tmp if p not in visited)
		try: key = min(tovisit, key=lambda x: tmp[x][1])
		except ValueError: return ([],0)
		if key==arr: return tmp[key]
		visited.add(key)
		for voisin in acote(key,1):
			if info_case(voisin) is not case_info.CASE_TOURELLE:
				poids = tmp[key][1] + 1
				for voisvoisin in acote(voisin,PORTEE_TOURELLE):
					t = tourelle_case(voisvoisin)
					if t.joueur not in [-1, moi()]:
						poids += t.attaque
				dejala = tmp.get(voisin)
				if dejala is None or poids < dejala[1]:
					tmp[voisin] = (tmp[key][0]+[voisin], poids)
	return tmp[key]

def utilite_tourelle(pos, poids_sorcier=1, poids_base=10, poids_artefact=20):
	'''Utilite d'une tourelle, existante ou a venir'''	
	utilite = 0	
	tourelle = tourelle_case(pos)
	if tourelle.portee is -1:
		tourelle.portee = PORTEE_TOURELLE
	for p in acote(pos, tourelle.portee):
		for adv in adversaires():
			utilite += poids_sorcier*nb_sorciers_deplacables(p,adv)
			utilite += poids_base*(p is mabase())
			utilite += poids_artefact*(p is (TAILLE_TERRAIN//2,TAILLE_TERRAIN//2))
	return utilite

class Jeu:
	def __init__(self):
		self.pos = mabase()
		self.tourelle = mabase()
		self.artefact = (TAILLE_TERRAIN//2,TAILLE_TERRAIN//2)
		self.direction_centre = div_pos(diff_pos(mabase(),self.artefact), TAILLE_TERRAIN//2)
		self.tourelles = [mabase()]

	def add_tourelle(self, pos):
		ret	 = construire(pos, PORTEE_TOURELLE)
		return ret is erreur.OK
	def unshift_tourelle(self):
		tourL = tourelles_joueur(moi())[2]
		supprimer(tourL.pos)

	def construction(self):
		tour = tour_actuel()
		if tour < 1 : pass		
		elif tour == 1:
			construire(add_pos(mabase(), (0,self.direction_centre[1])), PORTEE_TOURELLE+2)
		elif 1 < tour <= DEPART:
			nbsorciers = mamagie()/COUT_SORCIER
			creer(nbsorciers)
		elif tour == DEPART+1:
			construire(add_pos(mabase(), (self.direction_centre[0], 0)), PORTEE_TOURELLE)
		else:
			if len(tourelles_joueur(moi())) == 9:
				self.unshift_tourelle()
			for p in escargot():
				if self.add_tourelle(p):
					break

	def deplacement(self):
		if tour_actuel() < DEPART : return
		depl = chemin_intelligent(self.pos, self.artefact)[0]
		m = min(PORTEE_SORCIER, len(depl))
		if m > 0:
			deplacer(self.pos, depl[m-1], self.total_sorciers())
			self.pos = depl[m-1]

	def tir(self):
		# Attaque depuis les tourelles
		for t in tourelles_joueur(moi()):
			for p in acote(t.pos, t.portee):
				if nb_sorciers_total(p) > 0:
					tirer(ATTAQUE_TOURELLE, t.pos, p)
					break

	def siege(self):
		# Attaque depuis les sorciers
		for p in acote(self.pos, 1):
			t = tourelle_case(p)
			if t.joueur not in (moi(), -1):
				assieger(self.pos, p, self.total_sorciers())

	def total_sorciers(self):
		return nb_sorciers(self.pos, moi())
			

# Fonction appelée au début de la partie
def partie_debut():
	global j
	j = Jeu()

# Fonction appelée pendant la phase de construction
def phase_construction():
	global j
	j.construction()

# Fonction appelée pendant la phase de déplacement
def phase_deplacement():
	global j
	j.deplacement()

# Fonction appelée pendant la phase de tirs des tourelles
def phase_tirs():
	global j
	j.tir()

# Fonction appelée pendant la phase de siège des tourelles
def phase_siege():
	global j
	j.siege()

# Fonction appelée à la fin de la partie
def partie_fin():
    pass # Place ton code ici

