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();
}
}