Sujet n°14290
Posté par Therand le 27 Déc - 13:10 (2014)
Titre : [Résolu]Vérificatin de retranscription d'un calcul...
Bonjour à tous!

Je suis actuellement en développement d'un parc safari pour PSP 0.7.
Il est fonctionnel à 99% et utilisable avec une seul variable et trois attaques à créer dans la BDD.

Mon souci est au niveau du calcul général, mon but est de faire le parc en génération 1,
J'ai trouvé un site ou le calcul est écrit en "texte", j'ai donc tenté de le transcrire en script.

Voici le texte provenant de du site (anglais):

Spoiler

At the start of an encounter, two counters - an "angry counter" and an "eating counter" - are set to 0. Whenever Bait is thrown, the angry counter is reset while the eating counter increases by a random value between 1 and 5 (but to no more than 255). The opposite occurs if a Rock is thrown: the eating counter is reset and the angry counter increases on the same basis. The catch rate is doubled (to no more than 255) whenever a Rock is thrown, but halved (rounded down) whenever Bait is thrown.

At the end of each turn, if either the angry or eating counter is nonzero, it is decreased by 1; if the angry counter is decreased to 0, the modified catch rate resets to the Pokémon's initial catch rate. A random value between 0 and 255 inclusive is generated, and if this is less than half of the Pokémon's Speed rounded down (if the Pokémon is eating), double the Speed (if the Pokémon is in a neutral state), or four times the Speed (if the Pokémon is angry), the Pokémon escapes. A Pokémon will also always escape if its Speed is 128 or more, even if it is eating.


Et voici la formule que j'ai déduit de cela:

Spoiler

Code:

#J'initialise mes compteurs au début
            @angry = 0 #Compteur de colère
            @eating = 0 #Compteur de faim
            @chance_safari = 0 # la multiplication par multiple de 2 de la chance de capture

#Quand on lance l'APPAT
            @angry = 0
            @eating += 1 + rand(5)
            @chance_safari / 2
             if@chance_safari == 0
               @chance_safari + 1
             end

#Quand on lance le CAILLOU
            @angry += 1 + rand(5)
            @eating = 0
            @chance_safari * 2
             if@chance_safari == 0
               @chance_safari + 1
             end

#Vous l'aurez compris, jusque ici mon
#-compteur de colère(angry) et augmenté d'une valeur aléatoire allant de 1 à 5 si un caillou est lancé.
#-compteur de faim(eating) et augmenté d'une valeur aléatoire allant de 1 à 5 si un appat est lancé.
#-@chance_safari me permet de multiplier le catch_rate par 2 à chaque caillou lancé (ball_rate *= chance_safari) dans le battle_wild.
#-le compteur @chance_safari est divisé par 2 si un appat est lancé, si ce compteur est à zero, on ajoute 1 (pour revenir au taux initial de la ball et éviter une division par zero).

#Ici on voit si c'est l'appat le caillou ou la ball lancé

# Le skill manger
      if @eating != 0
        @eating -= 1
        @enemy_skill = Skill.new(564)
      end

# Le skill furieux
      if @angry != 0
        @angry -=1
        @enemy_skill = Skill.new(566)
      end

# Pour le skill paisible (ball) la méthode est un peut différente car j'utilise une autre variable (@ball) qui est augmenté de 1 si le joueur lance la ball et rate la capture)
      if @ball == 1
        #Ici une action permettant d'aller à la réponse plus bas dans le script.
        end
      end

#Ensuite! Après la "réponse" de l’adversaire par rapport à l'action utilisé par le joueur (ball, caillou ou appat),
#on va déterminé si l'adversaire fuit ou non:

# On crée un nombre aléatoire entre 1 et 255.
                @decision_safari = 0
                @decision_safari += 1 + rand(255)

# Ensuite, on détermine l'action en fonction de:
# (Ne cherchez pas de correspondance entre les skill précédent, ces actions sont initialisée autrement et mettre tout le code serait inutile et nuirait à la compréhension du post,
# sachez juste que ces fonctions s’exécutent après le skill)

# Si l'adversaire mange (appat)
                if @decision_safari <= (@enemy.spd / 2) #
                scene = end_battle_flee_enemy
                end

# Si l'adversaire ne fait rien (comme après avoir raté la capture par exemple)
                if @decision_safari <= (@enemy.spd * 2)
                scene = end_battle_flee_enemy
                end

# Si l'adversaire est furieux (caillou)
                if @decision_safari <= (@enemy.spd * 4)
                scene = end_battle_flee_enemy
                end



Voila, merci de me dire se que vous pensez de ma déduction par rapport au texte, je ne suis pas bilingue, j'ai donc surement fait une erreur...
Pourquoi, par exemple, me faire faire une variable aléatoire quand on lance l'appat alors que simplement l'augmenter de un ou le mettre à zero aurait suffit..?

Merci et bonne journée à tous Clin d'œil foireux

