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

📄 gamewindow.java

📁 ErGo是一个很早的Java通用围棋服务器(IGS/NNGS)客户端程序。有全部源码和文档
💻 JAVA
📖 第 1 页 / 共 5 页
字号:
  // Implement the PopupContributor interface
  //

  public boolean allowMoreItems (Component c) { return true; }

  public void populatePopupMenu (PopupMenu p, Component comp, int x, int y) {
    popupHandler.populatePopup(p, comp, x, y);
  }


  // This class isn't strictly necessary.  It's just here to encapsulate
  // some popup menu code.  Notably the menu items which may have the same
  // names as some in the outer class.

  class PopupHandler {
    private VariationMenuItem deleteVarItem;
    private VariationMenuItem sendVarItem;
    private MenuCommand deleteAllItem;
    // I'm assuming that it could confuse AWT if a menu item is used in
    // more than one menu, therefore creating a second one for "Copy as SGF".
    private MenuCommand browseItem;
    private MenuCommand copySGFItem;
    private MenuCommand statsBlackItem;
    private MenuCommand statsWhiteItem;
    private MenuCommand showObsItem;
    private MenuCommand reloadItem;

    // A place to save the row and column (on the goban) where the
    // popup was activated, since the actionPerformed() method doesn't
    // have access to the X and Y of the mouse click event.
    //
    // This hack is no longer needed, since the menu items are implemented
    // as MenuCommands and their executeCommand methods receive the event
    // object, with the X and Y coords of the mouse click.  -sigue
    private int row, col;

    public PopupHandler () {

      // Each of the menu items is implemented as an anonymous subclass of MenuCommand.

      deleteVarItem = new VariationMenuItem("Delete variation", null) {
	public void executeCommand (Object event) {
	  Move m = getVariation();
	  Move p = m.parent();
	  setVariation(null);
	  if (p != null) {
	    p.removeVariation(m);
	    // +++Kludge.  I can't remember at the moment how to update the
	    // board correctly.  This (almost) works, but the code below it doesn't.
	    goBackward(1, false);
	    goForward(1);
	    /*
	      PositionVector placed = m.placedPositions(getSize());
	      if (placed != null) {
		boolean decorate = false;
		for (int i = 0; i < placed.size(); i++) {
		  Position p1 = placed.elementAt(i);
		  invalidateInternal(p1.row, p1.column);
		  if (decorations.isMember(p1))
		    decorate = true;
		}
		if (decorate)
		  decorateStone(offg);
		updateInternal();
	      }
	    */
	  }
	} 
      };
      sendVarItem   = new VariationMenuItem("Insert variation as kibitz", null) {
	public void executeCommand (Object event) {
	  insertVariationAsKibitz(getVariation());
	}
      };
      browseItem = new MenuCommand("Browse to position") {
	public void executeCommand (Object event) {
	  goToMove(game.findMove(row, col));
	}
      };
      deleteAllItem = new MenuCommand("") {  // uses setLabel() later
	public void executeCommand (Object event) {
	  // Delete all groups in the region that are the same color as the
	  // one just clicked on.  Generate a RemovalMove for each such group.
	  SimpleGroupVector deadGroups = game.groupsInRegion(new Position(row, col));
	  Move parent = game.getCurrentMove();
	  if (deadGroups != null) {
	    for (int i = 0; i < deadGroups.size(); i++)
	      if (conn != null
		  && isNetGame()
		  && isParticipating()
		  && !isBrowsing())
		conn.send(deadGroups.elementAt(i).positionAt(0).toString(), false);
	      else {
		RemovalMove move
		  = new RemovalMove(parent, deadGroups.elementAt(i).positionAt(0),
				    parent.moveNumber() + 1, true);
		placeMove(move, false);
		parent = move;
	      }
	    game.ss.emit();
	  }
	}
      };
      copySGFItem = new MenuCommand ("Copy (as SGF)") {
	public void executeCommand (Object event) {
	  copyAsSGF();
	}
      };
      if (Ergo.inApplet)
	copySGFItem.setEnabled(false);  // causes security violation
      statsBlackItem = new MenuCommand("Stats " + game.blackName) {
	public void executeCommand (Object event) {
	  conn.send("stats " + game.blackName, true);
	}
      };
      statsWhiteItem = new MenuCommand("Stats " + game.whiteName) {
	public void executeCommand (Object event) {
	  conn.send("stats " + game.whiteName, true);
	}
      };
      showObsItem = new MenuCommand("Show Observers") {
	public void executeCommand (Object event) {
	  conn.send("all " + gameNumber, true);
	}
      };
      reloadItem = new MenuCommand("Load " + game.whiteName + "-" + game.blackName) {
	public void executeCommand (Object event) {
	  conn.send("load " + game.whiteName + "-" + game.blackName);
	}
      };
    }

    public void populatePopup (PopupMenu popup, Component comp, int x, int y) {
      row = boardCanvas.ytorow(y);
      col = boardCanvas.xtocol(x);

      if (comp == boardCanvas) {
	int stoneUnderMouse = game.ss.readStone(row, col);

	// "Browse to position" -- active on any stone
	// +++ Needs to be made to work on empty positions (i.e. browse forward)
	if (stoneUnderMouse != Move.EMPTY)
	  popup.add(browseItem);

	// "Delete variation" -- active on variation letters only
	for(int i = -1; ; i++) {
	  Move m = game.getCurrentMove().variationAt(i);
	  if (m == null)
	    break;
	  else {
	    PositionVector placed = m.placedPositions(game.getSize());
	    if (placed != null)
	      for (int j = 0; j < placed.size(); j++) {
		Position pos = placed.elementAt(j);
		if (pos.row == row && pos.column == col) {
		  deleteVarItem.setVariation(m);
		  sendVarItem.setVariation(m);
		  popup.add(deleteVarItem);
		  popup.add(sendVarItem);
		  break;
		}
	      }
	  }
	}

	// "Remove All" -- active on stones during scoring mode
	if (stoneUnderMouse != Move.EMPTY && game.scoringMode()) {
	  String text = ("Remove "
			 + (stoneUnderMouse == Move.WHITE ? "white" : "black")
			 + " groups in region");
	  deleteAllItem.setLabel(text);
	  popup.add(deleteAllItem);
	}

	// Copy as SGF item.  Active on goban only.
	popup.add(copySGFItem);
      } // end if on goban

      if (isNetGame()) {
	if (popup.getItemCount() > 0)
	  popup.addSeparator();
	popup.add(statsBlackItem);
	popup.add(statsWhiteItem);
	popup.add(showObsItem);
	if (gameStatus == ADJOURNED)
	  popup.add(reloadItem);
      }
    }
  }  // end inner class PopupHandler


  /*****************************************************
   *  Manage changes to Game Status/ Result            *
   *****************************************************/

  // placeMove() also changes gameStatus to PLAYING.

  public void adjourn () {
    statusPanel.stopTicking();
    if (gameStatus != GAMEOVER)
      gameStatus = ADJOURNED;
    //    conn.control.sgc.uninform(this);
    statusPanel.refresh();
  }

  public void resign (String result) {
    game.setResult(result);
    statusPanel.stopTicking();
    gameStatus = GAMEOVER;
    //    conn.control.sgc.uninform(this);
    statusPanel.refresh();
  }

  public void ensureActive () {
    int color = game.currentMove().color();
    statusPanel.startTicking(color);
    statusPanel.stopTicking(Move.nextColor(color));
    if (gameStatus != PLAYING) {
      gameStatus = PLAYING;
      statusPanel.refresh();
      conn.control.sgc.inform(this);
    }
  }

  public int timeLeft () {
    // +++ to do
    //System.currentTimeMillis()...
    return 0;
  }


  /*****************************************************
   *  Useful properties of this game                   *
   *****************************************************/
 
  public boolean isOnServer() { return gameStatus == PLAYING && !isLocalGame(); }

  // Whether or not the user is a participant in this game.
  public boolean isParticipating () { return isParticipating; }
  
  // can return Move.BOTH, indicating we are playing both sides!
  public int ourColor() { return ourColor; } 

  // This may be called after a game begins if users type "fteach".
  public void setOurColor (int c) {
    if (c == Move.BLACK || c == Move.WHITE || c == Move.BOTH)
      ourColor = c;
  }

  public boolean isTeachingGame () { return ourColor() == Move.BOTH; }

  // +++ Uh, isNetGame and isLocalGame should be inverses.

  public boolean isNetGame () { return game.isNetGame(); }

  public boolean isLocalGame () { return conn == null; }

  public boolean isBrowsing () {
    return browsing
      || !isNetGame()
      || gameStatus == ADJOURNED
      || gameStatus == GAMEOVER
      || game.finalServerMove() != game.getCurrentMove();
  }

  public void setBrowsing (boolean b) {
    browsing = b;
    browsingItem.setState(isBrowsing());
/***
    if (browseButton != null)
      browseButton.setLabel(browsing ? "Stop Browsing" : "Browse");
 ***/
  }

  private void exitBrowsingMode () {
    if (isBrowsing()) {
      // +++ Extremely heavyweight way to return to the final server move.
      goBackward(-1, false);
      goToEnd();
    }
  }
  
  private void setSound (boolean b) {
    sound = b;
    soundItem.setState(b);
  }

  /*************************
   * Manage Window Title.  *
   *************************/
  public String title () { return title(true); }

  public String title (boolean includeGameNumber) {
    StringBuffer b = new StringBuffer();
    if (includeGameNumber && isNetGame())
      b.append("Game " + gameNumber + " -- ");
    b.append(game.whiteName + " (W");
    if (game.whiteRank != null)
      b.append(" " + game.whiteRank);
    b.append(") vs " + game.blackName + " (B");
    if (game.blackName != null)
      b.append(" " + game.blackRank);
    b.append(")");
    return b.toString();
  }


  public String toString () { return title(); }

  public void updateTitle () { setTitle(title()); }

  // The Function Formerly Known As noteMove.
  public void noteCurrentMoveChanged () {
    updateKibitzArea();
    if (game.getCurrentMove() instanceof RootMove)
      handicapMenu.setEnabled(true);
    else
      handicapMenu.setEnabled(false);
  }

  /***********************************************************
   * Move/Variation manipulation                             *
   ***********************************************************/

  // Insert a variation into the command line as a kibitz.
  private void insertVariationAsKibitz (Move m) {
    int caret = inputField.getCaretPosition();
    String s = m.toVariationString();
    String input = inputField.getText();
    inputField.setText(input.substring(0, caret) + s + input.substring(caret));
    inputField.setCaretPosition(caret + s.length());
  }

  /**
    * Place a move on the board associated with this gamewindow.
    * This is called when a move is received from the server.
    */
  public void placeMove (Move m, boolean fromServer) {
    if (fromServer)
      gameStatus = PLAYING;	// in case it was ADJOURNED
    game.placeMove(m, window, isBrowsing(), fromServer);
    if (m instanceof PassMove)
      kibitzArea.appendText(m.moveNumber()
			    + ((m.color() == Move.BLACK) ? " Black" : " White")
			    + " passes");
    //    if (Ergo.opser.getBooleanOption(Ergo.opser.soundString))
    //      Toolkit.getDefaultToolkit().beep();
    statusPanel.refresh();
    noteCurrentMoveChanged();
    needsSaving = true;
    if (!Ergo.inApplet) {
      saveItem.setEnabled(true);
      saveAsItem.setEnabled(true);
    }
  }


  /**
    * Place a move on the board given the row and column of the move.
    * This is called when the local user clicks on a board position.
    * Note that if you click on a position that contains a variation
    * (whether or not the variation letter is drawn on the board) then
    * it has the same effect as choosing that variation from the 
    * Variations menu, unless it's a server game and you're not browsing.
    *
    */
  public void placeMove (int row, int column) {
    Move parent = game.getCurrentMove();
    // It's a local game or the user is browsing.  No need to send the
    // move to the server.  If the user clicked on a variation (whether
    // or not the variation letter is showing) then it's the same as if
    // they chose that variation from the Variations menu.
    if (game.scoringMode()
	&& game.ss.readStone(row, column) != Move.EMPTY) {
      if (conn != null && isNetGame() && isParticipating() && !isBrowsing())
	conn.send(new Position(row, column).toString(), false);
      else {
	placeMove(new RemovalMove(parent, new Position(row, column),
				  parent.moveNumber() + 1, true),
		  false);

⌨️ 快捷键说明

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