Sistema di inventario organizzato automaticamente / intelligente?


11

la scorsa settimana ho lavorato su un sistema di inventario con Unity3D. All'inizio ho ricevuto aiuto dai ragazzi di Design3, ma non è passato molto tempo prima che ci dividessimo il percorso, perché non mi piaceva davvero il modo in cui avevano scritto il loro codice, non aveva alcun odore di OOP.

Ho fatto ulteriori passi avanti: gli oggetti occupano più di uno slot, il sistema di posizionamento avanzato (gli articoli fanno del loro meglio per trovare la migliore aderenza ravvicinata), il sistema locale del mouse (il mouse rimane intrappolato nell'area attiva della borsa), ecc.

Ecco una demo del mio lavoro.

Ciò che vorremmo avere nel nostro gioco è una funzione di auto-organizzazione, non di auto-ordinamento. Vogliamo questa funzione perché il nostro inventario sarà in "tempo reale" - non come in Resident Evil 1,2,3 ecc., Dove metterebbe in pausa il gioco e fare cose nel tuo inventario. Ora immagina te stesso in una situazione appiccicosa circondata da zombi e non hai proiettili, ti guardi intorno, vedi che ci sono proiettili nelle vicinanze per terra, quindi vai per loro e provi a raccoglierli, ma loro non lo fanno in forma! guardi il tuo inventario e scopri che se riorganizzi alcuni degli articoli, andrà bene! - ora il giocatore - in quella situazione non ha il tempo di riorganizzarsi perché è circondato da zombi e morirà se si ferma e organizza l'inventario per fare spazio (ricorda l'inventario in tempo reale, nessuna pausa) - sarebbe bello che ciò accada automaticamente? - Sì!

