Git Product home page Git Product logo

showdown's People

Contributors

andyloris avatar dependabot[bot] avatar dpmaloney avatar github-actions[bot] avatar harounans avatar infinitepower18 avatar mixone-finallyhere avatar nailec avatar niklasriewald avatar pmariglia avatar pswan19 avatar somerandomguy009 avatar viitrexx avatar wtfseanscool avatar yuzeh avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

showdown's Issues

in the Nash-equilibrium mode the bot makes very questionable decisions. is this intentional?

here are some examples.

a. after rilllaboom gets choice band locked into drain punch and opponent goes to a ghost type it keeps using drain punch even though the opponent is immune
b. if a pokemon's only attack is a move that has an immunity ex. ground againist flying, and the pokemon is facing said type it will keep using the move that is immune instead of switching or using a utility move.
ex. a hippowdon
-slack off
-whirlwind
-stealth rocks
-earthquake
againist a pelipper would spam EQ even though it was immune,
c.when i had my rillaboom up againist a heatran it sacked melmetal and brang rillaboom back in resulting in both of them getting OHKO'd
d. when there was a Tapu KoKo as my opponent the bot brought out slowbro and dragonite before rillaboom which would've easily KO'd with grassy glide
e. the bot spams future sight consecutively as if it thinks its a insta damage psychic move.
f. a pokemon has regenerator and a swicth out move ex. u-turn and is faster then the opposing pokemon the bot will opt to hard switch instead of getting free chip againist the oposing pokemon by using for example u-turn.
g. tried to toxic a mon that already has a status condition
h. when out of damaging moves will spam status move instead of switching out allowing opponent to set up with swords dance, quiver dance etc
i. doesn't recognize magic bounce and spams status moves
j. went for a dragon move against a fairy type when an ice move was available

if you got here thanks for taking time to read the whole list :)

How does this work?

I know i have been annoying with all these issues but i am curious to know, how all of this works. I have gone through the code for 2 hours straight but i couldn't understand much, especially how it retrieves the data and executes the moves.
Can you point me to any tutorials or explain it yourself?
Discord if you want to message me there: ☙ Surya ❧#8330
Thankyou

challenge user mode not working?

Trying to set up two bots to fight each other in gen8ou to get data for move accuracy.

Have each bot running in their own docker instance on two separate VMs. Confirmed that the bots work fine in ladder mode and accept_challenge mode. But neither can send challenges

Cases I tried:

  1. Sending challenge to human account (none received)
  2. sending challenge to another bot (not received)
  3. separate IPs for bot and human account (not received)
  4. same IPs for bot and human (not received)
  5. changing game mode to gen8randombattle for each of the above cases
  6. removing "Team_Name" line and trying above cases

Here is the ENV file I have set up
image

Probably just me being dumb but...

