Python printing an Else statement when not supposed to

Question:

I’m having trouble trying to get a game creation exercise to stop printing the else statement (at the bottom of the code block). the idea is, you can navigate from room to room, but if you go in a direction you’re not supposed it should tell you. However, it seems to be doing that even when you CAN go somewhere. I’d greatly appreciate any advice.

Code is below:

class Room:

    number_of_rooms = 0

    def __init__(self, room_name):
        self.name = room_name
        self.description = None
        self.linked_rooms = {}
        self.character = None
        Room.number_of_rooms = Room.number_of_rooms + 1
         
    def set_description(self, room_description):
        self.description = room_description

    def get_description(self):
        return self.description

    def set_name(self, room_name):
        self.name = room_name

    def get_name(self):
        return self.name

    def describe(self):
        print(self.description)

    def set_character(self, new_character):
        self.character = new_character
    
    def get_character(self):
        return self.character

    def describe(self): 
        print( self.description )
        
    def link_room(self, room_to_link, direction):
        self.linked_rooms[direction] = room_to_link

    def get_details(self):
        print(self.name)
        print("--------------------")
        print(self.description)
        for direction in self.linked_rooms:
            room = self.linked_rooms[direction]
            print( "The " + room.get_name() + " is " + direction)
        
    def move(self, direction):
        if direction in self.linked_rooms:
            return self.linked_rooms[direction]
        else:
            print("You can't go that way")
            return self

I would greatly appreciate any advice on this, it’s maddening. I just need it to stop printing "You can’t go that way" when you can. It actually does work, it just insist on printing it every time you go into a new room as well as when you can’t.

This is the code it links to

    foyer = Room("foyer")
    ballroom = Room("ballroom")
    dining_hall = Room("dining_hall")
    kitchen = Room("kitchen")

    foyer.link_room(ballroom, "south")
    ballroom.link_room(foyer, "north")
    ballroom.link_room(dining_hall, "east")
    dining_hall.link_room(ballroom, "west")
    dining_hall.link_room(kitchen, "north")
    kitchen.link_room(dining_hall, "south")
Asked By: Battlebanana

||

Answers:

If you add the following test code to the end of your class (assuming that it is inside a module Room.py):

if __name__ == "__main__":
    print("Testing")

    # rooms
    room1 = Room("Floor")
    room2 = Room("Kitchen")
    room3 = Room("Living Room")

    # link the rooms
    room2.link_room(room1, "left")
    room3.link_room(room1, "right")

    # move
    room2.move("up") # not allowed
    room3.move("right")  # should be possible

Then you can run the test code directly if you execute the module.

Now if you are in room 3 (living room) it is possible to get out on the right.
But if you are in room 2 (kitchen) you can only move to the left.

The test prints "You can't go that way" only if you do a move like room2.move("up") which is correct, because only "left" is allowed. Comment that line and you won’t see that message any more.

According to this test, the class is behaving as it should. Note that you could (and should!) also write a unit test from the example I gave, asserting the expected output.


Update:

In your example, allowed moves are:

    # allowed
    kitchen.move("south")
    dining_hall.move("north")
    ballroom.move("east")
    foyer.move("south")

And examples for not allowed moves are:

    # not allowed
    kitchen.move("west")
    dining_hall.move("east")
    ballroom.move("south")
    foyer.move("north")

For these you will get "You can't go that way".

Maybe the issue you had was that you were using objects rather than strings as parameter to describe the direction.

For example, this will always fail (printing "You can't go that way"):

    foyer.move(ballroom)  # param should be a string, not an object

To prevent this kind of error, you could add a check to the move method:

    def move(self, direction):
        if not isinstance(direction, str):
                raise ValueError("Direction needs to be a string!")
        if direction in self.linked_rooms:
                return self.linked_rooms[direction]
        else:
                print("You can't go that way")
        return self

With that addition, the application will throw an exception, if you pass an object and not a string:

ValueError: Direction needs to be a string!

For testing, you could use this code:

    new_dir = "nop"
    current_room = foyer
    while new_dir != "":
        print("current room: " + current_room.name)
        print("please enter direction:")
        new_dir = input()
        new_room = current_room.move(str(new_dir))
        if new_room != current_room:
            print("moving to: " + new_room.name)
            current_room = new_room
Answered By: Matt
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.