(Credo che questo sia stato implementato in alcuni giochi come l'assedio di Dungeon o qualcosa del genere, quindi sicuramente è fattibile)

dai un'occhiata a questa immagine per esempio:

Cosa fa l'ordinamento automatico

Sì, quindi se ordinate automaticamente il problema otterrete i vostri spazi ma è un male perché: 1- Costoso: non ha bisogno di un'operazione di ordinamento completa per liberare quegli spazi, nella prima foto, basta scorrere l'elemento rosso sul in basso a sinistra, e ottieni gli stessi spazi che hai ottenuto dall'ordinamento automatico. 2- È fastidioso per il giocatore: "Chi ti ha detto di riordinare le mie cose?"

Non sto chiedendo "Come scrivere il codice" per questo, sto solo chiedendo una guida, dove cercare, quali algoritmi sono coinvolti? È qualcosa correlato ai grafici e agli elementi del percorso più breve? Spero di no perché non sono riuscito a continuare i miei studi universitari: / Ma anche se lo è, dimmelo e imparerò le cose relative.

Si noti che potrebbe esserci più di una soluzione. Quindi immagino che la prima cosa che devo fare sia capire se la situazione è "risolvibile" - se so come determinare se una situazione è risolvibile o meno, allora posso "risolverla". Devo solo conoscere le condizioni che lo rendono "risolvibile". E credo che ci debba essere qualche algoritmo / struttura dati per questo.

Ecco una foto per più di una soluzione nel tentativo di adattare un elemento 1x3:

inserisci qui la descrizione dell'immagine

Le frecce mostrano solo una delle soluzioni, ma se guardi ne troverai più di una. Questo è ciò che alla fine non eseguo l'ordinamento automatico, ma trovo una soluzione e l'applicazione.

Nota che se ci trascorro del tempo, mi verrà in mente un modo per risolverlo, ma non sarebbe il modo migliore, è come tenere una ruota dell'auto con i piedi invece delle mani! XD O semplicemente come cercare di risolvere un problema che richiede array, ma non sei ancora a conoscenza della loro esistenza! Quindi qual è l'approccio giusto a questo?

Aggiornamenti dal commento

@Stephen Non sono davvero un guru in Alogs, hai menzionato 'zaino' e @BlueRaja - Danny Pflughoeft ha menzionato un algoritmo di imballaggio bidone 2D. Sono in qualche modo correlati / uguali? - Sono ancora confuso su come dovrei affrontarlo.

E sì, sto già usando un "euristico" ma non sapevo davvero di essere: D trova il primo slot disponibile e controlla se l'oggetto si adatta.

Non so se ordinare gli articoli in base alla loro "voluminosità" (che chiamo nSlotsRequired = nRowsReq * nColsRec) funzionerebbe, perché ad esempio hai articoli 2x2 e 1x4, hanno la stessa voluminosità, ma forme diverse e avranno un effetto diverso su come andranno le altre voci successive. COSÌ... :/

Ho visto questo video, mi è piaciuta molto l'idea di imballaggio completo, ma mi chiedo come procedere poiché l'inventario è in 2D. Non sono nemmeno sicuro che l'imballaggio del cestino sia la chiave qui perché, beh, è ​​vero che posso avere più di una borsa, ma nel nostro gioco sarà solo una borsa. Quindi, si tratta di inserire gli articoli in una "borsa" e non di più. Quindi gli esempi in quel video (i tubi e gli autobus) non corrispondono davvero al mio problema. Ho anche visto alcune cose su questa cosa dello zaino, non ho visto come il "valore" sia correlato ai miei articoli / inventario, ma immagino che il "peso" sia lo stesso della voluminosità, non ne sono sicuro.


7
Questo è un bidone bidimensionale, NP-Complete. Pertanto, qualsiasi algoritmo che ti dirà se puoi adattare tutti gli elementi sarà inefficiente (nel peggiore dei casi). Tuttavia, puoi trovare alcuni algoritmi di approssimazione piuttosto buoni.
BlueRaja - Danny Pflughoeft il

Questo è esattamente il motivo per cui ho deciso il modello di inventario (più comune in questi giorni) con uno slot per articolo anziché questo. Vorrei avere una soluzione per te, ho rinunciato a questo problema ...
Ryno,

@ BlueRaja-DannyPflughoeft Mi chiedo se sia disponibile un algoritmo semplice / efficiente se gli articoli fossero limitati a determinate forme?
congusbongus,

Limitare le forme non riduce la complessità, ma semplifica la riflessione, quindi pensi che la complessità sia stata gestita, a dir poco.
Patrick Hughes,

@VeXe Mi dispiace aver perso l'aggiornamento sulla tua domanda. L'imballaggio del cestino e lo zaino non sono gli stessi. Ma entrambi sono problemi di imballaggio. Il "valore" nel tuo caso è la forma e la dimensione dei tuoi oggetti di inventario.
Stephen,

Risposte:


8

Questa è una variazione del problema dello zaino. Come menziona Danny Pflughoeft, NP-Complete. Significa che non può essere risolto in tempo lineare, se ricordo bene.

Ma puoi provare a risolverlo in più passaggi. È fondamentalmente un problema di ordinamento.

Vorrei iniziare calcolando la "voluminosità" di ciascun articolo: questo potrebbe essere calcolato in diversi modi:

  • voluminosità = max (lunghezza, larghezza);

  • voluminosità = lunghezza * larghezza

  • voluminosità = sqrt (lunghezza * larghezza)

Quindi inizia a mettere prima gli oggetti con il punteggio più alto nell'inventario. Dal momento che molto probabilmente non si adatteranno allo spazio rimanente in seguito. I piccoli oggetti si adatteranno sempre.

Hai bisogno di un euristico (un nome di fantasia per indovinare educato ;-)) per la tua strategia di piazzamento. Qualcosa come cercare di adattare gli oggetti nel primo slot libero in alto a sinistra o qualcosa del genere.

Penso che la strategia di smistamento delle scorte di Diablo II abbia funzionato in qualche modo simile. Cose come spade e lance sarebbero finite in alto a sinistra, poi vestiti e armature, poi fibbia e così via.

