Hébergeur de fichiers indépendant

functions.ls

À propos

Type de fichier
Fichier LS de 19 Ko (text/plain)
Confidentialité
Fichier public, envoyé le 18 mai 2015 à 14:12, depuis l'adresse IP 217.15.x.x (Belgique)
Sécurité
Ne contient aucun Virus ou Malware connus - Dernière vérification: 7 heures
Statistiques
La présente page de téléchargement a été vue 320 fois depuis l'envoi du fichier
Page de téléchargement

Aperçu du fichier


/**************************************************************************
*************************** FONCTIONS DIVERSES ****************************
***************************************************************************

Ce fichier reprend diverses fonctions qui peuvent être utiles pour une IA
Elles ne sont aucunement utiles seules, mais permettent de simplifier certains
calculs dans des IA plus avancées.
Regles générales: 
=> Dans le cas ou une fonction prend des paramètres par adresse,
cela sera mentionné dans le nom de la fonctions grace à "_adr"
=> les fonctions ont leurs propres sorties de debug, warning et erreurs.
Les debug simples ne seront affichés que si vous mettez le booléen FUNCTIONS_DEBUG à true
Voici les différents en-têtes des fonctions de ce fichier:

//initialise toutes les variables nécessaires au bon fonctionnement des méthodes 
//de ce fichier (il est désormais inutile de l'appeller soi-même)
Init_functions();

//appelable à chaque tour, cette fonction rafrachit différentes variables de calcul.
//appeler cette fonction en début de tour est nécessaire pour certains algorithmes.
refresh_functions();

//renvoie l'ennemi avec le moins de vie de l'équipe adverse
getLowestLifeEnemy();

//retourne l'effet demandé parmi une liste d'effet
//typiquement: getEffect(getChipEffect(CHIP_CURE), EFFECT_HEAL)[2]; 
//donnera le max de soins dela puce de soins
getEffect(effects, effetVoulu);

//retourne la vie totale actuelle de la team ennemie
getTotalLifeAlliesTeam();

//retourne la vie totale actuelle de la team alliée
getTotalLifeEnemyTeam();

//retourne la puissance d'une puce ou d'une arme utilisée sur une cible
// les puces d'amélioration retournent actuellement le bonus qui sera appliqué à
// la meilleure arme/puce qui correspond. Si vous comptez tirer plusieurs fois, 
//multipliez donc ce résultat!
//ne prend pas en compte le taux d'échec
//ne prend pas en compte les dégats/soins de zone, juste la puissance individuelle
getPower(Cheap_Weapon, target);

//retourne la moyenne des dégats d'une puce ou d'une arme
getMeanDamage(weapon);

//retourne la moyenne arithmétique entre 2 nombre
mean(a, b);

//utilise tous vos points de tour pour utiliser la puce/arme sur la cible
spendTPWith(weap_chip, target);

//retourne true si la puce est une puce aggressive
isAggressiveChip(chip);

//retourne toutes les puces aggressives équipées
getAllAgressiveChip();

//retourne l'arme/puce la moins cher de la liste
getCheapestCW(liste);

//retourne le cout d'une puce ou d'une arme, indistinctement
getCWCost(cw);

//construit la meilleure combinaison d'arme possible pour toucher la cible en un nombre
//de points de tour donné.
buildBetterWeapons(tp, target);

//retourne la case la plus proche ou on peut utiliser toutes les armes envoyées en 
//paramètre (en construction)
function getCellToUseWeapons(weapons, target)

//utilise toutes les armes envoyées en paramètre sur la cible (doublons possibles)
useWeaponsOnTarget(weapons, target);

//peut on utiliser l'arme cw depuis cell sur la cellule ct?
canUseCWFrom(cw, cell, ct);

//retourne toutes les puces qui ont l'effet concerné
getChipsWithEffect(effect);

//retourne le meilleur élément de tab grâce à l'évaluation par élément de fct
evalueElements(tab, fct);
*/

//mettez cette variable à true pour afficher les messages de debug
global FUNCTION_DEBUG = false;

//déclaration des différentes variables:
global functions_init = false;
global functions_futurs_damage = [];
global functions_futurs_damage_sum = 0;
global functions_last_turn_life;

/*********************************************************************************
**********************************************************************************
              FONCTIONS D INITIALISATION DES DIFFERENTES FONCIONNALITES 
**********************************************************************************
*********************************************************************************/

