📄 chessgame.java
字号:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.lang.*;
import java.io.*;
import java.net.*;
enum ChessMan
{
Black, White, Empty
}
enum GameType
{
LocalGame, ComputerGame, NetGame
}
enum GameStatus
{
NotReady, IsReady, Running, Over
}
/**
* @author JiangLei
*
* this class maintains the main components of the game
*
*/
class ChessGame
{
private static final long serialVersionUID = 1L;
//define the map size
static public final int mapSize = 15;
//two dimension array stores the board information
public ChessMan[][] chessMap = new ChessMan[mapSize][mapSize];
//player information
Player playerA;
Player playerB;
Player notLocalPlayer;
Player activePlayer = playerA;
//the game panel
ChessPad cpad = new ChessPad(this);
//the player status panel
PlayerStatusPanel playerPanelA;
PlayerStatusPanel playerPanelB;
//specify whether it's a local game, or a Human Vs. Computer or net game
GameType gameType;
//number of chess left in the board
int chessLeft = mapSize * mapSize;
//total time for the game
int totalTime;
//specify whether the game is ready or running or over
GameStatus status = GameStatus.NotReady;
//some additional elements for a net game
Thread netChessThread;
Socket sock;
Socket chatSock;
//thread for a computer game
Thread AIThread;
/**
*
* @param p1 specify the player with black chessman
* @param p2 specify the player with white chessman
* @param localPlayer specify the player who is in front of this computer
* @param totalTime the total time set up for the game
* @param gType specify which kind of game it is expected to be
*/
ChessGame(Player p1, Player p2, Player localPlayer, int totalTime, GameType gType)
{
playerA = p1;
playerB = p2;
playerPanelA = new PlayerStatusPanel(playerA, totalTime, this);
playerPanelB = new PlayerStatusPanel(playerB, totalTime, this);
playerA.playerPanel = playerPanelA;
playerB.playerPanel = playerPanelB;
gameType = gType;
this.totalTime = totalTime;
//empty the chess board
for(int i = 0; i < mapSize; i++)
for(int j = 0; j < mapSize; j++)
chessMap[i][j] = ChessMan.Empty;
cpad.listeningPlayer = localPlayer;
notLocalPlayer = (localPlayer == playerA)?playerB:playerA;
}
/**
* startGame() start a new game
*
*/
void startGame()
{
//empty the board
for(int i = 0; i < mapSize; i++)
for(int j = 0; j < mapSize; j++)
chessMap[i][j] = ChessMan.Empty;
//set up status
status = GameStatus.Running;
//set up player
activePlayer = playerA;
if(gameType == GameType.LocalGame)
cpad.listeningPlayer = playerA;
//reset the game time
playerPanelA.timeLeftInSeconds = this.totalTime;
playerPanelB.timeLeftInSeconds = this.totalTime;
//refresh the frame
MainFrame.mainFrame.repaint();
//start count time
playerPanelA.chessTimer.start();
//if not a local game, start the additional thread
if(gameType == GameType.NetGame)
{
netChessThread = new NetChessThread(this);
netChessThread.start();
}
else if(gameType == GameType.ComputerGame)
{
AIThread = new AIThread(this);
AIThread.start();
}
}
/**
* this method simulates the play game process, it put a chess of the active player on board,
* and then judge if the player wins or there're no space left, else it'll automatically
* switch to the other player
*
* @param x the x position of the chess
* @param y the y position of the chess
*/
void playChess(int x, int y)
{
this.chessMap[x][y] = this.activePlayer.chessMan;
this.cpad.repaint();
if(ChessGame.judge(x, y, this.chessMap))
{
gameOver();
//System.out.println(this.listeningPlayer.playerName + " wins!");
String s = this.activePlayer.playerName + "获胜!";
GameResultDialog d = new GameResultDialog(MainFrame.mainFrame, 100, 100, s);
d.setVisible(true);
}
else if(--chessLeft == 0)
{
gameOver();
//System.out.println("Nobody wins!");
String s = "双方平局";
GameResultDialog d = new GameResultDialog(MainFrame.mainFrame, 100, 100, s);
d.setVisible(true);
}
else
{
activePlayer.playerPanel.chessTimer.stop();
activePlayer = (activePlayer == playerA)?playerB:playerA;
activePlayer.playerPanel.chessTimer.start();
}
return;
}
/**
* this method test if the latest chess will contribute to a FIVE
*
* @param x the x position of the chess
* @param y the y position of the chess
* @return whether there is a FIVE
*/
static boolean judge(int x, int y, ChessMan[][] chessMap)
{
int ax = x;
int ay = y;
int count = 0;
//analysis the horizontal line
while(ax < mapSize && chessMap[ax][ay] == chessMap[x][y]){
count++;
ax++;
}
ax=x;
count--;
while(ax >= 0 && chessMap[ax][ay] == chessMap[x][y]){
count++;
ax--;
}
if(count > 4){
return true;
}
//analysis the vertical line
ax=x;
count=0;
while(ay < mapSize && chessMap[ax][ay] == chessMap[x][y]){
count++;
ay++;
}
ay=y;
count--;
while(ay >= 0 && chessMap[ax][ay] == chessMap[x][y]){
count++;
ay--;
}
if(count>4) {
return true;
}
//analysis the south east line
ax=x;
ay=y;
count=0;
while(ax >= 0 && ay >= 0 && chessMap[ax][ay] == chessMap[x][y]){
count++;
ay--;
ax--;
}
ay=y;
ax=x;
count--;
while(ax < mapSize && ay < mapSize && chessMap[ax][ay] == chessMap[x][y]){
count++;
ay++;
ax++;
}
if(count>4) {
return true;
}
//analysis the south west line
ax=x;
ay=y;
count=0;
while(ay < mapSize && ax >= 0 && chessMap[ax][ay] == chessMap[x][y]){
count++;
ay++;
ax--;
}
ay=y;
ax=x;
count--;
while(ay > 0 && ax < mapSize && chessMap[ax][ay] == chessMap[x][y]){
count++;
ay--;
ax++;
}
if(count>4){
return true;
}
return false;
}
/**
* set game over
*/
void gameOver()
{
status = GameStatus.Over;
}
}
/**
*
* @author JiangLei
* this class records the information about the player
*
*/
class Player{
public String playerName;
public ChessMan chessMan;
public PlayerStatusPanel playerPanel;
Player(String name, ChessMan chessMan){
playerName = name;
this.chessMan = chessMan;
}
}
/**
*
* this class draws the game board and process player's interaction with it
*
*/
class ChessPad extends JPanel implements MouseListener
{
private static final long serialVersionUID = 1L;
//game on this board
ChessGame game;
//the layout parameter of the board
public final int locationX = 20;
public final int locationY = 20;
public final int width = 30;
public final int sizeX;
public final int sizeY;
public int chessManRadius = 12;
//the player who will interact with the board
Player listeningPlayer;
ChessPad(ChessGame g)
{
this.game = g;
//set the appearance of the board
this.setBackground(Color.orange);
sizeX = (game.mapSize - 1) * width + 2 * locationX;
sizeY = (game.mapSize - 1) * width + 2 * locationY;
this.setSize(sizeX, sizeY);
addMouseListener(this);
}
/**
*
* @param g the graphics handler
* @param i the x position of the chess
* @param j the y position of the chess
*/
private void drawChessMan(Graphics g, int i,int j)
{
//x,y: the coordinates on panel
int x = i * width + locationX;
int y = j * width + locationY;
if(game.chessMap[i][j] == ChessMan.Black)
{
//draw the outline
g.setColor(Color.gray);
g.drawOval(x - chessManRadius,y - chessManRadius,chessManRadius * 2, chessManRadius * 2);
//fill the center
g.setColor(Color.BLACK);
g.fillOval(x - chessManRadius,y - chessManRadius,chessManRadius * 2, chessManRadius * 2);
}
else if(game.chessMap[i][j] == ChessMan.White)
{
//draw the outline
g.setColor(Color.gray);
g.drawOval(x - chessManRadius,y - chessManRadius,chessManRadius * 2, chessManRadius * 2);
//fill the center
g.setColor(Color.white);
g.fillOval(x - chessManRadius,y - chessManRadius,chessManRadius * 2, chessManRadius * 2);
}
}
public void paint(Graphics g)
{
super.paint(g);
//draw the grid
for (int i = 0; i < game.mapSize; i++)
{
g.drawLine(locationX, locationY + width * i, locationX + width * (game.mapSize - 1), locationY + width * i);
g.drawLine(locationX + width * i, locationY, locationX + width * i, locationY + width * (game.mapSize - 1));
}
//draw the chess
for(int i = 0; i < game.mapSize; i++)
{
for(int j = 0;j < game.mapSize; j++)
{
drawChessMan(g,i,j);
}
}
//System.out.println("Paint() finished!");
}
public void mousePressed(MouseEvent e)
{
//System.out.println("Mouse Pressed!");
if(game.status != GameStatus.Running)
return;
if(listeningPlayer == game.activePlayer)
{
//x, y: the position on board when mouse is pressed
int x = Math.round((float)(e.getX() - locationX) / (float)width);
int y = Math.round((float)(e.getY() - locationY) / (float)width);
//if all conditions permits
if(x >= 0 && x < game.mapSize && y >= 0 && y < game.mapSize && game.activePlayer == this.listeningPlayer && game.chessMap[x][y] == ChessMan.Empty)
{
//System.out.println("x:" + x + " " + "y:" + y);
game.playChess(x, y);
if(game.gameType == GameType.LocalGame)
{
//switch player
listeningPlayer = game.activePlayer;
}
else if(game.gameType == GameType.NetGame)
{
//send the chess information to the other player
try{
game.sock.getOutputStream().write(x);
game.sock.getOutputStream().write(y);
System.out.println("Write stream finished!");
}
catch(IOException ex)
{
System.out.println("Write Error!");
}
}
else if(game.gameType == GameType.ComputerGame)
{
game.AIThread.resume();
}
}
}
}
public void mouseReleased(MouseEvent e){}
public void mouseEntered(MouseEvent e){}
public void mouseExited(MouseEvent e){}
public void mouseClicked(MouseEvent e){}
}
/**
*
* this class draws the player status panel
*
*/
class PlayerStatusPanel extends JPanel
{
private static final long serialVersionUID = 1L;
//the appearance parameter
static final int width = 200;
static final int height = 80;
static final int chessManPosX = 20;
static final int chessManPosY = 30;
//player on this panel
Player player;
//label which shows the time left
JLabel timeLabel;
public int timeLeftInSeconds;
Timer chessTimer;
ChessGame game;
PlayerStatusPanel(Player pl, int seconds, ChessGame g)
{
this.player = pl;
this.game = g;
this.timeLeftInSeconds = seconds;
//set the layout of this panel
this.setBackground(Color.yellow);
this.setSize(PlayerStatusPanel.width, PlayerStatusPanel.height);
setLayout(new BorderLayout());
JLabel nameLb = new JLabel("玩家名称:" + player.playerName);
JPanel p = new JPanel();
p.setBackground(Color.yellow);
p.setLayout(new GridLayout(2, 1));
p.add(nameLb);
p.setSize(width - 2 * chessManPosX, height);
timeLabel = new JLabel("所剩时间:" + seconds/60 + ":" + seconds%60);
p.add(timeLabel);
add("East", p);
//add Timer
chessTimer = new Timer(1000, new ActionListener(){
public void actionPerformed(ActionEvent e)
{
if(game.status != GameStatus.Running)
chessTimer.stop();
timeLeftInSeconds--;
timeLabel.setText("所剩时间:" + timeLeftInSeconds/60 + ":" + timeLeftInSeconds%60);
if(timeLeftInSeconds == 0)
{ //超时判负
game.gameOver();
String s = player.playerName + "超时判负";
GameResultDialog d = new GameResultDialog(MainFrame.mainFrame, 100, 100, s);
d.setVisible(true);
}
}
});
}
/**
* this method paint this panel
*
*/
public void paint(Graphics g)
{
super.paint(g);
//refresh the label
timeLabel.setText("所剩时间:" + timeLeftInSeconds/60 + ":" + timeLeftInSeconds%60);
//paint the chess indicates the side
g.setColor(Color.gray);
g.drawOval(chessManPosX, chessManPosY, game.cpad.chessManRadius * 2, game.cpad.chessManRadius * 2);
if(player.chessMan == ChessMan.Black)
{
g.setColor(Color.BLACK);
}
else
{
g.setColor(Color.white);
}
g.fillOval(chessManPosX, chessManPosY, game.cpad.chessManRadius * 2, game.cpad.chessManRadius * 2);
}
}
/**
*
* this class is a dialog, it will show the result of the game
*
*/
class GameResultDialog extends JDialog
{
GameResultDialog(JFrame parent, int w, int h, String resultStr)
{
super(parent, "本局结果", true);
setSize(w, h);
setLocation(500, 300);
setLayout(new FlowLayout());
JLabel lb = new JLabel(resultStr);
JButton bn = new JButton("确定");
add("North", lb);
add("South", bn);
bn.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e)
{
MainFrame.mainFrame.startGameBn.setEnabled(true);
setVisible(false);
}
});
addWindowListener(new WindowAdapter()
{public void windowClosing(WindowEvent e)
{
MainFrame.mainFrame.startGameBn.setEnabled(true);
setVisible(false);
}
});
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -