Question

J'ai besoin d'avoir un rayon de 2 carte tirée du joueur en cours de la chambre de BOUE, je suis en train de construire en python (ou plus si possible).Les chambres sont des conteneurs avec une self.exits = {'west':1, 'north':2} lorsque la clé est la direction dans laquelle la valeur (UID de la pièce adjacente) est situé.Les chambres sont liés uniquement de cette façon.Un joueur avec une auto.emplacement de 0 pouvaient type " n " et leur emplacement, sur la base de ces variables, pourrait ensuite être 2 et que la salle de contenu aurait du joueur UID ajouté à son contenu.

Donc, je voudrais avoir une carte affichée, qui se présente comme suit, sur la base de ces variables, où le " u " est le joueur de la position actuelle..

    [ ]
     |
[ ]-[u]

J'ai réalisé cette partie, que c'est juste un rayon de 1.Voici un petit (fortement modifiées pour poster ici) extrait de comment je l'ai fait, et vous allez voir pourquoi je poste, comme c'est le pauvre de code.

mloc = '[u]'
mn = '   '
mw = '   '
spn= ' '
spw= ' '
for Exit in room.exits.keys():
  if Exit == 'north':
    mn = '[ ]'
    spn = '|'
  if Exit == 'west': 
    mw = '[ ]-'
# player.hear() is our function for printing a line to the player's screen
player.hear('    '+mn)
player.hear('     '+sp)
player.hear(mw+mloc)

Dans ma folie, j'ai réussi à faire ce travail avec tous les 8 directions différentes (les diagonales, et ne comprenant pas vers le haut ou vers le bas).Mais j'ai ensuite de boucle pour les chambres j'ai juste analysé avec ma première boucle, puis dessines, et puis l'espace et ensuite prendre en compte le chevauchement de la (sp)des as comme '\' ou '|' si il y a des chemins qui se croisent.Cette petite tâche tourné cauchemardesque immédiatement, et bien en 200 lignes avant j'ai été fait.

Un autre obstacle est que je ne peux impression ligne par ligne.Donc, si la carte est de 50 personnages haut, je dois avoir player.hear() sur 50 lignes, dont je ne suis pas opposé.Il suffit de garder cela à l'esprit avant de poster une réponse.

Je suis aussi pas pointilleux sur la mise en forme.Je voulez juste simplement une "carte à un coup d'œil" à l'aide des joueurs lors d'un voyage autour du monde.

Merci les gars.J'espère que j'ai fourni suffisamment d'informations.Laissez-moi savoir, si ce n'.(Ici est un lien vers l'intégralité de l' (inachevé et HORRIBLE) module je suis référencement. Map.py

Était-ce utile?

La solution

Ce code est en sérieuse difficulté.Nous allons commencer à concevoir à partir de zéro.Cela devrait servir comme une bonne leçon sur la façon de concevoir et de construire des classes et des structures de données.

Pour commencer, vous devez organiser votre code autour d'un Map de la classe, qui représente votre chambre comme une grille.Vous ne devez pas penser au sujet de "chambre 1", "chambre 2", etc (ce qui est très difficile de les suivre sur une carte), et pense plutôt à des chambres en termes de coordonnées.

Maintenant, il y a quelques fonctionnalités que nous ignorons au début, y compris le joueur ne voir que des chambres qu'il a été, le joueur restant au centre de la carte, et la diagonale des chemins.Si vous le souhaitez vous pouvez les mettre au plus tard, une fois que les fonctionnalités de base fonctionne.Pour l'instant, nous voulons avoir quelque chose qui ressemble un peu à ceci:

[ ]-[u] [ ] [ ]
 |
[ ]-[ ]-[ ] [ ]
     |
[ ]-[ ]-[ ] [ ]
 |
[ ]-[ ]-[ ]-[ ]

Qui est, nous sommes le représentant comme une grille où certaines chambres sont connectés, et d'autres ne le sont pas.Nous allons avoir dans chaque chambre une paire de coordonnées, un peu comme ceci:

      0   1   2   3
   0 [ ]-[u] [ ] [ ]
      |
   1 [ ]-[ ]-[ ] [ ]
          |
   2 [ ]-[ ]-[ ] [ ]
      |
   3 [ ]-[ ]-[ ]-[ ]

Soit x le long du haut et y, le long de la côte.Le haut à gauche est (0, 0), l'une avec [u] dans c'est (0, 1).

Maintenant, quelles sont les composantes de notre Map de classe?

  1. carte de la hauteur:entier

  2. carte de la largeur:entier)

  3. player_x, player_y:coordonnées de joueur

  4. les chemins d'accès possibles:une liste de paires de chambres que l'on peut déplacer entre.La carte ci-dessus est représenté sous la forme:

    [((0, 0), (1, 0)), ((0, 0), (1, 0)), ((1, 0), (1, 1)), ((1, 1), (2, 1)),
     ((1, 0), (1, 2)), ((0, 2), (1, 2)), ((1, 2), (2, 2)), ((0, 2), (0, 3)),
     ((0, 3), (1, 3)), ((1, 3), (2, 3)), ((2, 3), (3, 3))]
    

