Python 如何防止玩家移动到给定区域地图之外?

Python 如何防止玩家移动到给定区域地图之外?,python,dictionary,Python,Dictionary,我使用一个名为zonemap的字典创建了一个4x6区域地图。我在该词典中嵌套了多个词典;每个代表玩家可以访问和互动的区域。我希望能够将玩家的移动限制在4x6区域,并重新显示他们试图进入“禁止”区域的位置。只有当玩家尝试访问由空字符串标记的区域时,才会出现此限制。示例代码如下: import cmd import textwrap import sys import os import time import random class player: def __init__(self)

我使用一个名为zonemap的字典创建了一个4x6区域地图。我在该词典中嵌套了多个词典;每个代表玩家可以访问和互动的区域。我希望能够将玩家的移动限制在4x6区域,并重新显示他们试图进入“禁止”区域的位置。只有当玩家尝试访问由空字符串标记的区域时,才会出现此限制。示例代码如下:

import cmd
import textwrap
import sys
import os
import time
import random

class player:
    def __init__(self):
        self.name = ''
        self.job = ''
        self.hp = 0
        self.mp = 0
        self.stamina = 0
        self.faith = 0
        self.status_effects = []
        self.location = "a2"
        self.gameOver = False
myPlayer = player()

ZONENAME = ''
DESCRIPTION = 'description'
EXAMINATION = 'examine'
SOLVED = False
UP = 'up', 'north'
DOWN = 'down', 'south'
LEFT = 'left', 'west'
RIGHT = 'right', 'east'

