Showing posts with label OOP. Show all posts
Showing posts with label OOP. Show all posts

Friday, February 8, 2019

Building your world - part seven: movement

Refactoring what we have

The existing test program is a bit awkward, especially for me as I have to remember to remove the actual username and passwords when pasting them into the blog.

So, first off create a new file called adventureconnection.py.


import mysql.connector
def make_connection():
    # Create a database connection using the host, user name, password and database name
    mydb = mysql.connector.connect(
    host="<yourusername>.mysql.pythonanywhere-services.com",
    user="<yourusername>",
    passwd="<mysqlpassword>",
    database="<yourusername>$adventure"


    )
    return mydb


Now either modify the testroom.py file or create a new one. I have created a new one called testadventure.py.

Import the Room class, then import the contents of adventure connection. The make _connection function can then be called to make the database connection.

from room import Room
import adventureconnection
mydb = adventureconnection.make_connection()
mycursor = mydb.cursor()



aroom=Room(3,mycursor)

print(aroom.get_details())

Output:
Ballroom======A room whose floor is covered in brightly coloured balls.There is a grand door to the eastNone


Movement

At this point there is only one player, so we can store the location in the program.

Modification to the Room class

The Room class needs a method that returns the room id in the supplied direction. If there is no link in that direction, it just returns the current room id.

# Actions
    def move(self,direction):
        if direction in self.linked_rooms:
            return self.linked_rooms[direction].get_destinationID()
        else:
            return self.roomID

Modification to the testadventure code




First create your cursor for the database access.
Then set the player's initial location (room one)
Loop while the player's location is not 3
  Get current room
  Print room description
  Get command
  If command is a direction then 
    Get room number in that direction 
    If the room number is unchanged then
      You cannot go that way
    else
      Change the location
End loop
Print Exit message

from room import Room
import adventureconnection
mydb=adventureconnection.make_connection()
mycursor = mydb.cursor()

player_location=1
while player_location!=3:

    current_room=Room(player_location,mycursor)
    current_room.get_details()
    command=input("> ")
    if command in("north","south","east","west"):
        print("Go "+command)
        new_location=current_room.move(command)
        if player_location==new_location:
            print("You cannot go " +command)
        else:
            player_location=new_location

print("And you have left the building...")

Testing the code:
Kitchen======
A bright shiny IKEA kitchenThere is a plain door to the south> northGo northYou cannot go northKitchen======A bright shiny IKEA kitchenThere is a plain door to the south> southGo southDining Hall======A room containing pale Scandinavian furnitureThere is a discrete door to the northThere is a grand door to the west> westGo westAnd you have left the building...






Building your world - part six: extending the Room class to display the links

Displaying the links

Currently when we instantiate (create) a room, we pass the room id to the creator. Now that room id also identifies the source room, so we can add the code to retrieve the links to the Room class.

The Link class

The links need somewhere to store them, and as the direction will be unique for each room, we will use a Dictionary.

The Link class will store the room id (source room id), where the link goes (destination id), the direction and the description of the link.

class Link():
    def __init__(self,sourceID,destinationID,direction,description):
        self.sourceID=sourceID
        self.destinationID=destinationID
        self.direction=direction
        self.description=description

    # Getters and Setters
    def get_sourceID(self):
        return self.sourceID

    def get_destinationID(self):
        return self.destinationID

    def get_direction(self):
        return self.direction

    def get_description(self):
        return self.description

Adding Links to the Room class

So the first modification is to the creator:
    def __init__(self,room_id,acursor):
        sql="SELECT * FROM rooms where roomID=%s "
        roomID=(str(room_id),)

        acursor.execute(sql,roomID)

        myresult = acursor.fetchall()

        for x in myresult:
            self.roomID=x[0]
            self.name=x[1]
            self.description=x[2]
        self.linked_rooms = {}
    # Add linked rooms
        sql="select destinationRoomID,direction,description from               links where sourceRoomID=%s"

        acursor.execute(sql,roomID)

        myresult = acursor.fetchall()

        for x in myresult:
            newLink=Link(self.roomID,x[0],x[1],x[2])
            self.linked_rooms[newLink.get_direction()]=newLink

The other modification is to extend the get_details method.
    def get_details(self):
        print(self.get_name())
        print("======")
        print(self.get_description())
        for direction in self.linked_rooms:
            link=self.linked_rooms[direction]
            print("There is " + link.get_description()+" to the "+direction)

Now additional changes will need to be made as we continue development, especially once we get to moving between rooms, and when this progresses to being a web application.

