Trovare possibili mosse per un'entità in un gioco piastrellato 2D


10

Sto riscontrando problemi con un termine di ricerca specifico per questo, ma come si potrebbe trovare le possibili mosse in un gioco di strategia a turni 2D (cioè FF: Tactics, Fire Emblem, Advance Wars).

inserisci qui la descrizione dell'immagine

Non sto pensando molto al terreno (o anche alla collisione) a questo punto. Mi sto solo chiedendo quale algoritmo posso usare per capire che l'entità X può spostare 5 tessere e attaccare 2 tessere più lontane.

So di poter usare qualcosa come Dijkstra per trovare la distanza tra due punti. Un'implementazione possibile è iniziare dalla posizione dei giocatori e poi ramificarsi da lì fino a quando la distanza restituita da Dijkstra è maggiore del conteggio delle mosse.

Mi chiedo solo se qualcuno potrebbe indicarmi la giusta direzione (es. Nome di algoritmi, tecnica, articoli, ecc.).


Sto pensando che si chiama ricerca del percorso, per un termine di ricerca? Se usi la ricerca del percorso, potresti avere dei contatori per gestire ciò di cui hai bisogno
Exikle

Questo è essenzialmente parte della ricerca del percorso (calcolo dei metadati per i costi di movimento). Determinate solo le località che si trovano nel raggio d'azione, ma non necessariamente determinate anche il percorso che dovreste prendere.
Mario,

1
Non è in tempo reale (RTS) se è basato su turni alla FFTactics. : p
Alayric,

In 2d, è possibile utilizzare il calcolo Taxicab / Manhattan en.wikipedia.org/wiki/Taxicab_geometry
Gerben Jacobs,

Risposte:


5

Penso che un Dijkstra limitato sia esattamente quello che vuoi usare. Il modo in cui Dijkstra trova la distanza tra due punti è che mappa la distanza di ogni nodo da un nodo di origine, quindi "seleziona" il percorso più breve da questa mappa di distanza. Vuoi fare praticamente la stessa cosa, tranne che vuoi il grafico del nodo della distanza che crea come output, piuttosto che un percorso verso un punto particolare.

L'unica modifica che vorrai fare è saltare il calcolo della distanza dai nodi che hanno già superato il raggio di movimento massimo. Quindi avrai un grafico a nodi di tutti i nodi verso i quali l'unità può viaggiare, oltre a un bordo, quindi basta ritagliare i nodi che hanno una distanza maggiore della tolleranza di movimento.

Viola.

In altre parole, praticamente quello che hai descritto nella tua domanda è quello che devi fare. Ha anche il vantaggio di essere in grado di utilizzare l'output per eseguire l'indirizzamento dei percorsi, senza dover eseguire ulteriori calcoli.


Penso che Dijkstra sia eccessivo in questo caso. L'OP non ha bisogno di un percorso per tutte le possibili destinazioni di movimento, solo una risposta sì / no sul fatto che un agente possa arrivarci. Può calcolare un percorso in seguito una volta che l'utente ne ha scelto uno.
Michael Kristofik,

Il costo dell'utilizzo dell'algoritmo di Dijkstra per calcolare il percorso dopo che una destinazione è stata decisa è quasi lo stesso di usarlo in anticipo (a meno che non si usi un approccio euristico come A * per il percorso). Non farlo in anticipo crea semplicemente un lavoro ridondante, dal momento che Dijkstra rispondeva sia alle domande "dove posso andare" che a "come ci arrivo?". Consente inoltre l'aggiunta di complicazioni all'ambiente che modificano il costo del movimento, anche se ciò potrebbe non essere necessario per l'applicazione. Inoltre, l'approccio è ben documentato, il che è utile per l'implementatore.
TASagent,

1
Osservando la risposta di Mario, in realtà descrive l'algoritmo di Dijkstra, tranne che inverte la distanza e non menziona che è Dijkstra.
TASagent,

1
Non direi che è Dijkstra, perché non stai davvero cercando un percorso più breve né stai cercando di raggiungere un punto specifico. È essenzialmente la prima parte dell'algoritmo di Dijkstra, è vero però. Il problema con la tua formulazione, usando Dijkstra, può essere fuorviante e penso che questo sia anche ciò che ha confuso Michael. Probabilmente pensava che avresti suggerito di usare Dijkstra una volta per ogni campo / cella.
Mario,

1
Finire con questo approccio ha funzionato bene ed è molto facile estenderlo per gestire gli ostacoli.
NRaf,

12

L'approccio più semplice (e probabilmente più ingenuo) che mi viene in mente in questo momento:

  • Inizia dal tuo personaggio e segna tutti i campi circostanti come steps - 1.
  • Scorrere su tutti i campi appena contrassegnati e contrassegnare nuovamente i campi circostanti come steps - 1dove stepssarebbe il numero di passaggio del campo corrente, a meno che il nuovo campo abbia un numero già più alto.
  • Ripeti l'ultimo passaggio fino a quando non hai finito i passaggi.

1
Questo algoritmo ha un nome: Flood Fill .
Michael Kristofik,

6
@MichaelKristofik: la chiamerei per ampiezza prima ricerca . Il riempimento alluvione non tiene traccia delle distanze.
BlueRaja - Danny Pflughoeft

2

Penso che quello che stai cercando potrebbe essere Manhattan Distance . Supponendo che non ci siano ostacoli, puoi dire che un quadrato è raggiungibile semplicemente se:

| Tox-fromX | + | toY-fromY | <maxMoveDistance

Questo algoritmo potrebbe non essere la direzione giusta da percorrere se si incontrano ostacoli in seguito; un modo possibile per adattarlo potrebbe consistere nel fatto che gli ostacoli proiettino "ombre" e riesaminino dal punto più vicino.

EDIT (Perché ora ho un po 'più di tempo libero):

Per "ombre" intendo qualcosa del genere, se 0 è un quadrato raggiungibile, C è il personaggio e X è un ostacolo:

 012345678
0    0
1   00
2  000X
3 000C000
4  00000
5   000
6    0
 012345678

Dal momento che (5, 2) è un ostacolo, inizi partendo dal presupposto che non puoi arrivare a nulla con x> = 5 AND y <= 2. È quindi possibile ricalcolare da un altro quadrato; se vuoi andare a (5, 1) puoi calcolare la distanza di manhattan da (4, 1) e vedere se quella + la distanza dal personaggio a (4, 1) è inferiore alla distanza di movimento del giocatore.

Questo è un esempio abbastanza banale, ma se hai più ostacoli e / o un raggio di movimento un po 'più lungo, dovrebbe essere in grado di gestire la complessità.

Se sarebbe effettivamente meglio del semplice allagamento, sia nella complessità della programmazione che nell'efficienza dell'esecuzione, non ne ho idea. Sembrava solo un modo più interessante per risolvere il problema.


Cosa intendi per proiettare ombre?
NRaf

1
A cura di chiarimenti.
Tin Man,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.