hanze/game-client

src/main/java/nl/isygameclient/Headless.java in tournament
Repositories | Summary | Log | Files

Headless.java (5658B) download


  1package nl.isygameclient;
  2
  3import com.google.gson.Gson;
  4import com.google.gson.reflect.TypeToken;
  5import java.io.IOException;
  6import java.lang.reflect.Type;
  7import java.nio.file.Files;
  8import java.nio.file.NoSuchFileException;
  9import java.nio.file.Paths;
 10import java.util.*;
 11import java.util.concurrent.Executors;
 12import java.util.concurrent.locks.Lock;
 13import java.util.concurrent.locks.ReentrantLock;
 14import java.util.stream.Collectors;
 15import nl.isygameclient.models.Ai;
 16import nl.isygameclient.models.Game;
 17import nl.isygameclient.models.Player;
 18import nl.isygameclient.models.PlayerManager;
 19import nl.isygameclient.models.games.othello.Othello;
 20import nl.isygameclient.util.DataSaver;
 21import nl.isygameclient.util.Vector2D;
 22
 23
 24public class Headless {
 25	private static final String JSON_FILENAME	 = "heuristics.json";
 26	private static final int	THREAD_POOL_SIZE = 10;
 27	private static final int	ROUNDS_PER_GAME	 = 100;
 28
 29	private static long calculateAverage(List<Long> values) {
 30		long sum = values.stream().mapToLong(Long::longValue).sum();
 31		return sum / values.size();
 32	}
 33
 34	private static Map<String, Game> createGames(Map<String, int[][]> heuristics) {
 35		Map<String, Game> games = new HashMap<>();
 36		for (Map.Entry<String, int[][]> heuristic1 : heuristics.entrySet()) {
 37			for (Map.Entry<String, int[][]> heuristic2 : heuristics.entrySet()) {
 38
 39				ArrayList<Player> players = new ArrayList<>();
 40				players.add(new Ai(heuristic1.getKey(), "black", heuristic1.getValue()));
 41				players.add(new Ai(heuristic2.getKey(), "white", heuristic2.getValue()));
 42
 43				var		playerManager = new PlayerManager(0, players);
 44				Othello othello		  = new Othello(playerManager);
 45				games.put(heuristic1.getKey() + ", " + heuristic2.getKey(), othello);
 46			}
 47		}
 48		return games;
 49	}
 50
 51	private static String buildDataString(
 52		String gameName, int gameTurns, boolean isDraw, Player winner, long totalGameTime,
 53		Map<Player, ArrayList<Long>>					   playersTimePerMoves,
 54		Map<Player, ArrayList<Vector2D<Integer, Integer>>> playersMovesMade) {
 55		StringBuilder builder = new StringBuilder();
 56
 57		String joined = String.join(",", gameName, String.valueOf(gameTurns), String.valueOf(isDraw),
 58									winner.getPlayerName(), winner.getPlayingAs(), String.valueOf(totalGameTime)) +
 59						",";
 60		builder.append(joined);
 61
 62		playersTimePerMoves.forEach((k, v) -> {
 63			var average = calculateAverage(v);
 64			builder.append(average).append(",");
 65		});
 66		playersMovesMade.forEach((k, v) -> {
 67			String listString = v.stream().map(Object::toString).collect(Collectors.joining("; "));
 68			builder.append(listString).append(",");
 69		});
 70		return builder.toString();
 71	}
 72
 73	private static Map<String, int[][]> loadHeuristics() {
 74		try {
 75			Type mapType = new TypeToken<Map<String, int[][]>>() {
 76			}.getType();
 77			String inFile = new String(Files.readAllBytes(Paths.get(JSON_FILENAME)));
 78			return new Gson().fromJson(inFile, mapType);
 79		} catch (NoSuchFileException e) {
 80			System.err.println("NO HEURISTICS JSON HAS BEEN PROVIDED.");
 81			e.printStackTrace();
 82		} catch (IOException e) {
 83			e.printStackTrace();
 84		}
 85		return null;
 86	}
 87
 88	public static void main(String[] args) {
 89		var heuristics = loadHeuristics();
 90		if (heuristics == null) {
 91			System.err.println("No heuristics in file.");
 92			return;
 93		}
 94
 95		var executor  = Executors.newFixedThreadPool(THREAD_POOL_SIZE);
 96		var games	  = createGames(heuristics);
 97		var dataSaver = new DataSaver();
 98		dataSaver.saveData("Name Ai1, Name Ai2, Game Turns, Draw, Winner Name, Winner Playing As, Total Game Time,  Average Time Per Move Ai1, Average Time Per Move Ai2, Moves Ai1, Moves Ai2");
 99		for (Map.Entry<String, Game> game : games.entrySet()) {
100			Runnable simulation = new Simulation(game.getKey(), game.getValue(), ROUNDS_PER_GAME, new ReentrantLock(), dataSaver);
101			executor.execute(simulation);
102		}
103		executor.shutdown();
104
105		while (!executor.isTerminated()) {
106		}
107
108		System.out.println("All simulations completed successfully.");
109	}
110
111	private record Simulation(String gameName, Game game, int rounds, Lock lock, DataSaver dataSaver) implements Runnable {
112		@Override
113		public void run() {
114			System.out.println("Starting simulation: " + gameName);
115
116			var playerManager = game.getPlayerManager();
117			for (int i = 0; i < rounds; i++) {
118				System.out.println("Start round" + i + " " + gameName);
119
120				Map<Player, ArrayList<Long>>					   playersTimePerMoves = new HashMap<>();
121				Map<Player, ArrayList<Vector2D<Integer, Integer>>> PlayersMovesMade	   = new HashMap<>();
122
123				long totalGameTime = 0;
124				int	 gameTurns	   = 0;
125				while (!game.isGameOver()) {
126					gameTurns++;
127					var currentPlayer = playerManager.getCurrentPlayer();
128					if (game.getValidMoves(currentPlayer).isEmpty()) {
129						playerManager.nextPlayer();
130						continue;
131					}
132
133					final long startTime = System.currentTimeMillis();
134					var		   move		 = currentPlayer.onPlayerTurn();
135					game.move(currentPlayer, move);
136					final long endTime	 = System.currentTimeMillis();
137					final long deltaTime = endTime - startTime;
138					totalGameTime += deltaTime;
139
140					PlayersMovesMade.computeIfAbsent(currentPlayer, k -> new ArrayList<>()).add(move);
141					playersTimePerMoves.computeIfAbsent(currentPlayer, k -> new ArrayList<>()).add(deltaTime);
142				}
143
144				var winner = game.getWinners().get(0);
145				var data   = buildDataString(gameName, gameTurns, game.isDraw(), winner, totalGameTime, playersTimePerMoves, PlayersMovesMade);
146
147				lock.lock();
148				try {
149					dataSaver.saveData(data);
150				} finally {
151					lock.unlock();
152				}
153				game.restart();
154				System.out.println("end round" + i + " " + gameName);
155			}
156			System.out.println(gameName + " has finished");
157		}
158	}
159}