Testing the changes

Using the existing testroom.py code, you can examine the rooms by changing the room ID here:
   aroom=Room(1,mycursor)
   print(aroom.get_details())

Kitchen======A bright shiny IKEA kitchenThere is a plain door to the southNone>>>

   aroom=Room(2,mycursor)
   print(aroom.get_details())
Dining Hall======A room containing pale Scandinavian furnitureThere is a discrete door to the NorthThere is a grand door to the westNone>>>

   aroom=Room(3,mycursor)
   print(aroom.get_details())
Ballroom======A room whose floor is covered in brightly coloured balls.There is a grand door to the eastNone>>>

Next, moving between rooms.

References

https://www.w3schools.com/python/python_dictionaries.asp

Thursday, February 7, 2019

Building your world - part four: the Room class

The Room class

The Room class as developed on the course has a creator that takes room name because they are being created from scratch. However for this project, the room name and description exist on the database. This means the creator(__init__) will take a room ID and a database cursor as parameters.
  
class Room():
    def __init__(self,room_id,acursor):
        sql="SELECT * FROM rooms where roomID=%s "
        roomID=(str(room_id),)

        acursor.execute(sql,roomID)

        myresult = acursor.fetchall()

        for x in myresult:
            self.roomID=x[0]
            self.name=x[1]
            self.description=x[2]

    # Getters and Setters

    def get_description(self):
        return self.description

    def get_name(self):
        return self.name

    def get_details(self):
        print(self.get_name())
        print("======")
        print(self.get_description())




Here is the test code (testroom.py)

from room import Room
import mysql.connector
mydb = mysql.connector.connect(
  host="<yourusername>.mysql.pythonanywhere-services.com",
  user="<yourusername>",
  passwd="<mysqlpassword>",
  database="<yourusername>$adventure"
)
mycursor = mydb.cursor()



aroom=Room(1,mycursor)
print(aroom.get_details())

Kitchen======A bright shiny IKEA kitchenNone

Building your world - part two: creating your database and the first room

Creating the database

This project will be created using PythonAnywhere, if you are using another development environment, you may need to change the process.

So, once you are in your PythonAnywhere console, click on the Databases tab.

Scroll down to the Create Database option.
Type in the new database name, in this case: "adventure", and click on Create.

The new database will be added to the list under Your Databases.

Make sure you have not got two existing consoles (the limit on the free version). If you do, then you will need to go the Consoles tab and close one.

Click on the option to start a console on <your user name>$adventure.

The database is empty, you can check by entering the command show tables; at the command prompt. This will return an empty set message.

Creating your first table

The first table we require is rooms.
This will have the following fields:
  • an id number (an integer which will be auto incremented  so we do not need to set a value).
  • A name (up to twenty characters)
  • A description (up to one hundred characters)
At the command prompt type:
create table rooms( 
     roomID INT NOT NULL AUTO_INCREMENT,
     name VARCHAR(20) NOT NULL,
     description VARCHAR(100) NOT NULL,
     PRIMARY KEY(roomID)
);
Press return and it should add the table.

You can check by entering the command show tables; at the command prompt. 
mysql> show tables;+--------------------------------------+| Tables_in_technologyisnotd$adventure |+--------------------------------------+| rooms |+--------------------------------------+1 row in set (0.00 sec)

Of course there is nothing in there at the moment:
mysql> select * from rooms;Empty set (0.00 sec)

Populating the first room

To add some data to the table, enter the following at the command prompt:

insert into rooms(name,description) values('Kitchen','A bright shiny IKEA kitchen');

Now when you select from the table, you will see the first room.
mysql> select * from rooms;+--------+---------+-----------------------------+| roomID | name | description |+--------+---------+-----------------------------+| 1 | Kitchen | A bright shiny IKEA kitchen |+--------+---------+-----------------------------+1 row in set (0.01 sec)



Building your world - part one: what is a room?

What is a room?

You could write essays, even multi-volume books on this question, but what we are after is the bare skeleton that is required for our adventure.
Now a lot of this was covered on the course, but a room will have the following characteristics: 
  1.         A Name
  2.         A Description
  3.         A list of links to other rooms
  4.         Who is in there
  5.         What is in there
On the course, a class was developed to contain this information. Now for persistence we will be using a MySQL database to contain the information. This will be read into a Python class which the program will then use to describe the environment and allow interaction.

Who and what will be handled later, so the key information is the name, the description and the links. In addition we will also need to have a room identifier, an integer that we can use elsewhere in the program.