solved_places = {'a1': False, 'a2': False, # more places}

zonemap = {
    'a1': {
        ZONENAME: "West Mounatains",
        DESCRIPTION: "A mountain range.",
        EXAMINATION: "The slope is too steep to climb.",
        SOLVED: False,
        UP: '',
        DOWN: "Western Forest",
        LEFT: '', 
        RIGHT: "Central Mountains",
    },
    'a2': {
        ZONENAME: "Central Mountains",
        DESCRIPTION: "A mountain range",
        EXAMINATION: "These mountains go on for miles.",
        SOLVED: False,
        UP: '',
        DOWN: "Eastern Forest",
        LEFT: "Western Mountains",
        RIGHT: "Mountain Cave",
    },
    # more dictionaries
}

def prompt():
    print("\n" + "=========================")
    print("What would you like to do?")
    player_action = input("> ")
    acceptable_actions = ['move', 'go', 'travel', 'walk', 'quit', 'examine', 'inspect', 'interact', 'look']
    while player_action.lower() not in acceptable_actions:
        print("Unknown action, try again.\n")
        player_action = input("> ")
    if player_action.lower() == 'quit':
        sys.exit()
    elif player_action.lower() in ['move', 'go', 'travel', 'walk']:
        player_move(player_action.lower())
    elif player_action.lower() in ['examine', 'inspect', 'interact', 'look']:
        player_examine(player_action.lower())

def player_move(player_action):
    ask = "Where would you like to move?\n"
    dest = input(ask)
    if dest in ['up', 'north']:
        destination = zonemap[myPlayer.location][UP]
        movement_handler(destination)
    elif dest in ['down', 'south']:
        destination = zonemap[myPlayer.location][DOWN]
        movement_handler(destination)
    elif dest in ['left', 'west']:
        destination = zonemap[myPlayer.location][LEFT]
        movement_handler(destination)
    elif dest in ['right', 'east']:
        destination = zonemap[myPlayer.location][RIGHT]
        movement_handler(destination)

def movement_handler(destination):
    print("\n" + "You have moved to the " + destination + ".")
    myPlayer.location = destination
    print_location()


我想一个if语句会有用,但我不知道该放在哪里。任何帮助都将不胜感激。如果需要,我还可以提供更多的代码。

是的,一个
if
可以工作。检查用户想要去的地方如果无效,请打印一条消息,不要移动播放器其他移动它们

def player_move(player_action):
    ask = "Where would you like to move?\n"
    dest = input(ask).lower()
    if dest in ['up', 'north']:
        destination = UP
    elif dest in ['down', 'south']:
        destination = DOWN
    elif dest in ['left', 'west']:
        destination = LEFT
    elif dest in ['right', 'east']:
        destination = RIGHT
    else:
        print("Bad entry")
        return

    if "" == zonemap[myPlayer.location][destination]:
        print("Can't go there")
    else:
        movement_handler(zonemap[myPlayer.location][destination])

Johnny的解决方案是正确的,如果您正在学习Python,这可能是一个很好的解决方案。但是,一般来说,长系列的if/elif/elif/elif/else很难维护,并且通常表明代码可以简化

请允许我演示几个这样的问题

您可以定义一个函数,将所有可能的别名合并为4个方向值,例如:

def direction(whence):
    "define direction aliases"
    whence = whence.lower()
    return {
        'north': 'up',
        'east': 'right',
        'south': 'down',
        'west': 'left',
    }.get(whence, whence)
然后,您可以通过以下方式获得所需的方向:

destination = direction(input("where would you like to go? "))
您的区域可以定义为:

'a2': {
    ... 
    'up': "", 
    'down': "Eastern Forrest",
    'left': "Western Mountains",
    'right': "Mountain Cave"
这个特殊的问题也非常适合使用更面向对象的方法。您已经定义了一个玩家类,那么定义一个区域类怎么样

首先,让我们定义一些便利条件,以便在设置区域地图时不必重复太多次

我们知道,左是右的相反方向,等等,让我们来声明所有的对立面:

opposites = {
    'left': 'right',
    'up': 'down',
}
opposites.update({v: k for k, v in opposites.items()})
我们知道,如果你在A点向右移动到B点,那么你可以向左移动回到A点。描述符类有点神奇,但非常有用:

class Path(object):
    "Descriptor class that sets both ends of a path."
    def __init__(self, direction):
        self.direction = direction

    def __get__(self, obj, objtype):
        return obj.neighbors[self.direction]

    def __set__(self, obj, val):
        obj.neighbors[self.direction] = val
        val.neighbors[opposites[self.direction]] = obj
然后可以定义分区类:

class Zone(object):
    up = Path('up')
    right = Path('right')
    down = Path('down')
    left = Path('left')

    def __init__(self, name, description='', examination=''):
        self.name = name
        self.description = description
        self.examination = examination
        self.neighbors = dict(
            up=None,
            right=None,
            down=None,
            left=None)

    def __str__(self):
        return self.name

    def valid_moves(self):
        return [direction
                for direction, target in self.neighbors.items()
                if target is not None]
现在,我们可以直接定义关系,而不是在dict中间接地将地图拼接在一起:

def create_map():
    # create the zones as objects
    west_mountains = Zone('West Mountains')
    central_mountains = Zone('Central Mountains')
    eastern_forest = Zone('Eastern Forest')
    mountain_cave = Zone('Mountain Cave')
    western_forest = Zone('Western Forest')

    # connect the zones directly (the opposite direction is automagically
    # set by the Path descriptor class)
    west_mountains.down = western_forest     # western_forrest.up = west_mountains happens in Path descriptor
    west_mountains.right = central_mountains
    central_mountains.down = eastern_forest
    central_mountains.right = mountain_cave

    return central_mountains  # return starting position
在面向对象的设计中,移动播放器应该是播放器类上的一种方法,因此:

class Player(object):
    def __init__(self, name, location):
        self.name = name
        self.location = location

    def move(self, direction):
        if self.location.neighbors[direction] is None:
            raise ValueError("No such path")
        self.location = self.location.neighbors[direction]
然后我们可以在地图上移动:

def play():
    starting_location = create_map()

    p = Player(
        name=input("what is your name? "),
        location=starting_location
    )

    while 1:
        where = input('Where would you like to move? ')
        if where.lower() in ('quit', 'q'):
            break
        try:
            p.move(direction(where))
            print("you're at: ", p.location)
        except ValueError as e:
            print(e)
            print("Valid directions are:", p.location.valid_moves())


if __name__ == "__main__":
    play()
示例会话:

(dev) go|c:\srv\tmp> py3 mountains.py
what is your name? bjorn
Where would you like to move? North
No such path
Valid directions are: ['left', 'down', 'right']
Where would you like to move? West
you're at:  West Mountains
Where would you like to move? left
No such path
Valid directions are: ['down', 'right']
Where would you like to move? down
you're at:  Western Forest
Where would you like to move? South
No such path
Valid directions are: ['up']
Where would you like to move? north
you're at:  West Mountains
Where would you like to move? q

谢谢你,约翰尼。我来试试。谢谢,他们。现在我将尝试Johnny的解决方案,因为这是我第一次尝试这种类型的游戏。不过,我会考虑在未来的迭代中使用您的解决方案,因为我喜欢它的用法。