Domanda

Ho bisogno di avere un 2 raggio mappa disegnata spegnere il lettore attuale stanza in un FANGO sto costruendo in python (o più, se possibile).Le camere sono come contenitori con un self.exits = {'west':1, 'north':2} dove la chiave è la direzione che il valore (UID della stanza adiacente) è situato.Le camere sono collegate solo in questo modo.Un giocatore con un auto.posizione di 0 potrebbe digitare " n " e la loro posizione, sulla base di quanto sopra variabile, sarebbe di 2 e che il contenuto della stanza sarebbe il giocatore UID aggiunto al suo contenuto.

Così, mi piacerebbe avere una mappa che appare come il seguente, in base alla suddetta variabile, dove la 'u' è il giocatore della posizione corrente..

    [ ]
     |
[ ]-[u]

Ho realizzato questo parte, come questo è solo un raggio di 1.Ecco un piccolo (pesantemente modificato per postare qui) frammento di come ho fatto questo, e vedrete perché sto postando, come è povero di codice.

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)

Nella mia follia, sono riuscito a fare questo lavoro con tutte le 8 direzioni diverse (diagonali, e non in alto o in basso).Ma poi devo ciclo for sale ho appena analizzato con il mio primo ciclo for, e quindi disegnare quelle, e poi spazio del tutto, e poi prendere in considerazione la sovrapposizione di (sp)assi come '\' o '|' se ci sono percorsi che si incrociano.Questo è un piccolo compito trasformato da incubo immediatamente, e in 200 righe prima che mi è stato fatto.

Un altro ostacolo è che posso stampare solo una riga alla volta.Quindi, se la mappa è di 50 caratteri alta, devo player.hear() a 50 linee, che io non mi oppongo a.Basta tenere a mente prima di postare una risposta.

Io non sono schizzinosi riguardo la formattazione.Ho semplicemente una "mappa a colpo d'occhio" per aiutare i giocatori durante il viaggio intorno al mondo.

Grazie ragazzi.Spero che vi ho fornito abbastanza informazioni.Fammi sapere, se non.(Ecco un link per l'intero (incompiuto e ORRIBILE) modulo mi sto riferendo. Map.py

È stato utile?

Soluzione

Questo codice è in guai seri.Iniziamo a progettare da zero.Questo potrà servire come una buona lezione su come progettare e costruire classi e strutture di dati.

Per cominciare, si dovrebbe organizzare il tuo codice intorno a un Map classe, che rappresenta quindi il sale, come una griglia.Non si deve pensare a "camera 1", "camera 2", ecc (che è molto difficile tenere traccia di una mappa), e invece penso di camere, in termini di coordinate.

Ora, ci sono alcuni possibili funzioni che siamo ignorando all'inizio, tra cui il lettore di vedere solo le camere è stato a, il giocatore rimane al centro della mappa, e di percorsi diagonali.Se vuoi li puoi mettere, in seguito, una volta che la funzionalità di base funziona.Per ora, stiamo puntando a qualcosa che assomiglia un po ' a questo:

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

Che è, siamo, presentandola come una griglia in cui alcune camere sono comunicanti e altri non lo sono.Facciamo ogni camera dispone di una coppia di coordinate, un po ' come questo:

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

Sia x lungo la parte superiore e y lungo il lato.In alto a sinistra è (0, 0), l'uno con [u] in esso è (0, 1).

Ora, quali sono le componenti del nostro Map classe?

  1. mappa di altezza:integer

  2. mappa larghezza:integer)

  3. player_x, player_y:coordinate del giocatore

  4. possibili percorsi:un elenco di coppie di camere che ci si può spostare tra.Sopra la mappa dovrebbe essere rappresentato come:

    [((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))]
    

Notare che ho ordinato ogni coppia tale che il più grande tupla va per primo (che è importante).

Quindi, ora che abbiamo il nostro design, scriviamo Map di classe!

Posso pensare di quattro metodi vogliamo: print_map, move, e un inizializzatore.Intitialization è semplice:basta impostare i quattro attributi elencati sopra:

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

Ora, move è abbastanza semplice.Dato una direzione 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

Il move funzione per il "nord" e controlla se c'è un percorso per la stanza successiva a quella in cui ci troviamo.

Ora per la parte più interessante:stampa la mappa.Questo dal ciclo sulle righe (da 0 a self.height) e oltre le colonne (da 0 a self.width). (Nota:non è possibile utilizzare print in questa situazione, dal momento che si inserisce automaticamente una nuova riga o spazio dopo la stringa.Invece usiamo sys.stdout.scrivere.

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

Ora, mettiamo tutto insieme e provare.Ecco il codice:

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)

Notare che ho aggiunto una sezione in basso, che crea una mappa e permette al giocatore di muoversi.Ecco come appare quando viene eseguito:

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] [ ] 
     |          
[ ]-[ ]-[ ] [ ] 
 |              
[ ]-[ ]-[ ]-[ ] 

Ci sono molti miglioramenti che possono essere fatte a questo codice (in particolare, il move il metodo è ripetitivo), ma è un buon inizio.Provare a fare una mappa di 20x20 e vedrai che si espande bene.

ETA:Devo notare che print_map potrebbe essere riscritto in tempi molto più brevi forma come qualcosa di simile a:

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)])

Ma questo è un po ' più intenso.

Altri suggerimenti

L'ho fatto come un esercizio in cui le stanze e la griglia "stampano se stesse".Aggiungo questo alla discussione in quanto potrebbe essere più facile da implementare con un'eventuale griglia più grande.

La mappa ASCII

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

Ogni cella in questa griglia è un tre di tre serie di segni "+".Quattro camere sono implementate con valore ID da 1 a 4. Le connessioni tra le camere sono rappresentate come barrette, backslash e tubi.

il codice

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
.

La routine in movimento non è implementata, e per questa rappresentazione funziona, solo gli ID di caratteri singoli verranno visualizzati piacevolmente.

I vantaggi di questo sistema:

    .
  • Facile da aggiungere camere e rimuoverli
  • La definizione di una stanza è leggibile dall'uomo
  • Le funzioni di uscita sovraccaricano generacodictagcode e quindi le stanze e la griglia "Stampa se stesse" e questo potrebbe essere utile per il futuro debug o adattamento ai formati futuri ad es.come cellule in una tabella HTML.

Le mappe a base di coordinate hanno molti vantaggi, ma considerando che molti fanghi di qualità usano un tradizionale mondo della stanza, e le persone hanno reso le automobili per molti fanghi e clienti di fango, non è fuori questione per creare un Automap per A fango senza coordinati. Dovrai solo affrontare i conflitti in caso per caso.

Tuttavia, puoi ancora usare la risposta di @ David-Robinson. Quello che vuoi fare è mantenere una minimaata incidentale centrata sul lettore e aggiornando dinamicamente utilizzando i dati di uscita. Non cercare di tenere una mappa dell'intera area memorizzata; Aggiornamento dinamico avrai evitato alcuni conflitti geografici.

Per scrivere la mappa a un client di fango, tutto ciò che devi fare è scrivere la tua linea mappa correttamente distanziata e terminarla con una nuova riga. Metti tutte le linee della mappa in un elenco in modo che venga inviato come un singolo gruppo di righe (non vuoi un'altra linea inserita tra linee della mappa ad esempio quando viene inviata la presa), e qualsiasi client di fango lo stampa correttamente (con un font monospaziale ovviamente).

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top