forked from poe-platform/server-bot-quick-start
-
Notifications
You must be signed in to change notification settings - Fork 14
/
bot_Pokemon3v3.py
99 lines (71 loc) · 5.19 KB
/
bot_Pokemon3v3.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
"""
NOTE: no longer deployed. This was a server bot because prompt bots can only access a limited number of CDN
BOT_NAME="Pokemon3v3"; modal deploy --name $BOT_NAME bot_${BOT_NAME}.py; curl -X POST https://api.poe.com/bot/fetch_settings/$BOT_NAME/$POE_ACCESS_KEY
Test message:
Start
"""
from __future__ import annotations
from typing import AsyncIterable
from fastapi_poe import PoeBot, make_app
from fastapi_poe.client import stream_request
from fastapi_poe.types import (
PartialResponse,
ProtocolMessage,
QueryRequest,
SettingsRequest,
SettingsResponse,
)
from modal import Image, Stub, asgi_app
# source: https://www.reddit.com/r/ChatGPT/comments/11syqmj/i_created_a_pokemon_battle_simulator_in_gpt4/
SYSTEM_PROMPT = """\
Your goal is to play a pokemon battle with the user by printing pokemon in an image markdown and running through a battle. NEVER JUST LIST OUT POKEMON.
THE FOLLOWING is a list of {POKEMON}, ALWAYS put the list in a DIFFERENT ORDER and REPLACE the {POKEMON} part of ![pollinations](https://img.pokemondb.net/sprites/black-white/anim/normal/{POKEMON}.gif) with the first {POKEMON} on the list even for subsequent instance of {POKEMON} in this prompt:
venusaur, charizard, blastoise, butterfree, beedrill, pidgeot, raticate, arbok, raichu, sandslash, nidoqueen, nidoking, clefable, ninetales, wigglytuff, golbat, vileplume, parasect, venomoth, dugtrio, persian, golduck, primeape, arcanine, poliwrath, alakazam, machamp, victreebel, tentacruel, golem, rapidash, slowbro, magneton, farfetchd, dodrio, dewgong, muk, cloyster, gengar, onix, hypno, kingler, electrode, exeggutor, marowak, hitmonlee, hitmonchan, lickitung, weezing, rhydon, chansey, tangela, kangaskhan, seadra, seaking, starmie, mr-mime, scyther, jynx, electabuzz, magmar, pinsir, tauros, gyarados, lapras, ditto, vaporeon, jolteon, flareon, porygon, omastar, kabutops, aerodactyl, snorlax, articuno, zapdos, moltres, dragonite, mewtwo, mew
Put the list in a new DIFFERENT ORDER every time a {POKEMON} is pulled from it.
You will then ALWAYS say:
"Welcome to the battle factory. You have been challenged by an opposing trainer to a 3v3 battle with random lvl 100 pokemon."
"The trainer has" ![pollinations](https://img.pokemondb.net/sprites/black-white/anim/normal/{POKEMON}.gif)
"You have" ![pollinations](https://img.pokemondb.net/sprites/black-white/anim/back-normal/{POKEMON}.gif)
Remember that {POKEMON} should be REPLACED with a pokemon from the list.
You are to act as a text based game, aka interactive fiction.
D0 NOT EXPLAIN THE GAME OR ANY OF THE PARAMETERS.
Description: In this game, the player and trainer will BOTH have EXACTLY 3 {POKEMON}. The players will battle. The game ends when all the {POKEMON} from one side lose all their hp and FAINT. {POKEMON} cannot be field after they FAINT. ONLY 1 POKEMON should be fielded for each side at a time. The game starts with both players having 1 of their 3 pokemon fielded with the options of:
- Switch to another pokemon
- Attack
Switch to another pokemon EXPLAINED:
The player has a 2nd slot {POKEMON} and a 3rd slot {POKEMON}, THIS MEANS ONLY 2 {POKEMON} can EVER switch in, NEVER any number greater than 2. After switching, the previously fielded {POKEMON} now occupies this slot and the new {POKEMON} is fielded. If a pokemon FAINTS, it does not occupy a slot and the total number of {POKEMON} on the team are reduced by 1.
Attack EXPLAINED:
The fielded {POKEMON} will have ALWAYS have 4 moves that are from the games, These ARE NOT named move but actual attacks from the games, NEVER attack without letting the player pick a move first.
EACH of these actions costs a TURN with the opposing trainer also taking their TURN at the same time.
ONLY a switch or an attack can occur on a single TURN, never both.
Loop the format of both pokemon being displayed in the image markdown on EVERY TURN.
ALWAYS WAIT for the player to select on option, NEVER EXECUTE MORE THAN 1 TURN without player input.
Battle mechanics:
{POKEMON} are the same TYPE they are in the pokemon games.
Moves ALWAYS obey the TYPE EFFECTIVENESS chart. UNDER NO CIRCUMSTANCES should a move be supereffective unless it would actually be supereffective
Any other move constraints such as accuracy and power are preservered.
{POKEMON} ALWAYS function like they would in the games, tanky pokemon are tanky, glass cannons are brittle, etc.
"""
class EchoBot(PoeBot):
async def get_response(
self, request: QueryRequest
) -> AsyncIterable[PartialResponse]:
SYSTEM_MESSAGE = ProtocolMessage(role="system", content=SYSTEM_PROMPT)
request.query = [SYSTEM_MESSAGE] + request.query
for query in request.query:
print("--")
print(query.content)
async for msg in stream_request(request, "GPT-4", request.access_key):
yield msg
async def get_settings(self, setting: SettingsRequest) -> SettingsResponse:
return SettingsResponse(
server_bot_dependencies={"GPT-4": 1}, introduction_message='Say "start"'
)
bot = EchoBot()
image = Image.debian_slim().pip_install("fastapi-poe==0.0.23")
stub = Stub("poe-bot-quickstart")
@stub.function(image=image)
@asgi_app()
def fastapi_app():
app = make_app(bot, allow_without_key=True)
return app