Discuss Scratch
- Discussion Forums
- » Things I'm Making and Creating
- » PyRPG (Python Text Adventure)
- ScratchCatHELLO
-
1000+ posts
PyRPG (Python Text Adventure)
PyRPG (working title)
I'm working on making a text adventure in python (using a base by imfh that I expanded apon) using my own base.
It's not even close to done, but I'm excited about it
However, my spaghetti code is probably not very efficient, so please give feedback on how i could improve this.
note: the map is not complete, and is mostly for testing
for a (older) version that has a larger map, go here
I'm working on making a text adventure in python (using a base by imfh that I expanded apon) using my own base.
It's not even close to done, but I'm excited about it
However, my spaghetti code is probably not very efficient, so please give feedback on how i could improve this.
note: the map is not complete, and is mostly for testing
#PyRPG(v3): Beta 0.2 import os import random from difflib import SequenceMatcher from rich import print as rprint from rich import align version = "0.2 (BETA)" #blue = inventory #red = error/invalid command #orange = combat? #green = outside-game messages (changelog, clearing, quit prompt) class Room: """ Represents a room. Attributes ---------- name : str the room name (used in dev mode) passive : str the description that displays after each turn detail : str the description that displays when you type "look" directions : list a list of directions a player in the room can move items : dict a list of item objects ents : dict a list of entity objects Methods ------- ritem(itemname): removes an item by name rent(entname): removes an entity by name str(room): converts a room into a string listing attributes """ def __init__(room, name, descriptions, directions, items, ents): room.name = name room.passive = descriptions[0] room.detail = descriptions[1] room.directions = directions room.items = items room.ents = ents def __str__(room): tmpstr = f"{room.name} " for item in room.items: tmpstr += f"D There is a {item.name}.\n" for ent in room.ents: tmpstr += f"D A {ent.name} is standing here.\n" return tmpstr def ritem(room, itemname): room.items.pop(itemname) def rent(room, entname): room.items.pop(entname) class Item: """ Represents an item. Attributes ---------- name : str the item name short : str short description of the item long : str detailed description of the item stats : dict a list of stats structure is as follows: { "dmg": 10, #damage of the item "critdmg": 15, #damage of the item when it hits something critically "sellprice": 30, #sell value "buyprice": 35, #buy value "atkeffect": randomdmg #executes a function when you use the item to attack } weapon : bool False -> not a weapon True -> a weapon defaults to False """ def __init__(item, name, descriptions, stats, weapon=False): item.name = name item.d = descriptions item.short = descriptions[0] #brief item.long = descriptions[1] #detail item.stats = stats item.weapon = weapon class Ent: """ Represents an entity. Attributes ---------- name : str the entity name inv : dict the inventory of the entity. consists of a dict of Item objects stats : dict the stats of the entity structure is as follows: { "hp": 10, #current health "maxhp": 10, #full health "dmg": 5, #its damage in combat "acc": 2, #entity will hit (1/acc)*100 percent of the time "crit": 5, #entity will crit (1/crit)*100 percent of the time "critdmg": 7, #damage of a critical hit } hostilemode : int whether an entity will attack unprovoked 2: the entity will attack when the player enters the room it's in 1: the entity won't fight unprovoked 0: the entity won't fight """ def __init__(ent, name, inv, stats, hostilemode=1): ent.name = name ent.inv = inv ent.stats = stats ent.hostilemode = hostilemode def giveitem(ent, player, itemname): player["inv"][itemname] = ent.inv[itemname] ent.inv[itemname].pop() def damage(ent, amount): if ent.stats["hp"] - amount < 0: ent.stats["hp"] = 0 else: ent.stats["hp"] -= amount def heal(ent, amount): if ent.stats["hp"] + amount > ent.stats["maxhp"]: ent.stats["hp"] = ent.stats["maxhp"] else: ent.stats["hp"] += amount def attack(ent): stats = ent.stats hitper = (1/stats["acc"])*100 critper = (1/stats["crit"])*100 if bool(random.choices([1, 0], weights=[hitper, 100-hitper])[0]): if bool(random.choices([1, 0], weights=[critper, 100-critper])[0]): rprint(f"!![bold red]The {ent.name} critically hit you, doing {stats['critdmg']} damage!") return stats["critdmg"] else: rprint(f"! [bold]The {ent.name} hit you, doing {stats['dmg']} damage!") return stats["dmg"] else: rprint(f" [italic]The {ent.name} missed!") return 0 title = """ ::::::::: ::: ::: ::::::::: ::::::::: :::::::: :+: :+: :+: :+: :+: :+: :+: :+: :+: :+: +:+ +:+ +:+ +:+ +:+ +:+ +:+ +:+ +:+ +#++:++#+ +#++: +#++:++#: +#++:++#+ :#: +#+ +#+ +#+ +#+ +#+ +#+ +#+# #+# #+# #+# #+# #+# #+# #+# ### ### ### ### ### ######## """ versions = { "0.1 (BETA)": """[b green]0.1[/]\n - first version of game\n - added look, help, movement commands, grab/drop, inventory, inspect, clear, quit\n - added first map (two rooms with an item in one)\n""", "0.2 (BETA)": """[green][b]0.2[/]\n[i dim]The Feedback and Consistency Update[/][/green]\n - added changelog\n - fixed typos\n - consistent capitalization\n - 'inventory' now tells you when your inventory is empty\n - 'grab' and 'drop' now warn you when the item isn't in the room or your inventory, respectively.\n""" } commands = { "help": ["print list of commands and descriptions.", "[b]=HELP=[/]\nPrints a list of command and simple descriptions.\n[b]USAGE[/]\nhelp - print list of commands and descriptions\n command (opt) - print detailed description of the specified command."], "help <command>": ["print detailed explanation of <command>."], "quit": ["quit game.", "[b]=QUIT=[/]\nExits the game.\n[b]USAGE[/]\nquit - end game\nq - end game"], "look": ["look around at the current room.", "[b]=LOOK=[/]\nPrints a detailed description of the current room.\n[b]USAGE[/]\nlook - see description of current room"], "north": ["go north.", "[b]=NORTH=[/]\nMoves the player north.\n[b]USAGE[/]\nnorth - move player north\nn - move player north"], "west": ["go west.", "[b]=WEST=[/]\nMoves the player west.\n[b]USAGE[/]\nwest - move player west\nw - move player west"], "east": ["go east.", "[b]=EAST=[/]\nMoves the player east.\n[b]USAGE[/]\neast - move player east\ne - move player east"], "south": ["go south.", "[b]=WEST=[/]\nMoves the player south.\n[b]USAGE[/]\nwest - move player south\ns - move player south"], "grab": ["grab item from room.", "[b]=GRAB=[/]\nGrab an item out of the room and place it in your inventory.\n[b]USAGE[/]\ngrab - grab an item\n item - name of item to grab."], "drop": ["drop item into room.", "[b]=DROP=[/]\nDrop an item from your inventory and place it in the room.\n[b]USAGE[/]\ndrop - drop an item\n item - name of item to drop."], "inventory": ["list items in inventory.", "[b]=INVENTORY=[/]\nPrint a list of items in the player's inventory.\n[b]USAGE[/]\ninventory/i - read inventory"], "inspect": ["show detailed description of an item.", "[b]=INSPECT=[/]\nShow a detailed description of an item in your inventory.\n[b]USAGE[/]\ninspect - show long item description"], "clear": ["clear cmd prompt/terminal.", "[b]=CLEAR=[/]\nClear screen (for when the terminal has a lot of text in it).\n[b]USAGE[/]\nclear - clear cmd/terminal"], "changelog": ["show changelog for the current rpg version.", "[b]=CHANGELOG=[/]\nShow version changelog.\n[b]USAGE[/]\nchangelog - show changelog for the current version\n version (opt) - print changelog for specific version"], "changelog <version>": ["show changelog for a specific rpg version."] } #find the item of a list that is closest to a string def findsimilar(thing, inlist): similar = {} for item in inlist: similar[item] = SequenceMatcher(None, item, thing).ratio() return list(reversed(sorted(similar.items(),key=lambda x:x[1])))[0][0] player = {} def initplayer(name, startroom): global player player = { "name": name, "loc": startroom, "hp": 30, "maxhp": 30, "inventory": {} } def noeffect(): pass box = Item("box", ["An odd box", "There are no markings on the cardboard box. It looks like it's been sitting in the forest for a while."], {"sellprice": 100, "buyprice": 150}) startroom = Room("Crossroads", ["A crossroads between a mountain, a forest, a town, and a plains.", "To the west is a mountain that looms in the distance.\nTo the north is a town named <TODO: name town>.\nTo the east is a bridge over a river, leading to a path that trails off into the distance.\nTo the south is the dark forest you came out of."], {"s": "ft1"}, {}, {}) foresttrail1 = Room("Forest Trail", ["A dark trail that leads to a clearing to the south and a crossroads to the north.", "This place gives you the chills.\nTo the north is a crossroads between two trails.\nTo the south is a rocky clearing."], {"n": "sr"}, {"bx": box}, {}) allrooms = { "sr": startroom, "ft1": foresttrail1, } rprint(align.Align(f"[b green]{title}[/]", "center").center(f"[bold green]{title}[/]")) rprint(align.Align(f"[b]V{version}[/]", "center").center(f"[b]V{version}[/]")) name = input("What is your adventurer's name? ") initplayer(name, startroom) while True: room = player["loc"] rprint(room.passive) command = input(f"\n{player['name']}> ").split() #list commands if command == ["help"]: for command in commands: rprint(f"{command} - {commands[command][0]}") print() #detailed help for specific command elif command[0] == "help" and len(command) >= 2: rprint(f"{commands[command[1]][1]}\n") #look around elif command == ["look"]: rprint(room.detail) for item in room.items: rprint(f"There is a {room.items[item].name} here.") rprint() #movement elif command[0][0] in list(room.directions.keys()) and command[0] in ["north", "west", "east", "south", "up", "down", "n", "w", "e", "s", "u", "d"]: player["loc"] = allrooms[room.directions[command[0][0]]] #if the player tries to move in a direction that they can't elif command[0] in ["north", "west", "east", "south", "up", "down", "n", "w", "e", "s", "u", "d"]: if len(command[0]) == 1: tmpconvert = {"n": "north", "w": "west", "e": "east", "s": "south", "u": "up", "d": "down"} rprint(f"[red]You cannot go {tmpconvert[command[0]]}.") else: rprint(f"[red]You cannot go {command[0]}.") #grab items elif command[0] == "grab" and len(command) >= 2: items = {room.items[item].name:room.items[item] for item in room.items} if command[1] in items: item = items[command[1]] internalname = list(room.items.keys())[list(items.values()).index(item)] player["inventory"][internalname] = item room.items.pop(internalname) rprint(f"[blue_violet]{command[1]} grabbed!") else: if not len(items) == 0: rprint(f"[red]There is no {command[1]} here! There [i]is[/] a {findsimilar(command[1], items)} here. Did you mean that?") else: rprint(f"[red]There are no items here!") #let this code stand as a memorial of what not to do #item = [room.items[item] for item in room.items][[room.items[item].name for item in room.items].index(command[1].lower())] #itemname = list(room.items.keys())[list(room.items.values()).index(item)] #player["inventory"][itemname] = item #room.items[itemname].pop() #unspecified item elif command == ["grab"]: rprint("[red]Grab what?") #drop items elif command[0] == "drop" and len(command) >= 2: items = {player["inventory"][item].name:player["inventory"][item] for item in player["inventory"]} if command[1] in items: item = items[command[1]] internalname = list(player["inventory"].keys())[list(items.values()).index(item)] room.items[internalname] = item player["inventory"].pop(internalname) rprint(f"[blue_violet]{command[1]} dropped!") else: if not len(items) == 0: rprint(f"[red]There is no {command[1]} in your inventory! There [i]is[/] a {findsimilar(command[1], items)} in your inventory. Did you mean that?") else: rprint(f"[red]You don't have any items to drop!") #unspecified item elif command == ["drop"]: rprint("[red]Drop what?") #see detailed description of item in inventory elif command[0] == "inspect" and len(command) == 2: items = {player["inventory"][item].name:player["inventory"][item] for item in player["inventory"]} if command[1] in items: rprint(f"[b blue_violet]{items[command[1]].name.upper()}[/]\n[pale_turquoise1]{items[command[1]].long}[/]") #unspecified item elif command == ["inspect"]: rprint("[red]Inspect what?") #see inventory elif command == ["inventory"] or command == ["i"]: for i in player["inventory"]: item = player["inventory"][i] rprint(f"[b blue_violet]{item.name}[/] [b]-[/] [i pale_turquoise1]{item.short}[/]") if len(player["inventory"]) == 0: rprint("[red]Your inventory is empty!") #clear terminal/cmd prompt elif command == ["clear"]: os.system("cls||clear") #multiplatform clear command! rprint("[green]Cleared!") #changelog elif command == ["changelog"]: rprint(versions[version]) #access specific changelog elif command[0] == "changelog" and len(command) >= 2: #reassamble version names that have spaces name = " ".join(command[1:len(command)]) try: rprint(versions[name]) #if the version doesn't exist, find a similar one except KeyError: rprint(f"[red]'{name}' is not a valid version name. Did you mean '{findsimilar(name, list(versions.keys()))}'?") #quit game elif command == ["quit"] or command == ["q"]: rprint("[b green]Are you [i]sure[/i]?[/b green] (Y/n)") ynprompt = input().lower() if ynprompt in ["y", "yes"]: rprint("[green]Quitting game...") break elif ynprompt in ["n", "no", "nevermind"]: continue else: rprint("[red]Sorry, I don't understand. Can you try again? Valid answers are 'Y', 'Yes', 'N', 'No' (Case insensitive).") #find a similar command else: rprint(f"[red]Command not found. Did you mean '{findsimilar(command[0], list(commands.keys()))}'?")
Last edited by ScratchCatHELLO (June 24, 2021 18:06:22)
- gosoccerboy5
-
1000+ posts
PyRPG (Python Text Adventure)
Wow, this is cool. I'd never be un-lazy enough to actually write all this code
- ScratchCatHELLO
-
1000+ posts
PyRPG (Python Text Adventure)
Wow, this is cool. I'd never be un-lazy enough to actually write all this code
thanks!
I should probably rewrite this so I don't have to write the code to grab items every time there's an item. I should finally stop being lazy and learn how classes work.
- gosoccerboy5
-
1000+ posts
PyRPG (Python Text Adventure)
Whatever you're doing, classes are certainly a good investment to learn learn how classes work.
- ScratchCatHELLO
-
1000+ posts
PyRPG (Python Text Adventure)
Whatever you're doing, classes are certainly a good investment to learn learn how classes work.
here's an expiremental class-based system with movement and two levels of descriptions:
#expiremental version that uses classes class Room: def __init__(self, name, directions, descriptions, items, creatures): self.name = name self.directions = directions self.descriptions = descriptions self.items = items self.creatures = creatures F_E = Room( "Forest_Exit", {}, { "normal": "The trail on which you came.", "detail": "A dark, thin forest trail." }, {}, {} ) F_C = Room( "Forest_Clearing", {}, { "normal": "A rocky clearing in the forest.", "detail": "The trail widens out into a clearing. \nThere's a hole in the ground a few feet deep with a small pond in the center of the clearing." }, {}, {} ) F_P = Room( "Forest_Pond", {}, { "normal": "A pond in the center of the clearing.", "detail": "A frog sits on a lily pad in the pond." }, {}, {} ) F_E.directions["south"] = F_C F_C.directions["north"] = F_E F_C.directions["down"] = F_P F_P.directions["up"] = F_C place = F_E while True: #print(place.name) print(place.descriptions["normal"]) command = input(">") if command in place.directions: place = place.directions[command] elif command == "look": print(place.descriptions["detail"])
the only problem with this is I need to define directions separately from the initialization of the rooms. otherwise, python gets angry at me for referencing variables before assigning them.
- himanmario
-
15 posts
PyRPG (Python Text Adventure)
why are you discussing this on scratch when your using Java? could you not find another thing to discuss java? (if so, thats fine im just wondering)
also, is that c+/c++ cuz if so, sorry for calling it Java.
also, is that c+/c++ cuz if so, sorry for calling it Java.
- ScratchCatHELLO
-
1000+ posts
PyRPG (Python Text Adventure)
why are you discussing this on scratch when your using Java? could you not find another thing to discuss java? (if so, thats fine im just wondering)
also, is that c+/c++ cuz if so, sorry for calling it Java.
it's python
also, Things I'm Making and Creating is for things you're making outside of scratch
also, I don't have accounts anywhere else where I could share this, sorry
- ScratchCatHELLO
-
1000+ posts
PyRPG (Python Text Adventure)
question: is it okay to put Object 1 inside of Object 2 when Object 2 is also in Object 1? It doesn't seem to be breaking anything, but objects that contain each other infinitely is a kinda sketchy thing to do.
- ScratchCatHELLO
-
1000+ posts
PyRPG (Python Text Adventure)
here's an expiremental class-based system with movement and two levels of descriptions:
update: now with objects, a “grab” command and inventory
#expiremental version that uses classes #player class (make it a subclass of a "creature" class?) class Player: def __init__(self, name, flags, inventory, stats): self.name = name self.flags = flags self.inventory = inventory self.stats = stats #item class class Item: def __init__(self, name, detail): self.name = name self.detail = detail #weapon subclass of item class Weapon(Item): def __init__(self, name, detail, atkstr): super().__init__(name, attitude, behaviour, face) self.atkstr = atkstr #room class definition class Room: def __init__(self, name, directions, descriptions, items, creatures): self.name = name self.directions = directions self.descriptions = descriptions self.items = items self.creatures = creatures F_E = Room( "Forest_Exit", {}, { "normal": "The trail on which you came.", "detail": "A dark, thin forest trail." }, {}, {} ) F_C = Room( "Forest_Clearing", {}, { "normal": "A rocky clearing in the forest.", "detail": "The trail widens out into a clearing. \nThere's a hole in the ground a few feet deep with a small pond in the center of the clearing." }, {}, {} ) F_P = Room( "Forest_Pond", {}, { "normal": "A pond in the center of the clearing.", "detail": "A frog sits on a lily pad in the pond." }, {}, {} ) #add links between rooms F_E.directions["south"] = F_C F_C.directions["north"] = F_E F_C.directions["down"] = F_P F_P.directions["up"] = F_C #make a box and place it in the main room box = Item("Box", "mysterious box") F_E.items["box"] = box player = Player("Johnus Doeus", {}, {}) #starting room place = F_E while True: #show the normal description of the room print(place.descriptions["normal"]) #list items in the room for item in place.items: print("There is a " + place.items[item].name + " here") #get input command = input(player.name + ">") #allow player to move if command in place.directions: place = place.directions[command] #deeper descriptions elif command == "look": print(place.descriptions["detail"]) #grabbing objects elif command[0:4] == "grab": #figure out what they're grabbing for item in place.items: if place.items[item].name == command.replace("grab ", ""): #python gets upset when I put the code in this loop tmpitem = item break if tmpitem: print(place.items[tmpitem].name + " grabbed!") #copy item into inventory and remove item from room player.inventory[tmpitem] = place.items[tmpitem] place.items.pop(tmpitem) tmpitem = "" #show the player's inventory (make this better later) elif command == "inventory": print(player.inventory)
- ScratchCatHELLO
-
1000+ posts
PyRPG (Python Text Adventure)
#expiremental version that uses classes import pickle from difflib import SequenceMatcher def findsimilar(thing, inlist): similar = {} for item in inlist: similar[item] = SequenceMatcher(None, item, thing).ratio() return list(reversed(sorted(similar.items(),key=lambda x:x[1])))[0][0] #player class (make it a subclass of a "creature" class?) class Player: def __init__(self, name, flags, inventory, stats): self.name = name self.flags = flags self.inventory = inventory self.stats = stats #item class class Item: def __init__(self, name, description, detail): self.name = name self.description = description self.detail = detail #weapon subclass of item class Weapon(Item): def __init__(self, name, detail, atkstr): super().__init__(name, attitude, behaviour, face) self.atkstr = atkstr #room class definition class Room: def __init__(self, name, directions, descriptions, items, creatures): self.name = name self.directions = directions self.descriptions = descriptions self.items = items self.creatures = creatures F_Ex = Room( "Forest Exit", { "south": "Forest Clearing" }, { "normal": "The trail on which you came.", "detail": "A dark, thin forest trail." }, {}, {} ) F_C = Room( "Forest Clearing", { "north": "Forest Exit", "down": "Forest Pond" }, { "normal": "A rocky clearing in the forest.", "detail": "The trail widens out into a clearing. \nThere's a hole in the ground a few feet deep with a small pond in the center of the clearing. There is a door to the south." }, {}, {} ) F_P = Room( "Forest Pond", { "up": "Forest Clearing" }, { "normal": "A pond in the center of the clearing.", "detail": "A frog sits on a lily pad in the pond." }, {}, {} ) F_En = Room( "Forest Entrance", { "north": "Forest Clearing" }, { "normal": "The entrance to the forest.", "detail": "A dark, thin forest trail. The forest gradually thins into a plains." }, {}, {} ) allrooms = { "Forest Exit": F_Ex, "Forest Clearing": F_C, "Forest Pond": F_P, "Forest Entrance": F_En } allcommands = ["load", "save", "inspect", "inventory", "drop", "grab", "look", "north", "south", "east", "west"] #make a box and place it in the main room box = Item("Box", "mysterious box", "an unmarked cardboard box.") F_Ex.items["box"] = box player = Player("Johnus Doeus", {}, {}, {}) #starting room place = F_Ex while True: #print(place.directions) #show the normal description of the room print(place.descriptions["normal"]) #list items in the room for item in place.items: print("There is a " + place.items[item].name + " here") #get input command = input(player.name + ">") #allow player to move if command in place.directions: place = allrooms[place.directions[command]] elif place == allrooms["Forest Clearing"] and command == "south": print("The door is locked by a password.") if input("What is the password?\n") == "password": place.directions["south"] = 'Forest Entrance' print("The door shudders open.") else: print("Incorrect password.") #deeper descriptions elif command == "look": print(place.descriptions["detail"]) #grabbing objects elif command[0:4] == "grab": if command.replace("grab", ""): #figure out what they're grabbing tmpitem = "" for item in place.items: if place.items[item].name == command.replace("grab ", ""): #python gets upset when I put the code in this loop tmpitem = item break if tmpitem: print(place.items[tmpitem].name + " grabbed!") #copy item into inventory and remove item from room player.inventory[tmpitem] = place.items[tmpitem] place.items.pop(tmpitem) tmpitem = "" else: print("grab what?") elif command[0:4] == "drop": if command.replace("drop", ""): tmpitem = "" for item in player.inventory: if player.inventory[item].name == command.replace("drop ", ""): tmpitem = item break if tmpitem: print(player.inventory[tmpitem].name + " dropped!") #copy item into inventory and remove item from room place.items[tmpitem] = player.inventory[tmpitem] player.inventory.pop(tmpitem) else: print("drop what?") #show the player's inventory (make this better later) elif command == "inventory": for item in player.inventory: print(player.inventory[item].name) print(player.inventory[item].description) elif command[0:8] == "inspect ": for item in player.inventory: if player.inventory[item].name == command.replace("inspect ", ""): print(player.inventory[item].detail) elif command == "save": save = {} save["player"] = player save["place"] = place.name save["rooms"] = {} for room in allrooms: save["rooms"][room] = allrooms[room] with open('savedat2.txt', 'wb') as fh: pickle.dump(save, fh) print("Saved.") elif command == "load": savefile = open("savedat2.txt", "rb") loadedsave = pickle.load(savefile) player = loadedsave["player"] for room in loadedsave["rooms"]: allrooms[room] = loadedsave["rooms"][room] place = allrooms[loadedsave["place"]] print(F_C) print("Loaded.") savefile.close() elif command in allcommands: print("You cannot do that here.") else: print("command '" + command + "' not found.") print("did you mean: " + findsimilar(command, allcommands))
save, load
giving user feedback when the command is not found
added dropping items
- ScratchCatHELLO
-
1000+ posts
PyRPG (Python Text Adventure)
dialog system test:
instructions:
respond by inputting one of the choices given to you
input “goodbye” to exit
The only problem with this is that the dialog dicts are massive, even for short conversations.
But it works, and I don't know how I could make this much smaller.
dialog = { "ribbit": { "text": "Ribbit", "responses": { "A": { "text": "What?", "newdialog": "croak" }, "B": { "text": "Why am I talking to a frog??", "newdialog": "shrug" } } }, "croak": { "text": "Crrrroak", "responses": { "A": { "text": "What??", "newdialog": "ribbit" } } }, "shrug": { "text": "¯\_(ツ)_/¯", "responses": { "A": { "text": "uh... bye" } } } } userresp = "" currentdialog = "ribbit" while not userresp == "goodbye": print("Frog says " + dialog[currentdialog]["text"]) if dialog[currentdialog]["responses"]: responses = dialog[currentdialog]["responses"] for response in responses: print(response + ": " + responses[response]["text"]) else: break userresp = input(">") if userresp in responses: try: currentdialog = dialog[currentdialog]["responses"][userresp]["newdialog"] except: break elif not userresp == "goodbye": print(userresp + " is not a valid response")
instructions:
respond by inputting one of the choices given to you
input “goodbye” to exit
The only problem with this is that the dialog dicts are massive, even for short conversations.
But it works, and I don't know how I could make this much smaller.
- Delta135
-
100+ posts
PyRPG (Python Text Adventure)
Do you know of Repl.it? It supports HTML, CSS, JS, Java, Python 3, Python 2, and more. You can run them inside of a spotlight page, create a post, and even run it outside of the main website! You could upload your text adventure there!
I am Kizuo
I am Kizuo
- mybearworld
-
1000+ posts
PyRPG (Python Text Adventure)
[View post]dialog system test:I'm gonna check it out!print("Snip")
instructions:
respond by inputting one of the choices given to you
input “goodbye” to exit
The only problem with this is that the dialog dicts are massive, even for short conversations.
But it works, and I don't know how I could make this much smaller.
I'm going to copy and paste my game in here…
The trail on which you came.
There is a Box here
Johnus Doeus>box
command 'box' not found.
did you mean: look
The trail on which you came.
There is a Box here
Johnus Doeus>look
A dark, thin forest trail.
The trail on which you came.
There is a Box here
Johnus Doeus>look box
command 'look box' not found.
did you mean: look
The trail on which you came.
There is a Box here
Johnus Doeus>WHAT DO I DO
command 'WHAT DO I DO' not found.
did you mean: west
The trail on which you came.
There is a Box here
Johnus Doeus>west
You cannot do that here.
The trail on which you came.
There is a Box here
Johnus Doeus>north
You cannot do that here.
The trail on which you came.
There is a Box here
Johnus Doeus>east
You cannot do that here.
The trail on which you came.
There is a Box here
Johnus Doeus>south
A rocky clearing in the forest.
Johnus Doeus>what do i do now
command 'what do i do now' not found.
did you mean: inventory
A rocky clearing in the forest.
Johnus Doeus>inventory
A rocky clearing in the forest.
Johnus Doeus>uh
command 'uh' not found.
did you mean: south
A rocky clearing in the forest.
Johnus Doeus>south
The door is locked by a password.
What is the password?
1234
Incorrect password.
A rocky clearing in the forest.
Johnus Doeus>south
The door is locked by a password.
What is the password?
123456
Incorrect password.
A rocky clearing in the forest.
Johnus Doeus>south
The door is locked by a password.
What is the password?
password
The door shudders open.
A rocky clearing in the forest.
Johnus Doeus>south
The entrance to the forest.
Johnus Doeus>south
You cannot do that here.
The entrance to the forest.
Johnus Doeus>okay uh
command 'okay uh' not found.
did you mean: south
The entrance to the forest.
Johnus Doeus>inventory
The entrance to the forest.
Johnus Doeus>south
You cannot do that here.
The entrance to the forest.
Johnus Doeus>i'm confused
command 'i'm confused' not found.
did you mean: inspect
The entrance to the forest.
Johnus Doeus>inspect
You cannot do that here.
The entrance to the forest.
Johnus Doeus>goodbye
command 'goodbye' not found.
did you mean: look
The entrance to the forest.
Johnus Doeus> goodbye
command ' goodbye' not found.
did you mean: look
The entrance to the forest.
Johnus Doeus>UH
command 'UH' not found.
did you mean: west
The entrance to the forest.
Johnus Doeus>
Traceback (most recent call last):
File "e.py", line 105, in <module>
command = input(player.name + ">")
KeyboardInterrupt
- ScratchCatHELLO
-
1000+ posts
PyRPG (Python Text Adventure)
[View post]dialog system test:I'm gonna check it out!print("Snip")
instructions:
respond by inputting one of the choices given to you
input “goodbye” to exit
The only problem with this is that the dialog dicts are massive, even for short conversations.
But it works, and I don't know how I could make this much smaller.
I'm going to copy and paste my game in here…Please look at this xD
yeah, I should probably include instructions. It didn't occur to me because the script was meant to be a test.
also, you were running the wrong script. the “goodbye” command is only for dialog, which I just implemented and haven't posted yet
Do you know of Repl.it? It supports HTML, CSS, JS, Java, Python 3, Python 2, and more. You can run them inside of a spotlight page, create a post, and even run it outside of the main website! You could upload your text adventure there!
I am Kizuo
I know about replit, but I don't have an account :(
- Delta135
-
100+ posts
PyRPG (Python Text Adventure)
[View post]dialog system test:I'm gonna check it out!print("Snip")
instructions:
respond by inputting one of the choices given to you
input “goodbye” to exit
The only problem with this is that the dialog dicts are massive, even for short conversations.
But it works, and I don't know how I could make this much smaller.
I'm going to copy and paste my game in here…Please look at this xD
yeah, I should probably include instructions. It didn't occur to me because the script was meant to be a test.
also, you were running the wrong script. the “goodbye” command is only for dialog, which I just implemented and haven't posted yetDo you know of Repl.it? It supports HTML, CSS, JS, Java, Python 3, Python 2, and more. You can run them inside of a spotlight page, create a post, and even run it outside of the main website! You could upload your text adventure there!
I am Kizuo
I know about replit, but I don't have an account :(
Make one, it's free!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
- ScratchCatHELLO
-
1000+ posts
PyRPG (Python Text Adventure)
Make one, it's free!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!…real estate
I can't yet
believe me, I want to
- -EmeraldThunder-
-
1000+ posts
PyRPG (Python Text Adventure)
I really like this idea. I might actually make a text adventure for my next tutorial.
- ScratchCatHELLO
-
1000+ posts
PyRPG (Python Text Adventure)
I really like this idea. I might actually make a text adventure for my next tutorial.
thanks!
update with dialog and instructions (you may have to fix the instructions, because the string was so long my code editor may have inserted linebreaks):
#expiremental version that uses classes import pickle from difflib import SequenceMatcher #find the item of a list that is closest to a string def findsimilar(thing, inlist): similar = {} for item in inlist: similar[item] = SequenceMatcher(None, item, thing).ratio() return list(reversed(sorted(similar.items(),key=lambda x:x[1])))[0][0] #frog's dialog frogdialog = { "INITIAL": "ribbit", "ribbit": { "text": "Ribbit", "responses": { "A": { "text": "What?", "newdialog": "croak" }, "B": { "text": "Why am I talking to a frog??", "newdialog": "shrug" } } }, "croak": { "text": "Crrrroak", "responses": { "A": { "text": "What??", "newdialog": "ribbit" } } }, "shrug": { "text": "¯\_(ツ)_/¯", "responses": { "A": { "text": "uh... bye" } } } } class Creature: def __init__(self, name, dialog, stats, attackable): self.name = name self.dialog = dialog self.stats = stats self.attackable = attackable class Player: def __init__(self, name, flags, inventory, stats): self.name = name self.flags = flags self.inventory = inventory self.stats = stats #item class class Item: def __init__(self, name, description, detail): self.name = name self.description = description self.detail = detail #weapon subclass of item class Weapon(Item): def __init__(self, name, description, detail, atkstr): super().__init__(name, description, detail) self.atkstr = atkstr #room class definition class Room: def __init__(self, name, directions, descriptions, items, creatures): self.name = name self.directions = directions self.descriptions = descriptions self.items = items self.creatures = creatures F_Ex = Room( "Forest Exit", { "south": "Forest Clearing" }, { "normal": "The trail on which you came.", "detail": "A dark, thin forest trail. The trail continues south." }, {}, {} ) F_C = Room( "Forest Clearing", { "north": "Forest Exit", "down": "Forest Pond" }, { "normal": "A rocky clearing in the forest.", "detail": "The trail widens out into a clearing. \nThere's a hole in the ground a few feet deep with a small pond in the center of the clearing that you can climb into. \nThere is a door to the south.\n There is a trail to the north." }, {}, {} ) F_P = Room( "Forest Pond", { "up": "Forest Clearing" }, { "normal": "A pond in the center of the clearing.", "detail": "A frog sits on a lily pad in the pond.\n You can climb back out of the hole." }, {}, {} ) F_En = Room( "Forest Entrance", { "north": "Forest Clearing" }, { "normal": "The entrance to the forest.", "detail": "A dark, thin forest trail. The forest gradually thins into a plains.\nYou may go north back into the clearing." }, {}, {} ) allrooms = { "Forest Exit": F_Ex, "Forest Clearing": F_C, "Forest Pond": F_P, "Forest Entrance": F_En } allcommands = ["load", "save", "inspect", "inventory", "help", "instructions", "drop", "grab", "look at", "look", "up", "down", "north", "south", "east", "west"] #make a box and place it in the start room box = Item("box", "a mysterious box", "an unmarked cardboard box.") F_Ex.items["box"] = box #make a frog and place it in the pond room frog = Creature("frog", frogdialog, {}, False) F_P.creatures["frog"] = frog name = input("What is your name?\n") if name: player = Player(name, {}, {}, {}) else: player = Player("Johnus Doeus", {}, {}, {}) #starting room place = F_Ex #allow user to quit command = "" while not command == "quit": #show the normal description of the room print(place.descriptions["normal"]) #list items in the room for item in place.items: print("There is a " + place.items[item].name + " here.") #list creatures in the room for creature in place.creatures: print("There is a " + place.creatures[creature].name + " in the room.") #get input command = input(player.name + ">") #allow player to move if command in place.directions: place = allrooms[place.directions[command]] #door elif place == allrooms["Forest Clearing"] and command == "south": print("The door is locked by a password.") if input("What is the password?\n") == "password": place.directions["south"] = 'Forest Entrance' print("The door shudders open.") else: print("Incorrect password.") #print all command names (add descriptions?) elif command == "help": for command in allcommands: print(command) #print instuctions elif command == "instructions": print("This is just a test level, and there isn't much to just yet.\nYou can type 'help' for a list of commands.\nYou can type 'quit' to quit.\nYou can look around with 'look'\nYou can pick up and drop items with 'grab ___' and 'drop ___'\nYou can open your inventory with 'inventory'\nYou can inspect items you are holding with 'inspect ___'\nYou can look at items you aren't holding with 'look at ___'\nYou can talk to creatures by typing 'talk to ___'\nYou can load and save (EXPIREMENTAL) with 'load' and 'save'") #allow player to look at items they aren't holding elif command[0:7] == "look at": if command.replace("look at", ""): for item in place.items: if place.items[item].name == command.replace("look at ", ""): print(place.items[item].description) else: print("look at what?") #deeper descriptions elif command == "look": print(place.descriptions["detail"]) #allow player to grab items elif command[0:4] == "grab": if command.replace("grab", ""): #figure out what they're grabbing tmpitem = "" for item in place.items: if place.items[item].name == command.replace("grab ", ""): #python gets upset when I put the code in this loop tmpitem = item break if tmpitem: print(place.items[tmpitem].name + " grabbed!") #copy item into inventory and remove item from room player.inventory[tmpitem] = place.items[tmpitem] place.items.pop(tmpitem) tmpitem = "" else: print("There is no " + command.replace("grab ", "") + " in this room.") else: print("Grab what?") #allow player to drop items (does the inverse of "grab") elif command[0:4] == "drop": if command.replace("drop", ""): tmpitem = "" for item in player.inventory: if player.inventory[item].name == command.replace("drop ", ""): tmpitem = item break if tmpitem: print(player.inventory[tmpitem].name + " dropped!") #copy item into inventory and remove item from room place.items[tmpitem] = player.inventory[tmpitem] player.inventory.pop(tmpitem) else: print("There is no " + command.replace("drop ", "") + " in your inventory.") else: print("Drop what?") #show the player's inventory (make this better later) elif command == "inventory": for item in player.inventory: print(player.inventory[item].name) print(player.inventory[item].description) #show detailed description for items in inventory elif command[0:7] == "inspect": if command.replace("inspect ", ""): for item in player.inventory: if player.inventory[item].name == command.replace("inspect ", ""): print(player.inventory[item].detail) else: print("Inspect what?") #allow player to talk to creatures elif command[0:7] == "talk to": activecreature = "" #figure out what creature the player is talking to for creature in place.creatures: if place.creatures[creature].name == command.replace("talk to ", ""): activecreature = place.creatures[creature] break if activecreature: userresp = "" #get the initial dialog snippet currentdialog = activecreature.dialog[activecreature.dialog["INITIAL"]] while not userresp == "goodbye": print("The " + activecreature.name + " says '" + currentdialog["text"] + "'") #print possible responses for response in currentdialog["responses"]: print(response + ": " + currentdialog["responses"][response]["text"]) userresp = input(">").upper() if userresp in currentdialog["responses"]: try: print("You say '" + currentdialog["responses"][userresp]["text"] + "' to the " + activecreature.name) #set the current dialog snippet to the new dialog snippet currentdialog = activecreature.dialog[currentdialog["responses"][userresp]["newdialog"]] except: break elif not userresp == "goodbye": #tell user if they didn't type a valid response print("'" + userresp + "' is not a valid response.") #save (not updated) elif command == "save": save = {} save["player"] = player save["place"] = place.name save["rooms"] = {} for room in allrooms: save["rooms"][room] = allrooms[room] with open('savedat2.txt', 'wb') as fh: pickle.dump(save, fh) print("Saved.") #load (not updated) elif command == "load": savefile = open("savedat2.txt", "rb") loadedsave = pickle.load(savefile) player = loadedsave["player"] for room in loadedsave["rooms"]: allrooms[room] = loadedsave["rooms"][room] place = allrooms[loadedsave["place"]] print(F_C) print("Loaded.") savefile.close() #if the command is valid, but cannot be done in the current room elif command in allcommands: print("You cannot do that here.") #if the command is not valid (and is not "quit"), print a similar command elif not command == "quit": print("command '" + command + "' not found.") print("did you mean: " + findsimilar(command, allcommands))
truely ground-breaking dialog
- Discussion Forums
- » Things I'm Making and Creating
-
» PyRPG (Python Text Adventure)