Python Forum
Using classes for room movement (text game)
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Using classes for room movement (text game)
#1
Hello again. This time, I'm using a class to define different rooms, but am having trouble moving between them whenever I run the program:
class Rooms:

    def __init__(self, name, desc, co_x, co_y, directions):
        self.name = name
        self.desc = desc
        self.co_x = co_x
        self.co_y = co_y
        self.loc = (self.co_x, self.co_y)
        self.directions = directions

    def __str__(self):
        return f' {self.name}, {self.desc}, {self.co_x}, {self.co_y}'


room1 = Rooms('Room1', 'the first room', 0, 0, ['north', 'east',])
room2 = Rooms('Room2', 'the second room', 0, 1, ['south',])

current_room = room1


while True:
    command = input('Enter a command: ')
    print(current_room)
    if current_room.loc == (0, 0):
        current_room = room1
    if current_room.loc == (0, 1):
        current_room = room2
    if command in current_room.directions:
        if command == 'north':
            current_room.co_y = current_room.co_y + 1
I was hoping that when I changed the current_room.co_y by adding 1, the program would check current_room.loc and see that it had changed to (0, 1), but that isn't the case. Is there an easier, or more efficient way to set this up? I've been searching around and found a text rpg tutorial but I don't want to copy the tutorial's code since I won't learn anything that way. I understand that the program is just adding one to the current room's y value every time the command is 'north'. However, I want it to change to a different room via the location each time the command is inputted, if there is a room in that direction.
Reply
#2
One thing to do is store them by coordinate in a dictionary. You can even do this as a class attribute and automate it with __init__:

class Rooms:

    map = {}
 
    def __init__(self, name, desc, co_x, co_y, directions):
        self.name = name
        self.desc = desc
        self.co_x = co_x
        self.co_y = co_y
        self.loc = (self.co_x, self.co_y)
        Rooms.map[self.loc] = self
        self.directions = directions
 
    def __str__(self):
        return f' {self.name}, {self.desc}, {self.co_x}, {self.co_y}'
Now you get the current room from the dictionary, and move around based on that:

current_room = Rooms.map[(0, 0)]
while True:
    print(current_room.name)
    print(current_room.desc)
    command = input('Enter a command: ')
    if command in current_room.directions:
        loc = current_room.loc
        if command == 'north':
             current_room = Rooms.map[(loc[0], loc[1] + 1)]
        ...
If the tutorial you found isn't the one I wrote, I not so humbly suggest your read mine (link below in my signature).
Craig "Ichabod" O'Brien - xenomind.com
I wish you happiness.
Recommended Tutorials: BBCode, functions, classes, text adventures
Reply
#3
Alright, so let me restructure your question, to make sure I understand it right.

Given this code:
class Room:
    def __init__(self, x, y):
        self.x = x
        self.y = y
        self.loc = (x, y)

room_1 = Room(0, 0)
print(room_1.loc)
room_1.y += 1
print(room_1.loc)
...why is the same tuple printed twice? Or, why didn't the change to the y variable also change the loc variable?

The loc variable is created with copies of the x/y variables, not references to them. So changes to the x/y variables will not effect the loc.

The easy way to fix this, is to use a method to return the current location:
    def get_loc(self):
        return (self.x, self.y)
The other option would be to use objects to store positioning, instead of primitive types (like an int). That would look something like this:
class Point:
    def __init__(self, x, y):
        self.x = x
        self.y = y

    def get_loc(self):
        return (self.x, self.y)

    def __str__(self):
        return "Point: ({0}, {1})".format(self.x, self.y)

class Room:
    def __init__(self, x, y):
        self.loc = Point(x, y)

room_1 = Room(0, 0)
print(room_1.loc)
room_1.loc.y += 1
print(room_1.loc)
Reply
#4
(Aug-19-2019, 07:02 PM)nilamo Wrote: Alright, so let me restructure your question, to make sure I understand it right.

Given this code:
class Room:
    def __init__(self, x, y):
        self.x = x
        self.y = y
        self.loc = (x, y)

