Skip to content

Commit

Permalink
Merge branch 'v0.7.0'
Browse files Browse the repository at this point in the history
  • Loading branch information
DennisSoemers committed Apr 3, 2020
2 parents df56868 + dab3151 commit ad4fb02
Show file tree
Hide file tree
Showing 6 changed files with 43 additions and 50 deletions.
16 changes: 8 additions & 8 deletions src/experiments/RunCustomMatch.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import java.util.List;

import game.Game;
import player.GameLoader;
import player.utils.GameLoader;
import random.RandomAI;
import search.mcts.MCTS;
import util.AI;
Expand All @@ -14,20 +14,20 @@

/**
* An example of a custom implementation of a match between different AIs,
* i.e. not using the built-in Match functionality of Ludii.
* i.e. not using the built-in EvalGamesSet functionality of Ludii.
*
* By creating custom implementations of matches/experiments, we can more
* By creating custom implementations of experiments, we can more
* easily add our own custom stats to track, and request moves from AIs
* that do not implement Ludii's abstract AI class. The downside is that
* more boilerplate code must be written.
*
* See RunLudiiMatch for an example that uses Ludii's built-in Match
* See RunLudiiMatch for an example that uses Ludii's built-in EvalGamesSet
* implementation.
*
* Note that this example does not provide all of the functionality included
* in the built-in Match implementation. For instance, this example will always
* in the built-in EvalGamesSet implementation. For instance, this example will always
* use the same agents for the same player number (e.g. Random AI always player
* 1, UCT always player 2), whereas Ludii's built-in Match implementation can
* 1, UCT always player 2), whereas Ludii's built-in EvalGamesSet implementation can
* rotate through assignments of agents to player numbers.
*
* @author Dennis Soemers
Expand All @@ -38,7 +38,7 @@ public class RunCustomMatch
//-------------------------------------------------------------------------

/** Name of game we wish to play */
static final String GAME_NAME = "board/space/blocking/Amazons.lud";
static final String GAME_NAME = "Amazons.lud";

/** Number of games to play */
static final int NUM_GAMES = 10;
Expand All @@ -59,7 +59,7 @@ public static void main(final String[] args)
{
// load and create game
final Game game = GameLoader.loadGameFromName(GAME_NAME);
game.create(0);
game.create();

final Trial trial = new Trial(game);
final Context context = new Context(game, trial);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,28 +3,28 @@
import java.util.Arrays;

import game.Game;
import player.GameLoader;
import player.experiments.Match;
import player.experiments.EvalGamesSet;
import player.utils.GameLoader;
import random.RandomAI;
import search.mcts.MCTS;
import util.AI;

/**
* Example of an experiment that uses Ludii's built-in Match class to
* Example of an experiment that uses Ludii's built-in EvalGamesSet class to
* run games between AIs.
*
* See RunCustomMatch for an example that does not use Ludii's built-in Match
* implementation.
*
* @author Dennis Soemers
*/
public class RunLudiiMatch
public class RunLudiiEvalGamesSet
{

//-------------------------------------------------------------------------

/** Name of game we wish to play */
static final String GAME_NAME = "board/space/blocking/Amazons.lud";
static final String GAME_NAME = "Amazons.lud";

/** Whether to create a small GUI that can be used to manually interrupt the experiment */
static final boolean USE_GUI = false;
Expand All @@ -43,7 +43,7 @@ public class RunLudiiMatch
/**
* Constructor
*/
private RunLudiiMatch()
private RunLudiiEvalGamesSet()
{
// do not instantiate
}
Expand All @@ -54,19 +54,19 @@ public static void main(final String[] args)
{
// load and create game
final Game game = GameLoader.loadGameFromName(GAME_NAME);
game.create(0);
game.create();

// set up our match
final Match match =
new Match(USE_GUI, MAX_WALL_TIME)
final EvalGamesSet evalGamesSet =
new EvalGamesSet(USE_GUI, MAX_WALL_TIME)
.setGameName(GAME_NAME)
.setAgents(Arrays.asList(AGENTS))
.setNumGames(10)
.setMaxSeconds(1.0)
.setRotateAgents(true);

// start playing
match.startMatch();
evalGamesSet.startGames();
}

//-------------------------------------------------------------------------
Expand Down
30 changes: 15 additions & 15 deletions src/experiments/Tutorial.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,16 @@
import java.util.List;

import game.Game;
import game.types.GameType;
import main.FastArrayList;
import mcts.ExampleUCT;
import player.GameLoader;
import player.utils.GameLoader;
import random.RandomAI;
import util.AI;
import util.Context;
import util.Move;
import util.Trial;
import util.model.Model;
import util.state.GameType;
import util.state.containerState.ContainerState;

/**
Expand All @@ -34,15 +34,15 @@ public static void main(final String[] args)
System.out.println("Built-in games = " + Arrays.toString(games));

// one of the games is "Amazons.lud". Let's load it
Game game = GameLoader.loadGameFromName("board/space/blocking/Amazons.lud");
game.create(0);
Game game = GameLoader.loadGameFromName("Amazons.lud");
game.create();

// the game's "stateFlags" contain properties of the game that may be
// important for some AI algorithms to know about
final long stateFlags = game.stateFlags();

// for example, we may like to know whether our game has stochastic elements
final boolean isStochastic = ((stateFlags & GameType.Stochastic) != 0);
final boolean isStochastic = ((stateFlags & GameType.Stochastic) != 0L);
if (isStochastic)
System.out.println(game.name() + " is stochastic.");
else
Expand All @@ -66,13 +66,13 @@ public static void main(final String[] args)
// for every container state we find (often just 1), we'll print a few things:

// print the collection of locations that are empty
System.out.println("Empty locations = " + containerState.emptyChunkSet());
System.out.println("Empty locations = " + containerState.emptyChunkSetCell());

// for every location that is owned by a player, print the owner
System.out.println("Who = " + containerState.cloneWho().toChunkString());
System.out.println("Who = " + containerState.cloneWhoCell().toChunkString());

// for every location that is occupied by a piece, print what piece occupies it
System.out.println("What = " + containerState.cloneWhat().toChunkString());
System.out.println("What = " + containerState.cloneWhatCell().toChunkString());
}

// print the full list of all legal moves
Expand All @@ -88,9 +88,9 @@ public static void main(final String[] args)
// let's print our empty/who/what again, see how they have changed
for (final ContainerState containerState : trial.state().containerStates())
{
System.out.println("Empty locations = " + containerState.emptyChunkSet());
System.out.println("Who = " + containerState.cloneWho().toChunkString());
System.out.println("What = " + containerState.cloneWhat().toChunkString());
System.out.println("Empty locations = " + containerState.emptyChunkSetCell());
System.out.println("Who = " + containerState.cloneWhoCell().toChunkString());
System.out.println("What = " + containerState.cloneWhatCell().toChunkString());
}

// request legal moves again and play one of them again
Expand All @@ -102,9 +102,9 @@ public static void main(final String[] args)
// let's have a final look at how our state looks after this second move
for (final ContainerState containerState : trial.state().containerStates())
{
System.out.println("Empty locations = " + containerState.emptyChunkSet());
System.out.println("Who = " + containerState.cloneWho().toChunkString());
System.out.println("What = " + containerState.cloneWhat().toChunkString());
System.out.println("Empty locations = " + containerState.emptyChunkSetCell());
System.out.println("Who = " + containerState.cloneWhoCell().toChunkString());
System.out.println("What = " + containerState.cloneWhatCell().toChunkString());
}

//---------------------------------------------------------------------
Expand Down Expand Up @@ -195,7 +195,7 @@ public static void main(final String[] args)
)
{
game = GameLoader.loadGameFromName(gameName);
game.create(0);
game.create();

trial = new Trial(game);
context = new Context(game, trial);
Expand Down
8 changes: 3 additions & 5 deletions src/mcts/ExampleDUCT.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
import util.Move;
import util.Trial;
import util.action.Action;
import util.action.ActionPass;
import utils.AIUtils;

/**
Expand Down Expand Up @@ -110,7 +109,8 @@ public ExampleDUCT()
null,
0,
-1,
0.f
0.f,
ThreadLocalRandom.current()
);
}

Expand Down Expand Up @@ -344,9 +344,7 @@ public Node(final Node parent, final Context context)

if (legalMovesPerPlayer.get(p).isEmpty())
{
final Move passMove = new Move(new ActionPass());
passMove.setMover(p);
legalMovesPerPlayer.get(p).add(passMove);
legalMovesPerPlayer.get(p).add(Game.createPassMove(context));
}
}

Expand Down
10 changes: 4 additions & 6 deletions src/mcts/ExampleUCT.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
import util.Context;
import util.Move;
import util.Trial;
import util.action.ActionPass;
import utils.AIUtils;

/**
Expand Down Expand Up @@ -102,7 +101,8 @@ public ExampleUCT()
null,
0,
-1,
0.f
0.f,
ThreadLocalRandom.current()
);
}

Expand Down Expand Up @@ -285,7 +285,7 @@ private static class Node
* Constructor
*
* @param parent
* @param moveFromparent
* @param moveFromParent
* @param context
*/
public Node(final Node parent, final Move moveFromParent, final Context context)
Expand All @@ -303,9 +303,7 @@ public Node(final Node parent, final Move moveFromParent, final Context context)
if (unexpandedMoves.isEmpty())
{
// We need to add a forced pass move
final Move passMove = new Move(new ActionPass());
passMove.setMover(context.trial().state().mover());
unexpandedMoves.add(passMove);
unexpandedMoves.add(Game.createPassMove(context));
}

if (parent != null)
Expand Down
9 changes: 3 additions & 6 deletions src/random/RandomAI.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,11 @@
import java.util.concurrent.ThreadLocalRandom;

import game.Game;
import game.types.GameType;
import main.FastArrayList;
import util.AI;
import util.Context;
import util.Move;
import util.action.ActionPass;
import util.state.GameType;
import utils.AIUtils;

/**
Expand Down Expand Up @@ -50,14 +49,12 @@ public RandomAI()

if (legalMoves.isEmpty())
{
final Move passMove = new Move(new ActionPass());
passMove.setMover(player);
return passMove;
return Game.createPassMove(context);
}

// If we're playing a simultaneous-move game, some of the legal moves may be
// for different players. Extract only the ones that we can choose.
if ((game.stateFlags() & GameType.Simultaneous) != 0)
if ((game.stateFlags() & GameType.Simultaneous) != 0L)
legalMoves = AIUtils.extractMovesForMover(legalMoves, player);

final int r = ThreadLocalRandom.current().nextInt(legalMoves.size());
Expand Down

0 comments on commit ad4fb02

Please sign in to comment.