mirror of
https://github.com/veekun/pokedex.git
synced 2024-08-20 18:16:34 +00:00
Fix breeding gender restrictions. More tests.
This commit is contained in:
parent
17df21b420
commit
2862444402
2 changed files with 33 additions and 24 deletions
|
@ -5,7 +5,7 @@ from pokedex.tests import single_params
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
from pokedex.db import connect
|
from pokedex.db import connect
|
||||||
from pokedex.util.movesets import main
|
from pokedex.util.movesets import main, print_result
|
||||||
|
|
||||||
result_map = {'OK': True, 'NO': False}
|
result_map = {'OK': True, 'NO': False}
|
||||||
session = connect()
|
session = connect()
|
||||||
|
@ -59,9 +59,12 @@ OK deoxys superpower amnesia spikes taunt
|
||||||
OK deoxys counter extremespeed spikes pursuit
|
OK deoxys counter extremespeed spikes pursuit
|
||||||
OK pikachu reversal bide nasty-plot discharge
|
OK pikachu reversal bide nasty-plot discharge
|
||||||
NO pikachu surf charge
|
NO pikachu surf charge
|
||||||
|
NO nosepass head-smash
|
||||||
OK pikachu volt-tackle encore headbutt grass-knot
|
OK pikachu volt-tackle encore headbutt grass-knot
|
||||||
#OK suicune extremespeed dig icy-wind bite
|
#OK suicune extremespeed dig icy-wind bite
|
||||||
NO nidoran-m horn-drill head-smash -l 5 -v platinum --pomeg-glitch
|
NO nidoran-m horn-drill head-smash -l 5 -v platinum --pomeg-glitch
|
||||||
|
NO bulbasaur charm skull-bash
|
||||||
|
NO chansey aromatherapy counter copycat
|
||||||
""".strip().splitlines()
|
""".strip().splitlines()
|
||||||
|
|
||||||
@single_params(*argstrings)
|
@single_params(*argstrings)
|
||||||
|
@ -73,7 +76,10 @@ def test_moveset(argstring):
|
||||||
xfail = False
|
xfail = False
|
||||||
args = argstring.strip().split() + ['-q']
|
args = argstring.strip().split() + ['-q']
|
||||||
try:
|
try:
|
||||||
assert bool(main(args[1:], session=session)) == result_map[args[0]]
|
result = main(args[1:], session=session)
|
||||||
|
if result and not result_map[args[0]]:
|
||||||
|
print_result(result)
|
||||||
|
assert bool(result) == result_map[args[0]]
|
||||||
except AssertionError:
|
except AssertionError:
|
||||||
if xfail:
|
if xfail:
|
||||||
pytest.xfail()
|
pytest.xfail()
|
||||||
|
|
|
@ -123,6 +123,8 @@ class MovesetSearch(object):
|
||||||
self.goal_evolution_chain, 'family')
|
self.goal_evolution_chain, 'family')
|
||||||
|
|
||||||
# Hard moves: ones we have to breed for or do somehing even costlier
|
# Hard moves: ones we have to breed for or do somehing even costlier
|
||||||
|
# (we might also have to breed for the easy moves, but only within
|
||||||
|
# the family)
|
||||||
self.hard_moves = self.goal_moves - easy_moves
|
self.hard_moves = self.goal_moves - easy_moves
|
||||||
self.egg_moves = self.goal_moves - non_egg_moves
|
self.egg_moves = self.goal_moves - non_egg_moves
|
||||||
if self.hard_moves:
|
if self.hard_moves:
|
||||||
|
@ -372,8 +374,9 @@ class MovesetSearch(object):
|
||||||
groups = (g1, g2) if g2 else (g1, )
|
groups = (g1, g2) if g2 else (g1, )
|
||||||
if len(self.egg_groups.get(evolution_chain, ())) <= len(groups):
|
if len(self.egg_groups.get(evolution_chain, ())) <= len(groups):
|
||||||
self.egg_groups[evolution_chain] = groups
|
self.egg_groups[evolution_chain] = groups
|
||||||
for group in groups:
|
if not parent:
|
||||||
self.babies[group].add(pokemon)
|
for group in groups:
|
||||||
|
self.babies[group].add(pokemon)
|
||||||
self.evolution_chains[pokemon] = evolution_chain
|
self.evolution_chains[pokemon] = evolution_chain
|
||||||
self.pokemon_by_evolution_chain[evolution_chain].add(pokemon)
|
self.pokemon_by_evolution_chain[evolution_chain].add(pokemon)
|
||||||
if parent:
|
if parent:
|
||||||
|
@ -1050,6 +1053,11 @@ class PokemonNode(Node, Facade, namedtuple('PokemonNode',
|
||||||
# It doesn't make sense to train this any more, since there's
|
# It doesn't make sense to train this any more, since there's
|
||||||
# no way to pass the moves to the goal pokemon.
|
# no way to pass the moves to the goal pokemon.
|
||||||
return ()
|
return ()
|
||||||
|
gender_rate = search.gender_rates[evo_chain]
|
||||||
|
if gender_rate == 8 or gender_rate < 0:
|
||||||
|
# Female-only and genderless pokémon can not pass moves down at
|
||||||
|
# all.
|
||||||
|
return ()
|
||||||
if len(self.moves_) == 4:
|
if len(self.moves_) == 4:
|
||||||
learns = ()
|
learns = ()
|
||||||
else:
|
else:
|
||||||
|
@ -1224,35 +1232,30 @@ class PokemonNode(Node, Facade, namedtuple('PokemonNode',
|
||||||
if search.generation_id_by_version_group[self.version_group_] == 1:
|
if search.generation_id_by_version_group[self.version_group_] == 1:
|
||||||
return
|
return
|
||||||
evo_chain = search.evolution_chains[self.pokemon_]
|
evo_chain = search.evolution_chains[self.pokemon_]
|
||||||
|
gender_rate = search.gender_rates[evo_chain]
|
||||||
|
if gender_rate == 8 or gender_rate < 0:
|
||||||
|
# Female-only and genderless pokémon can not pass moves down at
|
||||||
|
# all.
|
||||||
|
return
|
||||||
egg_groups = search.egg_groups[evo_chain]
|
egg_groups = search.egg_groups[evo_chain]
|
||||||
breeds_required = search.breeds_required
|
breeds_required = search.breeds_required
|
||||||
moves = self.moves_
|
moves = self.moves_
|
||||||
cost = search.costs['breed']
|
cost = search.costs['breed']
|
||||||
cost += search.costs['egg'] * len(moves)
|
cost += search.costs['egg'] * len(moves)
|
||||||
cost += search.costs['breed-penalty'] * len(search.egg_moves - moves)
|
cost += search.costs['breed-penalty'] * len(search.egg_moves - moves)
|
||||||
gender_rate = search.gender_rates[evo_chain]
|
|
||||||
goal_family = search.goal_evolution_chain
|
goal_family = search.goal_evolution_chain
|
||||||
goal_groups = search.egg_groups[goal_family]
|
goal_groups = search.egg_groups[goal_family]
|
||||||
goal_compatible = set(goal_groups).intersection(egg_groups)
|
goal_compatible = set(goal_groups).intersection(egg_groups)
|
||||||
if 0 < gender_rate:
|
for group in egg_groups:
|
||||||
# Only pokemon that have males can pass down moves to other species
|
if moves in breeds_required[group]:
|
||||||
# (and the other species must have females: checked in BreedNode)
|
yield cost, None, BreedNode(search=self.search, dummy='b',
|
||||||
for group in egg_groups:
|
group_=group, version_group_=self.version_group_,
|
||||||
if moves in breeds_required[group]:
|
moves_=self.moves_)
|
||||||
yield cost, None, BreedNode(search=self.search, dummy='b',
|
# Since the target family is not included in our breed graph, we
|
||||||
group_=group, version_group_=self.version_group_,
|
# breed with it explicitly. There must be a female to breed with,
|
||||||
moves_=self.moves_)
|
# unless this is already the target family so we can breed w/ Ditto.
|
||||||
# Since the target family is not included in our breed graph, we
|
if goal_compatible and (goal_family == evo_chain or
|
||||||
# breed with it explicitly. But again, there must be a female to
|
0 <= search.gender_rates[search.goal_evolution_chain] < 8):
|
||||||
# breed with.
|
|
||||||
if goal_compatible and search.gender_rates[
|
|
||||||
search.goal_evolution_chain] < 8:
|
|
||||||
yield cost, None, GoalBreedNode(search=self.search, dummy='g',
|
|
||||||
version_group_=self.version_group_, moves_=self.moves_)
|
|
||||||
elif evo_chain == search.goal_evolution_chain:
|
|
||||||
# Single-gender & genderless pokemon can pass on moves via
|
|
||||||
# breeding with Ditto, to produce the same species again. Obviously
|
|
||||||
# this is only useful when breeding the goal species.
|
|
||||||
yield cost, None, GoalBreedNode(search=self.search, dummy='g',
|
yield cost, None, GoalBreedNode(search=self.search, dummy='g',
|
||||||
version_group_=self.version_group_, moves_=self.moves_)
|
version_group_=self.version_group_, moves_=self.moves_)
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue