Package de.axxeed.animosy.model

Source Code of de.axxeed.animosy.model.Game

/**
*
*/
package de.axxeed.animosy.model;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.InputEvent;
import java.awt.event.KeyEvent;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Iterator;
import java.util.TreeSet;

import javax.swing.AbstractAction;
import javax.swing.JMenu;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.KeyStroke;

import org.apache.log4j.Logger;

import de.axxeed.animosy.ai.MrX;
import de.axxeed.animosy.gui.MapPanel;
import de.axxeed.animosy.gui.OptionsDialog;
import de.axxeed.animosy.gui.PanelRepository;

/**
* Game.java
* Created 10.12.2007 14:08:16
* @author Markus J. Luzius
*
*/
public class Game {
  private static Logger log = Logger.getLogger(Game.class);
 
  public static final int NO_GAME   =  -1;
  public static final int MOVE_MRX  =   0;
  public static final int WIN_MRX   = 100;
  public static final int WIN_DET   = 101;
  private static final SimpleDateFormat sdf = new SimpleDateFormat("hh:mm:ss");

  private GameBoard board = new GameBoard();
  private int currentMove = 0;
    private int state = NO_GAME;
    private int strandedDetectives = 0;
    private MrXTracker tracker = null;
    private long gameStartTime = 0;

    public Game() {
      log.debug("Game created...");
    }
   
  public GameBoard getBoard() {
    return board;
  }
 
  public void startGame() {
    state = NO_GAME;
    OptionsDialog od = new OptionsDialog();
    od.setVisible(true);
   
    PanelRepository.get(PanelRepository.HISTORY_ITEM).setEnabled(true);

    board.init();
    tracker = new MrXTracker();
    tracker.setPotentialPosition(board.getMrX().getPosition().getPosition());
    currentMove = 1;
   
    log.info("Starting a new game");
    gameStartTime = System.currentTimeMillis();
    PanelRepository.get(PanelRepository.MAIN_WINDOW).repaint();
   
    state = MOVE_MRX;
    try {
      new MrX(Class.forName("de.axxeed.animosy.ai.RandomMrX"));
    } catch (ClassNotFoundException e) {
      log.error("MrX class not found - unable to start a game.");
      state = NO_GAME;
    }

    PanelRepository.get(PanelRepository.MAIN_WINDOW).requestFocus();

  }

  public int getState() {
    return state;
  }

  public MrXTracker getTracker() {
    return tracker;
  }
 
  public String getStateText() {
    if(state==NO_GAME) {
      return "No game";
    }
    else if(state==MOVE_MRX) {
      return "Move MrX";
    }
    else if(state==WIN_DET) {
      return "Detectives win";
    }
    else if(state==WIN_MRX) {
      return "MrX wins";
    }
    else if(state>NO_GAME && state<WIN_MRX) {
      return "Move detective #"+state;
    }
    return "undefined";
  }
 
  public int getCurrentMove() {
    return currentMove;
  }

  public int getActiveDetectiveIndex() {
    if(state>0 && state<WIN_MRX) {
      return state-1;
    }
    return -1;
  }
 
  public Detective getActiveDetective() {
    return board.getDetectives()[getActiveDetectiveIndex()];
  }
 
