我正在研究国际象棋的Java版本。我已经做了几年的程序员,但从未收到过面向对象,基于事件的编程的精彩解释。
这是我的问题:我当前的程序是一个线性的,控制台驱动的游戏,用户输入一种颜色的移动,而计算机为另一种颜色移动。为此,我有一个带有“getMove”方法的通用“Player”类。 HumanPlayer从控制台输入中移动,AIPlayer从算法生成移动。
我现在正在尝试创建第三种类型的播放器GUIPlayer,它可以从GUI事件中生成移动。这就是我想要发生的事情:
Game ---(request for move)---> GUIPlayer --------(request for move)---------> GUI
^------(resulting move)--------|<-----(resulting move from click events)-----|
换句话说,游戏允许玩家有限制地访问GUI以请求移动,然后玩家等待直到满足GUI中的特定条件。我喜欢这个设计,但我不确定如何实现它。我假设Player类或GUI需要某种线程等待通知结构。
这是我的代码的简化版本。这是一个非常粗略的原型,专门用于返回移动。
public class ChessPanel
extends Component
implements MouseListener, MouseMotionListener {
Board b;
Piece selectedPiece;
Position selectedPiecePosition;
Move playerMove;
public void mouseClicked(MouseEvent e) {
Position clickPosition = getSquare(e.getX(), e.getY());
if(this.selectedPiece.getType() == PieceType.NONE) {
// Attempts to select the piece that was just clicked
Piece piece = b.getPiece(clickPosition);
System.out.println("Selected "+piece);
if(piece.getType() != PieceType.NONE) {
this.selectedPiece = b.getPiece(clickPosition);
this.selectedPiecePosition = clickPosition;
}
} else {
// Attempts to move the selected piece
try {
this.playerMove = b.getMove(selectedPiecePosition, clickPosition);
System.out.println("Made a VALID move");
} catch(InvalidMoveException ex) {
// Deselects the selected piece if move is invalid
this.selectedPiece = new NonePiece();
System.out.println("Made an INVALID move");
}
}
}
}
基本上,我希望GUIPlayer等到(playerMove!= null)将其作为移动返回。这听起来像是好设计吗?如果是这样,我该如何实现呢?
答案 0 :(得分:0)
GOT IT。
原来这是一个基本的等待通知问题。这是我的ChessPanel&#34; mouseClicked&#34;的最终代码。方法:
public void mouseClicked(MouseEvent e) {
Position clickPosition = getSquare(e.getX(), e.getY());
if(this.selectedPiece.getType() == PieceType.NONE) {
// Attempts to select the piece that was just clicked
Piece piece = b.getPiece(clickPosition);
if(piece.getType() != PieceType.NONE) {
this.selectedPiece = b.getPiece(clickPosition);
this.selectedPiecePosition = clickPosition;
}
} else {
// Attempts to move the selected piece
try {
this.playerMove = b.getMove(selectedPiecePosition, clickPosition);
synchronized(this) {
this.notify();
}
} catch(InvalidMoveException ex) {
}
this.selectedPiece = new NonePiece();
this.selectedPiecePosition = new Position(0, 0);
updateCurrentHover(e.getX(), e.getY());
}
repaint();
}
对于GUI本身:
while(cp.getMove() == null) {
try {
synchronized(cp) {
cp.wait();
}
} catch (InterruptedException e) {}
}
这解决了它。