package ingsw.proj.cluedo.logica;
import static ingsw.proj.cluedo.utility.Utillity.lanciaDadi;
import ingsw.proj.cluedo.componenti.Congettura;
import ingsw.proj.cluedo.eventi.AccusaFormulataEvent;
import ingsw.proj.cluedo.eventi.AccusaFormulataListener;
import ingsw.proj.cluedo.eventi.AzioneSceltaEvent;
import ingsw.proj.cluedo.eventi.AzioneSceltaListener;
import ingsw.proj.cluedo.eventi.DestinazioneSceltaEvent;
import ingsw.proj.cluedo.eventi.DestinazioneSceltaListener;
import ingsw.proj.cluedo.eventi.IpotesiFormulataEvent;
import ingsw.proj.cluedo.eventi.IpotesiFormulataListener;
import ingsw.proj.cluedo.eventi.NomiSceltiEvent;
import ingsw.proj.cluedo.eventi.NomiSceltiListener;
import ingsw.proj.cluedo.gui.InterfacciaUtente;
import java.awt.Point;
import java.util.ArrayList;
import java.util.Iterator;
/**
* Generico main che gestisce l'avvio del gioco
*
* @author C&C
*
*/
public class MainLoop implements Runnable {
private ControlloreDiGioco controller;
private InterfacciaUtente ui;
private String giocatoreAttuale;
private class myNomiSceltiListener implements NomiSceltiListener {
@Override
public void notificaNomiScelti(NomiSceltiEvent evento) {
controller = new InitGioco(evento.getNomi()).getControllore();
ui.removeListener(this);
ui.disegnaTabellone(controller.getTabelloneRidotto());
ProssimoTurno();
}
}
private class myDestinazioneSceltaListener implements DestinazioneSceltaListener {
int rimanenti;
public myDestinazioneSceltaListener(int rimanenti) {
this.rimanenti = rimanenti;
}
@Override
public void notificaDestinazioneScelta(DestinazioneSceltaEvent evento) {
ui.removeListener(this);
controller.spostaGiocatore(evento.getGiocatore(), evento.getDestinazione());
ui.refreshTabellone(controller.getTabelloneRidotto());
if (rimanenti > 0) {
Iterator<Point> destIt = controller.getDestinazioniGiocatore(giocatoreAttuale);
ArrayList<Point> dest = new ArrayList<Point>();
while (destIt.hasNext())
dest.add(destIt.next());
Point[] destArray = (Point[]) dest.toArray(new Point[dest.size()]);
ui.addListener(new myDestinazioneSceltaListener(rimanenti - 1));
ui.chiediDestinazione(giocatoreAttuale, destArray);
} else {
ui.addListener(new myAzioneSceltaListener());
Iterator<AzioniEnum> azioniIt = controller.getPossibiliAzioni(giocatoreAttuale);
ArrayList<AzioniEnum> azioni = new ArrayList<AzioniEnum>();
while (azioniIt.hasNext())
azioni.add(azioniIt.next());
AzioniEnum[] azioniArray = (AzioniEnum[]) azioni.toArray(new AzioniEnum[azioni.size()]);
ui.chiediAzione(giocatoreAttuale, azioniArray);
}
}
}
private class myAzioneSceltaListener implements AzioneSceltaListener {
@Override
public void notificaAzioneScelta(AzioneSceltaEvent evento) {
AzioniEnum scelta = evento.getAzione();
ui.removeListener(this);
ui.refreshTabellone(controller.getTabelloneRidotto());
if (scelta == AzioniEnum.PASSA) {
ui.notificaFineTurno(giocatoreAttuale);
ProssimoTurno();
} else if (scelta == AzioniEnum.MOVIMENTO) {
int result = lanciaDadi(2);
ui.mostraLancioDadi(result);
Iterator<Point> destIt = controller.getDestinazioniGiocatore(giocatoreAttuale);
ArrayList<Point> dest = new ArrayList<Point>();
while (destIt.hasNext())
dest.add(destIt.next());
Point[] destArray = (Point[]) dest.toArray(new Point[dest.size()]);
if (destArray.length > 0) {
ui.addListener(new myDestinazioneSceltaListener(result - 1));
ui.chiediDestinazione(giocatoreAttuale, destArray);
} else {
ui.notificaErrore("Spiacente ma non puoi muoverti!");
ui.addListener(new myAzioneSceltaListener());
Iterator<AzioniEnum> azioniIt = controller.getPossibiliAzioni(giocatoreAttuale);
ArrayList<AzioniEnum> azioni = new ArrayList<AzioniEnum>();
while (azioniIt.hasNext())
azioni.add(azioniIt.next());
AzioniEnum[] azioniArray = (AzioniEnum[]) azioni.toArray(new AzioniEnum[azioni.size()]);
ui.chiediAzione(giocatoreAttuale, azioniArray);
}
} else if (scelta == AzioniEnum.ACCUSA) {
ui.addListener(new myAccusaFormulataListener());
ui.formulaAccusa(giocatoreAttuale);
} else if (scelta == AzioniEnum.IPOTESI) {
ui.addListener(new myIpotesiFormulataListener());
ui.forumlaIpotesi(giocatoreAttuale);
}
}
}
private class myIpotesiFormulataListener implements IpotesiFormulataListener {
@Override
public void notificaIpotesiFormulata(IpotesiFormulataEvent evento) {
Iterator<String> noteIt = controller.getNoteGiocatore(giocatoreAttuale);
ArrayList<String> note = new ArrayList<String>();
while (noteIt.hasNext())
note.add(noteIt.next());
String[] noteArray = (String[]) note.toArray(new String[note.size()]);
ui.removeListener(this);
controller.verificaIpotesi(new Congettura(evento.getIpotesi(), evento.getAccusante()));
ui.mostraAppunti(giocatoreAttuale, noteArray);
ui.refreshTabellone(controller.getTabelloneRidotto());
ui.addListener(new myAzioneSceltaListener());
Iterator<AzioniEnum> azioniIt = controller.getPossibiliAzioni(giocatoreAttuale);
ArrayList<AzioniEnum> azioni = new ArrayList<AzioniEnum>();
while (azioniIt.hasNext())
azioni.add(azioniIt.next());
AzioniEnum[] azioniArray = (AzioniEnum[]) azioni.toArray(new AzioniEnum[azioni.size()]);
ui.chiediAzione(giocatoreAttuale, azioniArray);
}
}
private class myAccusaFormulataListener implements AccusaFormulataListener {
@Override
public void notificaAccusaFormulata(AccusaFormulataEvent evento) {
boolean result;
ui.removeListener(this);
result = controller.verificaAccusa(new Congettura(evento.getAccusa(), evento.getAccusante()));
ui.refreshTabellone(controller.getTabelloneRidotto());
if (result)
ui.notificaGiocoVinto(giocatoreAttuale);
else {
ui.notificaGameOver(giocatoreAttuale);
Iterator<String> noteIt = controller.getNoteGiocatore(evento.getAccusante());
ArrayList<String> note = new ArrayList<String>();
while (noteIt.hasNext())
note.add(noteIt.next());
String[] noteArray = (String[]) note.toArray(new String[note.size()]);
ui.mostraAppunti(evento.getAccusante(), noteArray);
ProssimoTurno();
}
}
}
/**
* Costruttore con parametri del MainLoop
*
* @param ui
* tipo di interfaccia utente da passare
*/
public MainLoop(InterfacciaUtente ui) {
super();
this.ui = ui;
}
/**
* Metodo per avviare il gioco
*
* @throws NullPointerException
* se aggiunti listener con riferimento null
*/
public void AvviaGioco() throws NullPointerException {
ui.addListener(new myNomiSceltiListener());
ui.chiediNomiGiocatori();
}
private void ProssimoTurno() {
if (controller.giocoAttivo()) {
ArrayList<String> tmp = new ArrayList<String>();
String[] tmpArray;
giocatoreAttuale = controller.getProssimoGiocatore(giocatoreAttuale);
ui.notificaInizioTurno(giocatoreAttuale);
tmp.clear();
Iterator<String> carteIt = controller.getCarteGiocatore(giocatoreAttuale);
while (carteIt.hasNext())
tmp.add(carteIt.next());
tmpArray = (String[]) tmp.toArray(new String[tmp.size()]);
ui.mostraCarte(giocatoreAttuale, tmpArray);
tmp.clear();
Iterator<String> noteIt = controller.getNoteGiocatore(giocatoreAttuale);
while (noteIt.hasNext())
tmp.add(noteIt.next());
tmpArray = (String[]) tmp.toArray(new String[tmp.size()]);
ui.mostraAppunti(giocatoreAttuale, tmpArray);
ui.refreshTabellone(controller.getTabelloneRidotto());
ui.addListener(new myAzioneSceltaListener());
Iterator<AzioniEnum> azioniIt = controller.getPossibiliAzioni(giocatoreAttuale);
ArrayList<AzioniEnum> azioni = new ArrayList<AzioniEnum>();
while (azioniIt.hasNext())
azioni.add(azioniIt.next());
AzioniEnum[] azioniArray = (AzioniEnum[]) azioni.toArray(new AzioniEnum[azioni.size()]);
ui.chiediAzione(giocatoreAttuale, azioniArray);
} else {
ui.notificaGiocoFinito(controller.getSoluzione());
}
}
/**
* Metodo non utilizzato ma utile per threads separati
*/
@Override
public void run() {
AvviaGioco();
}
}