  public void nextDetective() {

    int mrXpos = board.getMrX().getPosition().getPosition();
    for (int i=0;i<board.getDetectives().length;i++) {
      if(mrXpos==board.getDetectives()[i].getPosition().getPosition()) {
        state = WIN_DET;
        log.info("The detectives win!");
        String additionalText = "";
        if(currentMove<10) {
          additionalText = "only ";
        }
        if(currentMove>Manager.getOptions().getNumberOfMoves()-8) {
          additionalText = "a long ";
        }
        JOptionPane.showMessageDialog( null, "The detectives have won!\n" +
            "You caught him in time on field "+board.getMrX().getPosition().getPosition()+"!\n"+
            "It took you "+additionalText+currentMove+" moves. \n\n" +
            "Game time: "+getGameTime(),
            "Detectives win", JOptionPane.INFORMATION_MESSAGE);
        return;
      }
    }
   
    log.debug(".nextDetective()");
    if(isCheckPoint()) {
      PanelRepository.get(PanelRepository.TRACKER_ITEM).setEnabled(true);
      tracker.reset();
      tracker.setPotentialPosition(board.getMrX().getPosition().getPosition());
    }
    else if(state!=MOVE_MRX) {
      tracker.removePotentialPosition(board.getDetectives()[state-1].getPosition().getPosition());
    }
    state++;
    if(state>board.getDetectives().length) {
      log.debug("Cleaning move menu...");
      cleanMoveMenu();

      currentMove++;
      if(currentMove>Manager.getOptions().getNumberOfMoves()) {
        state = WIN_MRX;
        log.info("MrX escaped in time, so he wins!");
        PanelRepository.get(PanelRepository.MAIN_WINDOW).repaint();
        JOptionPane.showMessageDialog( null, "MrX has won!\nYou didn't catch him in time!\n\nGame time: "+getGameTime(), "MrX wins", JOptionPane.INFORMATION_MESSAGE);
        return;
      }
      state = MOVE_MRX;
    }
    else {
      log.debug("Updating move menu...");
      updateMoveMenu();
    }
    PanelRepository.get(PanelRepository.MAIN_WINDOW).repaint();
  }

  private void undoMove() {
    if(state<=MOVE_MRX+1) return;
    int previousDetective = getActiveDetectiveIndex()-1;
    board.getDetectives()[previousDetective].undoMove();
    state--;
    updateMoveMenu();
    ((MapPanel)PanelRepository.get(PanelRepository.MAP_PANEL)).updatePositions();
    PanelRepository.get(PanelRepository.STATUS_PANEL).repaint();
  }
 
  public void moveDetective(Move move) {
    getActiveDetective().changePosition(BoardModel.getNode(move.getNode()), move.getType());
    ((MapPanel)PanelRepository.get(PanelRepository.MAP_PANEL)).updatePositions();
    if(getActiveDetective().isStranded()) {
      strandedDetectives += twoUp(getActiveDetectiveIndex());
      log.debug("Stranded detectives="+strandedDetectives);
      if(strandedDetectives==(twoUp(Manager.getOptions().getNumberOfDetectives())-1)) {
        log.info("All detectives are stranded - MrX wins!");
        state = WIN_MRX;
        JOptionPane.showMessageDialog( null, "MrX has won!\nAll detectives are unable to move!\n\nGame time: "+getGameTime(), "MrX wins", JOptionPane.INFORMATION_MESSAGE);
        return;
      }
    }
    if(getActiveDetective().getPosition().getPosition()==board.getMrX().getPosition().getPosition()) {
      state = WIN_DET;
      log.info("The detectives win!");
      String additionalText = "";
      if(currentMove<10) {
        additionalText = "only ";
      }
      if(currentMove>Manager.getOptions().getNumberOfMoves()-8) {
        additionalText = "a long ";
      }
      JOptionPane.showMessageDialog( null, "The detectives have won!\nYou caught him in time on field "+
          board.getMrX().getPosition().getPosition()+"!\n" +
          "It took you "+additionalText+currentMove+" moves.\n\n" +
          "Game time: "+getGameTime(),
          "Detectives win", JOptionPane.INFORMATION_MESSAGE);
    }
    else {
      nextDetective();
      int maxCount = 0;
      while(getActiveDetectiveIndex()>= 0 && getActiveDetective().isStranded() && maxCount<Manager.getOptions().getNumberOfDetectives()*2 && state<WIN_MRX) {
        maxCount++;
        nextDetective();
      }
    }
  }

    public boolean isCheckPoint() {
      return isCheckPoint(currentMove);
    }

