⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 boardmediator.java

📁 --- --- --- 基于J2ME的游戏程序--------很有技巧性的程序
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
// Copyright (c) 2005 Sony Ericsson Mobile Communications AB
//
// This software is provided "AS IS," without a warranty of any kind. 
// ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, 
// INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A 
// PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. 
//
// THIS SOFTWARE IS COMPLEMENTARY OF JAYWAY AB (www.jayway.se)

package bluegammon.logic;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

import bluegammon.Audio;
import bluegammon.Device;
import bluegammon.Bluegammon;
import bluegammon.Resources;
import bluegammon.RmsFacade;
import bluegammon.gui.BoardCanvas;
import bluegammon.gui.popup.Popup;

/**
 * <p>
 * The <code>BoardMediator</code> class is active during a backgammon game. It takes care
 * of coordination between <code>BoardState</code> and <code>BoardCanvas</code> i.e.
 * between the gui and the logic. <code>BoardCanvas</code> is detached from any
 * backgammon-logic - this connection is made by this class by implementing
 * <code>BoardStateListener</code> to receive events upon board state changes. The
 * <code>BoardMediator</code> then calls the <code>BoardCanvas</code> to update the gui
 * when state changes.
 * </p><p>
 * In order to save the game at any time, but still have animations, the
 * <code>BoardState</code> differs from the <code>BoardCanvas</code>: when the state 
 * is changed (e.g. a move is made), the <code>BoardState</code> is updated
 * directly. The <code>BoardCanvas</code> has intermittent states; e.g. during an animation
 * of a piece movement, one piece is "missing" from <code>BoardCanvas</code> board until
 * the piece is put down.
 * </p><p>  
 * This class is a simple coordinater, thus it does not have any state. The
 * <code>BoardMediator</code> is accessed statically.
 * <p>
 * 
 * @see bluegammon.gui.BoardCanvas
 * @see bluegammon.logic.BoardState
 * @author Peter Andersson
 */
public class BoardMediator implements BoardStateListener
{
  /**
   * Starts the BoardMediator.
   */
  public static void startup()
  {
    BoardState.getInstance().setGameListener(new BoardMediator());
  }

  /**
   * Initiates a new or resumed game with specified players.
   * @param p1			Player 1.
   * @param p2			Player 2.
   * @param resumed		True if resumed, false if new game.
   */
  public static void init(Player p1, Player p2, boolean resumed)
  {
    BoardState state =  BoardState.getInstance();
    BoardCanvas canvas = BoardCanvas.getInstance();

    state.setPlayers(p1,p2);
    state.setGameFinished(false);
    
    if (!resumed)
    {
      int whiteDice = newDiceValue();
      int blackDice = newDiceValue();
    
      if (whiteDice == blackDice)
      {
        if (whiteDice > 3)
        {
          whiteDice--;
        }
        else
        {
          whiteDice++;
        }
      }
    
      boolean whiteTurn = whiteDice > blackDice;
    
      state.setStartPositions();
      canvas.setStartPositions();
      canvas.invalidate();
      canvas.selectTurns(whiteDice, blackDice);
    }
  }

  /**
   * Shuts the BoardMediator down.
   */
  public static void shutdown()
  {
	BoardCanvas.getInstance().shutdown();
  }

  // Actions

  /**
   * Called from interaction, moves a player piece.
   * @param possibleMoveIndex	How to move according to current BoardState
   */
  public static void makePlayerMove(int possibleMoveIndex)
  {
    BoardState state = BoardState.getInstance();
    int[][] moves = getPossibleMoves();
    state.makeMove(
        moves[possibleMoveIndex][BoardState.PM_SOUR],
        moves[possibleMoveIndex][BoardState.PM_DEST],
        isCurrentPlayerWhite());
    int diceValIndex = moves[possibleMoveIndex][BoardState.PM_DICE];
    int diceValue = state.getDiceValue(diceValIndex); 
    BoardCanvas.getInstance().consumeDiceValue(diceValue);
    state.consumeDice(diceValIndex);
    state.commitMove(isCurrentPlayerWhite(), diceValue);
  }

  /**
   * Called from interaction, undoes the last move.
   * Does nothing if there are no moves to undo.
   */
  public static void undoLastMove()
  {
    BoardCanvas canvas = BoardCanvas.getInstance();
    int oldSourceIdx = BoardState.getInstance().undoLastMove(isCurrentPlayerWhite());
    canvas.setQueryCommit(false);
    canvas.cursorNearestIndex(oldSourceIdx, 0);
    canvas.updateUndoCommand();
    canvas.updateCursor();
  }

  /**
   * Called from interaction, commits players' moves.
   */
  public static void commitTurn()
  {
    newTurn(!BoardMediator.isCurrentPlayerWhite());
    BoardCanvas.getInstance().setQueryCommit(false);
  }

