JeuWeb - Crée ton jeu par navigateur
Algo de Combat - Ogame Like - Version imprimable

+- JeuWeb - Crée ton jeu par navigateur (https://jeuweb.org)
+-- Forum : Discussions, Aide, Ressources... (https://jeuweb.org/forumdisplay.php?fid=38)
+--- Forum : Programmation, infrastructure (https://jeuweb.org/forumdisplay.php?fid=51)
+--- Sujet : Algo de Combat - Ogame Like (/showthread.php?tid=5680)

Pages : 1 2


Algo de Combat - Ogame Like - Melimelo - 09-09-2011

Alors j'ai aidé un de mes vieux contacts a faire un algo de combat Ogame like maintenant j'ai un peu "baclé" le travail c'est une implémentation très naive et peu efficace (et pour cause après on peut difficilement lui demander de gérer des combat de dizaines milliers de vaisseaux).

Le code n'est pas commenté mais relativement claire, je suis disponible pour toutes questions et je mettrais une version plus optimisé en ligne dès que j'aurai le temps.

Je me suis basé sur un texte en français trouver sur un forum pour le faire :

Citation :Un combat se déroule toujours de la même manière :

- On calcule la valeur d'attaque ("valeur d'attaque" dans la fiche de chaque vaisseau), de coque ("points de structure" divisés par 10), et le bouclier ("puissance du bouclier"), pour chaque vaisseau en y ajoutant l'effet des technologies (+10% par niveau).

- On lance le combat, à chaque tour :
=> - On recharge les boucliers
=> - Chaque vaisseau tire sur un vaisseau ennemi aléatoirement. Si ce dernier à du rapidfire contre sa cible, il a un probabilité de continuer à tirer. Le bouclier de la cible absorbe les dégâts reçus, sauf s'ils sont inférieurs à 1% du bouclier dans quel cas aucun dommage n'est causé. Si le bouclier est détruit, la coque de la cible absorbe les dégâts.
=> - Chaque vaisseau endommagé à une probabilité d'exploser proportionelle aux dommages qu'il a subis s'ils sont supérieurs à 30% de la valeur de sa coque (60% de dommages donneront 60% de chances de destruction).

- A la fin du combat, on compte les pertes de l'attaquant et du défenseur.
- Un champ de débris contenant 30% du métal des vaisseaux détruits et 30% du cristal se forme en orbite de la planète.
- Un lune à un probabilité de se créer égale à l'arrondi inférieur de la valeur totale du champ de débris (métal + cristal) divisée par 100 000.



Le rapidfire désigne la possibilité pour certains vaisseaux de continuer à tirer lorsqu'ils atteignent certaines cibles, cf Déroulement d'un combat.

Le rapidfire de chaque vaisseau sur chaque cible est indiqué dans sa fiche.
La probabilité d'un vaisseau à continuer à tirer lorsqu'il touche un vaisseau sur lequel il a du rapidfire vaut 100-100/rapidfire %.
Par exemple, un Croiseur attaquant un Chasseur Léger (rapidfire de 6), aura 100-100/6 = 83,33% de chances de continuer à tirer. On voit donc bien que plus le rapidfire est élevé, plus ces chances augmentent et le vaisseau pourra causer des dégâts plus importants si la flotte ennemi est composée de bon nombre de ces vaisseaux.


- J'ai fait quelque ajustement par fainéantise (le bouclier se recharge contre chaque nouvel attaquant et non pas chaque tour)

- le Rapid fire permet de tier un nombre plus élevé que deux fois mais j'ai limité volontairement à deux (je corrigerai dans la prochaine version).

- L'attaquant à un grand avantage car toute sa flotte tir en premier, Alors que j'aurais dû alterner les tir mais cela aussi sera corrigé.

Voilà le code php :

<?php
$Vaisseau = array('Chasseur' => array('Nom' => 'Chasseur', 'Structure' => 400, 'Bouclier' => 10, 'Attaque' => 10, 'RapidFire' => array()),
'Croiseur' => array('Nom' => 'Croiseur', 'Structure' => 2700, 'Bouclier' => 50, 'Attaque' => 400, 'RapidFire' => array('Chasseur' => 6)),
'Traqueur' => array('Nom' => 'Traqueur', 'Structure' => 7000, 'Bouclier' => 400, 'Attaque' => 700, 'RapidFire' => array('Chasseur' => 10, 'Croiseur' => 2)));

$Joueur1 = array('Chasseur' => 2000, 'Croiseur' => 2000, 'Traqueur' => 2000);
$Joueur2 = array('Chasseur' => 2000, 'Croiseur' => 2000, 'Traqueur' => 2000);

function CalculArmee($param)
{
global $Vaisseau;

$Armee_Joueur = array();
reset($param);

for($i=0;$i < count($param); $i++)
{
$max = current($param);

for($j=0;$j < $max; $j++)
{
$Armee_Joueur[] = array('Nom' => $Vaisseau[Key($param)]['Nom'], 'Structure' => $Vaisseau[Key($param)]['Structure']);
}

next($param);
}

return $Armee_Joueur;

}

function Tir($Bouclier, $Attaque, $Structure, $Cible)
{
global $Vaisseau;

if(0 < $Bouclier-$Attaque)
{
$Bouclier -= $Attaque;
return $Structure;
}
else
{
$Structure -= ($Attaque-$Bouclier);
$Bouclier = 0;

$ratio = 1-$Structure/$Vaisseau[$Cible['Nom']]['Structure'];

if($ratio >= 0.4)
{
if(mt_rand(0, getrandmax()/getrandmax()) < $ratio)
{
return False;
}
else
{
if($Structure <= 0)
{
return false;
}
else
{
return $Structure;
}
}
}
else
{
return $Structure;
}
}
}

function Combat($Attaquant, $Defenseur)
{
global $Vaisseau;
$count = count($Defenseur)-1;


foreach($Attaquant as $element)
{
if($count+1 <= 0)
{
break;
}

$Cible = round(mt_rand(0, getrandmax()/getrandmax())*$count);

$Attaque = $Vaisseau[$element['Nom']]['Attaque'];

$Structure = $Defenseur[$Cible]['Structure'];
$Bouclier = $Vaisseau[$Defenseur[$Cible]['Nom']]['Bouclier'];

$Tir = Tir($Bouclier, $Attaque, $Structure, $Defenseur[$Cible]);

if($Tir)
{
$Structure = $Tir;
}
else
{
unset($Defenseur[$Cible]);
$Defenseur = array_values($Defenseur);
$count--;
}

if(!empty($Defenseur[$Cible]) && !empty($Vaisseau[$element['Nom']]['RapidFire'][$Defenseur[$Cible]['Nom']]))
{
if(mt_rand(0, getrandmax()/getrandmax()) <= 1-1/$Vaisseau[$element['Nom']]['RapidFire'][$Defenseur[$Cible]['Nom']])
{
$Tir = Tir($Bouclier, $Attaque, $Structure, $Defenseur[$Cible]);

if($Tir)
{
$Structure = $Tir;
}
else
{
unset($Defenseur[$Cible]);
$Defenseur = array_values($Defenseur);
$count--;
}
}
}

if(isset($Defenseur[$Cible]))
{
$Defenseur[$Cible]['Structure'] = $Structure;
}
}

return $Defenseur;
}

function CalculReste($param)
{
$Reste = array('Chasseur' => 0, 'Croiseur' => 0, 'Traqueur' => 0);

foreach($param as $element)
{
$Reste[$element['Nom']]++;
}

return $Reste;
}


$Armee_Joueur1_Attaquant = CalculArmee($Joueur1);
$Armee_Joueur2_Defenseur = CalculArmee($Joueur2);


for($i=0; $i < 6; $i++)
{
$Armee_Joueur2_Defenseur = Combat($Armee_Joueur1_Attaquant, $Armee_Joueur2_Defenseur);
$Armee_Joueur1_Attaquant = Combat($Armee_Joueur2_Defenseur, $Armee_Joueur1_Attaquant);

if(count($Armee_Joueur2_Defenseur) <= 0 || count($Armee_Joueur1_Attaquant) <= 0)
{
break;
}
}

$Joueur1 = CalculReste($Armee_Joueur1_Attaquant);
$Joueur2 = CalculReste($Armee_Joueur2_Defenseur);

print '<pre>';
print_r($Joueur1);
print '</pre><br/><br/>';

print '<pre>';
print_r($Joueur2);
print '</pre>';





?>

Je répète que ce n'est pas optimisé mais cela peut toujours aider (surtout que c'est une question relativement souvent posé). J'en mettrai un mieux plus tard. Je trouve le résultat relativement satisfaisant si l'on ne tient pas compte des piètre performance.

Cordialement Melimelo

ps: n'hésiter pas à faire des suggestion ou a proposer vous même un script optimiser à partir du texte ^^


RE: Algo de Combat - Ogame Like - niahoo - 09-09-2011

Heu je sais pas qui a imaginé ce système de combat (le texte que tu montres) mais il ne s'est pas foulé : en gros on fait la somme de tous les points de chaque vaisseau et après on tire aléatoirement sur les ennemis. Super !

Alors que normalement tu commences par démonter tout ce qui peut réparer l'ennemi, puis les petits vaisseaux qui sont fragiles, avec pas mal de puissance de feu sur le premier d'une liste de vaisseaux ennemis importants afin de les tomber un par un et donc plus rapidement.


RE: Algo de Combat - Ogame Like - Melimelo - 09-09-2011

C'est le principe de l'aglo de combat de OGame ....


RE: Algo de Combat - Ogame Like - niahoo - 09-09-2011

Et ben pour un jeu à plusieurs millions de joueurs c'est pas top.

Sinon merci pour le partage de ton code.


RE: Algo de Combat - Ogame Like - SorenS - 09-09-2011

Les concepts les plus simples marchent mieux généralement niahoo :]


RE: Algo de Combat - Ogame Like - Sephi-Chan - 09-09-2011

Mais là c'est un peu simpliste. La possibilité de séparer l'armée en escouades disposant de stratégies de ciblage, par exemple.


RE: Algo de Combat - Ogame Like - Melimelo - 09-09-2011

En soi ca doit pas être très difficile à faire ... C'est juste jouer avec les probabilité d'acquisition d'une cible ... je veux bien essayer de l'intégrer dans une prochaine version Smile


RE: Algo de Combat - Ogame Like - Argorate - 09-09-2011

(09-09-2011, 10:59 AM)niahoo a écrit : Et ben pour un jeu à plusieurs millions de joueurs c'est pas top.

Sinon merci pour le partage de ton code.

Depuis quand ogame c'est un jeu riche et intéressant? Confusediffle:


RE: Algo de Combat - Ogame Like - niahoo - 09-09-2011

(09-09-2011, 11:14 AM)SorenS a écrit : Les concepts les plus simples marchent mieux généralement niahoo :]