Notez que j'ai commandé chaque paire telle que le plus grand tuple va d'abord (c'est important plus tard).

Alors, maintenant que nous avons notre conception, nous allons écrire que Map la classe!

Je ne peux penser à de quatre méthodes que nous voulons: print_map, move, et un initialiseur.Intitialization est simple:il suffit de régler le quatre attributs que nous avons énumérés ci-dessus:

class Map:
    def __init__(self, height, width, player_x, player_y, paths):
        self.height = height
        self.width = width
        self.x = player_x
        self.y = player_y
        self.paths = paths

Maintenant, move est assez simple.Donné une direction n/e/s/w:

    def move(self, direction):
        if direction == "n":
            if ((self.x, self.y - 1), (self.x, self.y)) not in self.paths:
                print "Cannot go north"
            else:
                self.y -= 1

L' move la fonction de "nord" vérifie juste si il y a un chemin d'accès à la salle au-dessus de la nôtre.

Maintenant pour la partie la plus intéressante:l'impression de la carte.Pour ce faire, vous passez en boucle sur les lignes (de 0 à self.height) et sur les colonnes (de 0 à self.width). (Note:vous ne pouvez pas utiliser print dans cette situation, car il met automatiquement un saut de ligne ou un espace après la chaîne.Au lieu de cela, nous utilisons sys.la sortie standard stdout.écrire.

def print_map(self):
    for y in range(0, self.height):
        # print the yth row of rooms
        for x in range(0, self.width):
            if self.x == x and self.y == y:
                sys.stdout.write("[u]")  # this is the player's room
            else:
                sys.stdout.write("[ ]")  # empty room
            # now see whether there's a path to the next room
            if ((x, y), (x + 1, y)) in self.paths:
                sys.stdout.write("-")
            else:
                sys.stdout.write(" ")
        # now that we've written the rooms, draw paths to next row
        print  # newline
        for x in range(0, self.width):
            sys.stdout.write(" ")  # spaces for above room
            if ((x, y), (x, y + 1)) in self.paths:
                sys.stdout.write("|  ")
            else:
                sys.stdout.write("   ")
        print

Maintenant, nous allons mettre tout cela ensemble et de l'essayer.Voici le code:

import sys

class Map:
    def __init__(self, height, width, player_x, player_y, paths):
        self.height = height
        self.width = width
        self.x = player_x
        self.y = player_y
        self.paths = paths

    def move(self, direction):
        if direction == "n":
            if ((self.x, self.y - 1), (self.x, self.y)) not in self.paths:
                print "Cannot go north"
            else:
                self.y -= 1
        if direction == "s":
            if ((self.x, self.y), (self.x, self.y + 1)) not in self.paths:
                print "Cannot go south"
            else:
                self.y += 1
        if direction == "e":
            if ((self.x, self.y), (self.x + 1, self.y)) not in self.paths:
                print "Cannot go east"
            else:
                self.x += 1
        if direction == "w":
            if ((self.x - 1, self.y), (self.x, self.y)) not in self.paths:
                print "Cannot go west"
            else:
                self.x -= 1

    def print_map(self):
        for y in range(0, self.height):
            # print the yth row of rooms
            for x in range(0, self.width):
                if self.x == x and self.y == y:
                    sys.stdout.write("[u]")  # this is the player's room
                else:
                    sys.stdout.write("[ ]")  # empty room
                # now see whether there's a path to the next room
                if ((x, y), (x + 1, y)) in self.paths:
                    sys.stdout.write("-")
                else:
                    sys.stdout.write(" ")
            # now that we've written the rooms, draw paths to next row
            print  # newline
            for x in range(0, self.width):
                sys.stdout.write(" ")  # spaces for above room
                if ((x, y), (x, y + 1)) in self.paths:
                    sys.stdout.write("|  ")
                else:
                    sys.stdout.write("   ")
            print


paths = [((0, 0), (1, 0)), ((0, 0), (1, 0)), ((1, 0), (1, 1)), ((1, 1),
         (2, 1)), ((1, 1), (1, 2)), ((0, 2), (1, 2)), ((1, 2), (2, 2)),
         ((0, 2), (0, 3)), ((0, 3), (1, 3)), ((1, 3), (2, 3)), ((2, 3),
         (3, 3))]
m = Map(4, 4, 0, 0, paths)

while True:
    m.print_map()
    direction = raw_input("What direction do you want to move? [n/e/s/w] ")
    m.move(direction)

Notez que j'ai ajouté une section sur le fond qui crée une carte et permet au joueur de se déplacer autour d'elle.Voici à quoi il ressemble quand il s'exécute:

Davids-MacBook-Air:test dgrtwo$ python Map.py 
[u]-[ ] [ ] [ ] 
     |          
[ ] [ ]-[ ] [ ] 
     |          
[ ]-[ ]-[ ] [ ] 
 |              
[ ]-[ ]-[ ]-[ ] 

What direction do you want to move? [n/e/s/w] e
[ ]-[u] [ ] [ ] 
     |          
[ ] [ ]-[ ] [ ] 
     |          
[ ]-[ ]-[ ] [ ] 
 |              
[ ]-[ ]-[ ]-[ ] 

What direction do you want to move? [n/e/s/w] s
[ ]-[ ] [ ] [ ] 
     |          
[ ] [u]-[ ] [ ] 
     |          
[ ]-[ ]-[ ] [ ] 
 |              
[ ]-[ ]-[ ]-[ ] 

What direction do you want to move? [n/e/s/w] w
Cannot go west
[ ]-[ ] [ ] [ ] 
     |          
[ ] [u]-[ ] [ ] 
     |          
[ ]-[ ]-[ ] [ ] 
 |              
[ ]-[ ]-[ ]-[ ] 

What direction do you want to move? [n/e/s/w] e
[ ]-[ ] [ ] [ ] 
     |          
[ ] [ ]-[u] [ ] 
     |          
[ ]-[ ]-[ ] [ ] 
 |              
[ ]-[ ]-[ ]-[ ] 

Il y a beaucoup d'améliorations qui peuvent être apportées à ce code (en particulier, l' move la méthode est répétitif), mais c'est un bon début.Essayez de faire la carte de 20x20 et vous verrez qu'il se développe très bien.

