Dcumentation
- added docs for TrisAi - fixed errors in docs
This commit is contained in:
@@ -11,8 +11,8 @@ import java.util.function.Function;
|
|||||||
/**
|
/**
|
||||||
* Una classe che risolve problemi utilizzando l'algoritmo A*.
|
* Una classe che risolve problemi utilizzando l'algoritmo A*.
|
||||||
* @author Berack96
|
* @author Berack96
|
||||||
* @param State la classe degli stati in cui si trova il problema da risolvere
|
* @param State - la classe degli stati in cui si trova il problema da risolvere
|
||||||
* @param Action la classe di azioni che si possono compiere da uno stato e l'altro
|
* @param Action - la classe di azioni che si possono compiere da uno stato e l'altro
|
||||||
*/
|
*/
|
||||||
public class AStar<State, Action> {
|
public class AStar<State, Action> {
|
||||||
|
|
||||||
|
|||||||
@@ -8,9 +8,9 @@ import java.util.function.Function;
|
|||||||
* Algoritmo MiniMax per i giochi a due concorrenti.
|
* Algoritmo MiniMax per i giochi a due concorrenti.
|
||||||
*
|
*
|
||||||
* @author Berack96
|
* @author Berack96
|
||||||
* @param <State> la classe degli stati in cui si trova il problema da risolvere
|
* @param State - la classe degli stati in cui si trova il problema da risolvere
|
||||||
* @param <Action> la classe di azioni che si possono compiere da uno stato e l'altro
|
* @param Action - la classe di azioni che si possono compiere da uno stato e l'altro
|
||||||
* @param <Player> la classe che indica il giocatore, essa serve da dare in input alla funzione di gain
|
* @param Player - la classe che indica il giocatore, essa serve da dare in input alla funzione di gain
|
||||||
*/
|
*/
|
||||||
public class MiniMax<State, Action, Player> {
|
public class MiniMax<State, Action, Player> {
|
||||||
|
|
||||||
@@ -45,7 +45,7 @@ public class MiniMax<State, Action, Player> {
|
|||||||
*
|
*
|
||||||
* @param state lo stato corrente
|
* @param state lo stato corrente
|
||||||
* @param player il giocatore che deve fare la mossa
|
* @param player il giocatore che deve fare la mossa
|
||||||
* @param lookahead quante mosse guardare nel futuro
|
* @param lookahead quante mosse consecutive guardare nel futuro
|
||||||
* @return la migliore mossa localmente
|
* @return la migliore mossa localmente
|
||||||
*/
|
*/
|
||||||
public Action next(State state, int lookahead, Player player) {
|
public Action next(State state, int lookahead, Player player) {
|
||||||
|
|||||||
@@ -7,13 +7,27 @@ import java.util.function.BiFunction;
|
|||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Classe che viene usata per giocare a Tris.
|
||||||
|
* Questa classe permette dato una classe Tris di giocare contro una AI.
|
||||||
*
|
*
|
||||||
* @author Berack96
|
* @author Berack96
|
||||||
*/
|
*/
|
||||||
public class TrisAi {
|
public class TrisAi {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Funzione che permette di far vedere quali azioni sono disponibili dato uno stato della partita.
|
||||||
|
* Essa richiama la già esistente funzione dalla classe Tris
|
||||||
|
*/
|
||||||
public static final Function<Tris, Tris.Coordinate[]> ACTIONS = tris -> tris.availablePlays();
|
public static final Function<Tris, Tris.Coordinate[]> ACTIONS = tris -> tris.availablePlays();
|
||||||
|
/**
|
||||||
|
* Funzione che permette l'avanzamento della partita. Siccome e' solo una funzione temporanea,
|
||||||
|
* ovvero che la partita vera e propria non deve andara avanti, viene restituita una nuova istanza del gioco.
|
||||||
|
*/
|
||||||
public static final BiFunction<Tris, Tris.Coordinate, Tris> TRANSITION = (tris, coord) -> new Tris(tris, coord);
|
public static final BiFunction<Tris, Tris.Coordinate, Tris> TRANSITION = (tris, coord) -> new Tris(tris, coord);
|
||||||
|
/**
|
||||||
|
* Funzione euristica che permette di controllare, dato uno stato, quanto sia favorevole o meno al giocatore
|
||||||
|
* passato in input.
|
||||||
|
*/
|
||||||
public static final BiFunction<Tris, Tris.Symbol, Integer> GAIN = (tris, player) -> {
|
public static final BiFunction<Tris, Tris.Symbol, Integer> GAIN = (tris, player) -> {
|
||||||
var count = 0;
|
var count = 0;
|
||||||
|
|
||||||
@@ -36,6 +50,17 @@ public class TrisAi {
|
|||||||
return count;
|
return count;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Questo metodo restituisce un valore in base ai simboli passati, con valore positivo se
|
||||||
|
* sono uguali al primo parametro in input, altrimenti negativo:
|
||||||
|
* - Se ho 3 simboli uguali -> 100
|
||||||
|
* - Se ho 2 simboli uguali e uno vuoto -> 10
|
||||||
|
* - Se ho un solo simbolo e 2 vuoti -> 1
|
||||||
|
*
|
||||||
|
* @param symbol il simbolo da testare
|
||||||
|
* @param values i successivi simboli a cui assegnare un valore
|
||||||
|
* @return un punteggio in base alle combinazioni dei simboli e al fatto che siano uguali al primo parametro
|
||||||
|
*/
|
||||||
static int value(Tris.Symbol symbol, Tris.Symbol...values) {
|
static int value(Tris.Symbol symbol, Tris.Symbol...values) {
|
||||||
var totE = 0;
|
var totE = 0;
|
||||||
var totO = 0;
|
var totO = 0;
|
||||||
@@ -64,15 +89,38 @@ public class TrisAi {
|
|||||||
private Tris tris;
|
private Tris tris;
|
||||||
private MiniMax<Tris, Tris.Coordinate, Tris.Symbol> minimax;
|
private MiniMax<Tris, Tris.Coordinate, Tris.Symbol> minimax;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Crea una istanza dell'AI collegata al gioco passato in input.
|
||||||
|
* Questa AI non giocherà in automatico ma solo quando lo si
|
||||||
|
* ritiene opportuno attraverso il metodo {@link #playNext()}.
|
||||||
|
*
|
||||||
|
* @param tris il gioco a cui aggiungere una AI
|
||||||
|
*/
|
||||||
public TrisAi(Tris tris) {
|
public TrisAi(Tris tris) {
|
||||||
this.minimax = new MiniMax<>(TRANSITION, ACTIONS, GAIN);
|
|
||||||
this.tris = Objects.requireNonNull(tris);
|
this.tris = Objects.requireNonNull(tris);
|
||||||
|
this.minimax = new MiniMax<>(TRANSITION, ACTIONS, GAIN);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* L'AI farà una mossa sul gioco collegato ad essa.
|
||||||
|
* Equivale chiamare {@link #playNext(int)} con input 2
|
||||||
|
*/
|
||||||
public void playNext() {
|
public void playNext() {
|
||||||
this.playNext(2);
|
this.playNext(2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* L'AI farà una mossa sul gioco collegato ad essa.
|
||||||
|
* Questo metodo permette di passare in input il lookahead
|
||||||
|
* in modo da limitare lo spazio delle possibili mosse che
|
||||||
|
* l'AI andrà ad osservare per scegliere la sua azione.
|
||||||
|
* Un valore basso e la mossa sarà "peggiore", un valore alto e
|
||||||
|
* per trovare una mossa ci impiegherà più tempo.
|
||||||
|
* NOTA: Il valore del lookahead è un valore esponenziale, quindi
|
||||||
|
* se si mette 5 rispetto a 4, ci impiegherà un tempo almeno doppio.
|
||||||
|
*
|
||||||
|
* @param lookahead quante mosse consecutive può osservare
|
||||||
|
*/
|
||||||
public void playNext(int lookahead) {
|
public void playNext(int lookahead) {
|
||||||
var myself = tris.getNextPlaySymbol();
|
var myself = tris.getNextPlaySymbol();
|
||||||
var action = minimax.next(this.tris, lookahead, myself);
|
var action = minimax.next(this.tris, lookahead, myself);
|
||||||
|
|||||||
Reference in New Issue
Block a user