//initialise toutes les variables nécessaires au bon fonctionnement des méthodes 
//de ce fichier
function Init_functions()
{
	if (!functions_init) {
		if (FUNCTION_DEBUG)
			debug("*** Début de l'initialisation de <functions> ***");
		functions_init = true;
		functions_last_turn_life = getLife();
		if (FUNCTION_DEBUG)
			debug("*** Fin de l'initialisation de <functions> ***");
	}
}

//appelable à chaque tour, cette fonction rafrachit différentes variables de calcul.
//appeler cette fonction en début de tour est nécessaire pour certains algorithmes.
function refresh_functions()
{
	if (FUNCTION_DEBUG)
		debug("*** Début du rafraichissement de <functions> ***");
	Init_functions();
	analyse_danger();
	functions_last_turn_life = getLife(); //functions_last_turn_life non utilisable en dehors du refresh donc!
	if (FUNCTION_DEBUG)
		debug("*** Fin du rafraichissement de <functions> ***");
}


/*********************************************************************************
**********************************************************************************
                            FONCTIONS UTILITAIRES BASIQUES 
**********************************************************************************
*********************************************************************************/

//renvoie l'ennemi avec le moins de vie de l'équipe adverse. Le booléen permet de choisir
// si la fonction peut prendre les bulbes ou non
function getLowestLifeEnemy(bulbes)
{
	var enemies = getEnemies();
	var res;
	for (var i in enemies)
		if (getLife(i)>0 && ((!bulbes && !isSummon(i)) || (bulbes)))
			res = i;
	for (var i in enemies)
		if (getLife(i)>0 && getLife(i) < getLife(res) && ((!bulbes && !isSummon(i)) || (bulbes)))
			res = i;
	return res;
}

//ajoute un élément en fin de tableau
function arrayAppend_adr(@tab, element) {
	if (tab == null) {
		debugE("Votre tableau est null!");
		return;
	}
	if (typeOf(tab) == TYPE_ARRAY)
		tab[count(tab)] = element;
	else
		debugE("Attention, le tableau envoyé en paramètre n'en est pas un. Vérifiez que vous l'avez bien initialisé au moyen de = []");
}

//retourne l'effet demandé parmi une liste d'effet
//typiquement: getEffect(getChipEffect(CHIP_CURE), EFFECT_HEAL)[2]; 
//donnera le max de soins dela puce de soins
function getEffect(effects, wanted)
{
	var res;
	for (var i in effects) {
		if (i[0] == wanted)
			res = i;
	}
	return res;
}

//retourne la vie totale actuelle de la team ennemie
function getTotalLifeAlliesTeam()
{
	var res = 0;
	for (var i in getAllies())
		res = res + getLife(i);
	return res;
}

//retourne la vie totale actuelle de la team alliée
function getTotalLifeEnemyTeam()
{
	var res = 0;
	for (var i in getEnemies())
		res = res + getLife(i);
	return res;
}

//retourne la moyenne des dégats d'une puce ou d'une arme
function getMeanDamage(weapon)
{
	if (weapon == null)
		return -1;
	if (isChip(weapon)) {
		return (getEffect(getChipEffects(weapon), EFFECT_DAMAGE)[2] - 
			getEffect(getChipEffects(weapon), EFFECT_DAMAGE)[1]) / 2 +
			getEffect(getChipEffects(weapon), EFFECT_DAMAGE)[1];
	} else
		return (getEffect(getWeaponEffects(weapon), EFFECT_DAMAGE)[2] - 
		getEffect(getWeaponEffects(weapon), EFFECT_DAMAGE)[1]) /2 +
		getEffect(getWeaponEffects(weapon), EFFECT_DAMAGE)[1];
}

//retourne la moyenne arithmétique entre 2 nombre
function mean(a, b)
{
	return (a + b)/2;
}

//retourne true si la puce est une puce d'attaque
function isAggressiveChip(chip) {
	var res = false;
	for (var i in getChipEffects(chip))
	{
		if (i[0] == EFFECT_DAMAGE || i[0] == EFFECT_POISON)
			res = true;
	}
	return res;
}

//retourne toutes les puces d'attaque
function getAllAgressiveChip()
{
	var res = []; var index = 0;
	for (var i in getChips())
	{
		if (isAggressiveChip(i)) {
			res[index] = i; index ++;
		}
	}
	return res;
}

//retourne la puce/arme la moins cher
function getCheapestCW(liste)
{
	if (liste == null) {
		debugW("warning, la CW la moins cher d'une liste vide est null!");
		return null; 
	}
	var res = liste[0];
	for (var i in liste) {
		var actualCost;
		if (isChip(res))
			actualCost =getChipCost(res);
		else if (isWeapon(res))
			actualCost = getWeaponCost(res);
		if (isChip(i) && getChipCost(i) < actualCost)
			res = i;
		else if (isWeapon(i) && getWeaponCost(i) < actualCost)
			res = i;
	}
	return res;
}