ETA:Il est à noter que print_map pourrait être réécrit dans un temps beaucoup plus court formulaire comme quelque chose comme:

def print_map(self):
    for y in range(0, self.height):
        print "".join(["[%s]%s" %
                    ("u" if self.x == x and self.y == y else " ",
                     "-" if ((x, y), (x + 1, y)) in self.paths else " ")
                        for x in range(0, self.width)])
        print " " + "   ".join(["|" if ((x, y), (x, y + 1)) in self.paths
                              else " " for x in range(0, self.width)])

Mais c'est un peu plus intense.

Autres conseils

J'ai fait cela comme un exercice où les chambres et la grille "imprimer eux-mêmes".J'ai ajouter à la discussion comme il peut être plus facile à mettre en œuvre avec un éventuel réseau plus large.

L'ASCII Carte

+++++++++++++++
+++++++++++++++
+++++++++++++++
++++++   ++++++
++++++ 2 ++++++
++++++/| ++++++
+++  / | ++++++
+++ 3--1 ++++++
+++     \++++++
+++++++++\  +++
+++++++++ 4 +++
+++++++++   +++
+++++++++++++++
+++++++++++++++
+++++++++++++++

Chaque cellule de cette grille de trois par trois de '+' signes.Quatre chambres sont mis en œuvre avec la valeur de l'id de 1 à 4.Les connexions entre les chambres sont représentés comme des barres obliques inverses et des tuyaux.

