pmariglia / showdown Goto Github PK
View Code? Open in Web Editor NEWA Pokemon Showdown Battle Bot written in Python
License: GNU General Public License v3.0
A Pokemon Showdown Battle Bot written in Python
License: GNU General Public License v3.0
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.
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?
Is there any ways to get the adversary team ?
Thanks in advance
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!
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
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.
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)
(hope the image works... it just shows a link for me)
Did something go wrong or was I just dumb?
bot is idle and wont make moves
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.
The old invite is no longer valid. Would be nice if a new one is generated and added to the read-me.
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)
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.
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.
Playing gen8battlestadiumsingles on the default bot and through 10 games, Dynamax has not been used.
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.
When using the bot for a while it gets muted for spam
Due to spam from your internet provider, you can't challenge others right now. Logging into an account you've used a lot in the past will allow you to challenge.
possibly the bot is being rate limited or something
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
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.
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
`
here are a few suggestions from my experience of this script:
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!
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?
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:
Aurora Veil should fail when hail is not up - right now it works regardless of weather
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: ''
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'
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.
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.
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
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'
The bot has no notion of length for weather/terrain/trickroom.
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
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.
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.
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.
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),
...
]
}
}
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
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'
Title
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
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
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
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.
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
It would be beneficial if a "chatroom" variable or similar could be specified to allow the bot to join a chatroom. That way, users could send challenges to it without needing to look up its name.
-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.
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 '.
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 :)
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'
I cant find any .env file in the files.
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?
Error shows up at the end of each battle when logging is enabled, presumably it's trying to encode the star character (☆) before the username and is failing to do so.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.