on peut complexifier l'algo sans que ça paraisse plus compliqué pour le joueur. Et lui montrer les vaisseaux ennemis pour lui permettre de donner l'ordre dans lequel il faut les péter ça ajoute de la stratégie, c'est pas obligatoire, et ça peut être sympa sans pour autant que le jeu devienne plus compliqué.

Ben pour ceux qui veulent faire de la repompe y a dejà des moteurs tout prèts à l'emploi.

Je pense qu'il faudrait architecturer ça autrement :
un état qui contient les deux armées ensemble, et à chaque itération la boucle demande à tous les vaisseaux, un par un (et de chaque armée mélangés) ce qu'ils souhaitent faire en fonction du résultat de l'itération précédente/de l'état initial pour la première itération.

Chaque armée stocke également des listes de focus. Quand c'est au tour d'un vaisseau, il récupère la liste de focus qui correspond à sa catégorie, prend le premier élément et shoote dessus.
(genre si c'est un vaisseau lourd, il prends la liste des cibles principales ennemies et tire son plus gros shoot dispo).
Ou alors il peut fuir, ou récupérer le premier vaisseau de la liste de ceux qu'il faut soigner,
Ou autre.
Quand je parle de liste, on peut aussi définir simplement la nouvelle cible quand la cible actuelle est morte/full HP.

Une fois qu'on a recueilli ce que chaque vaisseau veut faire, on passe en mode résolution. On reprends la liste des demandes de chaque vaisseau et on exécute ce qu'ils ont demandé. Il est possible dans ce système que quand on arrive au 150 ème vaisseau il soit déjà mort à cause des demandes précédentes.
Dans ce cas, soit on exécute quand même ce qu'il a demandé, en partant du postulat que tout ça se passe simultanément, soit on décide qu'il est mort et que son action n'a pas lieu (l'ordre de départ des vaisseaux dépendrait alors d'un facteur de réaction, agilité ou autre truc des pilotes/du joueur) mais dans ce cas il faut à chaque fois vérifier que le vaisseau est toujours en lice.
Soit un autre système, genre trier les vaisseaux en X catégories, des plus rapides aux plus lents à bouger/tirer, certaines catégories étant résolues en mode simultané, d'autres non, etc..

Et là c'est la fin de l'itération, on regarde si les deux armées sont toujours présentes et si oui on recommence.


Bon désolé ça doit pas être très clair Smile


edit : sinon on peut prendre chaque vaisseau un par un et modifier l'état des deux armées en fonction de sa décision immédiatement : on ne peut plus simuler des décisions simultanée, par contre ce sera plus simple à implémenter (encore que, perso j'aime moins)


RE: Algo de Combat - Ogame Like - php_addict - 09-09-2011

(09-09-2011, 12:30 PM)Argorate a écrit : Depuis quand ogame c'est un jeu riche et intéressant? Confusediffle:

et où il n'y a pas des milliers de joueurs qui font du multicompte?