Sujet n°13210
Posté par Ku'rei le 1 Oct - 10:47 (2013)
Titre : Capture un peu trop facile
Bonjour,

Je créer ce sujet pour notifier la communauté d'un problème concernant la capture des Pokémon (je suis sous PSP 4G+ à la base, mais je n'ai pas touché aux scripts de calculs je le jure). Bref la situation, je fais tester le min projet à un pote, tout fièr de lui avoir mis des Rhinoféros niveau 97 pour lui barrer la route et là ... PAF ! Il lui balance une super ball dans un dernier geste de panique, ... Et hop ! Le Rhinoféros est capturé ... Niveau 97 ... Toutes sa vie... Aucun statut ...
Ca encore ça passe, mais quand il arrivait pas à attraper un Evoli niveau 19 a un tour de mourrir du poison...

Voilà, j'ai quand même jeter un coup d'oeil à la méthode de calcul de la capture mais déjà qu'écris à la main la méthode n'est pas simple, imaginez en ruby ^^ C'etait pour savoir si d'autres que moi avait le même problème, et pour encourager les motivés à revoir le code de capture Imbécile heureux

Jovialement,
Ku'rei

Posté par Girakoth le 1 Oct - 17:09 (2013)
Bah c'est tout à fait possible après, je me souviens avoir capturé un Rhinoféros niv.67 dans la Grotte Azurée, dans Pokémon Bleu.
J'avais utilisé une PokéBall et il avait aussi toute sa vie, je m'étais trompé d'objet sur le coup XD

Posté par TouzaxA le 1 Oct - 17:15 (2013)
Moi, j'appelle ça un coup de bol. Mais après, tu peux faire un nouvel algo que tu pourrais proposer à la communauté. Imbécile heureux

Posté par Pαlвσlѕку le 1 Oct - 17:32 (2013)
J'ai déjà attrapé Rayquaza avec une Pokéball, mais il était pas full PV (c'était l'inverse :D).

Je vais jeter un coup d'œil au calcul mais je pense qu'il est bon.

Posté par Ku'rei le 1 Oct - 17:35 (2013)
Ouai, fin le suivant, il a attrapé les deux suivant en 4 balls sans leurs faire baisser les PV ^^ A moins que ce soit un monstre chanceux je crois qu'il y a un probleme.

Merci Palb Imbécile heureux Je pense qu'il est bon aussi mais on ne sais jamais.

Posté par Pαlвσlѕку le 1 Oct - 18:03 (2013)
On dirait bien qu'il y a un problème :

Code de base présent dans PSP 0.7 (script Pokémon Battle Wild vers ligne 470) :
Code:
      multiplier = @enemy.rareness * (ball_rate)
      maxhp = @enemy.maxhp_basis
      hp = @enemy.hp
      catch_rate = Integer((((maxhp * 3 - hp * 2)*multiplier).to_f/(maxhp*3).to_f)*status_multiplier)
      catch_value = Integer(1048560 / (Math.sqrt(Math.sqrt(16711680/catch_rate.to_f))))

Ce n'est que le morceau le plus important.

Le problème ce que par rapport à cette source (Ici), il semblerait que le calcul de catch_value soit erroné.

Si je ne me trompe pas, voilà le calcul juste :
Code:
catch_value = Integer(65535*Math.sqrt(Math.sqrt(catch_rate.to_f/255)))


J'ai testé avec les deux calculs différents, la correction rend le Pokémon bien plus dur à attraper.
Sur un Nirondelle niveau 14, 5 tentatives pour l'attraper.

Avec l'ancien calcul, j'ai fais deux combats et réussi à l'attraper du premier coup à chaque fois.

Si tu pouvais essayer de ton coté, surtout ton pote, histoire de voir ce que ça donne. Imbécile heureux

PS : J'ai supprimé ton autre compte. Pas trop mal à la tête ? Imbécile heureux

Posté par Ku'rei le 1 Oct - 19:09 (2013)
Yes, dans le doute j'ai tout réécris et commenté (m'énerve Krosk quand il commente pas ses script on y comprend rien ^^)
Du coup je remplace :
Code:
multiplier = @enemy.rareness * (ball_rate)
maxhp = @enemy.maxhp_basis
hp = @enemy.hp
catch_rate = Integer((((maxhp * 3 - hp * 2)*multiplier).to_f/(maxhp*3).to_f)*status_multiplier)
catch_value = Integer(1048560 / (Math.sqrt(Math.sqrt(16711680/catch_rate.to_f))))
list = [rand(65536), rand(65536), rand(65536), rand(65536)]
j = 4 # nombre de fois que la balle oscille
for i in list
  j -= i > catch_value ? 1 : 0
end

par
Code:
# Calcul des la possibilité de capture.
# Source : Poképedia (http://www.pokepedia.fr/index.php/Capture_des_Pok%C3%A9mon)
# Conversion des valeurs utilisé en flottant
maxhp             = @enemy.maxhp_basis.to_f
hp                = @enemy.hp.to_f
rareness          = @enemy.rareness.to_f
ball_rate         = ball_rate.to_f
status_multiplier = status_multiplier.to_f
     
# Calcul du premier flottant (
a = Float(((maxhp * 3 - 2 * hp) * rareness * ball_rate * 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
#print(a, ", ", b, ", ", j, " / ", rareness, ", ", status_multiplier, ", ", ball_rate) # DEBUG


Ca marche bien, j'ai essayé sur plussieurs niveau et puissance de Pokémon, on retrouve la difficulté du jeu officiel. Sauf qu'on est toujours à environ (1/2)**4 soit 1 chances sur 16 de capturer mes Rhinoféros niveau 90 avec un Pokéball en début de combat... J'enrage !!! Quand je pense qu nombre de ball que j'ai passé sur Rayquaza et Mewtwo... Je vais les rendre incapturable ...

REPONSE PS : Merci Imbécile heureux Juste fatigué de la nuit blanche ^^ Mais plus jamais l'alcool, c'est trop relou le lendemain...

Posté par Pαlвσlѕку le 1 Oct - 19:45 (2013)
C'est du bon boulot. Imbécile heureux

Normalement ça doit pouvoir se mettre dans toutes les versions de PSP, sauf peut-être PSP4G+ avec le système de vol de Pokémon.

Le meilleur moyen pour savoir si la formule fonctionne bien c'est d'essayer la formule de probabilité donnée sur Poképédia.

PS : Une question d'habitude. Imbécile heureux

Posté par Ku'rei le 1 Oct - 20:06 (2013)
Merci,

Pour le système de vol; un copier/coller pour remplacer l'algo existant ligne 591 de Pokemon_Battle_Trainer et le tour est joué.

Oui en effet, ... Mais bon, ce qui me gène c'est la probabilité jamais nulle. Je suis pas le seul qui trouve ça dérangeant de pouvoir capturer des Pokémon nv 100 avec une Pokéball, non ?

PS : Oui, ou de choix. J'ai choisi pouvoir m’entraîner tout les jours ^^

Posté par Nuri Yuri le 1 Oct - 22:32 (2013)
Poképedia c'est le mal, il y a des erreurs partout, c'est pas une bonne idée de suivre ce qu'ils écrivent :/
Enfin bref, tant que ça fonctionne à peu près correctement. (Sinon Float() n'est pas très utile dans ton script.)

Posté par Sphinx le 2 Oct - 03:52 (2013)
Pαlвσlѕку a écrit:
Normalement ça doit pouvoir se mettre dans toutes les versions de PSP, sauf peut-être PSP4G+ avec le système de vol de Pokémon.


Ku'rei Jinwu a écrit:
Pour le système de vol; un copier/coller pour remplacer l'algo existant ligne 591 de Pokemon_Battle_Trainer et le tour est joué.

Je confirme que c'est aussi simple que ca ^o^ La méthode doit d'ailleurs porter le même nom (il y a bien cependant quelques différences entre la capture de pokémons sauvages et la capture de pokémons dressés, mais le calcul de probabilité de capture reste +/- le même ^o^)

Posté par Ku'rei le 2 Oct - 07:50 (2013)
Plus ou moins ? Tu as changer quoi ?

Posté par joeyw le 9 Oct - 11:49 (2013)
J'ai vérifié la formule (ici, celle des 3G et 4G) sur Bulbapédia et c'est la même que sur Poképedia, je pense qu'on peut donc avoir confiance.
Par contre je suis d'accord avec Ku'rei Jinwu : j'ai changé la formule et j'ai capturé le fameux Rhinoferos niveau 97 avec ma 2e Super Ball... C'est troublant, surtout que le niveau du Pokémon n'est pas pris en compte dans la formule Imbécile heureux

Après un rapide coup d'oeil sur la fiche de Rhinoferos, le catch rate de base (Pokéball + santé maximum) est de 7.8%. Ahaha 42
Qui veut tenter le Arceus, Mewtwo ou Rayquaza à 0,4% ? Imbécile heureux

Posté par Gold le 9 Oct - 17:06 (2013)
En ce moment je fais des corrections mineures de scripts pour PSP 0.8 en me basant sur le boulot de la commu, alors voici ma question : Quel script doit être modifié ?

Posté par Ku'rei le 9 Oct - 18:18 (2013)
Pokemon Battle Wild, ligne 550 environ :
Remplace
Code:
multiplier = @enemy.rareness * (ball_rate)
      maxhp = @enemy.maxhp_basis
      hp = @enemy.hp
      catch_rate = Integer((((maxhp * 3 - hp * 2)*multiplier).to_f/(maxhp*3).to_f)*status_multiplier)
      catch_value = Integer(1048560 / (Math.sqrt(Math.sqrt(16711680/catch_rate.to_f))))
      list = [rand(65536), rand(65536), rand(65536), rand(65536)]
      j = 4 # nombre de fois que la balle oscille
      for i in list
        j -= i > catch_value ? 1 : 0
      end

par
Code:
# Calcul des la possibilité de capture. 
# Source : Poképedia (http://www.pokepedia.fr/index.php/Capture_des_Pok%C3%A9mon) 
# Conversion des valeurs utilisé en flottant 
maxhp             = @enemy.maxhp_basis.to_f 
hp                = @enemy.hp.to_f 
rareness          = @enemy.rareness.to_f 
ball_rate         = ball_rate.to_f 
status_multiplier = status_multiplier.to_f 
       
# Calcul du premier flottant ( 
a = Float(((maxhp * 3 - 2 * hp) * rareness * ball_rate * 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 
#print(a, ", ", b, ", ", j, " / ", rareness, ", ", status_multiplier, ", ", ball_rate) # DEBUG 

Posté par Sphinx le 9 Oct - 22:04 (2013)
Pour 4G+, faut aussi changer Pokemon_Battle_Trainer, sachant que la méthode de capture intègre en plus un aléa qui donne une chance à l'IA de protéger ses pokémons