Posté par Nuri Yuri le 27 Déc - 13:26 (2014)
Manque plus que le cas "Si la vitesse du Pokémon est supérieur à 128, il fuit même si il est entrain de manger"
Une valeur entre 0 et 255 inclut ça veut dire rand(256) et non 1 + rand(255)

Sinon, il te reste plus qu'à mettre ça aux bons endroits.

Posté par Therand le 27 Déc - 14:13 (2014)
Merci pour ta réponse!

En faite, tout est déjà bien en place et fonctionnel en l'état (3 scripts).
Ce que je ne comprend pas, c'est pourquoi réinitialiser le compteur appat/caillou si caillou/appat est lancé car du coup, lancer l'un annule l'autre..
Et pourquoi un rand 1 + 5 au compteur si ma condition futur est juste si compteur est différent de zero?

Merci pour l'erreur rand, je vais corriger cela.
Pour la vitesse, je vais faire une pré-condition:
if @enemy.spd <= 128
scene = end_battle_flee_enemy
else
#le déroulement classique des décisions enemy.
end

Posté par Nuri Yuri le 27 Déc - 14:27 (2014)
Supérieur ou égal c'est ">=".
Je viens de voir ça aussi :
@chance_safari * 2
Tout seul ça ne fait rien du tout.

Pour ta question sur 1 + rand(5), on ajoute un nombre entre 1 et 5, et à chaque tours le compteur descend, c'est ce qui permet de faire des probabilités correctes mais qui restent aléatoires.
Si tu commences à 0 et que ton compteur vaut 1, après la fonction, tu retournera à 0 et t'auras pas de chances.
Si tu commences à 0 et que ton compteur augmente à 5, après la fonction tu arriveras à 4 mais tu auras beaucoup plus de chances que dans le cas précédent.

Posté par Therand le 27 Déc - 14:36 (2014)
Heuuu oui >= pardon.
Mon @chance_safari est inclus dans le calcul de capture comme suit:

chance_safari = @chance_safari
# Calcul du premier flottant
a = Float(((maxhp * 3 - 2 * hp) * rareness * (ball_rate *= chance_safari) * status_multiplier)/(maxhp * 3))

Comme cela, le ball_rate est doublé à chaque fois (dis moi si je me trompe pas ^^)
Sinon merci pour le reste, si tu confirme ça je valide mon script :p

Je vais faire un petit sondage voir si le script intéresse quelqu'un et pour le présenter un peu.

Posté par Nuri Yuri le 27 Déc - 15:44 (2014)
Ton calcul risque pas de toujours valoir zéro ?

Posté par Therand le 27 Déc - 18:35 (2014)
Pour la capture, je ne l'ai pas mis en entier sur le forum, car la suite du calcul est la même que dans le battle_wild.
Je voulais juste exposer la méthode utilisé pour doubler le drop_rate (@chance_safari)

"a" est ensuite calculé normalement.
D'après mes test, le drop_rate se double comme voulu..

Posté par Nuri Yuri le 27 Déc - 18:47 (2014)
Si ça fonctionne il n'y a pas de problèmes alors :p

Posté par Therand le 27 Déc - 20:41 (2014)
Bha je sais pas, j'ai peut etre fait une erreur, voila le calcul entier

Code:

maxhp             = @enemy.maxhp_basis.to_f   
hp                = @enemy.hp.to_f   
rareness          = @enemy.rareness.to_f   
ball_rate         = 1.5.to_f 
status_multiplier = status_multiplier.to_f   
chance_safari     = @chance_safari
         
# Calcul du premier flottant
a = Float(((maxhp * 3 - 2 * hp) * rareness * (ball_rate *= chance_safari) * status_multiplier)/(maxhp * 3))   
         
if a >= 255 # Le Pokémon est capturé   
  j = 4   
else           # Deuxième chance de capture   
  b = 65535.0 * Math.sqrt(Math.sqrt(a/255.0))   
  j = 0        # Initialement, la ball ne bouge pas.   
  for i in 0...4   
    if rand(65535) <= b   # Ajoute un mouvement de la ball pour chaque nombre aléatoire en dessous de b   
      j += 1                    # Il y a une chance pour qu'ils soient tous en dessous de b et que le Pokémon soit capturé au rattrapage (comme au bac)   
    end   
  end   
end 


J'ai testé avec des "print", le calcul semblait bon,
en jeu sa donnait +/- 1 chance sur 3 de capturer un mystherbe lvl 5 avec la safari ball (X1.5 drop_rate)
Je ferais les derniers test très bientôt du coup ^^
Merci

Posté par Zohran le 3 Jan - 21:09 (2015)
Ton problème est résolu?

Posté par Therand le 4 Jan - 16:42 (2015)
Oui oui, j'avais légèrement oublié ce topic à vrai dire.
Deux trois erreurs de signe dans mes calculs (*= au lieu de * dans la capture, et un ou deux autres)

Sinon tout fonctionne et peux être testé: ICI
Les erreurs sont corrigés dans les scripts.