From 8e06e3a5d900f40778c75e89553bb1afbd95ca3a Mon Sep 17 00:00:00 2001 From: Ahmed Yusuf <yusufa7@cardiff.ac.uk> Date: Tue, 18 Oct 2022 15:25:18 +0100 Subject: [PATCH] add files --- Group_game/game.py | 378 +++++++++++++++++++++++++++++++++++++++ Group_game/gameparser.py | 101 +++++++++++ Group_game/items.py | 51 ++++++ Group_game/map.py | 81 +++++++++ Group_game/player.py | 7 + 5 files changed, 618 insertions(+) create mode 100644 Group_game/game.py create mode 100644 Group_game/gameparser.py create mode 100644 Group_game/items.py create mode 100644 Group_game/map.py create mode 100644 Group_game/player.py diff --git a/Group_game/game.py b/Group_game/game.py new file mode 100644 index 0000000..27be0ff --- /dev/null +++ b/Group_game/game.py @@ -0,0 +1,378 @@ +#!/usr/bin/python3 + +from map import rooms +from player import * +from items import * +from gameparser import * + + + +def list_of_items(items): + """This function takes a list of items (see items.py for the definition) and + returns a comma-separated list of item names (as a string). For example: + + >>> list_of_items([item_pen, item_handbook]) + 'a pen, a student handbook' + + >>> list_of_items([item_id]) + 'id card' + + >>> list_of_items([]) + '' + + >>> list_of_items([item_money, item_handbook, item_laptop]) + 'money, a student handbook, laptop' + + """ + new_list = "" + for number in range(len(items)): + if number == len(items) - 1: + new_list += items[number]["name"] + else: + new_list += items[number]["name"] + ", " + + return new_list + + +def print_room_items(room): + """This function takes a room as an input and nicely displays a list of items + found in this room (followed by a blank line). If there are no items in + the room, nothing is printed. See map.py for the definition of a room, and + items.py for the definition of an item. This function uses list_of_items() + to produce a comma-separated list of item names. For example: + + >>> print_room_items(rooms["Reception"]) + There is a pack of biscuits, a student handbook here. + <BLANKLINE> + + >>> print_room_items(rooms["Office"]) + There is a pen here. + <BLANKLINE> + + >>> print_room_items(rooms["Admins"]) + + (no output) + + Note: <BLANKLINE> here means that doctest should expect a blank line. + + """ + + if room["items"]: + print("There is", list_of_items(room["items"]), "here." + "\n") + + + +def print_inventory_items(items): + """This function takes a list of inventory items and displays it nicely, in a + manner similar to print_room_items(). The only difference is in formatting: + print "You have ..." instead of "There is ... here.". For example: + + >>> print_inventory_items(inventory) + You have id card, laptop, money. + <BLANKLINE> + + """ + if items: + print("You have", list_of_items(items) + "." + "\n") + + +def print_room(room): + """This function takes a room as an input and nicely displays its name + and description. The room argument is a dictionary with entries "name", + "description" etc. (see map.py for the definition). The name of the room + is printed in all capitals and framed by blank lines. Then follows the + description of the room and a blank line again. If there are any items + in the room, the list of items is printed next followed by a blank line + (use print_room_items() for this). For example: + + >>> print_room(rooms["Office"]) + <BLANKLINE> + THE GENERAL OFFICE + <BLANKLINE> + You are standing next to the cashier's till at + 30-36 Newport Road. The cashier looks at you with hope + in their eyes. If you go west you can return to the + Queen's Buildings. + <BLANKLINE> + There is a pen here. + <BLANKLINE> + + >>> print_room(rooms["Reception"]) + <BLANKLINE> + RECEPTION + <BLANKLINE> + You are in a maze of twisty little passages, all alike. + Next to you is the School of Computer Science and + Informatics reception. The receptionist, Matt Strangis, + seems to be playing an old school text-based adventure + game on his computer. There are corridors leading to the + south and east. The exit is to the west. + <BLANKLINE> + There is a pack of biscuits, a student handbook here. + <BLANKLINE> + + >>> print_room(rooms["Admins"]) + <BLANKLINE> + MJ AND SIMON'S ROOM + <BLANKLINE> + You are leaning agains the door of the systems managers' + room. Inside you notice Matt "MJ" John and Simon Jones. They + ignore you. To the north is the reception. + <BLANKLINE> + + Note: <BLANKLINE> here means that doctest should expect a blank line. + """ + # Display room name + print() + print(room["name"].upper()) + print() + # Display room description + print(room["description"]) + print() + print_room_items(room) + + # + # COMPLETE ME! + # + +def exit_leads_to(exits, direction): + """This function takes a dictionary of exits and a direction (a particular + exit taken from this dictionary). It returns the name of the room into which + this exit leads. For example: + + >>> exit_leads_to(rooms["Reception"]["exits"], "south") + "MJ and Simon's room" + >>> exit_leads_to(rooms["Reception"]["exits"], "east") + "your personal tutor's office" + >>> exit_leads_to(rooms["Tutor"]["exits"], "west") + 'Reception' + """ + return rooms[exits[direction]]["name"] + + +def print_exit(direction, leads_to): + """This function prints a line of a menu of exits. It takes a direction (the + name of an exit) and the name of the room into which it leads (leads_to), + and should print a menu line in the following format: + + GO <EXIT NAME UPPERCASE> to <where it leads>. + + For example: + >>> print_exit("east", "you personal tutor's office") + GO EAST to you personal tutor's office. + >>> print_exit("south", "MJ and Simon's room") + GO SOUTH to MJ and Simon's room. + """ + print("GO " + direction.upper() + " to " + leads_to + ".") + + +def print_menu(exits, room_items, inv_items): + """This function displays the menu of available actions to the player. The + argument exits is a dictionary of exits as exemplified in map.py. The + arguments room_items and inv_items are the items lying around in the room + and carried by the player respectively. The menu should, for each exit, + call the function print_exit() to print the information about each exit in + the appropriate format. The room into which an exit leads is obtained + using the function exit_leads_to(). Then, it should print a list of commands + related to items: for each item in the room print + + "TAKE <ITEM ID> to take <item name>." + + and for each item in the inventory print + + "DROP <ITEM ID> to drop <item name>." + + For example, the menu of actions available at the Reception may look like this: + + You can: + GO EAST to your personal tutor's office. + GO WEST to the parking lot. + GO SOUTH to MJ and Simon's room. + TAKE BISCUITS to take a pack of biscuits. + TAKE HANDBOOK to take a student handbook. + DROP ID to drop your id card. + DROP LAPTOP to drop your laptop. + DROP MONEY to drop your money. + What do you want to do? + + """ + print("You can:") + # Iterate over available exits + for direction in exits: + # Print the exit name and where it leads to + print_exit(direction, exit_leads_to(exits, direction)) + for items in room_items: + print("TAKE", items["id"], "to take", items["name"] + ".") + + for items in inv_items: + print("DROP", items["id"], "to drop", items["name"] + ".") + # + # COMPLETE ME! + # + + print("What do you want to do?") + + +def is_valid_exit(exits, chosen_exit): + """This function checks, given a dictionary "exits" (see map.py) and + a players's choice "chosen_exit" whether the player has chosen a valid exit. + It returns True if the exit is valid, and False otherwise. Assume that + the name of the exit has been normalised by the function normalise_input(). + For example: + + >>> is_valid_exit(rooms["Reception"]["exits"], "south") + True + >>> is_valid_exit(rooms["Reception"]["exits"], "up") + False + >>> is_valid_exit(rooms["Parking"]["exits"], "west") + False + >>> is_valid_exit(rooms["Parking"]["exits"], "east") + True + """ + return chosen_exit in exits + + +def execute_go(direction): + """This function, given the direction (e.g. "south") updates the current room + to reflect the movement of the player if the direction is a valid exit + (and prints the name of the room into which the player is + moving). Otherwise, it prints "You cannot go there." + """ + global current_room + if is_valid_exit(current_room["exits"], direction): + new_room = move(current_room["exits"],direction) + current_room = new_room + return current_room + else: + print("you cannot go there") + + +def execute_take(item_id): + """This function takes an item_id as an argument and moves this item from the + list of items in the current room to the player's inventory. However, if + there is no such item in the room, this function prints + "You cannot take that." + """ + found = False + for items in current_room["items"]: + if item_id == items["id"]: + inventory.append(items) + current_room["items"].remove(items) + found = True + + if not found: + print("You cannot take that.") + + + +def execute_drop(item_id): + """This function takes an item_id as an argument and moves this item from the + player's inventory to list of items in the current room. However, if there is + no such item in the inventory, this function prints "You cannot drop that." + """ + found = False + for items in inventory: + if items["id"] == item_id: + current_room["items"].append(items) + inventory.remove(items) + found = True + + if not found: + print("You cannot drop that.") + + + +def execute_command(command): + """This function takes a command (a list of words as returned by + normalise_input) and, depending on the type of action (the first word of + the command: "go", "take", or "drop"), executes either execute_go, + execute_take, or execute_drop, supplying the second word as the argument. + + """ + + if 0 == len(command): + return + + if command[0] == "go": + if len(command) > 1: + execute_go(command[1]) + else: + print("Go where?") + + elif command[0] == "take": + if len(command) > 1: + execute_take(command[1]) + else: + print("Take what?") + + elif command[0] == "drop": + if len(command) > 1: + execute_drop(command[1]) + else: + print("Drop what?") + + else: + print("This makes no sense.") + + +def menu(exits, room_items, inv_items): + """This function, given a dictionary of possible exits from a room, and a list + of items found in the room and carried by the player, prints the menu of + actions using print_menu() function. It then prompts the player to type an + action. The players's input is normalised using the normalise_input() + function before being returned. + + """ + + # Display menu + print_menu(exits, room_items, inv_items) + + # Read player's input + user_input = input("> ") + + # Normalise the input + normalised_user_input = normalise_input(user_input) + + return normalised_user_input + + +def move(exits, direction): + """This function returns the room into which the player will move if, from a + dictionary "exits" of avaiable exits, they choose to move towards the exit + with the name given by "direction". For example: + + >>> move(rooms["Reception"]["exits"], "south") == rooms["Admins"] + True + >>> move(rooms["Reception"]["exits"], "east") == rooms["Tutor"] + True + >>> move(rooms["Reception"]["exits"], "west") == rooms["Office"] + False + """ + + # Next room to go to + return rooms[exits[direction]] + + +# This is the entry point of our program +def main(): + + # Main game loop + while True: + # Display game status (room description, inventory etc.) + print_room(current_room) + print_inventory_items(inventory) + + # Show the menu with possible actions and ask the player + command = menu(current_room["exits"], current_room["items"], inventory) + + # Execute the player's command + execute_command(command) + + + +# Are we being run as a script? If so, run main(). +# '__main__' is the name of the scope in which top-level code executes. +# See https://docs.python.org/3.4/library/__main__.html for explanation +if __name__ == "__main__": + main() + diff --git a/Group_game/gameparser.py b/Group_game/gameparser.py new file mode 100644 index 0000000..9336887 --- /dev/null +++ b/Group_game/gameparser.py @@ -0,0 +1,101 @@ +import string + +# List of "unimportant" words (feel free to add more) +skip_words = ['a', 'about', 'all', 'an', 'another', 'any', 'around', 'at', + 'bad', 'beautiful', 'been', 'better', 'big', 'can', 'every', 'for', + 'from', 'good', 'have', 'her', 'here', 'hers', 'his', 'how', + 'i', 'if', 'in', 'into', 'is', 'it', 'its', 'large', 'later', + 'like', 'little', 'main', 'me', 'mine', 'more', 'my', 'now', + 'of', 'off', 'oh', 'on', 'please', 'small', 'some', 'soon', + 'that', 'the', 'then', 'this', 'those', 'through', 'till', 'to', + 'towards', 'until', 'us', 'want', 'we', 'what', 'when', 'why', + 'wish', 'with', 'would'] + + +def filter_words(words, skip_words): + """This function takes a list of words and returns a copy of the list from + which all words provided in the list skip_words have been removed. + For example: + + >>> filter_words(["help", "me", "please"], ["me", "please"]) + ['help'] + + >>> filter_words(["go", "south"], skip_words) + ['go', 'south'] + + >>> filter_words(['how', 'about', 'i', 'go', 'through', 'that', 'little', 'passage', 'to', 'the', 'south'], skip_words) + ['go', 'passage', 'south'] + + """ + new_list = [] + + for elements in words: + found = False + for word in skip_words: + if elements == word: + found = True + if found == False: + new_list.append(elements) + + return new_list + + +def remove_punct(text): + """This function is used to remove all punctuation + marks from a string. Spaces do not count as punctuation and should + not be removed. The funcion takes a string and returns a new string + which does not contain any puctuation. For example: + + >>> remove_punct("Hello, World!") + 'Hello World' + >>> remove_punct("-- ...Hey! -- Yes?!...") + ' Hey Yes' + >>> remove_punct(",go!So.?uTh") + 'goSouTh' + """ + no_punct = "" + for char in text: + if not (char in string.punctuation): + no_punct = no_punct + char + + return no_punct + + +def normalise_input(user_input): + """This function removes all punctuation from the string and converts it to + lower case. It then splits the string into a list of words (also removing + any extra spaces between words) and further removes all "unimportant" + words from the list of words using the filter_words() function. The + resulting list of "important" words is returned. For example: + + >>> normalise_input(" Go south! ") + ['go', 'south'] + >>> normalise_input("!!! tAkE,. LAmp!?! ") + ['take', 'lamp'] + >>> normalise_input("HELP!!!!!!!") + ['help'] + >>> normalise_input("Now, drop the sword please.") + ['drop', 'sword'] + >>> normalise_input("Kill ~ tHe :- gObLiN,. wiTH my SWORD!!!") + ['kill', 'goblin', 'sword'] + >>> normalise_input("I would like to drop my laptop here.") + ['drop', 'laptop'] + >>> normalise_input("I wish to take this large gem now!") + ['take', 'gem'] + >>> normalise_input("How about I go through that little passage to the south...") + ['go', 'passage', 'south'] + + """ + # Remove punctuation and convert to lower case + no_punct = remove_punct(user_input).lower() + sentence = no_punct.strip() + new_list = sentence.split() + return filter_words(new_list,skip_words) + + + + + # + # COMPLETE ME! + # + diff --git a/Group_game/items.py b/Group_game/items.py new file mode 100644 index 0000000..3a9e0f2 --- /dev/null +++ b/Group_game/items.py @@ -0,0 +1,51 @@ +item_id = { + "id": "id", + + "name": "id card", + + "description": + """You new shiny student ID card. Expires 1 June 2017. +You wonder why they have printed a suicide hotline number on it?...""" +} + +item_laptop = { + "id": "laptop", + + "name": "laptop", + + "description": + "It has seen better days. At least it has a WiFi card!" +} + +item_money = { + "id": "money", + + "name": "money", + + "description": + "This wad of cash is barely enough to pay your tuition fees." +} + +item_biscuits = { + "id": "biscuits", + + "name": "a pack of biscuits", + + "description": "A pack of biscuits." +} + +item_pen = { + "id": "pen", + + "name": "a pen", + + "description": "A basic ballpoint pen." +} + +item_handbook = { + "id": "handbook", + + "name": "a student handbook", + + "description": "This student handbook explains everything. Seriously." +} diff --git a/Group_game/map.py b/Group_game/map.py new file mode 100644 index 0000000..0b67e92 --- /dev/null +++ b/Group_game/map.py @@ -0,0 +1,81 @@ +from items import * + +room_reception = { + "name": "Reception", + + "description": + """You are in a maze of twisty little passages, all alike. +Next to you is the School of Computer Science and +Informatics reception. The receptionist, Matt Strangis, +seems to be playing an old school text-based adventure +game on his computer. There are corridors leading to the +south and east. The exit is to the west.""", + + "exits": {"south": "Admins", "east": "Tutor", "west": "Parking"}, + + "items": [item_biscuits, item_handbook] +} + +room_admins = { + "name": "MJ and Simon's room", + + "description": + """You are leaning agains the door of the systems managers' +room. Inside you notice Matt "MJ" John and Simon Jones. They +ignore you. To the north is the reception.""", + + "exits": {"north": "Reception"}, + + "items": [] +} + +room_tutor = { + "name": "your personal tutor's office", + + "description": + """You are in your personal tutor's office. He intently +stares at his huge monitor, ignoring you completely. +On the desk you notice a cup of coffee and an empty +pack of biscuits. The reception is to the west.""", + + "exits": {"west": "Reception"}, + + "items": [] +} + +room_parking = { + "name": "the parking lot", + + "description": + """You are standing in the Queen's Buildings parking lot. +You can go south to the COMSC reception, or east to the +general office.""", + + "exits": {"east": "Office", "south": "Reception"}, + + "items": [] +} + +room_office = { + "name": "the general office", + + "description": + """You are standing next to the cashier's till at +30-36 Newport Road. The cashier looks at you with hope +in their eyes. If you go west you can return to the +Queen's Buildings.""", + + "exits": {"west": "Parking"}, + + "items": [item_pen] +} + + + +rooms = { + "Reception": room_reception, + "Admins": room_admins, + "Tutor": room_tutor, + "Parking": room_parking, + "Office": room_office +} diff --git a/Group_game/player.py b/Group_game/player.py new file mode 100644 index 0000000..d2bc130 --- /dev/null +++ b/Group_game/player.py @@ -0,0 +1,7 @@ +from items import * +from map import rooms + +inventory = [item_id, item_laptop, item_money] + +# Start game at the reception +current_room = rooms["Reception"] -- GitLab