//retourne le cout d'une arme ou d'une puce
function getCWCost(cw)
{
	if (cw == null) {
		debugW("warning, cout demandé d'une puce qui vaut null!");
		return 0; 
	}
	if (isChip(cw))	
		return getChipCost(cw);
	else
		return getWeaponCost(cw);
}

//retourne true si l'élément i est dans le tableau
function isInTab(i, tab)
{
	for (var j in tab)
		if (j == i)	
			return true;
	return false;
}

//retourne la case la plus proche d'une liste de cases
function getNearlyCell(cells) {
	if (count(cells) == 0)
		return getCell();
	var dist = getPathLength(getCell(), cells[0]);
	var res = 0;
	for (var i=0; i<count(cells); i++) {
		if (getPathLength(getCell(), cells[i])<=dist) {
			dist = getPathLength(getCell(), cells[i]);
			res = i;
		}
	}
	return cells[res];
}

//retourne toutes les puces qui ont l'effet concerné
function getChipsWithEffect(effect) {
	var res = [];
	var index = 0;
	for (var i in getChips()) {
		var hasEffect = false;
		for (var j in getChipEffects(i))
			if (j[0] == effect)
				hasEffect = true;
		if (hasEffect) {
			res[index] = i;
			index++;
		}
	}
	return res;
}

//retourne le meilleur élément de tab grâce à l'évaluation par élément de fct
function evalueElements(tab, fct) {
	if (tab == null)
		return null;
	if (count(tab) == 0)
		return null;
	var res = tab[0];
	for (var i in  tab) {
		if (fct(i) >= res) {
			res = i;
		}
	}
	return res;
}

/*********************************************************************************
**********************************************************************************
                     FONCTIONS D'AIDE A LA DECISION ET D'ESTIMATION
**********************************************************************************
*********************************************************************************/

//retourne la force de frappe potentielle de l'ennemi environant. Il ne s'agit que
// d'une approximation basée sur l'arme actuellement équipée, la distance, la force
// du/des poireau. Cette fonction stockera la liste des dégats subits (selon l'estimation)
// dans le tableau functions_futurs_damage et la somme de ces dégats dans
//functions_futurs_damage_sum
//aucune réduction de vos armures n'est calculée, ce sont donc les dégats bruts qui 
//sont retournés
function analyse_danger() {
	if (FUNCTION_DEBUG)
		debug("Résultat de la dernière prévoyance: " + (functions_last_turn_life- getLife() - functions_futurs_damage_sum) +
					" Dégats subis en plus");
	var sum = 0;
	var damages = [];
	var indexD = 0;
	for (var i in getAliveEnemies())
	{
		if (getWeapon(i) != null)
			for (var j=1; j<getTP(i); j+=getWeaponCost(getWeapon(i))) {
				//prerequis: lvl 37
				if (getWeaponMinScope(getWeapon(i)) <= getPathLength(getCell(), getCell(i))+getMP(i)) {
				//sinon:
				//if (getWeaponMinScope(getWeapon(i)) <= getDistance(getCell(), getCell(i))+getMP(i)) {
					var tedamage = getMeanDamage(getWeapon(i)) * (1 + getForce(i)/100) * 
							(1-getRelativeShield()/100) - getAbsoluteShield();
					if (tedamage <0)
						tedamage = 0;
					sum += tedamage;
					damages[indexD] = tedamage;
					indexD++;
				}
			}
	}
	functions_futurs_damage_sum = sum;
	functions_futurs_damage = damages;
	if (FUNCTION_DEBUG)
		debug("dangé détecté: " + sum + "dégats potentiels subis au prochain tour");
	return sum;
}

/*********************************************************************************
**********************************************************************************
                                 FONCTIONS DE CALCUL 
**********************************************************************************
*********************************************************************************/

