IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langage PHP Discussion :

Optimisation de code


Sujet :

Langage PHP

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre Expert Avatar de Madfrix
    Profil pro
    Inscrit en
    Juin 2007
    Messages
    2 326
    Détails du profil
    Informations personnelles :
    Localisation : France, Gironde (Aquitaine)

    Informations forums :
    Inscription : Juin 2007
    Messages : 2 326
    Par défaut Optimisation de code
    Bonjour,

    j'ai crée le bout de code suivant (simplifié) pour un petit jeu :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
     
    for($i=1; $i<=5; $i++){
    	foreach($attaquant as $cle){
     
    		if(mt_rand(1, 100) <= $rand_attaquant){
    			//L'attaquant attaque le defenseur puis eventuellement le defenseur s'il survit
    			//Calcul du coup critique eventuel
    			$coup_critique = mt_rand(1, 100);
    			($coup_critique <= $unites_desc_attaquant[$cle['type']]['coup_critique']) ? $coefficient = 5 : $coefficient = 1;
     
    			$indice_defenseur = mt_rand(0, count($defenseur)-1);
     
    			$degats_sur_def = $coefficient * $cle['valeur_attaque'] * ( 100 - $unites_desc_defenseur[$defenseur[$indice_defenseur]['type']][$cle['type_attaque']]) / 100 - $unites_desc_defenseur[$defenseur[$indice_defenseur]['type']]['armure'];
     
    			($degats_sur_def < 0) ? $degats_sur_def = 0;
     
    			$defenseur[$indice_defenseur]['vie'] -= $degats_sur_def;
     
    			//Contre attaque du defenseur s'il est en vie et qu'il a pas encore attaqué
    			if($defenseur[$indice_defenseur]['vie'] < 0){
    				unset($defenseur[$indice_defenseur]);
    				$defenseur = array_values($defenseur);
    			}
     
    		}else{
     
     
     
    		}
     
     
    	}
    }
    En fait il s'agit de simuler un combat entre 2 troupes prenant en compte plusieurs technologies associées au défenseur et à l'attaquant. Par exemple, j'ai une technologie "anticipation" qui permet au joueur possédant la meilleure techno des 2 d'attaquer le premier dans un combat avec un avantage de 5% par point de techno supplémentaire(ex: l'attaquant a une techno de 5, le def 3 -> l'attaquant aura 55% de chance d'attaquer le premier ce qui lui permettra s'il tue l'unité du defenseur de ne pas se faire attaquer par elle (logique^^)->variable $rand_attaquant).

    Enfin bref, ce n'est pas ce qui me pose problème, pas plus que de calculer la valeur de l'attaque du joueur attaquant en considérant l'armure ou la resistance du defenseur. Ce qui me pose problème, c'est de tirer une clé aléatoire sur le defenseur qui ne soit pas mort (mes clés de tableau sont des clé numériques triees 0,1, 2...). J'avais pensé supprimer, après chaque unité qui est attaqué et via un test, les clés du tableau du defenseur dont la valeur 'vie' est < 0 et via un array_values de recalculer le tableau du def, mais c'est extremement lourd en traitement...

    Voilà je sais pas si vous avez compris mon problème
    En gros, il serait simple d'attaquer chaque unité du defenseur eventuellement meme s'il est mort puis de faire le 'tri' entre les morts et les vivants a chaque fin de round, mais comment faire ce tri en milieu de round pour que chaque attaque se porte sur une unité encore vivante ? Faire un mt_rand au milieu du round de bataille ne sert pas puisque j'ai des "trous" dans mes clés de tableaux du aux morts

    Merci de votre aide et posez moi des questions, je sais que je m'explique mal lol

    @+

  2. #2
    Membre Expert Avatar de Madfrix
    Profil pro
    Inscrit en
    Juin 2007
    Messages
    2 326
    Détails du profil
    Informations personnelles :
    Localisation : France, Gironde (Aquitaine)

    Informations forums :
    Inscription : Juin 2007
    Messages : 2 326
    Par défaut
    Quelques infos complementaires :

    En fait j'attaque mon for avec les tableaux $attaquant et $defenseur de cette structure :

    $attaquant (ex) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
     
    Array
    (
        [0] => Array
            (
                [type] => archer
                [vie] => 220.00
                [valeur_attaque] => 36.60
                [type_attaque] => resistance_estoc
            )
     
        [1] => Array
            (
                [type] => archer
                [vie] => 220.00
                [valeur_attaque] => 36.60
                [type_attaque] => resistance_estoc
            )
     
        [2] => Array
            (
                [type] => arbaletrier
                [vie] => 275.00
                [valeur_attaque] => 11
                [type_attaque] => resistance_magique
            )
     
        [3] => Array
            (
                [type] => arbaletrier
                [vie] => 275.00
                [valeur_attaque] => 11
                [type_attaque] => resistance_magique
            )
     
    )

    $defenseur (ex) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
     
    Array
    (
        [0] => Array
            (
                [type] => fantassin_vouge
                [vie] => 100.00
                [valeur_attaque] => 0
                [type_attaque] => resistance_magique
                [r1] => 0
                [r2] => 0
                [r3] => 0
                [r4] => 0
                [r5] => 0
            )
     
        [1] => Array
            (
                [type] => fantassin_vouge
                [vie] => 100.00
                [valeur_attaque] => 0
                [type_attaque] => resistance_magique
                [r1] => 0
                [r2] => 0
                [r3] => 0
                [r4] => 0
                [r5] => 0
            )
    }
    Mes valeurs r1 à r5 pour le defenseur me servent a savoir si cette unité a déjà attaqué dans le round en cours (la valeur passe à 1) => max 1 attaque par tour

    Voilà ou j'en suis actuellement :

    Code php : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
     
    for($i=1; $i<=5; $i++){
     
    	if(!empty($attaquant) && !empty($defenseur)){
     
    		foreach($attaquant as $cle){
     
    		//on sort les unités attaquantes qui sont mortes au round précédent
    		if($cle['vie'] <= 0)
    			unset($cle);
     
    			if(!empty($attaquant) && !empty($defenseur) && isset($cle)){
     
    				if(mt_rand(1, 100) <= $rand_attaquant){
    					//L'attaquant attaque le defenseur puis eventuellement le defenseur s'il survit
    					//Calcul du coup critique eventuel
    					(mt_rand(1, 100) <= $unites_desc_attaquant[$cle['type']]['coup_critique']) ? $coefficient = 5 : $coefficient = 1;
     
    					$indice_defenseur = mt_rand(0, count($defenseur)-1);
     
    					$degats_sur_def = $coefficient * $cle['valeur_attaque'] * ( 100 - $unites_desc_defenseur[$defenseur[$indice_defenseur]['type']][$cle['type_attaque']]) / 100 - $unites_desc_defenseur[$defenseur[$indice_defenseur]['type']]['armure'];
    					if($degats_sur_def < 0) $degats_sur_def = 0;
     
    					$defenseur[$indice_defenseur]['vie'] -= $degats_sur_def;
     
    					//Contre attaque du defenseur s'il est en vie et qu'il a pas encore attaqué sinon on place a la clé morte la derniere clé du tableau
    					if($defenseur[$indice_defenseur]['vie'] <= 0 && count($defenseur) > 1){
    						$defenseur[$indice_defenseur] = $defenseur[count($defenseur)-1];
    						unset($defenseur[count($defenseur)-1]);
    					}else if($defenseur[$indice_defenseur]['vie'] > 0 && $defenseur[$indice_defenseur]['r'.$i] == 0){
    						(mt_rand(1, 100) <= $unites_desc_defenseur[$cle['type']]['coup_critique']) ? $coefficient = 5 : $coefficient = 1;
    						$degats_sur_att = $coefficient * $defenseur[$indice_defenseur]['valeur_attaque'] * ( 100 - $unites_desc_attaquant[$cle['type']][$defenseur[$indice_defenseur]['type_attaque']]) / 100 - $unites_desc_attaquant[$cle['type']]['armure'];
    						if($degats_sur_att < 0) $degats_sur_att = 0;
     
    						$cle['vie'] -= $degats_sur_att;		
    						$defenseur[$indice_defenseur]['r'.$i] = 1;
     
    						}
     
    				}else{
    					//Le defenseur attaque l'attaquant  puis eventuellement l'attaquant s'il survit
    					//if ci dessus mais inversé
     
    				}
    			}else break;
     
    		}
     
    		foreach($defenseur as $cle){
     
    		//on fait attaquer les unites du defenseur qui n'ont eventuellement pas encore attaqué sans contre attaque de l'attaquant -> toutes ses unites ont deja forcement toutes attaquées
    		}
     
     
    	}else break;
     
    }

    Maintenant, j'essaie de déplacer la derniere clé du tableau de defenseur en lieu et place dela clé dont la vie devient < 0. Dites moi ce que vous changeriez dans votre facon de procéder svp

    Bonjour, je suis en train de créer un jeu dans lequel je développe actuellement le script me permettant d'effectuer un combat entre le défenseur et l'attaquant en prenant en compte les technologies associées aux 2 joueurs (tableaux $unites_desc_attaquant et $unites_desc_defenseur). Voici mon code :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
     
    //Combat en 5 rounds
    $round = 1;
     
    while($round <= 5){
     
    if(empty($attaquant) || empty($defenseur))
    	break;
     
    //On melange les tableaux aleatoirement	
    shuffle($attaquant);
    shuffle($defenseur);
     
    $i=0;
    $max_occ = count($attaquant);
    $min_occ = count($defenseur);
    $max = 'attaquant';
     
    if($min_occ > $max_occ){
    	$max_occ = $min_occ;
    	$min_occ = count($attaquant);
    	$max = 'defenseur';
    	}
     
     
    while($i < $min_occ){
     
    	//l'attaquant attaque le premier sinon c'est le defenseur
    	if(mt_rand(1, 100) <= $rand_attaquant){
    		//Calcul du coup critique eventuel (X5)
    		(mt_rand(1, 100) <= $unites_desc_attaquant[$attaquant[$i]['type']]['coup_critique']) ? $coefficient = 5 : $coefficient = 1;
    		$degats = $coefficient * $attaquant[$i]['valeur_attaque'] * (100 - $unites_desc_defenseur[$defenseur[$i]['type']][$attaquant[$i]['type_attaque']]) / 100 - $unites_desc_defenseur[$defenseur[$i]['type']]['armure'];
    		$attaquant[$i]['r'.$round] = 1;
    		if($degats > 0) 		
    			$defenseur[$i]['vie'] -= $degats;
     
    		//Si l'unité du defenseur est vivante elle contre attaque si elle ne l'a pas déjà fait auparavant sur une autre unité 
    		if($defenseur[$i]['vie'] <= 0){
    			unset($defenseur[$i]);
     
    		}else if($defenseur[$i]['r'.$round] == 0){
    			$degats = $coefficient * $defenseur[$i]['valeur_attaque'] * (100 - $unites_desc_attaquant[$attaquant[$i]['type']][$defenseur[$i]['type_attaque']]) / 100 - $unites_desc_attaquant[$attaquant[$i]['type']]['armure'];
    			$defenseur[$i]['r'.$round] = 1;
    			if($degats > 0) 		
    				$attaquant[$i]['vie'] -= $degats;
    		}
    	}else{
    		//Calcul du coup critique eventuel (X5)
    		(mt_rand(1, 100) <= $unites_desc_defenseur[$defenseur[$i]['type']]['coup_critique']) ? $coefficient = 5 : $coefficient = 1;
    		$degats = $coefficient * $defenseur[$i]['valeur_attaque'] * (100 - $unites_desc_attaquant[$attaquant[$i]['type']][$defenseur[$i]['type_attaque']]) / 100 - $unites_desc_attaquant[$attaquant[$i]['type']]['armure'];
    		$defenseur[$i]['r'.$round] = 1;
    		if($degats > 0) 		
    			$attaquant[$i]['vie'] -= $degats;
     
    		//Si l'unité de l'attaquant est vivante elle contre attaque si elle ne l'a pas déjà fait auparavant sur une autre unité
    		if($attaquant[$i]['vie'] <= 0){
    			unset($attaquant[$i]);
     
    		}else if($attaquant[$i]['r'.$round] == 0){
    			$degats = $coefficient * $attaquant[$i]['valeur_attaque'] * (100 - $unites_desc_defenseur[$defenseur[$i]['type']][$attaquant[$i]['type_attaque']]) / 100 - $unites_desc_defenseur[$defenseur[$i]['type']]['armure'];
    			$attaquant[$i]['r'.$round] = 1;
    			if($degats > 0) 		
    				$defenseur[$i]['vie'] -= $degats;
    		}
     
    	}
     
     
    	$i++;
     
    }
     
    //Si les unités de l'attaquant sont plus nombreuses, alors le residu attaque sans resistances
    if($max == 'attaquant'){
     
    	//On remet d'aplomb le tableau du defenseur et le pointeur du defenseur à 0
    	$defenseur = array_values($defenseur);
    	$taille_def = count($defenseur);
    	$j=0;
     
    	while($i < $max_occ && !empty($defenseur)){
    		(mt_rand(1, 100) <= $unites_desc_attaquant[$attaquant[$i]['type']]['coup_critique']) ? $coefficient = 5 : $coefficient = 1;
    		$degats = $coefficient * $attaquant[$i]['valeur_attaque'] * (100 - $unites_desc_defenseur[$defenseur[$j]['type']][$attaquant[$i]['type_attaque']]) / 100 - $unites_desc_defenseur[$defenseur[$j]['type']]['armure'];
    		$attaquant[$i]['r'.$round] = 1;
    		if($degats > 0){ 		
    			$defenseur[$j]['vie'] -= $degats;
    			if($defenseur[$j]['vie'] <= 0)
    				unset($defenseur[$j]);
    		}
    		if($j == ($taille_def-1)){
    			$j=0;
    			$defenseur = array_values($defenseur);
    			$taille_def = count($defenseur);
    		}
    		$j++;
    		$i++;
     
    		}
     
    	}
     
    //Si les unités du defenseur sont plus nombreuses, alors le residu attaque sans resistances
    if($max == 'defenseur'){
     
    	//On remet d'aplomb le tableau du defenseur et le pointeur du defenseur à 0
    	$attaquant = array_values($attaquant);
    	$taille_att = count($attaquant);
    	$j=0;
     
    	while($i < $max_occ && !empty($attaquant)){
    		(mt_rand(1, 100) <= $unites_desc_defenseur[$defenseur[$i]['type']]['coup_critique']) ? $coefficient = 5 : $coefficient = 1;
    		$degats = $coefficient * $defenseur[$i]['valeur_attaque'] * (100 - $unites_desc_attaquant[$attaquant[$j]['type']][$defenseur[$i]['type_attaque']]) / 100 - $unites_desc_attaquant[$attaquant[$j]['type']]['armure'];
    		$defenseur[$i]['r'.$round] = 1;
    		if($degats > 0){ 		
    			$attaquant[$j]['vie'] -= $degats;
    			if($attaquant[$j]['vie'] <= 0)
    				unset($attaquant[$j]);
    		}
    		if($j == ($taille_att-1)){
    			$j=0;
    			$attaquant = array_values($attaquant);
    			$taille_att = count($attaquant);
    		}
    		$j++;
    		$i++;
     
    		}
     
    	}
     
     
    	//Remise à jour des tableaux pour utiliser mt_rand sur les clés sur les rounds suivants
    	if($round < 5){
    		$attaquant = array_values($attaquant);
    		$defenseur = array_values($defenseur);
    	}
     
    	$round++;
     
    }
    Voici la structure par exemple de mes tableaux $attaquant et $defenseur avant le combat :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
     
    Array
    (
        [0] => Array
            (
                [type] => fantassin_hallebarde
                [vie] => 220
                [valeur_attaque] => 0
                [type_attaque] => resistance_magique
                [r1] => 0
                [r2] => 0
                [r3] => 0
                [r4] => 0
                [r5] => 0
            )
     
        [1] => Array
            (
                [type] => arbaletrier
                [vie] => 275.00
                [valeur_attaque] => 11
                [type_attaque] => resistance_magique
                [r1] => 0
                [r2] => 0
                [r3] => 0
                [r4] => 0
                [r5] => 0
            )
     
        [2] => Array
            (
                [type] => arbaletrier
                [vie] => 275.00
                [valeur_attaque] => 11
                [type_attaque] => resistance_magique
                [r1] => 0
                [r2] => 0
                [r3] => 0
                [r4] => 0
                [r5] => 0
            )
     
        [3] => Array
            (
                [type] => cavalier_epee
                [vie] => 150
                [valeur_attaque] => 0
                [type_attaque] => resistance_magique
                [r1] => 0
                [r2] => 0
                [r3] => 0
                [r4] => 0
                [r5] => 0
            )
     
        [4] => Array
            (
                [type] => cavalier_epee
                [vie] => 150
                [valeur_attaque] => 0
                [type_attaque] => resistance_magique
                [r1] => 0
                [r2] => 0
                [r3] => 0
                [r4] => 0
                [r5] => 0
            )
     
    )
    Mon problème est la lenteur du code. Pour un combat de 100k vs 100k unités je mets 3s ce qui est trop. Cette lenteur est due à l'utilisation de la fonction array_values je pense qui soit dit en passant me bouffe pas mal de mémoire... J'utilise cette fonction pour boucler sur l'indice du tableau ayant le count le plus faible donc il me faut pas de "trou" dans mon indicage et comme je unset les unités mortes lors d'un round, je vois pas comment de pas m'en servir c'est pour cela que je fais appel à vous

    Je suis bien sur preneur de toute forme d'optimisation

Discussions similaires

  1. optimiser le code d'une fonction
    Par yanis97 dans le forum MS SQL Server
    Réponses: 1
    Dernier message: 15/07/2005, 08h41
  2. Optimiser mon code ASP/HTML
    Par ahage4x4 dans le forum ASP
    Réponses: 7
    Dernier message: 30/05/2005, 10h29
  3. optimiser le code
    Par bibi2607 dans le forum ASP
    Réponses: 3
    Dernier message: 03/02/2005, 14h30
  4. syntaxe et optimisation de codes
    Par elitol dans le forum Langage SQL
    Réponses: 18
    Dernier message: 12/08/2004, 11h54
  5. optimisation du code et var globales
    Par tigrou2405 dans le forum ASP
    Réponses: 2
    Dernier message: 23/01/2004, 10h59

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo