{"id":31761253,"url":"https://github.com/pmariglia/poke-engine","last_synced_at":"2025-10-09T21:48:47.381Z","repository":{"id":251546457,"uuid":"249090730","full_name":"pmariglia/poke-engine","owner":"pmariglia","description":"A Pokemon battle engine that can search through Pokemon states","archived":false,"fork":false,"pushed_at":"2025-10-05T14:19:18.000Z","size":2880,"stargazers_count":25,"open_issues_count":0,"forks_count":6,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-10-05T15:27:07.263Z","etag":null,"topics":["ai","battle","bot","engine","pokemon","pokemon-showdown","pokemon-showdown-bot","python","rust","showdown"],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/pmariglia.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2020-03-22T01:17:51.000Z","updated_at":"2025-10-05T14:19:22.000Z","dependencies_parsed_at":"2024-09-07T20:52:49.372Z","dependency_job_id":"f6713bdf-60ed-48c5-9034-5a9c5f441167","html_url":"https://github.com/pmariglia/poke-engine","commit_stats":null,"previous_names":["pmariglia/poke-engine"],"tags_count":41,"template":false,"template_full_name":null,"purl":"pkg:github/pmariglia/poke-engine","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pmariglia%2Fpoke-engine","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pmariglia%2Fpoke-engine/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pmariglia%2Fpoke-engine/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pmariglia%2Fpoke-engine/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/pmariglia","download_url":"https://codeload.github.com/pmariglia/poke-engine/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pmariglia%2Fpoke-engine/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":279002051,"owners_count":26083286,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-09T02:00:07.460Z","response_time":59,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ai","battle","bot","engine","pokemon","pokemon-showdown","pokemon-showdown-bot","python","rust","showdown"],"created_at":"2025-10-09T21:48:22.450Z","updated_at":"2025-10-09T21:48:47.372Z","avatar_url":"https://github.com/pmariglia.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Poke Engine\n\nAn engine for searching through Pokémon battles (singles only).\n\n**This is not a perfect engine**\n\nThis battle engine is meant to capture important aspects of Pokémon for the purposes of competitive single battles.\nIt is nowhere near as complete or robust as the [PokemonShowdown](https://github.com/smogon/pokemon-showdown) battle engine.\n\n## Links\n\n#### [Python Bindings](poke-engine-py)\n\n#### [CHANGELOG](CHANGELOG.md)\n\n## Running Directly\n\n### Building\n\nMake sure you have Rust / Cargo installed.\n\n[Features](https://doc.rust-lang.org/cargo/reference/features.html) are used to conditionally compile code for different generations of Pokemon.\nThe simplest way to build the project is with the Makefile.\n\ne.g. To build for generation 4:\n\n```shell\nmake gen4\n```\n\nRun with\n    \n```shell\n./target/release/poke-engine\n```\n\nGenerations 4 through 8 are available\n\n### Usage\n\nThere are several ways to interact with the engine through subcommands:\n\n1. **Generate Instructions**\n```shell\npoke-engine generate-instructions --state \u003cstate-string\u003e -o \u003cs1_move\u003e -t \u003cs2_move\u003e\n```\nGenerate and display the different Instructions that could be applied to the state if side 1 and side 2 used the given moves.\n\ne.g.\n```shell\npoke-engine generate-instructions --state \u003cstate-string\u003e -o shadowball -t breloom\n```\n```\nIndex: 0\nStateInstruction: \n\tPercentage: 80.00\n\tInstructions:\n\t\tSwitch SideTwo: P0 -\u003e P2\n\t\tDamage SideTwo: 184\n\nIndex: 1\nStateInstruction: \n\tPercentage: 20.00\n\tInstructions:\n\t\tSwitch SideTwo: P0 -\u003e P2\n\t\tDamage SideTwo: 184\n\t\tBoost SideTwo SpecialDefense: -1\n```\n\n2. **Expectiminimax**\n```shell\npoke-engine expectiminimax --state \u003cstate-string\u003e --depth \u003cdepth\u003e [--ab-prune]\n```\nSearch through the state using [expectiminimax](https://en.wikipedia.org/wiki/Expectiminimax) to the given depth.\nDisplays the results along with the best move found.\n\ne.g.\n```shell\npoke-engine expectiminimax --state \u003cstate-string\u003e -d 3\n```\n```\nside one options: psychic,grassknot,shadowball,hiddenpowerfire70,switch skarmory,switch tyranitar,switch mamoswine,switch jellicent,switch excadrill\nside two options: closecombat,stoneedge,stealthrock,taunt,xscissor,quickattack,switch lucario,switch breloom,switch keldeo,switch conkeldurr,switch toxicroak\nmatrix: 32.39,11.99,39.72,99.72,-9.94,69.44,55.46,75.91,75.91,75.91,101.19,32.39,-2.94,39.72,99.72,-28.60,69.44,53.51,79.84,108.92,78.63,-23.62,32.39,-20.35,34.37,94.37,-49.04,49.60,53.51,81.39,88.49,89.01,0.00,17.65,-43.57,11.15,71.15,-72.26,26.38,75.91,75.91,65.27,83.70,0.00,-76.18,-85.66,-72.00,-36.99,-34.19,-34.19,-50.07,-11.07,-25.16,-31.11,15.53,-119.69,-85.88,-101.20,-29.40,-100.00,-82.60,-90.04,-107.86,-77.15,-73.11,-25.90,-100.00,-95.17,-118.42,-75.85,-86.53,-86.53,-97.97,-102.52,-83.18,-74.85,-44.47,-45.01,-74.53,-117.55,-45.01,-56.64,-45.01,-84.08,-120.08,-45.01,-74.85,-44.47,-100.00,-47.20,-96.28,-32.62,-52.23,-42.56,-41.19,-120.08,-74.58,-74.85,-41.19\nchoice: psychic\nevaluation: -9.944763\n````\n\n3. **Iterative Deepening**\n```shell\npoke-engine iterative-deepening --state \u003cstate-string\u003e --time-to-search-ms \u003ctime\u003e\n```\nSimilar to expectiminimax, search through the state but use iterative deepening.\nSearches for the given amount of time, then returns the best move found.\n\ne.g.\n```shell\npoke-engine iterative-deepening --state \u003cstate-string\u003e -t 100\n```\n```\nside one options: psychic,switch jellicent,grassknot,shadowball,hiddenpowerfire70,switch skarmory,switch mamoswine,switch excadrill,switch tyranitar\nside two options: closecombat,stoneedge,stealthrock,taunt,xscissor,quickattack,switch lucario,switch breloom,switch keldeo,switch conkeldurr,switch toxicroak\nmatrix: 32.39,11.99,39.72,99.72,-9.94,69.44,55.46,75.91,75.91,75.91,101.19,-45.01,NaN,NaN,NaN,NaN,NaN,NaN,NaN,NaN,NaN,NaN,32.39,-2.94,39.72,99.72,-28.60,NaN,NaN,NaN,NaN,NaN,NaN,32.39,-20.35,NaN,NaN,NaN,NaN,NaN,NaN,NaN,NaN,NaN,17.65,-43.57,NaN,NaN,NaN,NaN,NaN,NaN,NaN,NaN,NaN,-76.18,NaN,NaN,NaN,NaN,NaN,NaN,NaN,NaN,NaN,NaN,-100.00,NaN,NaN,NaN,NaN,NaN,NaN,NaN,NaN,NaN,NaN,-100.00,NaN,NaN,NaN,NaN,NaN,NaN,NaN,NaN,NaN,NaN,-119.69,NaN,NaN,NaN,NaN,NaN,NaN,NaN,NaN,NaN,NaN\nchoice: psychic\nevaluation: -9.944763\n```\n\n4. **Monte Carlo Tree Search**\n```shell\npoke-engine monte-carlo-tree-search --state \u003cstate-string\u003e --time-to-search-ms \u003ctime\u003e\n```\nSearch through the state using [Monte Carlo Tree Search](https://en.wikipedia.org/wiki/Monte_Carlo_tree_search) for the given amount of time.\n\ne.g.\n```shell\npoke-engine monte-carlo-tree-search --state \u003cstate-string\u003e -t 100\n```\n```\nTotal Iterations: 25000\nside one: switch mamoswine,115.31,300|switch tyranitar,41.00,123|hiddenpowerfire70,58.14,165|switch jellicent,1067.52,2402|switch excadrill,3754.58,8173|shadowball,115.37,300|grassknot,298.20,715|psychic,4038.05,8780|switch skarmory,1826.44,4042\nside two: stoneedge,915.55,1723|switch lucario,70.53,159|closecombat,827.19,1562|switch breloom,181.84,373|switch keldeo,141.66,297|stealthrock,413.54,805|quickattack,84.78,187|taunt,123.90,263|xscissor,10745.95,19240|switch conkeldurr,153.71,320|switch toxicroak,26.94,71\n```\n\n5. **Calculate Damage**\n```shell\npoke-engine calculate-damage --state \u003cstate-string\u003e -o \u003cs1_move\u003e -t \u003cs2_move\u003e\n```\nCalculate the damage rolls for the given moves.\n\ne.g.\n```shell\npoke-engine calculate-damage --state \u003cstate-string\u003e -o shadowball -t closecombat\n```\n```\nDamage Rolls: 122,123,125,126,128,129,131,132,133,135,136,138,139,141,142,144\nDamage Rolls: 155,157,159,161,162,164,166,168,170,172,173,175,177,179,181,183\n```\n\n6. **Interactive Mode**: Run the engine and input commands directly\n\ne.g.\n```shell\npoke-engine --state \u003cstate-string\u003e\n```\n\nAvailable commands:\n\n| Command                                               | Shorthand | Function                                                                                                      |\n|-------------------------------------------------------|:---------:|---------------------------------------------------------------------------------------------------------------|\n| **state** *state-string*                              |     s     | Reset the state to *state-string*                                                                             |\n| **matchup**                                           |     m     | Display some information about the current state                                                              |\n| **generate-instructions** *side-1-move* *side-2-move* |     g     | Generate all of the instructions that would be applied to the state if side 1 and side 2 used the given moves |\n| **instructions**                                      |     i     | Display the last instructions generated by **generate-instructions**                                          |\n| **apply** *instruction-index*                         |     a     | Apply the last instructions instructions to the state, modifying it                                           |\n| **pop**                                               |     p     | Pops the last instructions from the state, undoing their changes                                              |\n| **pop-all**                                           |    pa     | Pops all applied instructions from the state                                                                  |\n| **evaluate**                                          |    ev     | Calculate the current state's evaluation                                                                      |\n| **calculate-damage** *side-1-move* *side-2-move*      |     d     | Calculate the damage rolls for the given moves                                                                |\n| **expectiminimax** *depth* *[ab-prune=false]*         |     e     | Perform expectiminimax (see above), and display the results                                                   |\n| **iterative-deepening** *time-ms*                     |    id     | Perform iterative-deepening (see above), and display the results                                              |\n| **monte-carlo-tree-search** *time-ms*                 |   mcts    | Perform monte-carlo-tree-search (see above), and display the results                                          |\n| **serialize**                                         |    ser    | Display the current state's serialized string                                                                 |\n| **exit/quit**                                         |     q     | Quit interactive mode                                                                                         |\n\n\n### State Representation\n\nWhen running directly, the engine parses the state of the game from a string.\n\nProperly representing the state of a Pokémon battle gets really complicated.\nSee the doctest for `State::deserialize` in [state.rs](src/state.rs)\nfor the source of truth on how to parse a state string.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpmariglia%2Fpoke-engine","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpmariglia%2Fpoke-engine","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpmariglia%2Fpoke-engine/lists"}