266 lines
7.9 KiB
Java
266 lines
7.9 KiB
Java
package magic.model;
|
|
|
|
import java.io.File;
|
|
import java.io.IOException;
|
|
import java.nio.file.Path;
|
|
import java.util.Properties;
|
|
|
|
import magic.data.DeckGenerators;
|
|
import magic.data.DuelConfig;
|
|
import magic.data.stats.MagicStats;
|
|
import magic.model.phase.MagicDefaultGameplay;
|
|
import magic.model.player.PlayerProfile;
|
|
import magic.utility.DeckUtils;
|
|
import magic.utility.FileIO;
|
|
import magic.utility.MagicFileSystem;
|
|
import magic.utility.MagicFileSystem.DataPath;
|
|
import magic.utility.SortedProperties;
|
|
|
|
public class MagicDuel {
|
|
|
|
private static final String GAME = "duel.game";
|
|
private static final String PLAYED = "duel.played";
|
|
private static final String WON = "duel.won";
|
|
private static final String START = "duel.start";
|
|
|
|
public static MagicDuel instance;
|
|
|
|
private final DuelConfig duelConfig;
|
|
private final int playerIndex = 0;
|
|
private final int opponentIndex = 1;
|
|
private int gameNr;
|
|
private int gamesPlayed;
|
|
private int gamesWon;
|
|
private int startPlayer;
|
|
|
|
public MagicDuel(final DuelConfig configuration) {
|
|
this.duelConfig=configuration;
|
|
restart();
|
|
}
|
|
|
|
public MagicDuel() {
|
|
this(new DuelConfig());
|
|
}
|
|
|
|
public DuelConfig getConfiguration() {
|
|
return duelConfig;
|
|
}
|
|
|
|
public int getGameNr() {
|
|
return gameNr;
|
|
}
|
|
|
|
public int getGamesPlayed() {
|
|
return gamesPlayed;
|
|
}
|
|
|
|
public int getGamesTotal() {
|
|
return (duelConfig.getPlayerConfigs().length-1)*duelConfig.getNrOfGames();
|
|
}
|
|
|
|
public int getGamesWon() {
|
|
return gamesWon;
|
|
}
|
|
|
|
private void determineStartPlayer() {
|
|
startPlayer=MagicRandom.nextRNGInt(2);
|
|
}
|
|
|
|
public void setStartPlayer(final int startPlayer) {
|
|
this.startPlayer=startPlayer;
|
|
}
|
|
|
|
public boolean isEditable() {
|
|
return gameNr==1;
|
|
}
|
|
|
|
public boolean isFinished() {
|
|
// if a duel consists of a total of X games, then in an interactive
|
|
// game it should be "best of" X games, not first to X.
|
|
final int player1GamesWon = getGamesWon();
|
|
final int player2GamesWon = getGamesPlayed() - player1GamesWon;
|
|
final int gamesRequiredToWin = (int)Math.ceil(getGamesTotal()/2.0);
|
|
return (player1GamesWon >= gamesRequiredToWin) || (player2GamesWon >= gamesRequiredToWin);
|
|
}
|
|
|
|
void advance(final boolean won, final MagicGame game) {
|
|
gameNr++;
|
|
gamesPlayed++;
|
|
|
|
if (won) {
|
|
gamesWon++;
|
|
startPlayer = opponentIndex;
|
|
} else {
|
|
startPlayer = playerIndex;
|
|
}
|
|
|
|
MagicStats.logStats(this, game);
|
|
}
|
|
|
|
public MagicGame nextGame() {
|
|
//create players
|
|
final MagicPlayer player = new MagicPlayer(duelConfig.getStartingLife(playerIndex), duelConfig.getPlayerConfig(playerIndex), playerIndex);
|
|
final MagicPlayer opponent = new MagicPlayer(duelConfig.getStartingLife(opponentIndex), duelConfig.getPlayerConfig(opponentIndex), opponentIndex);
|
|
|
|
//determine who starts first
|
|
final MagicPlayer[] players = new MagicPlayer[]{player,opponent};
|
|
final MagicPlayer start = players[startPlayer];
|
|
|
|
//create game
|
|
final MagicGame game = MagicGame.create(
|
|
this,
|
|
MagicDefaultGameplay.getInstance(),
|
|
players,
|
|
start
|
|
);
|
|
|
|
//create hand and library
|
|
player.createHandAndLibrary(duelConfig.getHandSize());
|
|
opponent.createHandAndLibrary(duelConfig.getHandSize());
|
|
return game;
|
|
}
|
|
|
|
public int getNrOfPlayers() {
|
|
return duelConfig.getPlayerConfigs().length;
|
|
}
|
|
|
|
public DuelPlayerConfig getPlayer(final int index) {
|
|
return duelConfig.getPlayerConfig(index);
|
|
}
|
|
|
|
public DuelPlayerConfig[] getPlayers() {
|
|
return duelConfig.getPlayerConfigs();
|
|
}
|
|
|
|
// only used by magic.test classes.
|
|
public void setPlayers(final DuelPlayerConfig[] aPlayerDefinitions) {
|
|
duelConfig.setPlayerConfigs(aPlayerDefinitions);
|
|
}
|
|
|
|
// Used by the "Generate Deck" button in DuelPanel.
|
|
public void buildDeck(final DuelPlayerConfig player) {
|
|
DeckGenerators.setRandomDeck(player);
|
|
}
|
|
|
|
public void buildDecks() {
|
|
for (final DuelPlayerConfig player : duelConfig.getPlayerConfigs()) {
|
|
switch (player.getDeckProfile().getDeckType()) {
|
|
case Random:
|
|
DeckGenerators.setRandomDeck(player);
|
|
break;
|
|
case Preconstructed:
|
|
setDeckFromFile(player, DeckUtils.getPrebuiltDecksFolder());
|
|
break;
|
|
case Custom:
|
|
setDeckFromFile(player, DeckUtils.getDecksFolder());
|
|
break;
|
|
case Firemind:
|
|
setDeckFromFile(player, DeckUtils.getFiremindDecksFolder());
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
private void setDeckFromFile(DuelPlayerConfig player, Path deckFolder) {
|
|
String deckFilename = DeckUtils.getNormalizedFilename(player.getDeckProfile().getDeckValue());
|
|
player.setDeck(loadDeck(deckFolder.resolve(deckFilename)));
|
|
}
|
|
|
|
private MagicDeck loadDeck(final Path deckFilePath) {
|
|
return DeckUtils.loadDeckFromFile(deckFilePath);
|
|
}
|
|
|
|
public void initialize() {
|
|
buildDecks();
|
|
}
|
|
|
|
public static final File getLatestDuelFile() {
|
|
return MagicFileSystem.getDataPath(DataPath.DUELS).resolve("latest.duel").toFile();
|
|
}
|
|
|
|
private void save(final Properties properties) {
|
|
duelConfig.save(properties);
|
|
properties.setProperty(GAME,Integer.toString(gameNr));
|
|
properties.setProperty(PLAYED,Integer.toString(gamesPlayed));
|
|
properties.setProperty(WON,Integer.toString(gamesWon));
|
|
properties.setProperty(START,Integer.toString(startPlayer));
|
|
}
|
|
|
|
public void save(final File file) {
|
|
final Properties properties = new SortedProperties();
|
|
save(properties);
|
|
try {
|
|
FileIO.toFile(file, properties, "Duel");
|
|
} catch (final IOException ex) {
|
|
System.err.println("ERROR! Unable save duel to " + file);
|
|
}
|
|
}
|
|
|
|
private void load(final Properties properties) {
|
|
duelConfig.load(properties, true);
|
|
gameNr=Integer.parseInt(properties.getProperty(GAME,"1"));
|
|
gamesPlayed=Integer.parseInt(properties.getProperty(PLAYED,"0"));
|
|
gamesWon=Integer.parseInt(properties.getProperty(WON,"0"));
|
|
startPlayer=Integer.parseInt(properties.getProperty(START,"0"));
|
|
}
|
|
|
|
public void load(final File file) {
|
|
load(FileIO.toProp(file));
|
|
}
|
|
|
|
public void restart() {
|
|
gameNr=1;
|
|
gamesPlayed=0;
|
|
gamesWon=0;
|
|
determineStartPlayer();
|
|
}
|
|
|
|
public PlayerProfile getWinningPlayerProfile() {
|
|
if (!isFinished()) {
|
|
return null;
|
|
} else {
|
|
final int playerOneGamesWon = getGamesWon();
|
|
final int playerTwoGamesWon = getGamesPlayed() - playerOneGamesWon;
|
|
if (playerOneGamesWon > playerTwoGamesWon) {
|
|
return getConfiguration().getPlayerProfile(0);
|
|
} else {
|
|
return getConfiguration().getPlayerProfile(1);
|
|
}
|
|
}
|
|
}
|
|
|
|
public static void restartDuel() {
|
|
if (instance != null) {
|
|
instance.restart();
|
|
}
|
|
}
|
|
|
|
public static void newDuel() {
|
|
instance = new MagicDuel(DuelConfig.getInstance());
|
|
instance.initialize();
|
|
}
|
|
|
|
public static boolean isDuelReady() {
|
|
return instance != null;
|
|
}
|
|
|
|
public boolean isNotFinished() {
|
|
return !isFinished();
|
|
}
|
|
|
|
public static void resumeDuel() {
|
|
final File duelFile = getLatestDuelFile();
|
|
if (duelFile.exists()) {
|
|
instance = new MagicDuel(DuelConfig.getInstance());
|
|
instance.load(duelFile);
|
|
}
|
|
}
|
|
|
|
public boolean hasInvalidDecks() {
|
|
return !getPlayer(0).getDeck().isValid()
|
|
|| !getPlayer(1).getDeck().isValid();
|
|
}
|
|
}
|