package pdp.scrabble.ihm;
import javax.swing.JDialog;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import javax.swing.JButton;
import java.io.File;
import java.util.TreeMap;
import java.util.Iterator;
import java.util.List;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JComboBox;
import javax.swing.JTextField;
import javax.swing.JCheckBox;
import javax.swing.JProgressBar;
import org.jdom.Element;
import org.jdom.Document;
import org.jdom.input.SAXBuilder;
import pdp.scrabble.InfiniteProgressPanel;
import pdp.scrabble.utility.Tool;
import pdp.scrabble.Language;
import pdp.scrabble.Background;
import pdp.scrabble.utility.Display;
import pdp.scrabble.Game;
import pdp.scrabble.Main_old;
import pdp.scrabble.game.Player;
import pdp.scrabble.game.impl.AIConfigImpl;
import pdp.scrabble.game.impl.GameEnvImpl;
import pdp.scrabble.game.impl.Human;
import pdp.scrabble.game.impl.SoloEngine;
import pdp.scrabble.game.AIConfig;
import pdp.scrabble.game.impl.SearchPlacementImpl;
import pdp.scrabble.game.GameEngine;
import pdp.scrabble.game.GameEnvironment;
import pdp.scrabble.game.Letter;
import pdp.scrabble.game.SearchStrategy;
import pdp.scrabble.game.SearchLevel;
import pdp.scrabble.game.SearchPriority;
import static pdp.scrabble.Factory.FACTORY;
import static pdp.scrabble.Language.getGameLang;
import static pdp.scrabble.Language.getMessagesLang;
import static javax.swing.JOptionPane.YES_NO_OPTION;
import static javax.swing.JOptionPane.YES_OPTION;
import static javax.swing.JOptionPane.CLOSED_OPTION;
import static javax.swing.JOptionPane.QUESTION_MESSAGE;
import static javax.swing.JOptionPane.INFORMATION_MESSAGE;
import static javax.swing.JOptionPane.showConfirmDialog;
import static javax.swing.JOptionPane.showOptionDialog;
/** Main program frame, containing all other elements
* such as board, stats, multiplayer panel ...
*/
public class MainFrame_old extends JFrame {
private static final long serialVersionUID = 1L;
/** List of all panels. */
private TreeMap<String, JPanel> panels = null;
/** Menu bar reference. */
private MenuBar menuBar = null;
/** Game reference. */
// private Game game = null;
private GameEngine gameEng;
private GameEnvironment gameEnv;
/** Background panel used on loading. */
private JPanel background = null;
/** Frame language. */
private String lang = null;
/** Progress loader reference. */
private InfiniteProgressPanel progress = null;
/** Center panel reference. */
private JPanel centerPanel = null;
/** Option panel reference. */
private JPanel options = null;
/** Stop simulation flag. */
private boolean stopSimulation = false;
/** Game type used. */
private int gameType = 0;
/** Current save file. */
private File saveFile = null;
/** Create a new main frame.
* @param language default language, null for input choice.
*/
public MainFrame_old(String language) {
super(Main_old.PROGRAM_NAME + " " + Main_old.PROGRAM_VERSION);
this.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
this.setLayout(new BorderLayout());
this.setResizable(false);
this.background = new Background();
this.add(this.background);
this.pack();
this.progress = new InfiniteProgressPanel();
this.setGlassPane(this.progress);
this.validate();
this.setLocationRelativeTo(null);
this.setVisible(true);
this.initialize(language);
}
/** Initialize main frame. */
private void initialize(String language) {
// Prepare frame
Tool.pause(250);
if (language == null) {
this.lang = Language.init(null);
}
else {
this.lang = language;
}
// Create and start progress bar
this.progress.start();
Tool.pause(250);
// Set default close operation (when clicking on exit)
this.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
exit();
}
});
// Initialize environement
SearchPlacementImpl.initAnagrams();
this.panels = new TreeMap<String, JPanel>();
//this.game = FACTORY.createGame(this.lang, this);
this.gameEnv = new GameEnvImpl(null, 0, lang);
// Create menu bar
this.menuBar = new MenuBar(this);
this.menuBar.create();
// Create center panel (containing board and multi)
this.centerPanel = new JPanel();
this.centerPanel.setLayout(new FlowLayout());
this.add(this.centerPanel, BorderLayout.CENTER);
// Board panel (in centerPanel)
JPanel boardpanel = new BoardPanel(this, this.gameEnv);
this.centerPanel.add(boardpanel);
this.panels.put("board", boardpanel);
//Create option panel (containing replay and stats)
this.options = new OptionsPanel(this, this.gameEnv);
this.options.setVisible(false);
this.centerPanel.add(this.options);
this.panels.put("options", this.options);
// Multiplayer panel (in centerPanel)
JPanel multiplayer = new MultiplayerPanel(this, this.gameEnv);
multiplayer.setVisible(false);
this.centerPanel.add(multiplayer);
this.panels.put("multiplayer", multiplayer);
// Create down panel (containing player planel and score)
JPanel downPanel = new JPanel();
downPanel.setLayout(new BorderLayout());
this.add(downPanel, BorderLayout.SOUTH);
// Player panel (in downPanel)
JPanel player = new PlayerPanel(this.gameEnv);
downPanel.add(player, BorderLayout.CENTER);
this.panels.put("player", player);
// Create stats panel (in downPanel)
JPanel stats = new StatsPanel();
downPanel.add(stats, BorderLayout.SOUTH);
this.panels.put("stats", stats);
// Terminate progress
this.progress.interrupt();
}
/** Start main frame. */
public void start() {
this.setVisible(false);
Tool.pause(250);
this.remove(this.background);
this.setSize(new Dimension(1024, 768));
this.setLocationRelativeTo(null);
this.validate();
this.repaint();
this.setVisible(true);
// Show new game
ChooseModeDialog welcome = new ChooseModeDialog(this);
welcome.start();
}
/** Create a solo game, initialize environment.
* @param name player name.
*/
public void createSoloBasedGame(String name) {
this.gameEng = new SoloEngine(gameEnv);
this.reset();
this.getOptionsPanel().setVisible(true);
//Player player = FACTORY.createPlayer(this.game, name, 0, false, null);
Player player = new Human(name, 0, gameEnv);
player.getRack().fill();
//player.initialize();
this.gameEnv.addPlayer(player);
this.getPlayerPanel().createScores();
PlayerPanel ppanel = this.getPlayerPanel();
ppanel.getButton("Validate").setEnabled(false);
ppanel.getButton("Cancel").setEnabled(false);
ppanel.getButton("Reset").setEnabled(false);
ppanel.action().clearLettersToReset();
this.setEnabled(true);
this.gameEng.start();
}
/** Create a turn based game, initialize environment.
* @param number number of players
* @param names players list.
* @param AIs ai paramater.
* @param AItime fast ai parameter.
* @param debug debug parameter.
* @param levels AI levels.
* @param strategies strategies used by the AI
*/
public void createTurnBasedGame(
int number, List<JTextField> names, List<JCheckBox> AIs,
List<JCheckBox> AItime, List<JCheckBox> debug,
List<JComboBox> levels, List<JComboBox> strategies) {
this.gameType = 1;
this.game.create();
this.reset();
this.getOptionsPanel().setVisible(true);
for (int i = 0; i < number; i++) {
SearchLevel level = SearchLevel.valueOf(
((String) levels.get(i).getSelectedItem()).toUpperCase());
SearchStrategy strategy = SearchStrategy.valueOf(
((String) strategies.get(i).getSelectedItem()).toUpperCase());
SearchPriority priority = SearchPriority.HIGHER_SCORE;
AIConfig config = new AIConfigImpl(level, strategy, priority);
Player player = FACTORY.createPlayer(
this.game, names.get(i).getText(), i,
AIs.get(i).isSelected(), config);
player.getRack().fill();
// player.setColor(Player.COLORS[i]);
if (AItime.get(i).isSelected()) {
player.setAITimer(0);
}
player.setDebug(debug.get(i).isSelected());
player.initialize();
this.game.addPlayer(player);
}
names.clear();
AIs.clear();
debug.clear();
PlayerPanel ppanel = this.getPlayerPanel();
ppanel.getButton("Validate").setEnabled(false);
ppanel.getButton("Cancel").setEnabled(false);
ppanel.getButton("Reset").setEnabled(false);
ppanel.getButton("Game Over").setEnabled(true);
ppanel.action().clearLettersToReset();
ppanel.createScores();
this.setEnabled(true);
this.game.start(false);
}
/** Create a multiplayer game, initialize environment.
* @param name player name.
*/
public void createMultiplayerBasedGame(String name) {
this.gameType = 2;
this.reset();
this.getOptionsPanel().setVisible(false);
MultiplayerPanel mpanel = this.getMultiplayerPanel();
mpanel.setVisible(true);
mpanel.getButton("Create").setEnabled(true);
mpanel.getButton("Connect").setEnabled(true);
mpanel.getButton("Disconnect").setEnabled(false);
mpanel.getButton("Ready").setEnabled(false);
PlayerPanel ppanel = this.getPlayerPanel();
ppanel.getButton("Validate").setEnabled(false);
ppanel.getButton("Cancel").setEnabled(false);
ppanel.getButton("Help").setEnabled(false);
ppanel.getButton("Game Over").setEnabled(false);
ppanel.getButton("Reset").setEnabled(false);
ppanel.action().clearLettersToReset();
ppanel.createScores();
this.game.reset();
Player player = FACTORY.createPlayer(this.game, name, 0, false, null);
player.initialize();
this.game.addPlayer(player);
this.game.setPlayerTurn(0);
mpanel.getAction().setPlayer(player);
}
/** Create a simulation based on a battle with two IA.
* @param num number of simulations (games).
* @param priorities AI priorities.
*/
public void createAIBattleGame(final int num, JComboBox[] priorities) {
this.gameType = 3;
this.reset();
// Prepare stats
final int[] scores = new int[2];
// Prepare progress
final JProgressBar prgs = new JProgressBar();
prgs.setMinimum(0);
prgs.setMaximum(num - 1);
prgs.setStringPainted(true);
prgs.setIndeterminate(false);
prgs.setPreferredSize(new Dimension(256, 48));
// Simulation window
final JDialog frame = new JDialog(this, getGameLang("Progress ..."));
frame.setSize(new Dimension(256, 192));
frame.setLayout(new BorderLayout());
frame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
frame.setResizable(false);
frame.add(prgs, BorderLayout.SOUTH);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
// Stop simulation
final JButton button = new JButton("Stop");
this.stopSimulation = false;
button.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
gameOver(true);
StringBuilder txt = new StringBuilder(
getGameLang("Simulation results:"));
txt = txt.append("\n");
txt = txt.append(getGameLang("On")).append(" ");
txt = txt.append(num + 1).append(" ");
txt = txt.append(getGameLang("games, the average scores are:"));
txt = txt.append("\n");
txt = txt.append(game.getPlayer(0).getName()).append(": ");
txt = txt.append(scores[0]).append("\n");
txt = txt.append(game.getPlayer(1).getName()).append(": ");
txt = txt.append(scores[1]).append("\n");
stopSimulation = true;
game.terminate();
frame.dispose();
showConfirmDialog(MainFrame_old.this, txt, getGameLang("Results:"),
CLOSED_OPTION, INFORMATION_MESSAGE);
setEnabled(true);
}
});
frame.add(button, BorderLayout.NORTH);
// Waiting bar
JProgressBar waiter = new JProgressBar();
waiter.setIndeterminate(true);
frame.add(waiter, BorderLayout.CENTER);
frame.validate();
this.game.create();
for (int i = 0; i < 2; i++) {
SearchLevel lvl = (SearchLevel) priorities[i].getSelectedItem();
SearchStrategy strategy = SearchStrategy.AUTOMATIC;
SearchPriority priority = SearchPriority.HIGHER_SCORE;
AIConfig cfg = new AIConfigImpl(lvl, strategy, priority);
StringBuilder name = new StringBuilder("AI ");
name = name.append(i).append(" (").append(lvl).append(")");
Player player = FACTORY.createPlayer(
this.game, name.toString(), i, true, cfg);
player.setAITimer(-1);
this.game.addPlayer(player);
}
//this.getPlayerPanel().createScores();
this.getOptionsPanel().setVisible(false);
this.setPlayerPanelPlayer(null);
this.setEnabled(false);
// For each simulation
new Thread() {
@Override
public void run() {
setName("Simulation");
for (int i = 0; i < num; i++) {
// Update progress
prgs.setValue(i);
// Prepare next simulation
game.board().clear();
game.bag().clear();
game.bag().fill();
for (int j = 0; j < 2; j++) {
Player player = game.getPlayer(j);
List<Letter> list = player.getLetters();
player.clearRack(list.iterator());
list.clear();
player.fillRack();
player.initialize();
player.setSimulation(true);
}
// Start simulation
game.start(true);
// Update scores
scores[0] += game.getPlayer(0).getScore() / (num + 1);
scores[1] += game.getPlayer(1).getScore() / (num + 1);
if (stopSimulation) {
break;
}
}
// Terminate progress
if (!stopSimulation) {
button.doClick();
}
frame.dispose();
}
}.start();
}
/** Terminate program. */
public void exit() {
int answer = showConfirmDialog(
null, getMessagesLang("Do you really want to exit ?"),
getGameLang("Exit"), YES_NO_OPTION);
if (answer == YES_OPTION) {
System.exit(0);
}
}
/** Save current turn.
* @param root root element.
*/
public void saveTurn(Element root) {
this.game.saveTurn(root);
}
/** Save current game.
* @param root root element.
*/
public void save(Element root) {
this.game.save(root);
}
/** Load a turn.
* @param filename name filename.
* @param i id of turn.
*/
public void loadTurn(File filename, int i) {
Document gamesave = null;
SAXBuilder sxb = new SAXBuilder();
Element root = null;
try {
gamesave = sxb.build(filename);
root = gamesave.getRootElement();
}
catch (Exception e) {
Display.information("Load", "An error occured during loading !");
}
PlayerPanel ppanel = this.getPlayerPanel();
ppanel.getButton("Validate").setEnabled(false);
ppanel.getButton("Cancel").setEnabled(false);
ppanel.getButton("Help").setEnabled(false);
ppanel.getButton("Game Over").setEnabled(false);
ppanel.getButton("Reset").setEnabled(false);
if (root != null) {
this.game.loadTurn(root, i);
}
this.repaint();
}
/** Load game.
* @param filename game file name.
*/
public void load(File filename) {
Document gamesave = null;
SAXBuilder sxb = new SAXBuilder();
Element root = null;
try {
gamesave = sxb.build(filename);
root = gamesave.getRootElement();
}
catch (Exception e) {
Display.information("Load", "An error occured during loading !");
}
PlayerPanel ppanel = this.getPlayerPanel();
ppanel.getButton("Validate").setEnabled(false);
ppanel.getButton("Cancel").setEnabled(false);
ppanel.getButton("Help").setEnabled(true);
ppanel.getButton("Game Over").setEnabled(true);
ppanel.getButton("Reset").setEnabled(false);
this.game.create();
this.game.setIsLoading(true);
this.game.load(root);
this.getPlayerPanel().createScores();
this.getPlayerPanel().updateScores();
this.setPlayerPanelPlayer(this.game.getPlayer(this.game.getPlayerTurn()));
this.repaint();
this.game.start(false);
}
public void setSaveFile(File saveFile) {
this.saveFile = saveFile;
}
public File getSaveFile() {
return this.saveFile;
}
/** Get player panel.
* @return player panel reference.
*/
public PlayerPanel getPlayerPanel() {
return (PlayerPanel) this.getPanel("player");
}
/** Get multiplayer panel.
* @return multiplayer panel reference.
*/
public MultiplayerPanel getMultiplayerPanel() {
return (MultiplayerPanel) this.getPanel("multiplayer");
}
/** Get stats panel.
* @return stats panel reference.
*/
public StatsPanel getStatsPanel() {
return (StatsPanel) this.getPanel("stats");
}
/** Get options panel
* @return options panel reference
*/
public OptionsPanel getOptionsPanel() {
return (OptionsPanel) this.getPanel("options");
}
/** Set the current player which is playing.
* @param player player which is playing.
*/
public void setPlayerPanelPlayer(Player player) {
this.getPlayerPanel().action().setPlayer(player);
}
/** Get sub panel from its name.
* @param name panel name.
* @return sub panel found.
*/
public JPanel getPanel(String name) {
return this.panels.get(name);
}
/** Get menubar.
* @return menubar reference.
*/
public MenuBar getMenubar() {
return this.menuBar;
}
/** Check if this is player turn.
* @param name player name.
*/
public void getTurn(String name) {
if (name.equals(this.game.getPlayer(0).getName())) {
this.game.mainFrame().getPlayerPanel().setEnabled(true);
this.game.mainFrame().getPlayerPanel().unlock();
this.game.setPlayerTurn(0);
this.getMultiplayerPanel().getAction().setMyTurn();
this.setPlayerPanelPlayer(this.game.getPlayer(0));
}
}
/** Game over box.
* @param skip skip box state.
*/
public void gameOver(boolean skip) {
// Add score from remaining letters
this.getMenubar().getItem("New Game").setEnabled(true);
this.getMenubar().getItem("Load Game").setEnabled(true);
this.getMenubar().getItem("Replay").setEnabled(true);
this.getMenubar().getItem("Load Game").setEnabled(true);
// TODO WTF is it doing here ? adding score should be done by gameEngine on end of the game
Iterator<Player> itr = this.game.getPlayersList();
for (Player player : this.gameEnv.getPlayerList()) {
Player player = itr.next();
if (player.getRack().getLetters().isEmpty()) {
while (itr.hasNext()) {
Player othersPlayers = itr.next();
Iterator<Letter> let = othersPlayers.getRack().iterator();
while (let.hasNext()) {
player.addScore(let.next().getValue());
}
}
} else {
Iterator<Letter> let = player.getLetters().iterator();
while (let.hasNext()) {
player.subtractScore(let.next().getValue());
}
}
}
if (!skip) {
//itr = this.game.getPlayersList();
StringBuilder msg = new StringBuilder(
getGameLang("Game result:") + "\n");
for (Player player : this.gameEnv.getPlayerList()) {
msg = msg.append(player.getName()).append(": ");
msg = msg.append(player.getScore()).append("\n");
}
msg = msg.append("\n").append(getGameLang("Letters used:")).append(" ");
msg = msg.append(this.gameEnv.board().getNumberOfDroppedLetters());
String[] choices = {
getGameLang("New Game"),
getGameLang("Close")
};
int choice = showOptionDialog(
null, msg, getGameLang("Game Over"),
YES_NO_OPTION, QUESTION_MESSAGE,
null, choices, choices[0]);
if (choice == YES_OPTION) {
this.getMenubar().getAction().newGame();
}
}
}
/** Get game.
* @return game reference.
*/
public Game game() {
return this.game;
}
/** Get NewGameSelection
* @return
*/
public int getGameSelection() {
return this.gameType;
}
/** Reset game stats, in case of new game. */
public void reset() {
this.centerPanel.remove(this.options);
this.panels.remove("options");
this.options = new OptionsPanel(this, this.game);
this.options.setVisible(true);
this.centerPanel.add(this.options);
this.panels.put("options", this.options);
this.centerPanel.validate();
}
}