  /**
   * Called from interaction and logic, changes turn.
   * 
   * @param whiteTurn	true if turn changes to white player, false otherwise.
   */
  public static void newTurn(boolean whiteTurn)
  {
    if (!BoardState.getInstance().isGameFinished())
    {
      BoardState.getInstance().setTurn(whiteTurn);
      Player p = BoardState.getInstance().getCurrentPlayer();
      if (p instanceof LocalPlayer)
      {
        BoardCanvas.getInstance().setCurrentLocalPlayer((LocalPlayer)p);
      }
      else
      {
        BoardCanvas.getInstance().setCurrentLocalPlayer(null);
      }

      BoardState.getInstance().newDiceValues(
          newDiceValue(), newDiceValue());
      BoardCanvas.getInstance().throwDices(whiteTurn);

      if (Bluegammon.getGameType() != Bluegammon.GAME_TYPE_LOCAL &&
          !isRemoteTurn())
      {
        Device.vibrate(100,0,1);
      }
    }
  }
  
  /**
   * Called from interaction, exits current game.
   * 
   * @param reason	An integer denoting the reason for quitting,
   * 				one of <code>PlayerListener.LOCAL_QUIT</code>,
   * 				<code>PlayerListener.REMOTE_QUIT,</code>
   * 				<code>PlayerListener.LOCAL_GIVE_UP,</code>
   * 				<code>PlayerListener.REMOTE_GIVE_UP</code>
   */
  public synchronized static void exitGame(int reason)
  {
    if (reason == PlayerListener.LOCAL_GIVE_UP ||
        reason == PlayerListener.REMOTE_GIVE_UP)
    {
      boolean localLoser = reason == PlayerListener.LOCAL_GIVE_UP;
      boolean whiteWinner = !BoardMediator.getLocalPlayer().isWhite();
      if (reason == PlayerListener.REMOTE_GIVE_UP)
      {
        whiteWinner = !whiteWinner;
        Bluegammon.showPopup(Resources.getChars(Resources.TXT_REMOTE_GAVE_UP),
            Popup.ALT_OK, 10, 0, 0, null);
      }
      int piecesLeft = BoardState.getInstance().calculatePiecesLeft(!whiteWinner);
      int points = BoardState.getInstance().calculatePoints(!whiteWinner);
      
      // Only show animation to the winning player, the player who gives up
      // probably just want to quit
      BoardMediator.finishGame(whiteWinner, piecesLeft, points, !localLoser);
      if (localLoser)
      {
        Bluegammon.exitGame();
      }
    }
    else if (reason == PlayerListener.REMOTE_QUIT)
    {
      if (!isGameFinished())
      {
        Bluegammon.showPopup(Resources.getChars(Resources.TXT_BT_REMOTE_QUIT), 
            Popup.ALT_OK, 0, 0, 0, null);
        Bluegammon.exitGame();
      }
    }
    else
    {
      if (Bluegammon.isShowingPopup())
      {
        Bluegammon.getCurrentPopup().dispose();
      }
      Bluegammon.exitGame();
    }
  }
  
  /**
   * Called from IO framework remote connection is lost in a 
   * remote game.
   * @param e		The exception that was
   * 				the reason of losing connection.
   */
  public synchronized static void lostRemoteConnection(IOException e)
  {
    if (!isGameFinished())
    {
      System.err.println("Lost remote connection!");
      e.printStackTrace();
      Audio.playSound(Audio.CONN_FAIL);
      Bluegammon.showPopup(Resources.getChars(Resources.TXT_BT_CONN_LOST), 
          Popup.ALT_OK, 0, 0, 0, null);
      Bluegammon.exitGame();
    }
  }  
  
  /**
   * Called when remote player sent a message
   * @param mess	the message.
   */
  public static void showMessage(char[] mess)
  {
    Device.vibrate(100,50,3);
    Audio.playSound(Audio.MESSAGE);
    mess =
      (new String(getOpponentPlayer().getName()) + ":\n\n" + new String(mess)).toCharArray();
    Bluegammon.showPopup(mess, null, 60, 0, 0, null);
  }
  
  /**
   * Returns the player whos holding the turn, i.e. can make moves.
   * This method returns null if current player has not yet been chosen,
   * meaning that the first dice roll is still ongoing.
   * @return The current player or null.
   */
  public static Player getCurrentPlayer()
  {
    return BoardState.getInstance().getCurrentPlayer();
  }
  
  /**
   * Returns opponent player. In case of local game, this method returns
   * the player currently waiting for his or her turn. In a remote game,
   * it returns the remote player.
   * 
   * @return The opponent.
   */
  public static Player getOpponentPlayer()
  {
    Player p1 = BoardState.getInstance().getCurrentPlayer();
    Player p2 = BoardState.getInstance().getWaitingPlayer();
    if (Bluegammon.getGameType() == Bluegammon.GAME_TYPE_LOCAL)
    {
      return p2;
    }
    else
    {
      return (p1 instanceof LocalPlayer) ? p2 : p1;
    }
  }
  
  /**

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -