package pdp.scrabble.game.impl;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.jdom.Attribute;
import org.jdom.Element;
import pdp.scrabble.Game;
import pdp.scrabble.Main_old;
import pdp.scrabble.ihm.MainFrame_old;
import pdp.scrabble.game.Bag;
import pdp.scrabble.game.Board;
import pdp.scrabble.game.Dictionary;
import pdp.scrabble.game.Player;
import pdp.scrabble.ihm.PlayerPanel;
import pdp.scrabble.ihm.GameStatisticsModelImpl;
import pdp.scrabble.ihm.GameStatisticsModel;
import pdp.scrabble.utility.Tool;
import static pdp.scrabble.Factory.FACTORY;
public class GameImpl implements Game {
private Bag bag = null;
private Board board = null;
private GameStatisticsModel stats = null;
private List<Player> players = null;
private Dictionary dictionary = null;
private String language = null;
private MainFrame_old mainFrame = null;
/** Player id which is playing. */
private int playerTurn = 0;
/** Total turn iteration. */
private int globalTurn = 0;
/** Max global turn. */
private int globalTurnMax = 0;
/** Auto Save flag. */
private boolean autoSave = false;
/** Game thread reference. */
private Thread gameThread = null;
/** Game thread alive state. */
private boolean alive = false;
/** Loading flag */
private boolean isLoading = false;
public GameImpl(String language, MainFrame_old mainFrame) {
this.language = language;
this.mainFrame = mainFrame;
this.bag = FACTORY.createBag();
this.bag.initWithLanguage(language);
this.board = FACTORY.createBoard();
this.dictionary = FACTORY.createDictionary();
this.dictionary.initWithLanguage(language);
this.players = new ArrayList<Player>(1);
this.playerTurn = -1;
this.stats = new GameStatisticsModelImpl();
this.gameThread = null;
this.alive = false;
}
@Override
public void reset() {
if (this.mainFrame != null) {
this.mainFrame.getMultiplayerPanel().getAction().setMyTurn();
}
this.bag.clear();
this.board.clear();
Iterator<Player> itr = this.players.iterator();
while (itr.hasNext()) {
Player p = itr.next();
p.clearRack(p.getLetters().iterator());
}
this.players.clear();
this.stats.clear();
}
@Override
public void create() {
this.reset();
this.board.setDictionary(this.dictionary);
this.bag.fill();
this.playerTurn = 0;
this.globalTurn = 0;
}
@Override
public void addPlayer(Player player) {
this.players.add(player);
}
@Override
public void setPlayerTurn(int id) {
Player player = this.getPlayer(id);
this.playerTurn = id;
if (!player.isAI()) {
this.mainFrame.setPlayerPanelPlayer(player);
PlayerPanel ppanel = this.mainFrame.getPlayerPanel();
ppanel.getButton("Help").setEnabled(true);
ppanel.getButton("Game Over").setEnabled(true);
}
else {
this.mainFrame.setPlayerPanelPlayer(null);
}
}
@Override
public int getPlayerTurn() {
return this.playerTurn;
}
@Override
public void increaseTurn() {
this.globalTurn++;
this.playerTurn++;
if (this.playerTurn < this.players.size()) {
this.setPlayerTurn(this.playerTurn);
}
else {
this.setPlayerTurn(0);
}
this.board.prepareTurn();
}
@Override
public void start(final boolean simulation) {
if (!this.isLoading) {
this.playerTurn = 0;
this.globalTurn = 0;
this.setPlayerTurn(Tool.random(0, this.players.size() - 1));
} else {
this.setPlayerTurn(this.getPlayerTurn());
}
this.mainFrame.getMenubar().getItem("New Game").setEnabled(false);
this.mainFrame.getMenubar().getItem("Load Game").setEnabled(false);
this.mainFrame.getMenubar().getItem("Replay").setEnabled(false);
this.mainFrame.getMenubar().getItem("Load Game").setEnabled(false);
this.gameThread = new Thread() {
@Override
public void run() {
setName("Game");
alive = true;
repaint();
play(simulation);
}
};
this.gameThread.start();
if (simulation) {
try {
this.gameThread.join();
}
catch (InterruptedException ex) {
this.alive = false;
}
}
}
@Override
public void terminate() {
this.alive = false;
}
@Override
public void play(boolean simulation) {
while (this.getPlayer(this.playerTurn).canPlay()) {
if (!this.alive) {
break;
}
if (this.getPlayer(this.playerTurn).isAI()) {
this.getPlayer(this.playerTurn).simulate();
}
else {
synchronized (MONITOR) {
try {
MONITOR.wait();
}
catch (InterruptedException ex) {
this.alive = false;
}
}
}
}
this.mainFrame().gameOver(simulation);
}
@Override
public Player getPlayer(int id) {
if (this.players.isEmpty()) {
return null;
}
else {
return this.players.get(id);
}
}
@Override
public Iterator<Player> getPlayersList() {
return this.players.iterator();
}
@Override
public int getPlayersNumber() {
return this.players.size();
}
@Override
public void repaint() {
this.mainFrame.validate();
this.mainFrame.repaint();
}
@Override
public void clearPlayers() {
this.players.clear();
}
@Override
public void setAutoSave(boolean autoSave) {
this.autoSave = autoSave;
this.board().setAutoSave(autoSave);
}
@Override
public boolean isAutoSave() {
return this.autoSave;
}
@Override
public void setIsLoading(boolean isLoading) {
this.isLoading = isLoading;
}
@Override
public boolean isLoading() {
return this.isLoading;
}
@Override
public int getGlobalTurnMax() {
return this.globalTurnMax;
}
@Override
public void setGlobalTurnMax(int globalTurnMax) {
this.globalTurnMax = globalTurnMax;
}
@Override
public MainFrame_old mainFrame() {
return this.mainFrame;
}
@Override
public Board board() {
return this.board;
}
@Override
public Bag bag() {
return this.bag;
}
@Override
public Dictionary dictionary() {
return this.dictionary;
}
@Override
public GameStatisticsModel stats() {
return this.stats;
}
@Override
public String getLanguage() {
return this.language;
}
@Override
public void saveTurn(Element root) {
Element element = null;
Element Eturn = null;
if (root.getChild("Game") != null) {
element = root.getChild("Game");
Eturn = new Element("Turn");
element.addContent(Eturn);
}
else {
element = new Element("Game");
root.addContent(element);
element.setAttribute(new Attribute("version", Main_old.PROGRAM_VERSION));
element.setAttribute(new Attribute("language", this.language));
Eturn = new Element("Turn");
element.addContent(Eturn);
}
this.saveElements(Eturn, false);
}
@Override
public void save(Element root) {
Element element = new Element("Game");
root.addContent(element);
element.setAttribute(new Attribute("version", Main_old.PROGRAM_VERSION));
element.setAttribute(new Attribute("language", this.language));
Element Eturn = new Element("Turn");
element.addContent(Eturn);
Eturn.setAttribute(new Attribute(
"PlayerTurn", String.valueOf(this.getPlayerTurn())));
this.saveElements(Eturn, true);
}
private void saveElements(Element Eturn, boolean saveBag) {
Eturn.setAttribute(new Attribute(
"GlobalTurn", String.valueOf(this.globalTurn)));
if (saveBag) {
this.bag.save(Eturn);
this.board.save(Eturn);
}
else {
this.board.saveTurn(Eturn);
}
this.stats.save(Eturn);
Element Eplayers = new Element("Players");
Eturn.addContent(Eplayers);
Iterator<Player> itr = this.players.iterator();
while (itr.hasNext()) {
Player player = itr.next();
player.save(Eplayers);
}
}
@Override
public void loadTurn(Element root, int i) {
Element element = this.prepareLoad(root);
Element elementTurn = null;
@SuppressWarnings("unchecked")
List<Element> listElementTurn = element.getChildren("Turn");
Iterator<Element> it = listElementTurn.iterator();
while (it.hasNext()) {
Element Eturn = it.next();
int EglobalTurn = Integer.parseInt(
Eturn.getAttributeValue("GlobalTurn"));
if (this.globalTurnMax <= EglobalTurn) {
this.setGlobalTurnMax(EglobalTurn);
}
if (i == EglobalTurn) {
elementTurn = Eturn;
}
}
if (elementTurn != null) {
this.loadElements(elementTurn, false);
}
this.mainFrame.getOptionsPanel().update();
}
@Override
public void load(Element root) {
Element element = this.prepareLoad(root);
Element elementTurn = element.getChild("Turn");
int playerTurnID = Integer.parseInt(
elementTurn.getAttributeValue("PlayerTurn"));
this.loadElements(elementTurn, true);
this.setPlayerTurn(playerTurnID);
this.mainFrame.getOptionsPanel().update();
}
private Element prepareLoad(Element root) {
Element element = root.getChild("Game");
String lang = element.getAttributeValue("language");
if (!this.language.equals(lang)) {
this.language = lang;
this.bag.initWithLanguage(this.language);
this.dictionary.initWithLanguage(this.language);
this.board.setDictionary(this.dictionary);
}
return element;
}
private void loadElements(Element elementTurn, boolean loadBag) {
if (loadBag) {
this.bag.load(elementTurn);
}
this.board.load(elementTurn);
this.stats.load(elementTurn);
Element Eplayers = elementTurn.getChild("Players");
@SuppressWarnings("unchecked")
Iterator<Element> itr = Eplayers.getChildren().iterator();
while (itr.hasNext()) {
Element Eplayer = itr.next();
boolean isIA = Boolean.parseBoolean(
Eplayer.getAttributeValue("isIA"));
Player player = FACTORY.createPlayer(
this, null, 0, isIA, null);
player.initialize();
player.load(Eplayer);
this.addPlayer(player);
}
this.mainFrame.getOptionsPanel().update();
}
}