room_1 = Room(0, 0)
print(room_1.loc)
room_1.y += 1
print(room_1.loc)
...why is the same tuple printed twice? Or, why didn't the change to the y variable also change the loc variable?

The loc variable is created with copies of the x/y variables, not references to them. So changes to the x/y variables will not effect the loc.

The easy way to fix this, is to use a method to return the current location:
    def get_loc(self):
        return (self.x, self.y)
The other option would be to use objects to store positioning, instead of primitive types (like an int). That would look something like this:
class Point:
    def __init__(self, x, y):
        self.x = x
        self.y = y

    def get_loc(self):
        return (self.x, self.y)

    def __str__(self):
        return "Point: ({0}, {1})".format(self.x, self.y)

class Room:
    def __init__(self, x, y):
        self.loc = Point(x, y)

room_1 = Room(0, 0)
print(room_1.loc)
room_1.loc.y += 1
print(room_1.loc)

Thanks nilamo, you answered a few questions of mine. :) I hadn't taken into consideration that the loc variable just copied the x and y vars and left it at that. I'll probably use both your method and Ichabod's to make a more expanded piece of code, and then move on to more complicated practices for learning purposes ^^

(Aug-19-2019, 06:59 PM)ichabod801 Wrote: One thing to do is store them by coordinate in a dictionary. You can even do this as a class attribute and automate it with __init__:

class Rooms:

    map = {}
 
    def __init__(self, name, desc, co_x, co_y, directions):
        self.name = name
        self.desc = desc
        self.co_x = co_x
        self.co_y = co_y
        self.loc = (self.co_x, self.co_y)
        Rooms.map[self.loc] = self
        self.directions = directions
 
    def __str__(self):
        return f' {self.name}, {self.desc}, {self.co_x}, {self.co_y}'
Now you get the current room from the dictionary, and move around based on that:

current_room = Rooms.map[(0, 0)]
while True:
    print(current_room.name)
    print(current_room.desc)
    command = input('Enter a command: ')
    if command in current_room.directions:
        loc = current_room.loc
        if command == 'north':
             current_room = Rooms.map[(loc[0], loc[1] + 1)]
        ...
If the tutorial you found isn't the one I wrote, I not so humbly suggest your read mine (link below in my signature).

Your tutorial (and some old MUD's) was my inspiration to make a more complicated version of a text-based rpg, for learning purposes of course. Your response was very informative, I had no clue one could use a dictionary within a class object to automate some processes. I'll grind this information into memory, thanks again!!

p.s Your tutorial is VERY useful for newbie programmers like myself to learn the ropes to some basic python practices, excellent work!
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  Laggy Game Movement game_slayer_99 12 4,323 Oct-05-2022, 11:34 AM
Last Post: metulburr
  [PyGame] Particle movement mystery XavierPlatinum 10 2,956 Jul-09-2022, 04:28 AM
Last Post: deanhystad
  [PyGame] Isometric Movement on Tiled Map Josselin 0 2,360 Nov-02-2021, 06:56 AM
Last Post: Josselin
  [PyGame] object's movement to left leave shadow on the screen Zhaleh 3 3,138 Aug-02-2020, 09:59 PM
Last Post: nilamo
  Adding an inventory and a combat system to a text based adventure game detkitten 2 6,870 Dec-17-2019, 03:40 AM
Last Post: detkitten
  Problem with coding for movement keys Aresofthesea 3 3,467 Jul-05-2019, 07:05 PM
Last Post: nilamo
  Pygame Movement X/Y coord TheHumbleIdiot 2 3,511 Mar-19-2019, 02:21 PM
Last Post: TheHumbleIdiot
  Movement after KEYUP, only after pause func esteel 2 3,280 Aug-22-2018, 03:03 PM
Last Post: Windspar
  Text Based Game DuaneJack 3 3,545 Aug-15-2018, 12:02 PM
Last Post: ichabod801
  [PyGame] How to stop the sprite's movement when it touches the edges of the screen? mrmn 5 11,571 May-13-2018, 06:33 PM
Last Post: mrmn

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020