//retourne la puissance d'une puce ou d'une arme utilisée sur une cible
// les puces d'amélioration retournent actuellement le bonus qui sera appliqué à
// la meilleure arme/puce qui correspond, multiplié par le nombre de tour de l'effet.
//Si vous comptez tirer plusieurs fois, multipliez donc ce résultat!
//ne prend pas en compte le taux d'échec
//ne prend pas en compte les dégats/soins de zone, juste la puissance individuelle
//pour les armures, la plage de dégats stoppés est basée sur l'analyse du danger
//refresh_functions() est donc nécessaire au bon fonctionnement de cette évaluation
function getPower(cw, target)
{
	var effects;
	if (isChip(cw))	
		effects = getChipEffects(cw);
	else
		effects = getWeaponEffects(cw);
	var resultat = 0;
	for (var i in effects) {
		if (i[0] == EFFECT_DAMAGE || i[0] == EFFECT_POISON) {
			var temp = mean(i[1],i[2]) * (1 + getForce() / 100) *
			(1 - getRelativeShield(target) / 100) - getAbsoluteShield(target);
			temp = temp * (i[3]==0?1:i[3]); // fois le nombre de tours
			resultat = resultat + (temp>=0 ? temp: 0);
		} else if (i[0] == EFFECT_HEAL) {
			resultat = resultat + (1+getAgility()/100) * mean(i[1],i[2]) * i[3];
		} else if (i[0] == EFFECT_ABSOLUTE_SHIELD) {
			var result_shield = i[1] * (1+getAgility()/100);
			for (var j in functions_futurs_damage)
			{
				resultat = resultat + ((functions_futurs_damage[j]-result_shield)>=0
							? result_shield:functions_futurs_damage[j]);
			}
		} else if (i[0] == EFFECT_RELATIVE_SHIELD) {
			var result_shield = i[1] + getAgility()/50;
			for (var j in functions_futurs_damage)
			{
				resultat = resultat + functions_futurs_damage[j] - 
					(functions_futurs_damage[j]*result_shield/100);
			}
		} else if (i[0] == EFFECT_BUFF_AGILITY) { //avec CHIP_CURE codé en dur comme référence
			resultat = resultat + i[3] * (mean(35,43) * (1+(getAgility()+i[1])/100)-
				mean(35,43) * (1+(getAgility())/100));
		} else if (i[0] == EFFECT_BUFF_FORCE) {
			resultat = resultat + i[3] * (getMeanDamage(getWeapon()) * (1+(getForce()+i[1])/100)-
				getMeanDamage(getWeapon()) * (1+(getForce())/100));
		}
	}
	return resultat;
}

//retourne la puissance de l'arme/puce en fonction de son cout (basé sur getPower)
// le cout est augmenté de 1 si withEquip est à true (pour les armes)
function getPowerPerTP(cw, target, withEquip)
{
	if (isChip(cw)) {
		if (FUNCTION_DEBUG)
			debug("puissance de " + getChipName(cw) + ": " + getPower(cw, target)/getChipCost(cw));
		return getPower(cw, target)/getChipCost(cw);
	} else{
	if (FUNCTION_DEBUG)
			debug("puissance de " + getWeaponName(cw) + ": " + getPower(cw, target)/(getWeaponCost(cw)+ 
									(withEquip)?1:0));
		return getPower(cw, target)/(getWeaponCost(cw)+ 
									(withEquip)?1:0);
	}
}

//sans check de cible ni d'équipage, à n'utiliser que pour les puces non offensives
function getPowerPerTPF(cw) {
	return getPowerPerTP(cw, getLeek(), false);
}

//utilise tous vos points de tour pour utiliser la puce/arme sur la cible
function spendTPWith(weap_chip, target)
{
	if (weap_chip == null)
		return;
	if (isChip(weap_chip)) {
		if (!canUseChip(weap_chip, target))
			return;
		useChip(weap_chip, target);
		while(getTP() >= getChipCost(weap_chip) && canUseChip(weap_chip, target) && getChipCooldown(weap_chip) == 0) 
			useChip(weap_chip, target);
	} else {
		if (getWeapon() != weap_chip)
			setWeapon(weap_chip);
		if (!canUseWeapon(weap_chip, target))
			return;
		while(getTP() >= getWeaponCost(weap_chip) && canUseWeapon(weap_chip, target))
			useWeapon(target);
	}
	if (getTP() >= getChipCost(CHIP_SPARK))
		spendTPWith(CHIP_SPARK, target);
}

//construit la meilleure combinaison d'arme possible pour toucher la cible en un nombre
//de points de tour donné.
function buildBetterWeapons(cw, tp, target)
{
	if (cw == null || count(cw) ==0)
		return [];
	var res = []; var index = 0;
	var equiped_w;
	var tempTP = tp;
	var weap_chips = cw;
	var bestW = getWeapon();
	while (tempTP >= getCWCost(getCheapestCW(weap_chips)))
	{
		var lastWeap = bestW;
		for (var i in weap_chips)
		{
			if (bestW == null || getCWCost(bestW)>tempTP)
				bestW = i;
			if (getPowerPerTP(bestW, target, (lastWeap == i)) < 
				getPowerPerTP(i, target, (lastWeap == i)))
				if ((getCWCost(i)+((lastWeap==i)?0:1))<=tempTP)
					bestW = i;
		}
		if ((getCWCost(bestW)+((lastWeap==bestW)?0:1))<=tempTP) {
			res[index] = bestW;
			tempTP = tempTP - getCWCost(bestW) ;
			if (lastWeap != bestW)
				tempTP--;
			index++;
			debug("tp restants: "+ tempTP);
		} else
			tempTP = -1;
	}
	if (FUNCTION_DEBUG)
		debug("la meilleure combinaison d'arme est " + res);
	return res;
}