Basically I was trying to get the bot working using Heroku and it went well until after I deployed it and went into the "Resources" tab. There I clicked on the "Open App" button and I see this (I'm assuming I clicked the wrong thing lol)
image

(hope the image works... it just shows a link for me)

Did something go wrong or was I just dumb?

Bot doesn't see it's regenerator heal

There is no message from the PS server that a Pokemon has healed from switching out when it has regenerator. This is just something that the PS client does visually the user's side when you 100% know that your Pokemon has regenerator.

The module that tracks the battle's state needs to give the heal to the bot's side at the very least. Optionally, it can also give the heal to the opponent's side if it knows that the opponent has regenerator.

Inferring choicescarf fails if opponent knocks out the bot's Pokemon

This line in the check_choicescarf function causes the check to exit early when exactly 2 moves are not found from the turn's log. This means that if both Pokemon select a same-priority move but the opponent (being faster) knocks out the bot's pokemon before the bot's pokemon gets a chance to move, then the check is stopped when in reality there is enough information to infer a choicescarf from the turn.

Checking for exactly 2 moves was done so that if either side decided to switch, this check wouldn't be done.

Here is an example test that will need to be included in a commit fixing this. It should be put in this test class

    def test_guess_choicescarf_when_opponent_knocks_out_the_bots_pokemon(self):
        self.battle.user.active.stats[constants.SPEED] = 210  # opponent's speed should not be greater than 207 (max speed caterpie)

        messages = [
            '|move|p2a: Caterpie|Tackle|',
            '|-damage|p1a: Caterpie|0 fnt',
            '|faint|p1a: Caterpie',
            '|',
            '|upkeep',
        ]

        check_choicescarf(self.battle, messages)

        self.assertEqual('choicescarf', self.battle.opponent.active.item)

There are undoubtedly more edge-cases to test - this is just one example. The actual solution will require far more tests. For example: a move versus a switch-out.

/hideroom prevents the bot from acting

What the title says, if you use the command /hideroom the bot stops acting for the rest of the game (which means after the bot loses because of timeout), i have been trying to do something about this but my knowledge isn't enough to understand how this bot works. I'm still trying to figure how and why and any help will be much appreciated. I'm posting this here because it seems relevant enough.

Steps to reproduce: Just use /hideroom when facing a bot.

Any public ranking available for all known battle bots?

Hi,

just heard for the first time about Pokemon showdown and initiatives similar like yours to develop an almighty battle bot: the one that'll defeat 'em all!
Are you guys gathering every known bot's performance into a single Top Bots Elo Ranking board by any chance? I can't get an overview of all the past and ongoing bots and how they eventually perform against real players.

Thanks!

Get link of saved battle

The link of a saved battle is not displayed, and it is difficult to get the link because when spectators are disabled, which is the default, the replay link has a code of random characters in it. I'm not experienced with the web socket stuff and I don't want to get into it.

Error when running python run.py

Traceback (most recent call last):
File "C:\Users\who\Downloads\showdown-master\showdown-master\run.py", line 111, in
asyncio.get_event_loop().run_until_complete(showdown())
File "C:\Users\who\AppData\Local\Programs\Python\Python39\lib\asyncio\base_events.py", line 642, in run_until_complete
return future.result()
File "C:\Users\who\Downloads\showdown-master\showdown-master\run.py", line 70, in showdown
parse_configs()
File "C:\Users\who\Downloads\showdown-master\showdown-master\run.py", line 36, in parse_configs
config.username = env("PS_USERNAME")
File "C:\Users\whoAppData\Local\Programs\Python\Python39\lib\site-packages\environs_init_.py", line 80, in method
raise EnvError('Environment variable "{}" not set'.format(proxied_key or parsed_key))
environs.EnvError: Environment variable "PS_USERNAME" not set

whats wrong :(

also, how do i create an .env file? do i right click and create text document and name it .env?

Ditto is breaking the bot when it transforms

My bot breaks anytime the user transforms with ditto:

[battle_modifier]        [DEBUG]    Opponent has switched - clearing the last used move
[battle_modifier]        [DEBUG]    Opponent ditto transformed into dracozolt
Traceback (most recent call last):
  File "run.py", line 115, in <module>
    asyncio.get_event_loop().run_until_complete(showdown())
  File "/usr/lib/python3.6/asyncio/base_events.py", line 484, in run_until_complete
    return future.result()
  File "run.py", line 96, in showdown
    winner = await pokemon_battle(ps_websocket_client, config.pokemon_mode)
  File "/showdown/showdown/run_battle.py", line 170, in pokemon_battle
    action_required = await async_update_battle(battle, msg)
  File "/showdown/showdown/battle_modifier.py", line 772, in async_update_battle
    return update_battle(battle, msg)
  File "/showdown/showdown/battle_modifier.py", line 753, in update_battle
    function_to_call(battle, split_msg)
  File "/showdown/showdown/battle_modifier.py", line 557, in transform
    battle.opponent.active.stats = deepcopy(transformed_into.stats)
AttributeError: 'NoneType' object has no attribute 'stats'

image

I'm not sure if this is replicatable. I did make some changes on my fork but I'm not sure if they're causing this. It may be the nicknames that break it. Theres a line of code that says:

if battle_copy.user.active.name == transformed_into_name or battle_copy.user.active.name.startswith(transformed_into_name):
            transformed_into = battle_copy.user.active

It might be the nicknames that is messing up the bot.

Bot runs out of time at search depth above 2

Not sure why, but the bot runs pretty much instantaneously at a search depth of 2, but when I change it to 3 in config.py, it bogs down to the point where within a few turns, it loses on time. I might be wrong, but this feels like a bug to me, even if the increase in time is exponential per search depth, going from 0-2 seconds per move to 100+ seconds seems excessive. If not, perhaps the bot could detect when the timer is close to running out and reduce search depth at that point?

This occurs regardless of battle_bot mode, and regardless of whether I run locally or on Docker.

Bot uses ground move on pokemon with levitate

I had a pokemon with earthquake and it used earthquake on a rotom with levitate
but all the next turns it used that same move again and again and again
even though the other pokemon had levitate

Free for all

Add Support for free for all battles. I think it might kind of difficult to track all pokemon though but u could make it try to predict what pokemon attacks which and make act accordingly there might also be other challenges though

PP management with engine

Hello! I have been using your showdown engine and it's really cool. I just had a quick question- is PP management implemented? It looks like PP management isn't an "instruction" from giving a move, and also "Side" methods like get_self_options don't check if a move is out of PP, but rather if a move is disabled. Do I need to manually reduce a move's PP count by changing it in mutator.state, and then disable the move if the PP is 0, or is that functionality already there somewhere with the engine? Thanks!

Natures aren't being imported from Team-Converter

Errors in line 125, 126 of team_converter.py, boolean is never coming out as true when importing teams directly from showdown team import/export. Tried 'Nature', ' Nature', 'Nature ', and ' Nature '.

Bot not utilizing Dynamax

Playing gen8battlestadiumsingles on the default bot and through 10 games, Dynamax has not been used.

Issue building docker container

I get this error when I run docker build . -t showdown
Need to get 65.5 MB of archives. After this operation, 160 MB of additional disk space will be used. Err:1 http://archive.ubuntu.com/ubuntu bionic-updates/main amd64 libpython3.6-minimal amd64 3.6.8-1~18.04.1 404 Not Found [IP: 91.189.88.31 80] Err:2 http://archive.ubuntu.com/ubuntu bionic-updates/main amd64 python3.6-minimal amd64 3.6.8-1~18.04.1 404 Not Found [IP: 91.189.88.31 80] Get:3 http://archive.ubuntu.com/ubuntu bionic-updates/main amd64 python3-minimal amd64 3.6.7-1~18.04 [23.7 kB] Get:4 http://archive.ubuntu.com/ubuntu bionic/main amd64 mime-support all 3.60ubuntu1 [30.1 kB] Get:5 http://archive.ubuntu.com/ubuntu bionic/main amd64 libmpdec2 amd64 2.4.2-1ubuntu1 [84.1 kB] Err:6 http://archive.ubuntu.com/ubuntu bionic-updates/main amd64 libpython3.6-stdlib amd64 3.6.8-1~18.04.1 404 Not Found [IP: 91.189.88.31 80] Err:7 http://archive.ubuntu.com/ubuntu bionic-updates/main amd64 python3.6 amd64 3.6.8-1~18.04.1 404 Not Found [IP: 91.189.88.31 80]
.
.
.
E: Failed to fetch http://archive.ubuntu.com/ubuntu/pool/main/p/python3.6/libpython3.6-minimal_3.6.8-1~18.04.1_amd64.deb 404 Not Found [IP: 91.189.88.31 80] E: Failed to fetch http://archive.ubuntu.com/ubuntu/pool/main/p/python3.6/python3.6-minimal_3.6.8-1~18.04.1_amd64.deb 404 Not Found [IP: 91.189.88.31 80] E: Failed to fetch http://archive.ubuntu.com/ubuntu/pool/main/p/python3.6/libpython3.6-stdlib_3.6.8-1~18.04.1_amd64.deb 404 Not Found [IP: 91.189.88.31 80] E: Failed to fetch http://archive.ubuntu.com/ubuntu/pool/main/p/python3.6/python3.6_3.6.8-1~18.04.1_amd64.deb 404 Not Found [IP: 91.189.88.31 80] E: Failed to fetch http://archive.ubuntu.com/ubuntu/pool/main/p/python3-stdlib-extensions/python3-lib2to3_3.6.8-1~18.04_all.deb 404 Not Found [IP: 91.189.88.31 80]

Im not exactly sure whats going on

Abstract bot class to allow extension with other decision methods

Currently, decision and state processing logic are tightly coupled. I suggest we rework this logic to allow a superclass to be defined which handles all decision logic.

This superclass should not handle modifying or determining what's allowed in our current state. Ideally, it's only given information and constraints on our current state. Each turn, the superclass will be asked to make a decision based on whatever criteria.

This extension will allow this project to be used with other methods of selecting the best move. In particular, I'm interested in extending this project using Reinforcement Learning but this is difficult without some rework of the current code. I will be willing to work on this rework myself, but I need information on the classes I should touch as well as the structure that is preferred for this project. I want to make sure this feature is implemented in a way where it's aligned with the project's goal.

Only sends 1 move at a time for doubles

When trying to run this in doubles (specifically vgc) it does not move because it requires a move sent from each pokemon with a slot chosen. Is there going to be support for doubles in the future?

Error examples:
|error|[Invalid choice] Can't move: Poison Jab needs a target
|error|[Invalid choice] Incomplete choice: move blizzard - missing other pokemon
|error|[Invalid choice] Incomplete choice: switch 4 - missing other pokemon

KeyError: 'pikachusinnoh'

Hey! Nice work on this :)

Trying to evaluate your bot on something I've been working on in the past year, and it looks like its dex is missing a few entries :\

Traceback (most recent call last):
  File "run.py", line 91, in <module>
    asyncio.get_event_loop().run_until_complete(showdown())
  File "/Users/Dan/miniconda2/envs/pmariglia-showdown/lib/python3.7/asyncio/base_events.py", line 584, in run_until_complete
    return future.result()
  File "run.py", line 60, in showdown
    winner = await pokemon_battle(ps_websocket_client, is_random_battle)
  File "/Users/Dan/projects/pkmn/pmariglia-showdown/showdown/run_battle.py", line 168, in pokemon_battle
    action_required = await update_battle(battle, msg)
  File "/Users/Dan/projects/pkmn/pmariglia-showdown/showdown/state/battle_modifiers.py", line 336, in update_battle
    function_to_call(battle, split_msg)
  File "/Users/Dan/projects/pkmn/pmariglia-showdown/showdown/state/battle_modifiers.py", line 55, in switch_or_drag
    pkmn = Pokemon.from_switch_string(split_msg[3])
  File "/Users/Dan/projects/pkmn/pmariglia-showdown/showdown/state/pokemon.py", line 47, in from_switch_string
    return Pokemon(name, level)
  File "/Users/Dan/projects/pkmn/pmariglia-showdown/showdown/state/pokemon.py", line 18, in __init__
    self.base_stats = pokedex[self.name][constants.BASESTATS]
KeyError: 'pikachusinnoh'

problem with nash-equilibrium mode

under showdown in the battlebots folder, nash-equilibrium is not working for me. Apparently the problem is in main.py(in the nash-equilibrium folder) caused by the line
"from nashpy import Game" in line 8 but nashpy doesn't exist.
Thankyou.

directing the bot to localhost

Hi pmariglia, I much appreciate your effort in making this project. Lately I attempted to test it on my local showdown server by editing the WEBSOCKET_URI item in .env to be localhost:xxxx, but the bot would still connect to the default port sim.smogon.com:8000. Which module should I edit to fix this?

can't add new team I get the following error:

Traceback (most recent call last):
File "run.py", line 111, in
asyncio.get_event_loop().run_until_complete(showdown())
File "/usr/local/lib/python3.6/asyncio/base_events.py", line 488, in run_until_complete
return future.result()
File "run.py", line 84, in showdown
team = load_team(config.team_name)
File "/showdown/teams/load_team.py", line 24, in load_team
raise ValueError("Path must be file or dir: {}".format(name))
ValueError: Path must be file or dir: gen8/ou2

And when I tried replacing your sample team with my own team it went back to the sample team
Do teams need to be defined elsewhere other than teams/teams/gen8/ou

Replace Text Smogon Usage Parser With Chaos JSON parser

This parser is for the text version of the smogon usage stats. It was written before I knew that there are chaos jsons containing much more information as well as more organized information.

This parser should be replaced.

  1. It would require much simpler code to extract the same data from a JSON rather than a text-file
  2. The JSON contains more information about items/abilities/spreads/moves. The text file groups everything after a certain point into "other".

The output of this function should be in this format:

{
  <pokemon_name>: {
    'spreads': [
      (<nature>, <spread>, <percentage>)
    ],
    'items': [
      (<item>, <percentage>),
    ],
    'moves': [
      (<move>, <percentage>),
    ],
    'abilities': [
      (<ability>, <percentage>),
    ]
  }
}

Example:

{
  'cinderace': {
    'spreads': [
      ('jolly', '0,252,0,0,4,252', 65.159),
      ('jolly',  '4,252,0,0,0,252', 10.305),
      ...
    ],
    'items': [
      ('heavydutyboots', 50.191),
      ('lifeorb', 16.138),
      ...
    ],
    'moves': [
      ('pyroball', 94.751),
      ('uturn', 60.731),
      ...
    ],
    'abilities': [
      ('libero', 92.144),
      ('blaze', 7.856),
      ...
    ]
  }
}

Moves that bypass substitute

The bot does not understand that certain moves can ignore substitute.

The code that deals with generating damage instructions is here

See here for a list of these moves

tries to load .DS_Store as a team (macOS problem)

MacOS creates a hidden .DS_Store file in most folders that are opened. When choosing teams from a folder the bot sometimes crashes because it tries to read the .DS_Store file as a team.

It would probably make sense to make the team selector ignore hidden files.

Meanwhile, I just avoid opening the team folders in Finder, so .DS_Store does not get created.

KeyError: hiddenpower

In Gen 4, 5, if a pokemon has a hidden power move, and trys to use it, the ai will crash. It also seems to generate the modified_moves.json (not sure if related).

Here is the stack trace

  File "./run.py", line 109, in <module>
    asyncio.get_event_loop().run_until_complete(showdown())
  File "/usr/lib/python3.6/asyncio/base_events.py", line 484, in run_until_complete
    return future.result()
  File "./run.py", line 92, in showdown
    winner = await pokemon_battle(ps_websocket_client, config.pokemon_mode)
  File "/home/snow/Documents/showdown/showdown/run_battle.py", line 174, in pokemon_battle
    best_move = await async_pick_move(battle)
  File "/home/snow/Documents/showdown/showdown/run_battle.py", line 49, in async_pick_move
    pool, find_best_move, battle
  File "/usr/lib/python3.6/concurrent/futures/thread.py", line 56, in run
    result = self.fn(*self.args, **self.kwargs)
  File "/home/snow/Documents/showdown/showdown/engine/select_best_move.py", line 210, in find_best_move
    battles = battle.prepare_battles(join_moves_together=True)
  File "/home/snow/Documents/showdown/showdown/battle.py", line 107, in prepare_battles
    pkmn.guess_most_likely_attributes()
  File "/home/snow/Documents/showdown/showdown/battle.py", line 417, in guess_most_likely_attributes
    self.set_likely_moves_unless_revealed()
  File "/home/snow/Documents/showdown/showdown/battle.py", line 391, in set_likely_moves_unless_revealed
    self.moves.append(Move(m))
  File "/home/snow/Documents/showdown/showdown/battle.py", line 529, in __init__
    move_json = all_move_json[name]
KeyError: 'hiddenpowerice6070'

KeyError: 'mewtwomegax'

The bot crashes during the game if the bot uses a team with 2 or more of the same pokemon, specifically when it brings out said pokemon. Obviously, this is not a problem in metagames like OU where there is a species clause, but it is a problem for other metas like Balanced Hackmons where there is no species restriction. Sadly, I do not have much experience with python so I am having trouble fixing the issue..
Replays:
me vs the bot with 6 Mega-Mewtwo-X:
https://replay.pokemonshowdown.com/gen7balancedhackmons-897012029
error: (sorry for the Won currency signs, it is supposed to be \ but Korean Language)
keyerror mmx

me vs the bot with 2 Mega-Mewtwo-X: https://replay.pokemonshowdown.com/gen7balancedhackmons-897009410
(error is identical: everything seemed to be running fine until the Keyerror made the bot crash)

me vs the bot with no duplicate pokemon (Replaced Mega-Mewtwo-X with Mega-Mewtwo-Y):
https://replay.pokemonshowdown.com/gen7balancedhackmons-896857312
As you can see, the bot does not crash and battles until the end as expected.

Timer

Hi,
I would like the bot to keep track of the timer, because I made many modifications to the state evaluating algorithm and my bot sometimes runs out of time. So I would like to make it skip some steps if the timer is running out to avoid losing. Could you please guide me on how to do this?

How did you guys did this?

I'm building something similar but don't know where to get starteted. Can you tell me about how did you do this, no code, just an explanation

[gen3ou] ValueError: spd is not a valid boost

Traceback (most recent call last):
  File "run.py", line 111, in <module>
    asyncio.get_event_loop().run_until_complete(showdown())
  File "D:\Documenten\Python\Python3\lib\asyncio\base_events.py", line 568, in run_until_complete
    return future.result()
  File "run.py", line 94, in showdown
    winner = await pokemon_battle(ps_websocket_client, config.pokemon_mode)
  File "D:\Downloads\Showdown AI 2\showdown\run_battle.py", line 179, in pokemon_battle
    battle = await start_battle(ps_websocket_client, pokemon_battle_type)
  File "D:\Downloads\Showdown AI 2\showdown\run_battle.py", line 170, in start_battle
    battle = await start_standard_battle(ps_websocket_client, pokemon_battle_type)
  File "D:\Downloads\Showdown AI 2\showdown\run_battle.py", line 135, in start_standard_battle
    await read_messages_until_first_pokemon_is_seen(ps_websocket_client, battle, opponent_id, user_json)
  File "D:\Downloads\Showdown AI 2\showdown\run_battle.py", line 113, in read_messages_until_first_pokemon_is_seen
    best_move = await async_pick_move(battle)
  File "D:\Downloads\Showdown AI 2\showdown\run_battle.py", line 38, in async_pick_move
    pool, battle_copy.find_best_move
  File "D:\Documenten\Python\Python3\lib\concurrent\futures\thread.py", line 57, in run
    result = self.fn(*self.args, **self.kwargs)
  File "D:\Downloads\Showdown AI 2\showdown\battle_bots\safest\main.py", line 49, in find_best_move
    safest_move = pick_safest_move_from_battles(battles)
  File "D:\Downloads\Showdown AI 2\showdown\battle_bots\safest\main.py", line 32, in pick_safest_move_from_battles
    scores = get_payoff_matrix(mutator, user_options, opponent_options, depth = config.search_depth, prune=True)
  File "D:\Downloads\Showdown AI 2\showdown\engine\select_best_move.py", line 102, in get_payoff_matrix
    state_instructions = get_all_state_instructions(mutator, user_move, opponent_move)
  File "D:\Downloads\Showdown AI 2\showdown\engine\find_state_instructions.py", line 462, in get_all_state_instructions
    all_instructions += get_state_instructions_from_move(mutator, opponent_move, user_move, constants.OPPONENT, constants.SELF, False, instruction)
  File "D:\Downloads\Showdown AI 2\showdown\engine\find_state_instructions.py", line 387, in get_state_instructions_from_move
    temp_instructions += instruction_generator.get_states_from_boosts(mutator, boosts_target, boosts, boosts_chance, instruction_set)
  File "D:\Downloads\Showdown AI 2\showdown\engine\instruction_generator.py", line 743, in get_states_from_boosts
    pkmn_boost = get_boost_from_boost_string(side, k)
  File "D:\Downloads\Showdown AI 2\showdown\engine\instruction_generator.py", line 1242, in get_boost_from_boost_string
    raise ValueError("{} is not a valid boost".format(boost_string))
ValueError: spd is not a valid boost

PokemonShowdown parser does not parse item from "-status" message

the status function does not parse an opponent's item if their status came from said item.

Here is a sample message:

|
|switch|p2a: Machamp|Machamp, M|100/100
|move|p1a: Porygon2|Foul Play|p2a: Machamp
|-resisted|p2a: Machamp
|-damage|p2a: Machamp|79/100
|
|-status|p2a: Machamp|brn|[from] item: Flame Orb  // <-- this one
|upkeep
|turn|3

Phantom Force does not work properly

  • In the engine, the bot doesn't know that Phantom Force provides the user with a semi-invulnerable turn when charging/preparing.
  • In the PS parser, the bot doesn't parse the -prepare message from the PS server to set the charge flag and put the user in a semi-invulnerable turn. The charge flag aspect applies to all multi-turn moves, not just phantom force
|move|p2a: Dragapult|Phantom Force||[still]
|-prepare|p2a: Dragapult|Phantom Force

This leads to some weird results where the bot never thinks phantomforce does any damage.

trying to calculate the maximum damage each mon deal to the opponent

This is the code I have. Please excuse how bad it is, I am just starting and I am learning by reading your code.

`
def find_most_damage_move(state, pkmn, opponent_pokemon):

#Here I was trying to make a switch before getting all state options, as mentioned in the previous message. I realize this way to do it doesn't work.

poke = state.self.active
state.self.active = pkmn

my_options, opponent_options = state.get_all_options()
moves = []
switches = []
for option in my_options:
    if option.startswith(constants.SWITCH_STRING + " "):
        switches.append(option)
    else:
        moves.append(option)

conditions = {
    constants.REFLECT: state.opponent.side_conditions[constants.REFLECT],
    constants.LIGHT_SCREEN: state.opponent.side_conditions[constants.LIGHT_SCREEN],
    constants.AURORA_VEIL: state.opponent.side_conditions[constants.AURORA_VEIL],
    constants.WEATHER: state.weather,
    constants.TERRAIN: state.field
}
most_damage = -1

#Here I was also trying to do for move in pkmn.moves:, which also didn't work. I need to be able to get here the 4 moves of 
#the current pokemon I am analyzing, in order to get the maximum damage it can inflict to the current opponent pokemon.
for move in moves:
    move_dict = all_move_json[move]
    attacking_move = update_attacking_move(
        pkmn,
        opponent_pokemon,
        move_dict,
        {},
        False,
        state.weather
    )
    damage_amounts = calculate_damage(pkmn, opponent_pokemon, attacking_move, conditions=conditions)
    damage = damage_amounts[0] if damage_amounts else 0

    if damage > most_damage:
        most_damage = damage
        
#this is just what I was trying to switch back the pokemon to the active spot.  

state.self.active = poke

return round(most_damage)

#I also need to calculate the maximum damage each opponent pokemon can inflict on each of the bot's

def find_most_damage_move_opponent(state, pkmn, opponent_pokemon):

poke = state.opponent.active
state.opponent.active = pkmn

my_options, opponent_options = state.get_all_options()
moves = []
switches = []
for option in opponent_options:
    if option.startswith(constants.SWITCH_STRING + " "):
        switches.append(option)
    else:
        moves.append(option)

conditions = {
    constants.REFLECT: state.opponent.side_conditions[constants.REFLECT],
    constants.LIGHT_SCREEN: state.opponent.side_conditions[constants.LIGHT_SCREEN],
    constants.AURORA_VEIL: state.opponent.side_conditions[constants.AURORA_VEIL],
    constants.WEATHER: state.weather,
    constants.TERRAIN: state.field
}
most_damage = -1

for move in moves:
    move_dict = all_move_json[move]
    attacking_move = update_attacking_move(
        pkmn,
        opponent_pokemon,
        move_dict,
        {},
        False,
        state.weather
    )
    damage_amounts = calculate_damage(pkmn, opponent_pokemon, attacking_move, conditions=conditions)
    damage = damage_amounts[0] if damage_amounts else 0

    if damage > most_damage:
      
        most_damage = damage
state.opponent.active = poke

return round(most_damage)

#Here is how I count how many opponent pokemon each of the bot's kills in one hit given their #current hp and the current conditions of the state.

def how_many_each_sweeps(state, user_pkmn):

count = 0
#I was also trying to make it with this filter, but was not working, I think the wrong part was the x.is_alive()
#for pkmn in filter(lambda x: x.is_alive(), state.opponent.reserve):
if state.opponent.active.hp > 0:
    if find_most_damage_move(state, user_pkmn, state.opponent.active) >= state.opponent.active.hp:
            count = count + 1
for pkmn in state.opponent.reserve.values():
    if pkmn.hp > 0:
        if find_most_damage_move(state, user_pkmn, pkmn) >= pkmn.hp:
            count = count + 1
return count

def how_many_each_sweeps_opponent(state, opponent_pkmn):

count = 0
if state.self.active.hp > 0:
    if find_most_damage_move_opponent(state, opponent_pkmn, state.self.active) >= state.self.active.hp:
            count = count + 1
for pkmn in state.self.reserve.values():
    if pkmn.hp > 0:

        if find_most_damage_move_opponent(state, opponent_pkmn, pkmn) >= pkmn.hp:
            count = count + 1
return count

`

nash_equilibrium bot not working in challenges

I've tried using the nash_equilibrium bot multiple times in the accept_challenge mode, but it seems to hitch every time and leaves the match before even starting.

2 things it has done every time this happens are the following:
-it's displayed this (blank when i tried for gen8ou and saying kartana when i tried gen8randombattle):
[DEBUG] Making HTTP request to https://www.smogon.com/stats/2020-07/moveset/gen8ou-0.txt for usage stats
[WARNING] No sets for , trying to find most likely attributes
[WARNING] not in the sets lookup, using random battle abilities
[WARNING] not in the random-battle sets lookup
[WARNING] not in the sets lookup, using random battle items
[WARNING] not in the random-battle sets lookup
[WARNING] not in the sets lookup
[WARNING] not in the random-battle sets lookup
[WARNING] not in the sets lookup

and it has also displayed this:
Traceback (most recent call last):
File "run.py", line 110, in
asyncio.get_event_loop().run_until_complete(showdown())
File "E:\Program Files (x86)\Microsoft Visual Studio\Shared\Python37_64\lib\asyncio\base_events.py", line 579, in run_until_complete
return future.result()
File "run.py", line 93, in showdown
winner = await pokemon_battle(ps_websocket_client, config.pokemon_mode)
File "E:\Programming\GitPortable\showdown\showdown\run_battle.py", line 156, in pokemon_battle
battle = await start_battle(ps_websocket_client, pokemon_battle_type)
File "E:\Programming\GitPortable\showdown\showdown\run_battle.py", line 147, in start_battle
battle = await start_standard_battle(ps_websocket_client, pokemon_battle_type)
File "E:\Programming\GitPortable\showdown\showdown\run_battle.py", line 137, in start_standard_battle
await handle_team_preview(battle, ps_websocket_client)
File "E:\Programming\GitPortable\showdown\showdown\run_battle.py", line 47, in handle_team_preview
best_move = await async_pick_move(battle_copy)
File "E:\Programming\GitPortable\showdown\showdown\run_battle.py", line 32, in async_pick_move
pool, battle_copy.find_best_move
File "E:\Program Files (x86)\Microsoft Visual Studio\Shared\Python37_64\lib\concurrent\futures\thread.py", line 57, in run
result = self.fn(*self.args, **self.kwargs)
File "E:\Programming\GitPortable\showdown\showdown\battle_bots\nash_equilibrium\main.py", line 191, in find_best_move
decision = pick_move_in_equilibrium_from_multiple_score_lookups(list_of_payoffs)
File "E:\Programming\GitPortable\showdown\showdown\battle_bots\nash_equilibrium\main.py", line 154, in pick_move_in_equilibrium_from_multiple_score_lookups
weighted_choices = get_weighted_choices_from_multiple_score_lookups(score_lookups)
File "E:\Programming\GitPortable\showdown\showdown\battle_bots\nash_equilibrium\main.py", line 139, in get_weighted_choices_from_multiple_score_lookups
eq = find_nash_equilibrium(sl)
File "E:\Programming\GitPortable\showdown\showdown\battle_bots\nash_equilibrium\main.py", line 112, in find_nash_equilibrium
equilibria = find_all_equilibria(df)
File "E:\Programming\GitPortable\showdown\showdown\battle_bots\nash_equilibrium\main.py", line 88, in find_all_equilibria
sp = subprocess.Popen(cmd, stdout=subprocess.PIPE, stdin=subprocess.PIPE)
File "E:\Program Files (x86)\Microsoft Visual Studio\Shared\Python37_64\lib\subprocess.py", line 800, in init
restore_signals, start_new_session)
File "E:\Program Files (x86)\Microsoft Visual Studio\Shared\Python37_64\lib\subprocess.py", line 1207, in _execute_child
startupinfo)
OSError: [WinError 87] The parameter is incorrect.

If you need any additional information I'd be happy to supply it. I hope the problem is something I overlooked, and if it is then pointing it out would be a great help.

doesn't handle ties

If a battle ends in a tie, the bot doesn't start a new battle. I encountered this when making two bots battle each other with stally teams and they triggered the endless battle clause.

KeyError: '' when opponent has a pokemon that likely has less than 4 moves

The bot crashes with a KeyError when trying to list likely moves for a pokemon that often has the move Nothing or '' listed in the usage statistics.

For example when starting a battle against a team with Ditto.

File ".../showdown/battle.py", line 643, in __init__
    move_json = all_move_json[name]
KeyError: ''

A few suggestions

here are a few suggestions from my experience of this script:

  1. make nash-equilibrium run without docker. the docker took like 2 gb so making it run without docker would be appreciated.
  2. it doesn't switch pokemon. when its a in a sticky situation in a fight, it doesn't switch pokemon making the pokemon die.
  3. making it a neural network for extra intelligence???
  4. add a stall feature. I noticed when the bot was being slow due to other applications, the timer would be on and people would leave if no move would be done increasing my elo a lot.
    Overall the bot is amazing ,very fast and works very well.
    Thanks in advance

Error when starting battle

Traceback (most recent call last):

File "run.py", line 110, in

asyncio.get_event_loop().run_until_complete(showdown())

