(运行下面源代码中的 ClientUI.java 即可实现棋盘界面运行)
(每当黑子或者白子赢时,游戏则可结束。)
//ChessComponent.java
import java.awt.*;
// The Component interface for the composite pattern
public abstract class ChessComponent {
public abstract void setPosition(int x, int y);
public abstract int[ ] getPosition();
public abstract String showInfo();
public abstract int getColor();
}
//BlackPiece.java
import java.awt.*;
// Black Piece for Game of Go
// Used to encapsulate the data needed for a
// black chess piece: position and color
class BlackPiece extends ChessComponent {
int[] position = null;
private static final int BLACK = 1;
BlackPiece() {
position = new int[2];
}
public int[ ] getPosition(){
return position;
}
public void setPosition(int x, int y){
position[0] = x;
position[1] = y;
}
public String showInfo(){
return "This is black piece.";
}
public int getColor(){
return BLACK;
}
}
//Board.java
import java.awt.*;
import java.awt.event.*;
import javax.swing.JPanel;
import java.util.Iterator;
// Chess board for Wu Zi Qi
class Board extends JPanel implements MouseListener{
final static int BLACK = 1, WHITE = -1, R=13;
private String blackPlayer = null, whitePlayer = null;
private Composite arrPieces = new Composite();
private GChessPiece graphicPiece = null;
private ChessComponent conceptPiece = null;
int[][] whitePieces = new int[15][15];
int[][] blackPieces = new int[15][15];
boolean isGameOver = false;
public static int LENGTH = 15;
int inset=10, leftEdge, rightEdge, top, bottom;
int width, height, unit;
int x = -1, y = -1, chessColor = BLACK;
int m=0, n=0;
int count =0;
public Board(){
setSize(420,420);
width = getWidth()- 2*inset;
height = getHeight()- 2*inset;
unit = width/14;
top = inset;
bottom = height+inset;
leftEdge = inset;
rightEdge = width+inset;
setBackground(Color.orange);
addMouseListener(this);
}
// Paint the Wuzi Qi board
public void paint(Graphics g){
drawBoard(g);
drawPlayers();
}
public void mousePressed(MouseEvent e){
if(e.getModifiers()==InputEvent.BUTTON1_MASK){
if( (isGameOver == false) && (blackPlayer != null) && (whitePlayer != null) ) {
x = (int)e.getX();
y = (int)e.getY();
addPieceToBoard(x, y);
}
}
}
private void addPieceToBoard(int x, int y){
convertToGrid(x, y);
if ( x>= leftEdge-5 && x<= rightEdge+5 && y>=top-5 && y<=bottom +5) {
if(chessColor == BLACK) {
conceptPiece = new BlackPiece();
blackPieces[m][n]=1;
graphicPiece = new GChessPiece(Color.black);
}
else if(chessColor == WHITE){
conceptPiece = new WhitePiece();
whitePieces[m][n]=1;
graphicPiece = new GChessPiece(Color.white);
}
this.add(graphicPiece);
graphicPiece.setBounds(m*unit+inset-R, n*unit+inset-R, 2*R, 2*R);
conceptPiece.setPosition(x, y);
arrPieces.attach(conceptPiece); /// save to array
evaluateGame();
chessColor = chessColor*(-1);
}
}
private void convertToGrid(int x, int y){
for(int i=0; i< 15; i++){
int k=(inset+i*unit)/unit;
if( (x >=k*unit -unit/2) && (x <k*unit+ unit/2 ) )
m=k;
}
for(int j=0; j< 15; j++){
int p =(inset+j*unit)/unit;
if( (y >=p*unit -unit/2) && (y <p*unit+ unit/2 ) )
n=p;
}
}
private void evaluateGame(){
GameOperations g = new GameOperations(this);
if(chessColor == WHITE){
g.checkMatixLines(whitePieces);
g.checkLeftSlantDiagonal(whitePieces);
g.checkRightSlantDiagonal(whitePieces);
if(isGameOver == true)
anounceWinner();
}
if(chessColor == BLACK){
g.checkMatixLines(blackPieces);
g.checkLeftSlantDiagonal(blackPieces);
g.checkRightSlantDiagonal(blackPieces);
if(isGameOver == true)
anounceWinner();
}
}
// This replay method will recover the whole game step by step
// One call of this method will do only one step
public void replay(){
if(count ==0)
this.removeAll();
if (count >=0 && count < arrPieces.getSize()){
GChessPiece gBlackPiece = new GChessPiece(Color.black);
GChessPiece gWhitePiece = new GChessPiece(Color.white);
ChessComponent element = arrPieces.getElement(count);
int[] coordinates = element.getPosition();
int c = element.getColor();
int x=coordinates[0];
int y=coordinates[1];
convertToGrid(x, y);
if(c == BLACK ){
this.add(gBlackPiece);
gBlackPiece.setBounds(m*unit+inset-R, n*unit+inset-R, 2*R, 2*R);
}
else if(c == WHITE ){
this.add(gWhitePiece);
gWhitePiece.setBounds(m*unit+inset-R, n*unit+inset-R, 2*R, 2*R);
}
count++;
}
drawPlayers();
}
private void drawBoard(Graphics g){
for(int m=leftEdge; m<=rightEdge; m=m+unit) // draw ||||
g.drawLine(m, top, m, bottom-10);
for(int n=top; n<=bottom; n=n+unit) //draw -----
g.drawLine(leftEdge, n, rightEdge-10, n);
}
public void setPlayers(String blackPlayer, String whitePlayer){
this.blackPlayer = blackPlayer;
this.whitePlayer = whitePlayer;
drawPlayers();
}
private void drawPlayers() {
Graphics2D g2 = (Graphics2D)getGraphics();
g2.drawString("Black Player: "+blackPlayer, 55, bottom+20);
g2.drawString("White Player: "+whitePlayer, 250, bottom+20);
}
private void anounceWinner() {
Graphics2D g2 = (Graphics2D)getGraphics();
if(chessColor == BLACK)
g2.drawString("Black player won the game: ", 55, bottom+30);
else if(chessColor == WHITE)
g2.drawString("White player won the game: ", 250 , bottom+30);
}
public void resetGame(){
isGameOver = false;
whitePieces = new int[15][15];
blackPieces = new int[15][15];
arrPieces.removeAllElements();
count=0;
}
public void setGameOver(boolean b){
isGameOver = b;
}
public void mouseReleased(MouseEvent e){
}
public void mouseEntered(MouseEvent e){
}
public void mouseExited(MouseEvent e){
}
public void mouseClicked(MouseEvent e){
}
}
//ClientUI.java
import java.awt.event.*;
import java.awt.*;
import javax.swing.*;
public class ClientUI extends JFrame {
private JSplitPane bigSplitPane;
private JScrollPane showInfoPane;
private JPanel btnPanel;
private JLabel lblPlayers;
private JTextField txtPlayerBlack, txtPlayerWhite;
private Dimension minimumSize;
private Board board;
public static final String PLAY = "Start Game";
public static final String EXIT = "Exit";
public static final String REPLAY = "Replay";
public static final String NEXTGAME = "Next Game";
public ClientUI() {
super("Composite Pattern- Wuzi Qi ");
minimumSize = new Dimension(130, 100);
board = new Board();
setUpChoicePanel();
setUpScrollPanes();
}
private void setUpChoicePanel() {
lblPlayers = new JLabel("Enter players before Playing");
txtPlayerBlack = new JTextField("player-black");
txtPlayerWhite = new JTextField("player-white");
ButtonListener btnListener = new ButtonListener();
//Create button objects
JButton playButton = new JButton(PLAY);
JButton nextButton = new JButton(NEXTGAME);
JButton exitButton = new JButton(EXIT);
JButton replayButton = new JButton(REPLAY);
playButton.setMnemonic(KeyEvent.VK_S);
nextButton.setMnemonic(KeyEvent.VK_S);
exitButton.setMnemonic(KeyEvent.VK_X);
replayButton.setMnemonic(KeyEvent.VK_X);
playButton.addActionListener(btnListener);
exitButton.addActionListener(btnListener);
replayButton.addActionListener(btnListener);
nextButton.addActionListener(btnListener);
btnPanel = new JPanel();
btnPanel.setBackground(Color.gray);
GridBagLayout gridbag = new GridBagLayout();
btnPanel.setLayout(gridbag);
GridBagConstraints gbc = new GridBagConstraints();
btnPanel.add(lblPlayers);
btnPanel.add(txtPlayerBlack);
btnPanel.add(txtPlayerWhite);
btnPanel.add(playButton);
btnPanel.add(nextButton);
btnPanel.add(exitButton);
btnPanel.add(replayButton);
gbc.insets.top = 5;
gbc.insets.bottom = 5;
gbc.insets.left = 5;
gbc.insets.right = 5;
gbc.gridx = 0;
gbc.gridy = 1;
gridbag.setConstraints(lblPlayers, gbc);
gbc.gridx = 1;
gbc.gridy = 1;
gridbag.setConstraints(txtPlayerBlack, gbc);
gbc.gridx = 2;
gbc.gridy = 1;
gridbag.setConstraints(txtPlayerWhite, gbc);
gbc.insets.left = 2;
gbc.insets.right = 2;
gbc.insets.top = 15;
gbc.gridx = 0;
gbc.gridy = 5;
gridbag.setConstraints(playButton, gbc);
gbc.gridx = 1;
gbc.gridy = 5;
gridbag.setConstraints(nextButton, gbc);
gbc.gridx = 2;
gbc.gridy = 5;
gridbag.setConstraints(exitButton, gbc);
gbc.gridx = 3;
gbc.gridy = 5;
gridbag.setConstraints(replayButton, gbc);
}
private void setUpScrollPanes() {
showInfoPane = new JScrollPane( board);
showInfoPane.setBackground(Color.orange);
bigSplitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT, showInfoPane, btnPanel);
bigSplitPane.setDividerLocation(450);
getContentPane().add(bigSplitPane);
setSize(new Dimension(450, 600));
setVisible(true);
}
class ButtonListener implements ActionListener {
public void actionPerformed(ActionEvent ae) {
if (ae.getActionCommand().equals(EXIT)) {
System.exit(1); }
if (ae.getActionCommand().equals(PLAY)) {
String blackPlayer = txtPlayerBlack.getText();
String whitePlayer = txtPlayerWhite.getText();
if(blackPlayer.length() != 0 && whitePlayer.length() !=0){
board.setPlayers(blackPlayer, whitePlayer);
board.resetGame();
}
}
if (ae.getActionCommand().equals(NEXTGAME)) {
board.removeAll();
String blackPlayer = txtPlayerBlack.getText();
String whitePlayer = txtPlayerWhite.getText();
if(blackPlayer.length() != 0 && whitePlayer.length() !=0)
board.setPlayers(blackPlayer, whitePlayer);
board.resetGame();
}
if (ae.getActionCommand().equals(REPLAY)) {
board.replay();
}
}
}
public static void main(String args[]) {
try {
UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
} catch (Exception evt) {
}
ClientUI frame = new ClientUI();
frame.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0); }} );
frame.setSize(450, 600);
frame.setVisible(true);
}
}
//Composite.java
import java.util.ArrayList;
import java.util.Iterator;
// Chess board for Game of Go
class Composite extends ChessComponent{
private int[] position = null;
private ArrayList<ChessComponent> arrGoStone = null;
private ChessComponent currentPiece = null;
public Composite(){
arrGoStone = new ArrayList<ChessComponent>();
}
public void attach(ChessComponent piece){
if(piece != null)
arrGoStone.add(piece);
}
public void detach(ChessComponent piece){
if(piece != null)
arrGoStone.remove(piece);
}
public void removeAllElements(){
arrGoStone.clear();
}
public Iterator<ChessComponent > elements(){
return arrGoStone.iterator();
}
public ChessComponent getElement(int k){
return arrGoStone.get(k);
}
public void setPosition(int x, int y){
}
public int[ ] getPosition(){
return position;
}
public String showInfo(){
return "This is composite.";
}
public int getSize(){
return arrGoStone.size();
}
public int getColor(){
return 0;
}
}
//GameOperations.java
// This class encapsulates all the operations
// needed by the game logic. All the methods
// here are to called by the class Board
public class GameOperations{
private int LEN = Board.LENGTH;
private Board b = null;
public GameOperations(Board b){
this.b = b;
}
// Get a right slant line from a 2D integer array, 0 <= k < 29
public int[] getALeftSlantLine(int[][] intArr, int k){
int n=0;
int[] temp = new int[LEN];
for(int i=0; i<LEN; i++) {
for(int j=0; j<LEN; j++) {
if(i + j == k){
temp[n] = intArr[i][j];
} // if
} // for j ended, only assign term n of temp
n++;
} // for i ended, temp is filled with a left matrix diagonal line
return temp;
}
// Get a right slant line from a 2D integer array, k=-14 to 14 inclusive
public int[] getARightSlantLine(int[][] intArr, int k){
int n=0;
int[] temp = new int[LEN];
for(int i=0; i<LEN; i++) {
for(int j=0; j<LEN; j++) {
if(i == j+ k){
temp[n] = intArr[i][j];
} // if
} // for j ended, only assign term n of temp
n++;
} // for i ended, temp is filled with a right matrix diagonal line
return temp;
}
// Check a line to decide if a player wins or not
public void checkAline(int[] a){
int len = a.length;
for(int m=3; m< len-2; m++){
if( (a[m-2]==1)&&(a[m-1]==1)&&(a[m]==1)&&(a[m+1]==1)&&(a[m+2]==1) ){
b.setGameOver(true);
}
}
}
// Check all horizental and vertical lines of the matrix to
// see if the black player or white player wins or not
public void checkMatixLines(int[][] intArr){
for(int n=0; n<LEN; n++){
int[] b = new int[LEN];
for(int i=0; i<LEN; i++)
b[i] = intArr[i][n];
checkAline(b);
}
for(int m=0; m<LEN; m++){
int[] c = new int[LEN];
for(int j=0; j<LEN; j++)
c[j] = intArr[m][j];
checkAline(c);
}
}
// Check all left slant lines of the matrix to see if
// the black player or white player wins or not
public void checkLeftSlantDiagonal(int[][] board){
for (int k=0; k<2*LEN-1; k++) {
int[] temp = new int[LEN];
temp=getALeftSlantLine(board, k);
checkAline(temp);
}
}
// Check all right slant lines of the matrix to see if
// the black player or white player wins or not
public void checkRightSlantDiagonal(int[][] board){
for (int k=-(LEN-1); k<LEN; k++) {
int[] temp = new int[LEN];
temp=getARightSlantLine(board, k);
checkAline(temp);
}
}
}
//GChessPiece.java
import java.awt.*;
import java.awt.event.*;
import javax.swing.JOptionPane;
import java.awt.geom.Ellipse2D;
// Represents a Piece of the Wuzi Qi Game
class GChessPiece extends Canvas {
Color color = null;
Ellipse2D circle = new Ellipse2D.Double(0.0d, 0.0d, 26.0d, 26.0d);
GChessPiece(Color color) {
this.color=color;
setSize(26, 26);
}
public void paint(Graphics g) {
Graphics2D g2 = (Graphics2D)g;
g2.setColor(color);
g2.fill(circle);
}
}
//WhitePiece.java
import java.awt.*;
// White Stone of Game of Go
// Used to encapsulate the data needed for a
// white chess piece: position and color
class WhitePiece extends ChessComponent {
int[] position = new int[2];
private static final int WHITE = -1;
WhitePiece() {
position = new int[2];
}
public int[ ] getPosition(){
return position;
}
public void setPosition(int x, int y){
position[0] = x;
position[1] = y;
}
public String showInfo(){
return "This is white piece.";
}
public int getColor(){
return WHITE;
}
}