Penso che tu abbia davvero bisogno di provarlo e modificare l'algoritmo (diverso calcolo dell'ingombro, diversa euristica), fino a quando non funziona abbastanza ragionevolmente.


1
NP-complete è un insieme di problemi con complessità superiore al polinomio. Per un inventario relativamente piccolo (meno di mille articoli direi :)) anche l'algoritmo esponenziale funzionerebbe abbastanza velocemente, perché un passaggio di tale algoritmo richiede pochissimo tempo. Tuttavia, usare la tua idea dovrebbe essere abbastanza buono e più semplice rispetto all'implementazione di un algoritmo di programmazione dinamica -> +1
MartinTeeVarga,

grazie per il voto. Sì, l'inventario non dovrebbe essere potenzialmente infinito, quindi gli algoritmi esponenziali dovrebbero funzionare bene ^^
Stephen,

@ sm4: Mille sono in genere un numero enorme per problemi NP-Complete. Ricorda, questi problemi sono O (2 ^ n) - anche solo 2 ^ 64 è impossibile dal punto di vista computazionale!
BlueRaja - Danny Pflughoeft

3

Haha, @Ognuno che ha aiutato, grazie. Sono riuscito a risolverlo finalmente. Ecco cosa ho praticamente fatto:

IEnumerator AddItem_Sorted (Item item)
  1. Condizione di prova: controlla se abbiamo ottenuto il minimo nRequiredSlots per l'articolo per adattarsi, se ce l'abbiamo, procedi ...
  2. svuoteremo tutta la borsa - mettendo gli articoli in un segnaposto (elenco o qualcosa del genere)
  3. aggiungi l'elemento desiderato all'ultimo MOLTO slot / luogo in cui potrebbe adattarsi, assicurandoti che sia sicuro nella sua forma orizzontale
  4. usando l'algo decrescente di primo adattamento aggiungeremo il resto dei nostri articoli
  5. durante l'aggiunta, useremo la programmazione dinamica (memoisation) per ricordare quell'indice a cui stiamo aggiungendo (indice del prossimo slot disponibile)
  6. se tutte le aggiunte hanno successo, siamo riusciti ad adattare il nostro articolo desiderato e in qualche modo riordinare la borsa, dai grandi ai piccoli
  7. se non potessimo aggiungere tutti gli articoli, ciò significa che non si trattava di una situazione risolvibile, quindi dobbiamo riportare la borsa al suo stato precedente
  8. un modo per farlo, (è venuto fuori dalla mia mente), è copiare lo stato della borsa prima di tutta questa oppressione, e quindi se fallisce, passeremo a quello stato precedente, o anche meglio, durante il ' svuotamento 'della borsa, memorizziamo dove si trovava ogni elemento, in modo che se l'operazione fallisce, li recupereremo - usando AddItem (oggetto, indice) - ai loro indici precedenti :)
  9. l'intero processo potrebbe richiedere del tempo, quindi potremmo dividere il carico su frame separati, usando la mia bella resa :)
  10. FATTO ! \ m / (@ ~ 9: 00)

AGGIORNARE:

  1. Ho creato un array che ha memorizzato gli indici di tutti gli elementi aggiunti, in questo modo non devo andare a cercare le slot occupate per liberarmi - grande spinta.

  2. non è necessario aggiungere all'ultimo slot, infatti a volte potrebbe non funzionare in questo modo, ho aggiunto l'elemento desiderato al resto degli altri e l'ho ordinato con loro.

Come puoi vedere dal video, ha bisogno di un po 'di ottimizzazione, l'ordinamento non è perfetto, vorrei usare l'imballaggio completo del cestino, ma è già avido di prestazioni. Sono aperto a qualsiasi suggerimento di ottimizzazione, grazie ancora :)


Prego! :) Vorrei ringraziare BlueRaja - Danny Pflughoeft per aver menzionato l'imballaggio del cestino, @Stephen per l'idea di volgarità e Richard Buckland per la sua lezione di programmazione dinamica e tutte le lezioni.
vexe,
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.