Pagina 1 di 2 1 2 ultimoultimo
Visualizzazione dei risultati da 1 a 10 su 14

Discussione: Aiuto eseguire class

  1. #1
    Utente di HTML.it
    Registrato dal
    Nov 2007
    Messaggi
    8

    Aiuto eseguire class

    Sto scrivendo un gioco in java e mi trovo davanti ad un problema, dovrei eseguire un pezzo di programma differente a seconda di un nome all'interno di una variabile, ma i pezzi non sono fissi ma scritti dal giocatore... mi spiego meglio... un giocatore scrive la sua AI e il gioco la deve eseguire...
    il giocatore per quello che posso pensare io (poi voi mi direte) scrive una classe ereditata dal gioco contenente tutte le risorse necessarie. es: pippo eredita dal carroarmato ma come faccio ad esegure la AI pippo giusta parametrizzandola all'interno del gioco...
    naturalmente la classe ereditata deve essere compilata .class
    ma poi come faccio a importarla parametrizzandola... spero di essermi spiegato bene..
    ciao e grazie

  2. #2
    Utente di HTML.it
    Registrato dal
    Dec 2010
    Messaggi
    268
    non ho ben capito, cosa è AI? e perchè pippo deve ereditare qualcosa? se mi spieghi forse posso aiutarti

  3. #3
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,284

    Re: Aiuto eseguire class

    Originariamente inviato da byanto
    il giocatore per quello che posso pensare io (poi voi mi direte) scrive una classe ereditata dal gioco contenente tutte le risorse necessarie. es: pippo eredita dal carroarmato ma come faccio ad esegure la AI pippo giusta parametrizzandola all'interno del gioco...
    naturalmente la classe ereditata deve essere compilata .class
    ma poi come faccio a importarla parametrizzandola...
    Sì dovrei aver intuito bene, un sistema a mo' di "plug-in". E certo, è possibile e richiederebbe quasi sicuramente l'uso della "reflection" e a seconda dello scenario anche di "class loader" specifici (che potrebbe anche essere il java.net.URLClassLoader già implementato), dipende da come/dove vuoi che vengano "scoperti" a runtime i "plug-in".

    Non è banale ... o perlomeno, è tutto sommato facile se conosci i due argomenti che ho citato.
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    java.util.function Interfaces Cheat SheetJava Versions Cheat Sheet

  4. #4
    Utente di HTML.it
    Registrato dal
    Nov 2007
    Messaggi
    8
    ok per ora grazie vedo di dare un occhio a quello che mi hai detto e poi ti dico... grazie ancora

  5. #5
    Utente di HTML.it
    Registrato dal
    Nov 2007
    Messaggi
    8
    ok la reflection sembra quello che cerco, sono riuscito a caricare la classe giusta e lo vedo con
    Class c = Class.forName("paolo");
    Method m[] = c.getDeclaredMethods();

    ma riesco anche a eseguire un metodo o la main? se si come si fa? se no allora passo a qualcosa di differente...
    ciao

  6. #6
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,284
    Originariamente inviato da byanto
    ok la reflection sembra quello che cerco, sono riuscito a caricare la classe giusta e lo vedo con
    Class c = Class.forName("paolo");
    Method m[] = c.getDeclaredMethods();

    ma riesco anche a eseguire un metodo o la main? se si come si fa? se no allora passo a qualcosa di differente...
    No, la strada è questa ... intendo: la reflection.

    Poi è chiaro che se il nome della classe lo "cabli" nel sorgente ... tanto generico/flessibile non lo è il tuo codice. Se vuoi fornire alla applicazione il nome della classe come parametro o in un file di configurazione è un altro livello. Se vuoi che la tua applicazione possa gestire più "motori" di AI in stile a plug-in (ad esempio che possa scoprire qualunque jar compatibile che è stato copiato in una cartella X nota alla applicazione) allora è ancora un altro ulteriore livello più complesso.

    Poi c'è la questione di cosa il "plug-in" deve esporre alla applicazione. E questo dipende principalmente da cosa deve fare il plug-in in relazione a cosa la applicazione gli permette di fare.

    Ho comunque l'impressione che non riesci a cogliere la questione in profondità. Il punto non è tanto (e solo) caricare una classe, rintracciare un metodo (noto o no) ed invocarlo.
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    java.util.function Interfaces Cheat SheetJava Versions Cheat Sheet

  7. #7
    Utente di HTML.it
    Registrato dal
    Nov 2007
    Messaggi
    8
    Originariamente inviato da andbin
    No, la strada è questa ... intendo: la reflection.

    Poi è chiaro che se il nome della classe lo "cabli" nel sorgente ... tanto generico/flessibile non lo è il tuo codice. Se vuoi fornire alla applicazione il nome della classe come parametro o in un file di configurazione è un altro livello. Se vuoi che la tua applicazione possa gestire più "motori" di AI in stile a plug-in (ad esempio che possa scoprire qualunque jar compatibile che è stato copiato in una cartella X nota alla applicazione) allora è ancora un altro ulteriore livello più complesso.

    Poi c'è la questione di cosa il "plug-in" deve esporre alla applicazione. E questo dipende principalmente da cosa deve fare il plug-in in relazione a cosa la applicazione gli permette di fare.

    Ho comunque l'impressione che non riesci a cogliere la questione in profondità. Il punto non è tanto (e solo) caricare una classe, rintracciare un metodo (noto o no) ed invocarlo.
    hai ragione non colgo in profondità... sono programmatore da anni ma di java sono nubie... e non conosco i comandi (sto ancora studiando!!!)
    la classe l'ho caricata con :
    Class c = Class.forName("paolo");
    con questi comandi :
    Method m[] = c.getDeclaredMethods();
    for (int i = 0; i < m.length; i++)
    System.out.println(m[i].toString());
    leggo i metodi e quindi vuol dire che la classe è caricata bene...

    poi con questo :
    Object retobj = c.newInstance();
    lancio la classe e me la legge bene perchè esegue il costruttore.
    a questo punto dovrei eseguire un metodo e credo si usi "invoke();" ma non so come....
    mi puoi scrivere un esempio... di
    metodo.invoke() ; mi dice che () non va bene, ma in mezzo cosa ci passo?
    grazie

  8. #8
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,284
    Originariamente inviato da byanto
    a questo punto dovrei eseguire un metodo e credo si usi "invoke();" ma non so come....
    mi puoi scrivere un esempio... di
    metodo.invoke() ; mi dice che () non va bene, ma in mezzo cosa ci passo?
    Ok, vediamo questo "passettino" piccolo, ovvero invocare per reflection un metodo:

    Dal Class devi intanto ottenere un Method. Puoi prendere una lista dei metodi (vedi i metodi di Class che restituiscono un Method[]) e cercare quello che ti serve in base a dei criteri oppure puoi voler andare a colpo sicuro sapendo a priori il nome e quantità/tipi dei parametri.

    In quest'ultimo caso puoi usare:
    Method getMethod(String name, Class[] parameterTypes)
    che si aspetta di trovare un metodo pubblico con nome e tipi dei parametri specificati. Attenzione! I Class che indichi devono essere precisi per quanto riguarda la distinzione tra i primitivi e le classi "wrapper" (Integer, Long, ecc...).

    Cioè specificare come Class ad esempio int.class oppure Integer.class è differente.

    per un metodo es.:
    void pippo(String x, int y)
    dovrai usare:

    Method m = c.getMethod("pippo", new Class[] { String.class, int.class });

    Se il secondo parametro fosse Integer (e non int!), allora bisogna mettere Integer.class.

    Una volta ottenuto un Method lo puoi invocare. Method ha un invoke() che si aspetta dei parametri.

    Il primo è l'oggetto su cui deve essere invocato, ma solo se è di "istanza". Se fosse un metodo statico, non c'è oggetto e va passato un null.
    Se è un metodo di istanza, prima di questo passo dovresti ottenere una istanza della classe dal Class.

    Poi invoke si aspetta un array di parametri. Qui in questo caso non c'è distinzione tra tipi primitivi e relativi wrapper. L'array è di Object, un int va comunque passato come Integer.

    Quindi es.:

    m.invoke(laIstanza, new Object[] { "blabla", new Integer(123) });

    Da Java 5 c'è l'autoboxing, basterebbe passare direttamente 123 (o una variabile int).
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    java.util.function Interfaces Cheat SheetJava Versions Cheat Sheet

  9. #9
    Vorrei dare anche io il mio apporto, ho già diverse volte tratto il caso di creare un "Gioco" per programmatori (sfide aziendali... ).
    Di solito io preferisco creare una classe astratta Player in cui vado ad esporre l'interfaccia generica che un ipotetico giocatore deve avere. Per esempio se pensiamo al gioco della briscola dentro la classe Player avrò sicuramente il metodo "prendiCarte" oppure "giocaCarta".
    Ovviamente è inutile dire che chi poi dovrà creare l'IA(cioè un giocatore) dovrà estendere questa classe.
    In questo modo limiti l'uso della reflection, il che non è un male perché è abbastanza onerosa di risorse, infatti l'unica cosa che dovrai fare è caricare a runtime la classe del giocare (class.formName("pippo")) e chiamare in "newInstance" la differenza è che l'object che ti ritorna newInstance lo puoi tranquillamente castare a "Player" e quindi richiamare tutti i metodi che hai definito in esso.
    Allego un po di codice di esempio:
    codice:
    public abstract class Player implements Comparable<Player>
    {
    	private int punteggio = 0;
    
    	private String id;
    
    	private Manager manager;
    
    	public Manager getManager()
    	{
    		return manager;
    	}
    
    	public void setManager(Manager manager)
    	{
    		this.manager = manager;
    	}
    
    	public abstract Card play(Collection<PlayerCardPlayed> collection);
    
    	public Player()
    	{
    
    	}
    
    	public void setId(String id)
    	{
    		this.id = id;
    	}
    
    	/**
    	 * Metodo che restituisce il nome del giocatore
    	 * 
    	 * @return <String> nome giocatore
    	 */
    	public abstract String getName();
    
    	/**
    	 * Metodo che il mazziere chiama per dare le carte
    	 * 
    	 * @param yourCards
    	 *            lista contenente tre carte
    	 */
    	public abstract void takeYourCards(List<Card> yourCards);
    
    	/**
    	 * Dopo ogni turno viene data una carta pescata dal mazzo
    	 * 
    	 * @param card
    	 */
    	public abstract void takeOneCard(Card card);
    
    	/**
    	 * Metodo che restituisce true se nelle proprie carte c'è una briscola Invocato a richiesta dal compagno di gioco
    	 * 
    	 * @return
    	 */
    	public abstract boolean containsBriscola();
    
    	/**
    	 * Metodo che restituisce true se nelle proprie carte c'è un carico Invocato a richiesta dal compagno di gioco
    	 * 
    	 * @return
    	 */
    	public abstract boolean containsCarico();
    
    	public int getPunteggio()
    	{
    		return punteggio;
    	}
    
    	public void addPunteggio(int punteggio)
    	{
    		this.punteggio += punteggio;
    	}
    
    	public int compareTo(Player o)
    	{
    		if (this.getName().equals(o.getName()))
    		{
    			return 0;
    		}
    		else
    		{
    			return -1;
    		}
    	}
    
    	@Override
    	public int hashCode()
    	{
    		final int prime = 31;
    		int result = 1;
    		result = prime * result + ((id == null) ? 0 : id.hashCode());
    		return result;
    	}
    
    	@Override
    	public boolean equals(Object obj)
    	{
    		if (this == obj)
    			return true;
    		if (obj == null)
    			return false;
    		if (getClass() != obj.getClass())
    			return false;
    		Player other = (Player) obj;
    		if (id == null)
    		{
    			if (other.id != null)
    				return false;
    		}
    		else if (!id.equals(other.id))
    			return false;
    		return true;
    	}
    
    	public String toString()
    	{
    		return this.getName();
    	}
    }
    //Classe che si occupa di caricare i giocatori
    public class Manager
    {
       public Manager(String[] classNames)
       {
    		for (int i = 0; i < classNames.length; i++)
    		{
    			Player player = this.loadPlayer(classNames[i]);
    			player.setId(player.getName() + count);
    			this.initializePlayer(player);
    			this.players.add(player);
    		}
       }
    private Player loadPlayer(String classNames) throws ClassNotFoundException, InstantiationException, IllegalAccessException
    	{
    		Class<Player> player = (Class<Player>) Class.forName(classNames);
    		return player.newInstance();
    	}
    
    }

  10. #10
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,284
    Originariamente inviato da francesco.muia
    Di solito io preferisco creare una classe astratta Player in cui vado ad esporre l'interfaccia generica che un ipotetico giocatore deve avere. [...]
    In questo modo limiti l'uso della reflection
    Certo, questo è ancora meglio.
    Se la conoscenza che il "plug-in" ha della applicazione è nei termini di "devo implementare una interfaccia o estendere una certa classe (non importa ora se astratta o no) fornita dalla applicazione" e al contrario la conoscenza che la applicazione ha del plug-in è nei termini di "ho scoperto (come, ora non importa) un nome di classe, creo una istanza e la uso vedendola attraverso il tipo base", allora riduce l'uso della reflection e permette di disaccoppiare applicazione e plug-in.
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    java.util.function Interfaces Cheat SheetJava Versions Cheat Sheet

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.