    public boolean isCheckPoint(int move) {
      if(move==3) {
        return true;
      }
      int level = Manager.getOptions().getLevel();
      // log.debug("("+move+"-3)%(3+"+level+")="+(move-3)+"%"+(3+level)+"="+((move-3)%(3+level)));
        if((move-3)%(3+level)==0) {
        return true;
        }
     
      return false;
    }
 
  private int twoUp(int up) {
    if(up>20) return -1;
    if(up==0) return 1;
    else return 2*twoUp(up-1);
  }

  private void updateMoveMenu() {
    int activeDet = Manager.getGame().getActiveDetectiveIndex();
    JMenu detectiveMenu = (JMenu) PanelRepository.get(PanelRepository.MOVE_MENU);
    detectiveMenu.removeAll();
    TreeSet<Move> possibleMoves = board.getDetectives()[activeDet].getPossibleMoves();
    JMenuItem undo = new JMenuItem("Undo move");
    undo.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent arg0) {
        undoMove();
      }
    });
    undo.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_Z, InputEvent.CTRL_DOWN_MASK));
    if(state<=MOVE_MRX+1 || state>=WIN_MRX) {
      undo.setEnabled(false);
    }
    detectiveMenu.add( undo );
    detectiveMenu.addSeparator();
   
    if(possibleMoves==null || possibleMoves.isEmpty()) {
      AbstractAction action = new AbstractAction("Skip turn")
        {
          private static final long  serialVersionUID  = 0L;
          public void actionPerformed( ActionEvent e ) {
            Manager.getGame().nextDetective();
            ((MapPanel)PanelRepository.get(PanelRepository.MAP_PANEL)).updatePositions();
            PanelRepository.get(PanelRepository.STATUS_PANEL).repaint();
          }
        };
      detectiveMenu.add( action );
    }
    else {
      log.debug("Possible moves: "+possibleMoves.size()+" - "+possibleMoves);
      Iterator<Move> i = possibleMoves.iterator();
      while(i.hasNext()) {
        Move m = (Move) i.next();
        StringBuilder linkText = new StringBuilder();
        linkText.append(m.getNode()).append(" (");
        switch(m.getType()) {
          case BoardModel.TAXI: linkText.append("TAXI").append(")"); break;
          case BoardModel.BUS: linkText.append("BUS").append(")"); break;
          case BoardModel.UG: linkText.append("UG").append(")"); break;
          case BoardModel.BLACK: break;
          case BoardModel.INF: linkText.append("INF").append(")"); break;
          default: linkText.append("???").append(")"); break;
        }
       
        // detectiveMenu.add( new JMenuItem(linkText.toString()) );
        AbstractAction action = new AbstractAction(linkText.toString())
          {
            private static final long  serialVersionUID  = -4379938472159497577L;
            public void actionPerformed( ActionEvent e ) {
              log.debug("Selected move: "+((Move)this.getValue(e.getActionCommand())));
              Manager.getGame().moveDetective((Move)this.getValue(e.getActionCommand()));
              PanelRepository.get(PanelRepository.STATUS_PANEL).repaint();
            }
          };
        action.putValue(linkText.toString(), m);
        action.putValue("Detective", board.getDetectives()[activeDet]);
        detectiveMenu.add( action );
      }
    }
  }

  private void cleanMoveMenu() {
    JMenu detectiveMenu = (JMenu) PanelRepository.get(PanelRepository.MOVE_MENU);
    detectiveMenu.removeAll();
    JMenuItem item = null;
    detectiveMenu.add(item = new JMenuItem("no move available"));
    item.setEnabled(false);
  }

  public String getGameTime() {
    if(state>NO_GAME && state<WIN_MRX) {
      return sdf.format(new Date(System.currentTimeMillis()-gameStartTime-3600000));
    }
    return "---";
  }
}
TOP

Related Classes of de.axxeed.animosy.model.Game

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.