//retourne toutes les cases ou on peut utiliser toutes les armes (puce) envoyées en 
//paramètre et les marque en noir sur le terrain
function getCellToUseWeapons(cw, target)
{
	var cells= [];
	var cellsres = [];
	if (count(cw) == 0)
		return getCell();
	for (var i in cw) {
		if (isChip(i))
			cells[count(cells)] = getCellsToUseChip(i, target);
		else
			cells[count(cells)] = getCellsToUseWeapon(i, target);
	}
	for (var i in cells[0]) {
		for (var j in cells) {
			var isIn = true;
			if (!isInTab(i, j))
				isIn = false;
			if (isIn)
				cellsres[count(cellsres)] = i;
		}
	}
	for (var i in cellsres)
		mark(i);
	return getNearlyCell(cellsres);
}

//utilise toutes les armes envoyées en paramètre sur la cible (doublons possibles)
function useWeaponsOnTarget(weapons, target)
{
	for (var i in weapons) {
		if (isWeapon(i)) {
			if (getWeapon() != i)	
				setWeapon(i);
			useWeapon(target);
		} else
			useChip(i, target);
	}
}

//peut on utiliser l'arme cw depuis cell sur la cellule ct?
function canUseCWFrom(cw, cell, ct)
{
	if (isChip(cw)) {
		if (isInlineChip(cw)) {
			if (getCellX(cell) == getCellX(ct) && getCellY(cell) == getCellY(ct))
				if (getChipMinScope(cw) <= getDistance(cell, ct) && getDistance(cell, ct) <= getChipMaxScope(cw))
					return true;
		} else if (cw != CHIP_SPARK) {
			if (getPathLength(cell, ct) <= getChipMaxScope(cw) && getPathLength(cell, ct) >= getChipMinScope(cw)) {
				//vérifier si il n'y a pas d'obstacle au moyen de la longueur du chemin:
				var dist = abs(getCellX(cell) - getCellX(ct)) + abs(getCellY(cell) - getCellY(ct)) + 1;
				if (getPathLength(cell, ct) == dist)
					return true;
			}
		} else {//dans le cas de chip_spark
			var dist = abs(getCellX(cell) - getCellX(ct)) + abs(getCellY(cell) - getCellY(ct)) + 1;
			if (dist <= 10)
				return true;
		}
	} else if (isWeapon(cw)) {
		if (isInlineWeapon(cw)) {
			if (getCellX(cell) == getCellX(ct) && getCellY(cell) == getCellY(ct))
				if (getWeaponMinScope(cw) <= getDistance(cell, ct) && getDistance(cell, ct) <= getWeaponMaxScope(cw))
					return true;
		} else {
			if (getPathLength(cell, ct) <= getWeaponMaxScope(cw) && getPathLength(cell, ct) >= getWeaponMinScope(cw)) {
				//vérifier si il n'y a pas d'obstacle au moyen de la longueur du chemin:
				var dist = abs(getCellX(cell) - getCellX(ct)) + abs(getCellY(cell) - getCellY(ct)) + 1;
				if (getPathLength(cell, ct) == dist)
					return true;
			}
		}
	}
	return false;
}

//enlève des armes envoyées en paramètre toutes les armes qu'il sera impossible d'utiliser
//, c'est à dire toutes les armes qui ne pourraient toucher personne, même en se déplacant
function removeUselessCW(cw, target) {
	var res = [];
	for (var i in cw) {
		var cells;
		if (isWeapon(i))
			cells = getCellsToUseWeapon(i, target);
		else 
			cells = getCellsToUseChip(i, target);
		mark(getNearlyCell(cells));
		for (var j in getPath(getCell(), getNearlyCell(cells)))
			mark(j);
		if (getMP() >= getPathLength(getCell(),getNearlyCell(cells)))
			arrayAppend_adr(res, i);
	}
	return res;


Partager le fichier

Télécharger functions.ls

Télécharger le fichier (19 Ko)