public int idAdiacente(int idTile, Direzioni dir) { if (!idValido(idTile)) return -1; int id = idTile; switch (dir) { case Direzioni.Sopra: id -= Colonne; break; case Direzioni.Sotto: id += Colonne; break; case Direzioni.Sinistra: if (id-- % Colonne == 0) return -1; break; case Direzioni.Destra: if (++id % Colonne == 0) return -1; break; case Direzioni.AltoADestra: return idAdiacente(idAdiacente(id, Direzioni.Sopra), Direzioni.Destra); case Direzioni.AltoASinistra: return idAdiacente(idAdiacente(id, Direzioni.Sopra), Direzioni.Sinistra); case Direzioni.BassoASinistra: return idAdiacente(idAdiacente(id, Direzioni.Sotto), Direzioni.Sinistra); case Direzioni.BassoADestra: return idAdiacente(idAdiacente(id, Direzioni.Sotto), Direzioni.Destra); default: return -1; } return idValido(id) ? id : -1; }
// METODI PRIVATI /// <summary> /// Algoritmo ricorsivo /// </summary> /// <param name="IDtile">Indirizzo del tile su cui sta adesso il pathfinder</param> /// <param name="count">Lunghezza attuale del percorso di questo ramo</param> /// <param name="percorso">Array che rappresenta gli indirizzi delle caselle percorse da questo ramo dell'algoritmo</param> /// <param name="direzioneProvenienza">La direzione da cui è stato chiamato l'algoritmo; per evitare chiamate inutili non proseguirà il percorso in questa direzione</param> void crawl(int IDtile, int count, int[] percorso, Direzioni direzioneProvenienza) { Casella casella = Tile.id2Tile(IDtile) as Casella; if (casella == null // non è una casella valida // OR c'è una nave alleata che non è la nave che stiamo muovendo || (casella.PresenzaAlleata(_nave) && count != 0) // OR percorso già esistente e più breve di quello che ha trovato questo ramo della ricorsione || (_matrice[IDtile].Length > 0 && _matrice[IDtile].Length <= percorso.Length)) return; if (count > 0) //Scrittura su memoria del percorso { percorso[count - 1] = IDtile; Array.Resize(ref _matrice[IDtile], count); Array.Copy(percorso, _matrice[IDtile], count); } count++; if (casella.Occupante != null && !casella.PresenzaAlleata(_nave)) return; if (count < DISTANZAMAX) // Chiamate ricorsive { int pos; // Direzioni ortogonali if (_muoveInDiagonale) { pos = (casella + Direzioni.AltoASinistra)?.ID ?? -1; if (direzioneProvenienza != Direzioni.AltoASinistra && Tile.idValido(pos)) { int[] tempArray = new int[count]; Array.Copy(percorso, tempArray, count - 1); crawl(pos, count, tempArray, Direzioni.BassoADestra); } pos = (casella + Direzioni.AltoADestra)?.ID ?? -1; if (direzioneProvenienza != Direzioni.AltoADestra && Tile.idValido(pos)) { int[] tempArray = new int[count]; Array.Copy(percorso, tempArray, count - 1); crawl(pos, count, tempArray, Direzioni.BassoASinistra); } pos = (casella + Direzioni.BassoASinistra)?.ID ?? -1; if (direzioneProvenienza != Direzioni.BassoASinistra && Tile.idValido(pos)) { int[] tempArray = new int[count]; Array.Copy(percorso, tempArray, count - 1); crawl(pos, count, tempArray, Direzioni.AltoADestra); } pos = (casella + Direzioni.BassoADestra)?.ID ?? -1; if (direzioneProvenienza != Direzioni.BassoADestra && Tile.idValido(pos)) { int[] tempArray = new int[count]; Array.Copy(percorso, tempArray, count - 1); crawl(pos, count, tempArray, Direzioni.AltoASinistra); } } //Direzioni ortogonali pos = (casella + Direzioni.Sopra)?.ID ?? -1; if (direzioneProvenienza != Direzioni.Sopra && Tile.idValido(pos)) { int[] tempArray = new int[count]; Array.Copy(percorso, tempArray, count - 1); crawl(pos, count, tempArray, Direzioni.Sotto); } pos = (casella + Direzioni.Sotto)?.ID ?? -1; if (direzioneProvenienza != Direzioni.Sotto && Tile.idValido(pos)) { int[] tempArray = new int[count]; Array.Copy(percorso, tempArray, count - 1); crawl(pos, count, tempArray, Direzioni.Sopra); } pos = (casella + Direzioni.Sinistra)?.ID ?? -1; if (direzioneProvenienza != Direzioni.Sinistra && Tile.idValido(pos)) { int[] tempArray = new int[count]; Array.Copy(percorso, tempArray, count - 1); crawl(pos, count, tempArray, Direzioni.Destra); } pos = (casella + Direzioni.Destra)?.ID ?? -1; if (direzioneProvenienza != Direzioni.Destra && Tile.idValido(pos)) { int[] tempArray = new int[count]; Array.Copy(percorso, tempArray, count - 1); crawl(pos, count, tempArray, Direzioni.Sinistra); } } }
public int idAdiacente(int id, Direzioni dir) { return (id2Tile(id) + dir)?.ID ?? -1; // -1 se il tile di arrivo non è valido (vuoto/inesistente) }
/// <summary> /// Metodo che permette di cambiare ambiente all'interno della mappa e ottenere i messaggi per il giocatore /// </summary> /// <param name="comando">Direzione da prendere</param> /// <returns>Stringa con i messaggi per il giocatore</returns> public string CambiaAmbiente(Direzioni comando) { //All'avvio viene inizializzata la mappa partendo dall'ambiente con indice 0 //Il codice è simile a quello per le altre direzioni, quindi si consiglia di guardare subito sotto se si hanno dubbi if (_inCombattimento) return "Sei in combattimento! Non puoi spostarti!\n"; if (comando == Direzioni.Avvio) { IndiceStanza = 0; string s = "Benvenuto nel " + Mappa[IndiceStanza].Descrizione + "\n"; for (int i = 0; i < Mappa[IndiceStanza].Passaggi.Length; i++) { if (Mappa[IndiceStanza].Passaggi[i] != null) { string direzione; string chiuso = ""; if (i == 0) direzione = "Nord"; else if (i == 1) direzione = "Est"; else if (i == 2) direzione = "Sud"; else direzione = "Ovest"; if (!Mappa[IndiceStanza].Passaggi[i].Aperto) { chiuso = "(Chiuso)"; _pulsantiSpostamento[i].IsEnabled = false; } else _pulsantiSpostamento[i].IsEnabled = true; s += "A " + direzione + " " + Mappa[IndiceStanza].Passaggi[i].Titolo + chiuso + ". "; } else _pulsantiSpostamento[i].IsEnabled = false; } return s + "\n"; } //Per tutti gli altri comandi che non sono Direzione.Avvio viene eseguita questa parte di codice IndiceStanza = Mappa[IndiceStanza].Passaggi[(int)comando].IndiceAmbienteDestinazione; //Trova l'indice della stanza di arrivo string st = "Sei andato in " + Mappa[IndiceStanza].Descrizione + ".\n"; //Comincia a riempire la stringa st che conterrà tutte le informazioni sullo spostamento //Controllo delle eventuali azioni da applicare for (int i = 0; i < Mappa.Length; i++) { if(Mappa[i].Azioni != null) { for (int j = 0; j < Mappa[i].Azioni.Count; j++) { if (Mappa[i].Azioni[j] != null && Mappa[i].Azioni[j].GetType() == typeof(ApriPassaggio)) { if (IndiceStanza == i) { st += Mappa[i].Azioni[j].Esegui(this); } } } } } //Controllo delle eventuali entità presenti nell'Ambiente di arrivo if(Mappa[IndiceStanza].Cose.Count != 0) { _interlocutore.Items.Clear(); bool checkDialogs = false; foreach (Entità ent in Mappa[IndiceStanza].Cose) { if (ent is Persona) { Persona p = (Persona)ent; st += p.Descrizione + "\n"; if (p.Dial != null) { _frase.Items.Clear(); _interlocutore.Items.Add(p.Nome); checkDialogs = true; } } if (ent is Nemico) { Nemico n = (Nemico)ent; st += n.Descrizione + "\n"; _avversariCoinvolti.Items.Add(n); _combatti.IsEnabled = true; _fuggi.IsEnabled = false; } } _parla.IsEnabled = checkDialogs; } else { _interlocutore.Items.Clear(); _frase.Items.Clear(); _parla.IsEnabled = false; } _invAmbiente.Items.Clear(); _oggettiCoinvolti.Items.Clear(); if (Mappa[IndiceStanza].Inv.Oggetti.Count != 0) { st += CaricaInventarioAmbiente(); } _interlocutoreAttuale = ""; _profonditàScelta = -1; //Ciclo per finire il riempimento della stringa st con informazioni riguardanti gli ambienti visibili //Inoltre permette di disabilitare i pulsanti qualora mancassi il passaggio o fosse chiuso for (int i = 0; i < Mappa[IndiceStanza].Passaggi.Length; i++) { if (Mappa[IndiceStanza].Passaggi[i] != null) { string direzione; string chiuso = ""; if (i == 0) direzione = "Nord"; else if (i == 1) direzione = "Est"; else if (i == 2) direzione = "Sud"; else direzione = "Ovest"; if (!Mappa[IndiceStanza].Passaggi[i].Aperto) { chiuso = "(Chiuso)"; _pulsantiSpostamento[i].IsEnabled = false; } else _pulsantiSpostamento[i].IsEnabled = true; st += "A " + direzione + " " + Mappa[IndiceStanza].Passaggi[i].Titolo + chiuso + ". "; } else _pulsantiSpostamento[i].IsEnabled = false; } return st + "\n"; }