Come simulare gli esseri viventi nel software [chiuso]

3

Stavo pensando di creare un semplice gioco / simulazione in cui le auto circolano in una città come parte di un progetto per animali domestici.

Questo mi ha fatto pensare a come avrei simulato queste singole auto in un mondo simulato. Come faresti a far fronte a quanto segue:

L'ambiente simulato ha il concetto di tempo. Quindi credo che tu abbia bisogno di una sorta di "world-thread". Un thread che continua a funzionare e simula il tempo di questo mondo e di tutto ciò che vive al suo interno.

Ma hai anche le macchine che girano in questa città. Queste auto possono singolarmente accelerare, frenare, fermare, parcheggiare o essere distrutte / create.

Ora la mia domanda: come simulare al meglio questo mondo. Ogni macchina sarebbe una discussione propria. Quindi se ci sono 10000 automobili, avresti 10001 thread (10000 auto + 1 thread mondiale). O ci sarebbe solo un thread che calcola lo stato di ogni cosa che vive al suo interno su ogni "tick" del tempo che è passato in questo mondo simulato? Conoscete alcuni documenti / riferimenti / libri / blog che spiegano alcuni meccanismi del mondo di gioco e come simularli?

    
posta bvanvelsen 28.07.2017 - 15:51
fonte

3 risposte

4

Non avresti mille thread perché questo sarebbe un overhead delle prestazioni se non utilizzi un supercomputer in parallelo.

Un'architettura software comune dovrebbe avere una coda con tutti gli oggetti e un paio di thread ottimali che ciascuno legge dalla coda il prossimo oggetto da elaborare e mettere l'oggetto con il suo nuovo stato alla fine della coda .

In genere, questo può essere combinato con l'uso del schema dei pesi volanti che mira a ottimizzare le risorse necessarie per un alto numero di oggetti simili.

    
risposta data 28.07.2017 - 16:54
fonte
3

Puoi acquisire le competenze di programmazione necessarie facendo prima un progetto più semplice: simula un sistema di massa primaverile secondo la fisica. Una volta raggiunto questo traguardo, sarà più facile per te concettualizzare un sistema più grande.

Il tuo programma è un ciclo. Ad ogni passo temporale ("tick of time"), ad esempio t , il tuo programma deve calcolare i parametri (posizione, velocità, accelerazione, decisione dell'autista) di ogni auto per il passo successivo, ad esempio t + 1 .

  • Avrai una serie di macchine, diciamo carCurrentStates[carNumber] .
  • Potrebbe essere necessario creare un array duplicato, carNextStates[carNumber] .
  • Ad ogni passaggio temporale, utilizza le informazioni da carCurrentStates[carNumber] per calcolare le nuove informazioni per carNextStates[carNumber] . Quando tutti i calcoli per la fase temporale sono terminati, copia le informazioni da carNextStates[carNumber] a carCurrentStates[carNumber] .
  • L'array duplicato carNextStates[carNumber] può essere riutilizzato (sovrascritto) nel passaggio successivo.

Dovrai sincronizzare questi calcoli.

Sia che tu usi i thread o meno, dovrai usare alcuni tipi di tecniche di sincronizzazione. Le tecniche di sincronizzazione per i thread sono anche conosciute come barriere.

Gli scheduler dei thread non causano magicamente l'esecuzione dei thread in modo sincronizzato. Non danno magicamente la stessa quota di tempo a ciascuno dei tuoi thread. Se non si utilizzano tecniche di sincronizzazione, alcuni thread avranno tempi di esecuzione maggiori rispetto ad altri; perderanno la sincronizzazione.

Se più thread devono aggiornare (scrivere su) una determinata variabile di programma, che deve essere serializzata. La serializzazione indica che un thread può completare una sequenza di "lettura-modifica-scrittura" prima che un altro thread possa iniziare la propria sequenza di "lettura-modifica-scrittura". Se l'accesso alle variabili del programma non è serializzato, il risultato scritto di ciascun thread comprimerà il risultato precedente, o che un thread potrebbe eseguire calcoli basati su un risultato vecchio che è stato successivamente danneggiato.

Una volta che sai come implementare i calcoli in modo sincronizzato e aggiornare correttamente gli stati del programma, potresti scoprire che puoi implementare il progetto con o senza thread.

Per simulare il comportamento del conducente, ogni driver accelererà o decelererà secondo:

  • Qual è la mia velocità? (Bassa / media / alta)
  • Qual è la velocità delle corsie adiacenti?
  • Quanto è distante l'auto di fronte a me?
  • Lo spazio tra me e la macchina di fronte: crescente (accelerando più veloce di me), stesso (stessa velocità / stessa accelerazione) o decrescente?
  • Sto progettando di cambiare corsia? Se è così, ho bisogno di abbinare la velocità di quell'altra corsia.
  • Ho qualche altra ragione per rallentare? Se ho intenzione di uscire da un'autostrada, o se c'è un semaforo, o se c'è una curva strong, allora ho bisogno di rallentare.
  • Devo fermarmi completamente a un certo punto? Se sto raggiungendo la mia destinazione, o se il semaforo è rosso, allora non mi è permesso di oltrepassarlo. Devo frenare il più strong possibile, se necessario.
risposta data 28.07.2017 - 21:44
fonte
3

Potresti dare un'occhiata alla documentazione di un motore di gioco, come Unreal Engine 4, che ti darà una buona idea di ciò che è coinvolto nella modellazione di un mondo nel software. In questo contesto, tutto in un gioco / mondo è un "attore" e il motore di gioco li gestisce tutti. Dalla loro documentazione, ho l'impressione che ogni attore non sia il suo filo conduttore. Ecco un link che descrive il loro sistema "ticking":

link

Ottengo l'impressione che gli oggetti attore siano gestiti dal runtime in modo lineare e non massicciamente multi-thread. Vale anche la pena sottolineare che simulando un mondo con le automobili esiste anche un sistema fisico, un sistema meteorologico, ecc. Diventa molto complesso molto rapidamente.

È molto interessante fare un tuffo in profondità in una moderna documentazione sui motori di gioco e nel codice sorgente.

    
risposta data 29.07.2017 - 16:11
fonte