Le Code

class Room(object):
    def __init__(self, id, loc, exits):
        self.id = id # unique identifier, may be a name
        self.row = loc[0] # loc is tuple of (row, col)
        self.col = loc[1] 
        # exits is a list where 'X' means no exit and 
        # any other value is id of destination
        self.exits = exits 

    def __str__(self):
        directions = '\\|/- -/|\\'
        room = [ e if e == 'X' else ' ' for e in self.exits ]
        for idx in range(len(room)):
            if room[idx] == ' ':
                room[idx] = directions[idx]
            if room[idx] == 'X':
                room[idx] = ' '
        room[4] = self.id[0] # only print first char of id
        return ''.join(room)

class Map(object):
    def __init__(self, rows, cols, rooms):
        self.rows = rows
        self.cols = cols
        self.rooms = rooms

    def __str__(self):
        world = []
        for i in range(self.rows * 3):
            world.append( ['+++'] * self.cols )
        for room in self.rooms:
            ascii = str(room)
            x = room.col
            y = room.row
            for idx in range(0, 3):
                cell = ascii[idx*3:idx*3+3]
                world[y*3+idx][x] = cell
        return '\n'.join( [ ''.join(row) for row in world ] )


if __name__ == '__main__':
    # set up four rooms
    # each room has unique id (string of any length) and coordinates
    # it also has a set of 8 possible exits, represented as a list where
    # 'X' means exit is blocked and valid exits contain the id of the target room
    r1 = Room(id='1', loc=(2,2), exits=['X','2','X',
                                        '3',' ','X',
                                        'X','X','4',])
    r2 = Room(id='2', loc=(1,2), exits=['X','X','X',
                                        'X',' ','X',
                                        '3','1','X',])
    r3 = Room(id='3', loc=(2,1), exits=['X','X','2',
                                        'X',' ','1',
                                        'X','X','X',])
    r4 = Room(id='4', loc=(3,3), exits=['1','X','X',
                                        'X',' ','X',
                                        'X','X','X',])
    # initialize Map with a list of these four rooms
    map = Map(rows = 5, cols=5, rooms=[r1, r2, r3, r4])
    print map

Le déplacement de routine n'est pas mis en œuvre, et pour cette représentation au travail, à caractère unique id va se montrer bien.

Les avantages de ce système:

  • facile d'ajouter des chambres et de les supprimer
  • la définition d'une chambre est lisible par l'homme
  • les fonctions de sortie surcharge __str__ et, partant, des chambres et de la grille "imprimer eux-mêmes" et cela pourrait être utile pour l'avenir de débogage ou d'adaptation à de futurs formats par exemplecomme les cellules dans un tableau HTML.

Coordonner les cartes ont beaucoup d'avantages, mais vu que beaucoup de la qualité des boues d'utiliser une chambre traditionnelle à base de monde, et les gens ont fait automappers pour beaucoup de boue et de la boue de clients, il n'est pas hors de question de faire un automap pour une boue sans coordonnées.Vous aurez juste à faire face à des conflits sur une base de cas par cas.

Cependant, vous pouvez toujours utiliser la réponse par @david-robinson.Ce que vous voulez faire est de garder une minicarte à peu près centrée sur le joueur et mettre à jour dynamiquement à l'aide de la sortie des données.N'essayez pas de garder une carte de l'ensemble de la zone de conservation;par une mise à jour dynamique vous permettra d'éviter certains géographique des conflits.

Pour l'écriture de la carte pour une boue client, tout ce que vous devez faire est d'écrire votre carte en ligne correctement espacés et terminer par une nouvelle ligne.Vous mettez tous la carte des lignes dans une liste afin d'être envoyé en un seul groupe de lignes (vous ne voulez pas que d'autres inséré entre les lignes de la carte par exemple lorsqu'on a envoyé la prise), et toute la boue client de l'imprimer correctement (avec une police à espacement fixe, bien sûr).

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top