游戏与界面
转载请保留作者信息:
作者:88250
Blog:http:/blog.csdn.net/DL88250
MSN & Gmail & QQ:DL88250@gmail.com
有了以上的基础,我们加个游戏管理与界面就可以进行游戏了!呵呵~
/*
* @(#)ChineseChessGUIView.java
* Author: 88250 <DL88250@gmail.com>, http://blog.csdn.net/DL88250
* Created on May 26, 2008, 3:52:51 PM
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Library General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
package cn.edu.ynu.sei.chinesechess.ui;
import org.jdesktop.application.Action;
import org.jdesktop.application.ResourceMap;
import org.jdesktop.application.SingleFrameApplication;
import org.jdesktop.application.FrameView;
import org.jdesktop.application.TaskMonitor;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.Timer;
import javax.swing.Icon;
import javax.swing.JDialog;
import javax.swing.JFrame;
/**
* Chinese chess application's main frame view.
* @author 88250 <DL88250@gmail.com>, http://blog.csdn.net/DL88250
* @version 1.0.1.4, Jun 4, 2008
*/
public class ChineseChessGUIView extends FrameView {
/**
* Constructor with parameter.
* @param app single frame application
*/
public ChineseChessGUIView(SingleFrameApplication app) {
super(app);
initComponents();
// status bar initialization - message timeout, idle icon and busy animation, etc
ResourceMap resourceMap = getResourceMap();
int messageTimeout = resourceMap.getInteger("StatusBar.messageTimeout");
messageTimer = new Timer(messageTimeout, new ActionListener() {
public void actionPerformed(ActionEvent e) {
statusMessageLabel.setText("");
System.out.println("!");
}
});
messageTimer.setRepeats(false);
int busyAnimationRate = resourceMap.getInteger("StatusBar.busyAnimationRate");
for (int i = 0; i < busyIcons.length; i++) {
busyIcons[i] = resourceMap.getIcon("StatusBar.busyIcons[" + i + "]");
}
busyIconTimer = new Timer(busyAnimationRate, new ActionListener() {
public void actionPerformed(ActionEvent e) {
busyIconIndex = (busyIconIndex + 1) % busyIcons.length;
statusAnimationLabel.setIcon(busyIcons[busyIconIndex]);
}
});
idleIcon = resourceMap.getIcon("StatusBar.idleIcon");
statusAnimationLabel.setIcon(idleIcon);
progressBar.setVisible(false);
// connecting action tasks to status bar via TaskMonitor
TaskMonitor taskMonitor = new TaskMonitor(getApplication().getContext());
taskMonitor.addPropertyChangeListener(new java.beans.PropertyChangeListener() {
public void propertyChange(
java.beans.PropertyChangeEvent evt) {
String propertyName = evt.getPropertyName();
if ("started".equals(propertyName)) {
if (!busyIconTimer.isRunning()) {
statusAnimationLabel.setIcon(
busyIcons[0]);
busyIconIndex = 0;
busyIconTimer.start();
}
progressBar.setVisible(true);
progressBar.setIndeterminate(true);
} else if ("done".equals(propertyName)) {
busyIconTimer.stop();
statusAnimationLabel.setIcon(idleIcon);
progressBar.setVisible(false);
progressBar.setValue(0);
} else if ("message".equals(propertyName)) {
String text =
(String) (evt.getNewValue());
statusMessageLabel.setText((text == null)
? "" : text);
messageTimer.restart();
} else if ("progress".equals(propertyName)) {
int value =
(Integer) (evt.getNewValue());
progressBar.setVisible(true);
progressBar.setIndeterminate(false);
progressBar.setValue(value);
}
}
});
}
@Action
public void showAboutBox() {
if (aboutBox == null) {
JFrame mainFrame = ChineseChessGUIApp.getApplication().getMainFrame();
aboutBox = new ChineseChessGUIAboutBox(mainFrame);
aboutBox.setLocationRelativeTo(mainFrame);
}
ChineseChessGUIApp.getApplication().show(aboutBox);
}
/** This method is called from within the constructor to
* initialize the form.
* WARNING: Do NOT modify this code. The content of this method is
* always regenerated by the Form Editor.
*/
@SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">
private void initComponents() {
mainPanel = new javax.swing.JPanel();
chessboardPanel = new ChessBoardPanel();
jScrollPane1 = new javax.swing.JScrollPane();
HumanOutput = new javax.swing.JTextArea();
jScrollPane2 = new javax.swing.JScrollPane();
ComputerOutput = new javax.swing.JTextArea();
unMoveBtn = new javax.swing.JButton();
menuBar = new javax.swing.JMenuBar();
javax.swing.JMenu fileMenu = new javax.swing.JMenu();
newItem = new javax.swing.JMenuItem();
javax.swing.JMenuItem exitMenuItem = new javax.swing.JMenuItem();
javax.swing.JMenu helpMenu = new javax.swing.JMenu();
javax.swing.JMenuItem aboutMenuItem = new javax.swing.JMenuItem();
statusPanel = new javax.swing.JPanel();
javax.swing.JSeparator statusPanelSeparator = new javax.swing.JSeparator();
statusMessageLabel = new javax.swing.JLabel();
statusAnimationLabel = new javax.swing.JLabel();
progressBar = new javax.swing.JProgressBar();
mainPanel.setName("mainPanel"); // NOI18N
chessboardPanel.setName("chessboardPanel"); // NOI18N
javax.swing.GroupLayout chessboardPanelLayout = new javax.swing.GroupLayout(chessboardPanel);
chessboardPanel.setLayout(chessboardPanelLayout);
chessboardPanelLayout.setHorizontalGroup(
chessboardPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGap(0, 305, Short.MAX_VALUE)
);
chessboardPanelLayout.setVerticalGroup(
chessboardPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGap(0, 219, Short.MAX_VALUE)
);
jScrollPane1.setName("jScrollPane1"); // NOI18N
HumanOutput.setColumns(20);
HumanOutput.setRows(5);
HumanOutput.setName("HumanOutput"); // NOI18N
jScrollPane1.setViewportView(HumanOutput);
jScrollPane2.setName("jScrollPane2"); // NOI18N
ComputerOutput.setColumns(20);
ComputerOutput.setRows(5);
ComputerOutput.setName("ComputerOutput"); // NOI18N
jScrollPane2.setViewportView(ComputerOutput);
org.jdesktop.application.ResourceMap resourceMap = org.jdesktop.application.Application.getInstance(cn.edu.ynu.sei.chinesechess.ui.ChineseChessGUIApp.class).getContext().getResourceMap(ChineseChessGUIView.class);
unMoveBtn.setText(resourceMap.getString("unMoveBtn.text")); // NOI18N
unMoveBtn.setEnabled(false);
unMoveBtn.setName("unMoveBtn"); // NOI18N
unMoveBtn.addMouseListener(new java.awt.event.MouseAdapter() {
public void mousePressed(java.awt.event.MouseEvent evt) {
unMoveBtnMousePressed(evt);
}
});
javax.swing.GroupLayout mainPanelLayout = new javax.swing.GroupLayout(mainPanel);
mainPanel.setLayout(mainPanelLayout);
mainPanelLayout.setHorizontalGroup(
mainPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(mainPanelLayout.createSequentialGroup()
.addComponent(chessboardPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGap(160, 160, 160)
.addGroup(mainPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 164, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(jScrollPane2, javax.swing.GroupLayout.PREFERRED_SIZE, 164, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(unMoveBtn))
.addGap(384, 384, 384))
);
mainPanelLayout.setVerticalGroup(
mainPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(mainPanelLayout.createSequentialGroup()
.addGroup(mainPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(chessboardPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGroup(mainPanelLayout.createSequentialGroup()
.addContainerGap()
.addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGap(21, 21, 21)
.addComponent(jScrollPane2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGap(27, 27, 27)
.addComponent(unMoveBtn)))
.addContainerGap(205, Short.MAX_VALUE))
);
menuBar.setName("menuBar"); // NOI18N
fileMenu.setText(resourceMap.getString("fileMenu.text")); // NOI18N
fileMenu.setName("fileMenu"); // NOI18N
newItem.setText(resourceMap.getString("newItem.text")); // NOI18N
newItem.setName("newItem"); // NOI18N
newItem.addMouseListener(new java.awt.event.MouseAdapter() {
public void mousePressed(java.awt.event.MouseEvent evt) {
newItemMousePressed(evt);
}
});
fileMenu.add(newItem);
javax.swing.ActionMap actionMap = org.jdesktop.application.Application.getInstance(cn.edu.ynu.sei.chinesechess.ui.ChineseChessGUIApp.class).getContext().getActionMap(ChineseChessGUIView.class, this);
exitMenuItem.setAction(actionMap.get("quit")); // NOI18N
exitMenuItem.setName("exitMenuItem"); // NOI18N
fileMenu.add(exitMenuItem);
menuBar.add(fileMenu);
helpMenu.setText(resourceMap.getString("helpMenu.text")); // NOI18N
helpMenu.setName("helpMenu"); // NOI18N
aboutMenuItem.setAction(actionMap.get("showAboutBox")); // NOI18N
aboutMenuItem.setName("aboutMenuItem"); // NOI18N
helpMenu.add(aboutMenuItem);
menuBar.add(helpMenu);
statusPanel.setName("statusPanel"); // NOI18N
statusPanelSeparator.setName("statusPanelSeparator"); // NOI18N
statusMessageLabel.setName("statusMessageLabel"); // NOI18N
statusAnimationLabel.setHorizontalAlignment(javax.swing.SwingConstants.LEFT);
statusAnimationLabel.setName("statusAnimationLabel"); // NOI18N
progressBar.setName("progressBar"); // NOI18N
javax.swing.GroupLayout statusPanelLayout = new javax.swing.GroupLayout(statusPanel);
statusPanel.setLayout(statusPanelLayout);
statusPanelLayout.setHorizontalGroup(
statusPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(statusPanelSeparator, javax.swing.GroupLayout.DEFAULT_SIZE, 1013, Short.MAX_VALUE)
.addGroup(statusPanelLayout.createSequentialGroup()
.addContainerGap()
.addComponent(statusMessageLabel)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 829, Short.MAX_VALUE)
.addComponent(progressBar, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(statusAnimationLabel)
.addContainerGap())
);
statusPanelLayout.setVerticalGroup(
statusPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(statusPanelLayout.createSequentialGroup()
.addComponent(statusPanelSeparator, javax.swing.GroupLayout.PREFERRED_SIZE, 2, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addGroup(statusPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(statusMessageLabel)
.addComponent(statusAnimationLabel)
.addComponent(progressBar, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
.addGap(3, 3, 3))
);
setComponent(mainPanel);
setMenuBar(menuBar);
setStatusBar(statusPanel);
}// </editor-fold>
public static boolean isUnmoved = false;
private void unMoveBtnMousePressed(java.awt.event.MouseEvent evt) {
((ChessBoardPanel) chessboardPanel).gameManager.unMove();
isUnmoved = true;
}
private void newItemMousePressed(java.awt.event.MouseEvent evt) {
((ChessBoardPanel) chessboardPanel).reset();
}
// Variables declaration - do not modify
public static javax.swing.JTextArea ComputerOutput;
public static javax.swing.JTextArea HumanOutput;
private javax.swing.JPanel chessboardPanel;
private javax.swing.JScrollPane jScrollPane1;
private javax.swing.JScrollPane jScrollPane2;
private javax.swing.JPanel mainPanel;
private javax.swing.JMenuBar menuBar;
private javax.swing.JMenuItem newItem;
private javax.swing.JProgressBar progressBar;
private javax.swing.JLabel statusAnimationLabel;
private javax.swing.JLabel statusMessageLabel;
private javax.swing.JPanel statusPanel;
public static javax.swing.JButton unMoveBtn;
// End of variables declaration
private final Timer messageTimer;
private final Timer busyIconTimer;
private final Icon idleIcon;
private final Icon[] busyIcons = new Icon[15];
private int busyIconIndex = 0;
private JDialog aboutBox;
}
/*
* @(#)ChineseChessGUIAboutBox.java
* Author: 88250 <DL88250@gmail.com>, http://blog.csdn.net/DL88250
* Created on May 26, 2008, 2:52 PM
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Library General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
package cn.edu.ynu.sei.chinesechess.ui;
import cn.edu.ynu.sei.chinesechess.game.ComputerPlayer;
import cn.edu.ynu.sei.chinesechess.game.GameManager;
import cn.edu.ynu.sei.chinesechess.ui.util.LocationDeterminator;
import cn.edu.ynu.sei.chinesechess.ui.util.UIResourcesHolder;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Point;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JPanel;
/**
* Chinese chessboard panel.
* @author 88250 <DL88250@gmail.com>, http://blog.csdn.net/DL88250
* @version 1.0.1.2, Jun 4, 2008
*/
public class ChessBoardPanel extends JPanel {
private static final long serialVersionUID = 1L;
/**
* Resources holder
*/
UIResourcesHolder resHolder = UIResourcesHolder.getInstance();
/**
* chessboard' image
*/
Image chessboardImg = resHolder.getChessBoardImage();
/**
* Size of a chessman's image
*/
public static final int SIZE_CHESSMAN = 40;
/**
* game manager
*/
public GameManager gameManager;
/**
* computer player, only has a little AI :-)
*/
private ComputerPlayer computerPlayer;
// from/to location in human's turn
private Point from, to;
/** Creates new form ChessBoardPanel */
public ChessBoardPanel() {
mouseEventHandle();
gameManager = new GameManager(this);
computerPlayer = new ComputerPlayer(gameManager);
}
/**
* Rests the whole chessboard, and restarts the game.
*/
public void reset() {
gameManager.restartGame();
ChineseChessGUIView.unMoveBtn.setEnabled(false);
}
/**
* Hanlds mouse event.
*/
private void mouseEventHandle() {
MouseAdapter mouseAdpater = new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
super.mouseClicked(e);
Point crossing = LocationDeterminator.belongCrossing(e.getPoint());
if (gameManager.isRedGo) {
if (from != null) {
// get destintion
to = crossing;
gameManager.moveMotion(from, to);
from = to = null;
new Thread(computerPlayer).start();
} else if (gameManager.isRedChessman(crossing)) {
// get from location
from = crossing;
ChineseChessGUIView.HumanOutput.setText("From : " +
from.x + ", " + from.y);
}
}
}
};
addMouseListener(mouseAdpater);
}
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
int imgWidth = chessboardImg.getWidth(null);
int imgHeight = chessboardImg.getHeight(null);
this.setBounds(0, 0, imgWidth, imgHeight);
g.drawImage(chessboardImg, 0, 0, null);
}
}
/*
* @(#)Chessman.java
* Author: 88250 <DL88250@gmail.com>, http://blog.csdn.net/DL88250
* Created on May 26, 2008, 3:43:48 PM
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Library General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
package cn.edu.ynu.sei.chinesechess.game;
import cn.edu.ynu.sei.chinesechess.ui.ChessBoardPanel;
import cn.edu.ynu.sei.chinesechess.ui.util.LocationDeterminator;
import cn.edu.ynu.sei.chinesechess.ui.util.UIResourcesHolder;
import java.awt.Image;
import java.awt.Point;
import javax.swing.ImageIcon;
import javax.swing.JLabel;
/**
* Canvas for paint chessmans.
* @author 88250 <DL88250@gmail.com>, http://blog.csdn.net/DL88250
* @version 1.0.0.1, Jun 4, 2008
*/
public class Chessman extends JLabel {
private static final long serialVersionUID = 1L;
/**
* Resources holder
*/
UIResourcesHolder resHolder = UIResourcesHolder.getInstance();
/**
* this label's location
*/
Point location;
/**
* label's image
*/
Image chessmanImg;
/**
* Constructor with parameters.
* @param x x coordinate of this chessman in chessboard
* @param y y coordinate of this chessman in chessboard
*/
public Chessman(int x, int y) {
location = LocationDeterminator.getRealLocation(new Point(x, y));
this.setBounds(location.x, location.y,
ChessBoardPanel.SIZE_CHESSMAN,
ChessBoardPanel.SIZE_CHESSMAN);
chessmanImg = resHolder.getChessmanImage(x, y);
if (chessmanImg != null) {
this.setIcon(new ImageIcon(chessmanImg));
}
}
/**
* Moves this chessman to a new location.
* @param destinate the specified destination
*/
public void move(Point destinate) {
location = LocationDeterminator.getRealLocation(destinate);
setLocation(location);
}
}
/*
* @(#)ComputerPlayer.java
* Author: 88250 <DL88250@gmail.com>, http://blog.csdn.net/DL88250
* Created on May 23, 2008, 12:02:50 PM
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Library General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
package cn.edu.ynu.sei.chinesechess.game;
import cn.edu.ynu.sei.chinesechess.infrastructure.search.SearchEngine;
import java.awt.Point;
/**
* Computer player.
* @author 88250 <DL88250@gmail.com>, http://blog.csdn.net/DL88250
* @version 1.0.0.4, Jun 7, 2008
*/
public class ComputerPlayer implements Runnable {
/**
* game manager
*/
private GameManager gameManager;
/**
* game tree search engine
*/
private SearchEngine searchEngine;
/**
* Constructor with parameters.
* @param gameManager game manager
*/
public ComputerPlayer(GameManager gameManager) {
this.gameManager = gameManager;
searchEngine = new SearchEngine(gameManager.situation);
SearchEngine.SEARCH_DEPTH = 6;
}
/**
* Using search algorithm to find a best move and make move.
*/
private void doBestMotion() {
if (!gameManager.isRedGo) {
long startTime = System.nanoTime();
if (!searchEngine.bookSearch()) {
int value = searchEngine.findTheBestMove(gameManager.situation.chessboard);
if (value == -SearchEngine.WIN) {
// TODO game is over
System.out.println("You win!");
}
}
gameManager.moveMotion(new Point(searchEngine.bestMotion.fromX,
searchEngine.bestMotion.fromY),
new Point(searchEngine.bestMotion.toX,
searchEngine.bestMotion.toY));
long estimatedTime = System.nanoTime() - startTime;
System.out.println("Elapsed Time: " + estimatedTime / 1000000000.0 + "s");
}
}
@Override
public void run() {
doBestMotion();
}
}
/*
* @(#)GameManager.java
* Author: 88250 <DL88250@gmail.com>, http://blog.csdn.net/DL88250
* Created on Jun 2, 2008, 5:30:47 PM
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Library General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
package cn.edu.ynu.sei.chinesechess.game;
import cn.edu.ynu.sei.chinesechess.infrastructure.common.Situation;
import cn.edu.ynu.sei.chinesechess.infrastructure.search.TranspositionTable;
import cn.edu.ynu.sei.chinesechess.ui.ChessBoardPanel;
import cn.edu.ynu.sei.chinesechess.ui.ChineseChessGUIView;
import cn.edu.ynu.sei.chinesechess.ui.util.UIResourcesHolder;
import java.awt.Point;
import java.util.Stack;
/**
* Chinese chess game manager. A game at least contains two players,
* a set of chessboard, a chessboard and so on.
* @author 88250 <DL88250@gmail.com>, http://blog.csdn.net/DL88250
* @version 1.0.0.1, Jun 4, 2008
*/
public class GameManager {
/**
* to user interface, all coordinates from (1, 1),
* left-bottom corner(1, 1), right-top corner(9, 10)
*/
public Chessman[][] chessboard = new Chessman[9][10];
/**
* is red side's trun?
*/
public boolean isRedGo;
/**
* infrastructure control
*/
Situation situation = new Situation();
/**
* holds history motions
*/
public static Stack<LatestMove> latestMotions = new Stack<LatestMove>();
private ChessBoardPanel boardPanel;
private UIResourcesHolder resHolder = UIResourcesHolder.getInstance();
/**
* Restarts the game.
*/
public void restartGame() {
latestMotions.clear();
situation.init();
isRedGo = situation.isRedGo;
boardPanel.removeAll();
for (int i = 0; i < 9; i++) {
for (int j = 0; j < 10; j++) {
int who = situation.chessboard[i][j];
if (who != 0) {
chessboard[i][j] = new Chessman(i, j);
boardPanel.add(chessboard[i][j]);
}
}
}
boardPanel.updateUI();
}
/**
* Undo the leaste motion.
*/
synchronized public void unMove() {
// unmove infrastructure chessman
if (!latestMotions.isEmpty()) {
situation.unMove();
LatestMove latestMotion = latestMotions.pop();
// recovery move
chessboard[latestMotion.from.x][latestMotion.from.y] = latestMotion.chessman;
chessboard[latestMotion.to.x][latestMotion.to.y].move(latestMotion.from);
// recovery eaten
chessboard[latestMotion.to.x][latestMotion.to.y] = latestMotion.latestBeEaten;
if (chessboard[latestMotion.to.x][latestMotion.to.y] != null) {
boardPanel.add(chessboard[latestMotion.to.x][latestMotion.to.y]);
}
// recovery who's go
isRedGo = latestMotion.isRedGo;
}
setUnMoveButtonStatus();
}
/**
* Move a chessman to desination.
* @param from location of chessman
* @param to destination of chessman
*/
synchronized public void moveMotion(Point from, Point to) {
// move infrastructure chessman
int moveStatus = situation.makeMove(from.x, from.y, to.x, to.y);
TranspositionTable.moveHash(from.x, from.y, to.x, to.y,
situation.chessboard);
if (moveStatus != -100) {
// move successfully, changes the GUI display
ChineseChessGUIView.ComputerOutput.setText("From : " +
from.x + ", " + from.y +
"/nTo : " +
to.x + ", " + to.y);
Chessman chessman = chessboard[from.x][from.y];
Chessman latestBeEaten = chessboard[to.x][to.y];
latestMotions.push(new LatestMove(chessman, from, to,
latestBeEaten,
isRedGo));
resHolder.getAudioPa().play();
if (moveStatus != 0) {
// eat move
boardPanel.remove(chessboard[to.x][to.y]);
chessboard[to.x][to.y] = null;
resHolder.getAudioPata().play();
}
chessboard[from.x][from.y].move(to);
chessboard[to.x][to.y] = chessboard[from.x][from.y];
chessboard[from.x][from.y] = null;
isRedGo = situation.isRedGo;
}
setUnMoveButtonStatus();
}
/**
* The specified location has a red chessman?
* @param location the specified location
* @return if there is red chessman, returns <code>true</code>,
* otherwise, returns <code>false</code>
*/
public boolean isRedChessman(Point location) {
return Situation.isRed(situation.chessboard[location.x][location.y]);
}
private void setUnMoveButtonStatus() {
if (!GameManager.latestMotions.isEmpty()) {
ChineseChessGUIView.unMoveBtn.setEnabled(true);
} else {
ChineseChessGUIView.unMoveBtn.setEnabled(false);
}
}
/**
* Default constructor with parameter.
* @param boardPanel chessboard panel
*/
public GameManager(ChessBoardPanel boardPanel) {
this.boardPanel = boardPanel;
restartGame();
}
}
可以把代码贴到带Javadoc查看的IDE里看一下,那样比较清晰 : )
最终的效果如下:
完整工程下载地址:http://download.csdn.net/source/528837