Add files via upload

Added files for launching the game locally or remotely
This commit is contained in:
charlesbvll 2019-09-30 12:47:31 +02:00 committed by GitHub
parent 77327c8c33
commit 539223ae07
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 314 additions and 0 deletions

240
LocalMain.java Normal file
View File

@ -0,0 +1,240 @@
package ch.epfl.javass;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;
import ch.epfl.javass.gui.GraphicalPlayerAdapter;
import ch.epfl.javass.jass.JassGame;
import ch.epfl.javass.jass.MctsPlayer;
import ch.epfl.javass.jass.PacedPlayer;
import ch.epfl.javass.jass.Player;
import ch.epfl.javass.jass.PlayerId;
import ch.epfl.javass.net.RemotePlayerClient;
import javafx.application.Application;
import javafx.stage.Stage;
/**
* An application to launch a Jass Game locally.
* @author Célia Houssiaux
* @author Charles Beauville
*
*/
public final class LocalMain extends Application {
private static final double MIN_TIME = 1.0;
private static final int WAIT_TIME = 1000;
private static final int TYPE_INDEX = 0;
private static final int NAME_INDEX = 1;
private static final int ADDRESS_INDEX = 2;
private static final int ITER_NBR_INDEX = 2;
/**
*
* @param args
* parametres donnés a l'application sous cette forme :
*
* <pre>
* {j1}{j4} [{graine}] :
* {jn} spécifie le joueur n, ainsi:
* h:{nom} un joueur humain nommé {nom}"
*
* s:{nom}:{n} un joueur simulé nommé {nom} qui itère l'algorithme MCTS {n} fois"
*
* r:{nom}:{adresse} un joueur distant nommé {nom} et sur le serveur d'adresse : {adresse}
*
* Les agruments {nom}, {n} et {adresses} sont optionnelles et ont pour valeurs par défaut :
*
* Aline, Bastien, Colette et David attribués dans l'ordre, à défaut de {nom}
*
* 10 000 iterations de MCTS, à défaut de {n}
* et localhost, à défaut de {adresse}.
* </pre>
*/
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage primaryStage) throws Exception {
List<String> args = getParameters().getRaw();
Map<PlayerId, Player> players = new HashMap<>();
Map<PlayerId, String> playerNames = new HashMap<>();
// Setting up the default values.
String[] defaultNames = { "Aline", "Bastien", "Colette", "David" };
int iterNbr = 10000;
Random rnd = new Random();
String adress = "localhost";
// Explaining the syntax if too much arguments are detected.
if (!(args.size() == 4 || args.size() == 5)) {
System.err.println(
"Utilisation: java ch.epfl.javass.LocalMain <j1>…<j4> [<graine>] où :");
System.err.println("<jn> spécifie le joueur n, ainsi:");
System.err.println(" h:<nom> un joueur humain nommé <nom>");
System.err.println(
" s:<nom>:<n> un joueur simulé nommé <nom> qui itère l'algorithme MCTS <n> fois");
System.err.println(
" r:<nom>:<adresse> un joueur distant nommé <nom> et sur le serveur d'adresse : <adresse>");
System.err.println("");
System.err.println(
"Les agruments <nom>, <n> et <adresses> sont optionnelles et ont pour valeurs par défaut : ");
System.err.println(
" Aline, Bastien, Colette et David attribués dans l'ordre, à défaut de <nom>,");
System.err
.println(" 10 000 iterations de MCTS, à défaut de <n>,");
System.err.println(" et localhost, à défaut de <adresse>,");
System.exit(1);
}
// Checking if the given seed is correct.
if (args.size() == 5) {
try {
rnd.setSeed(Long.parseLong(args.get(4)));
} catch (Exception NumberFormatException) {
System.err.println(
"Erreur : seed de génération aléatoire incorrect");
System.exit(1);
}
}
int gameSeed = rnd.nextInt();
for (int i = 0; i < PlayerId.COUNT; i++) {
String[] playerInfo = args.get(i).split(":", -1);
String playerType = playerInfo[TYPE_INDEX];
if (!(playerType.equals("h") || playerType.equals("s")
|| playerType.equals("r"))) {
System.err
.println("Erreur : spécification de joueur invalide : "
+ args.get(i));
System.exit(1);
}
if (playerInfo.length > 3) {
System.err
.println("Erreur : trop de composantes sur le joueur : "
+ args.get(i));
System.exit(1);
}
// Handles the case where the type argument is "h", creates a
// GraphicalPlayerAdapter.
if (playerType.equals("h")) {
// Check if their aren't too many components.
if (playerInfo.length > 2) {
System.err.println(
"Erreur : trop de composantes sur le joueur : "
+ args.get(i));
System.exit(1);
}
// Creates the GraphicalPlayerAdapter.
players.put(PlayerId.ALL.get(i), new GraphicalPlayerAdapter());
// Assigns the given name to the player if it is correct.
if (playerInfo.length > 1)
if (!playerInfo[NAME_INDEX].isEmpty())
playerNames.put(PlayerId.ALL.get(i), playerInfo[NAME_INDEX]);
else
playerNames.put(PlayerId.ALL.get(i), defaultNames[i]);
else
playerNames.put(PlayerId.ALL.get(i), defaultNames[i]);
}
// Handles the case where the type argument is "r", creates a
// RemotePlayerClient.
if (playerType.equals("r")) {
// Sets the adress to the given argument if it isn't null.
if (playerInfo.length > 1)
if (!playerInfo[ADDRESS_INDEX].isEmpty())
adress = playerInfo[ADDRESS_INDEX];
try {
// Creates the RemotePlayerClient, quits if it can't
// connect.
players.put(PlayerId.ALL.get(i),
new RemotePlayerClient(adress));
} catch (Exception IOError) {
System.err.println(
"Erreur : Connexion impossible au joueur simulé : "
+ args.get(i));
System.exit(1);
}
// Assigns the given name to the player if it is correct.
if (playerInfo.length > 1)
if (!playerInfo[NAME_INDEX].isEmpty())
playerNames.put(PlayerId.ALL.get(i), playerInfo[NAME_INDEX]);
else
playerNames.put(PlayerId.ALL.get(i), defaultNames[i]);
else
playerNames.put(PlayerId.ALL.get(i), defaultNames[i]);
}
// Handles the case where the type argument is "s", creates a
// MCTSPlayer.
if (playerType.equals("s")) {
// Sets the number of iteration to the given argument if it is
// correct.
if (playerInfo.length > 1)
if (!playerInfo[ITER_NBR_INDEX].isEmpty()) {
try {
iterNbr = Integer
.parseInt(playerInfo[ITER_NBR_INDEX]);
} catch (Exception NumberFormatException) {
System.err.println(
"Erreur : Nombre d'iterations du MCTS non valide pour le joueur simulé : "
+ args.get(i));
System.exit(1);
}
if (iterNbr < 10) {
System.err.println(
"Erreur : Nombre d'iterations du MCTS non valide pour le joueur simulé : "
+ args.get(i));
System.exit(1);
}
}
// Creates the simulated player.
players.put(PlayerId.ALL.get(i),
new PacedPlayer(new MctsPlayer(PlayerId.ALL.get(i),
rnd.nextLong(), iterNbr), MIN_TIME));
// Assigns the given name to the player if it is correct.
if (playerInfo.length > 1)
if (!playerInfo[NAME_INDEX].isEmpty())
playerNames.put(PlayerId.ALL.get(i), playerInfo[NAME_INDEX]);
else
playerNames.put(PlayerId.ALL.get(i), defaultNames[i]);
else
playerNames.put(PlayerId.ALL.get(i), defaultNames[i]);
}
}
// Launches the game with the givem arguments
Thread gameThread = new Thread(() -> {
JassGame g = new JassGame(gameSeed, players, playerNames);
while (!g.isGameOver()) {
g.advanceToEndOfNextTrick();
try {
Thread.sleep(WAIT_TIME);
} catch (Exception e) {
}
}
});
gameThread.setDaemon(true);
gameThread.start();
}
}