File "/usr/lib/python3.6/asyncio/base_events.py", line 484, in run_until_complete

return future.result()

File "run.py", line 93, in showdown

winner = await pokemon_battle(ps_websocket_client, config.pokemon_mode)

File "/showdown/showdown/run_battle.py", line 156, in pokemon_battle

battle = await start_battle(ps_websocket_client, pokemon_battle_type)

File "/showdown/showdown/run_battle.py", line 147, in start_battle

battle = await start_standard_battle(ps_websocket_client, pokemon_battle_type)

File "/showdown/showdown/run_battle.py", line 137, in start_standard_battle

await handle_team_preview(battle, ps_websocket_client)

File "/showdown/showdown/run_battle.py", line 47, in handle_team_preview

best_move = await async_pick_move(battle_copy)

File "/showdown/showdown/run_battle.py", line 32, in async_pick_move

pool, battle_copy.find_best_move

File "/usr/lib/python3.6/concurrent/futures/thread.py", line 56, in run

result = self.fn(*self.args, **self.kwargs)

File "/showdown/showdown/battle_bots/nash_equilibrium/main.py", line 188, in find_best_move

scores = get_payoff_matrix(mutator, user_options, opponent_options, prune=False)

File "/showdown/showdown/engine/select_best_move.py", line 115, in get_payoff_matrix

safest = pick_safest(get_payoff_matrix(mutator, next_turn_user_options, next_turn_opponent_options, depth=depth, prune=prune))

File "/showdown/showdown/engine/select_best_move.py", line 102, in get_payoff_matrix

state_instructions = get_all_state_instructions(mutator, user_move, opponent_move)

File "/showdown/showdown/engine/find_state_instructions.py", line 456, in get_all_state_instructions

instructions = get_state_instructions_from_move(mutator, opponent_move, user_move, constants.OPPONENT, constants.SELF, True, instructions)

File "/showdown/showdown/engine/find_state_instructions.py", line 379, in get_state_instructions_from_move

temp_instructions += instruction_generator.get_states_from_boosts(mutator, boosts_target, boosts, boosts_chance, instruction_set)

File "/showdown/showdown/engine/instruction_generator.py", line 756, in get_states_from_boosts

new_boost = pkmn_boost + v

TypeError: unsupported operand type(s) for +: 'NoneType' and 'int'

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.