33
Preconditions.java Normal file
View File

@ -0,0 +1,33 @@
package ch.epfl.javass;
/**
* Gives a set of function to test conditions.
* @author Charles BEAUVILLE
* @author Celia HOUSSIAUX
*
*/
public final class Preconditions {
private Preconditions() {}
/**
* Checks if a boolean expression is true or throws exception.
* @param b boolean expression on the arguments.
* @throws IllegalArgumentException if b is false.
*/
public static void checkArgument(boolean b) {
if(!b)
throw new IllegalArgumentException();
}
/**
* Checks if an index is positive and inferior to a size.
* @throws IndexOutOfBoundsException if the index is bigger than the size or negative.
* @return the given index if it is valid.
*/
public static int checkIndex(int index, int size) {
if(index < 0 || index >= size)
throw new IndexOutOfBoundsException();
return index;
}
}

41
RemoteMain.java Normal file
View File

@ -0,0 +1,41 @@
package ch.epfl.javass;
import java.io.IOException;
import ch.epfl.javass.gui.GraphicalPlayerAdapter;
import ch.epfl.javass.net.RemotePlayerServer;
import javafx.application.Application;
import javafx.stage.Stage;
/**
* An application to launch a Jass Game remotely.
* @author Célia Houssiaux
* @author Charles Beauville
*
*/
public final class RemoteMain extends Application{
/**
* Starts a Remote game once the client connects.
* @param args no arguments are needed to start a remote game
*/
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage primaryStage) throws Exception {
Thread gameThread = new Thread(() -> {
try {
new RemotePlayerServer(new GraphicalPlayerAdapter()).run();
} catch (IOException e) {
throw new Error(e);
}
});
gameThread.setDaemon(true);
gameThread.start();
System.out.println("La partie commencera à la connexion du client…");
}
}