package com.zjh.game;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
/**
*
* @author sky
*
*/
public class FiveChessGame {
/**
* 控制項屬性
*/
private JFrame frame; // 五子棋遊戲的窗口框架
private GameMap map; // 五子棋遊戲的窗口容器
private JMenuBar bar; // 菜單
private JMenu game; // 菜單項
private JMenuItem[] items; // 菜單下拉項
/**
* 靜態數據屬性
*/
private static final int BOARD_SIZE = 15; // 棋盤大小(15 * 15)
private static final int ROW_WIDTH = 36; // 間距
private static final int SPACE = ROW_WIDTH / 2; // 上下邊間距
/**
* 數據屬性
*/
private boolean player; // true黑,false白
private char[][] board; // 後台虛擬棋盤
public FiveChessGame() {
player = true; // 遊戲先黑子下
board = new char[BOARD_SIZE][BOARD_SIZE]; // 建立後台虛擬棋盤
clearMap();
createGUI();
}
/**
* 對GUI控制項的創建
*/
private void createGUI() {
frame = new JFrame("五子棋"); // 實現五子棋遊戲窗口框架
bar = new JMenuBar(); // 建立菜單欄
game = new JMenu("遊戲"); // 建立名為「遊戲」的菜單
items = new JMenuItem[2]; // game菜單下創建2個子菜單項
game.add(items[0] = new JMenuItem("重新開始"));// 第一個子菜單為「重新開始」
game.add(items[1] = new JMenuItem("退出")); // 第二個子菜單為「退出」
bar.add(game);// 菜單項加入菜單欄
map = new GameMap(); // 實現五子棋遊戲窗口容器
map.setPreferredSize(new Dimension(ROW_WIDTH * (BOARD_SIZE - 1) +
SPACE* 2, ROW_WIDTH * (BOARD_SIZE - 1) + SPACE * 2));// 設置容器大小
frame.setJMenuBar(bar);
frame.add(map);
frame.pack();
frame.setLocation(1200, 200);
frame.setResizable(false);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
}
/**
* 清空棋子
*/
protected void clearMap() {
for (int i = 0; i < BOARD_SIZE; i++) {
for (int j = 0; j < BOARD_SIZE; j++) {
board[i][j] = '+';
}
}
}
/**
* 運行遊戲
*/
public void start() {
map.addMouseListener(new MouseAdapter() {
// 滑鼠點擊事件
public void mouseClicked(MouseEvent e) {
// 將用戶滑鼠事件的座標轉換成棋子數組的座標。
int xPos = (int) (e.getX() / ROW_WIDTH);
int yPos = (int) (e.getY() / ROW_WIDTH);
if (board[xPos][yPos] == '+') {// 判斷是否下過棋
board[xPos][yPos] = player ? 'b' : 'w'; // 給虛擬鍵盤賦值
map.repaint(); // 通過讀取board數組進行貼圖
if (isWin(xPos, yPos)) {// 如果有滿足勝利條件的玩家了
map.repaint(); // 刷新圖像
String str = player ? "黑方勝利" : "白方勝利";
JOptionPane.showMessageDialog(null, str, "遊戲結束",
JOptionPane.PLAIN_MESSAGE); // 彈出消息框
clearMap(); // 清空棋盤
map.repaint(); // 刷新棋盤
player = true; // 新一局繼續黑子先下
} else {
player = player ? false : true; // 切換玩家
}
}
}
});
// 點擊重新開始事件
items[0].addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
String str = "是否要重新開始遊戲?";
// 添加消息對話框
if (JOptionPane.showConfirmDialog(null, str, "重新開始",
JOptionPane.YES_NO_OPTION) == JOptionPane.YES_OPTION) {
clearMap(); // 清空棋盤
map.repaint(); // 刷新棋盤
player = true; // 玩家為黑棋
}
}
});
// 點擊退出事件
items[1].addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
String str = "是否要退出遊戲?";
// 添加消息對話框
if (JOptionPane.showConfirmDialog(null, str, "重新開始",
JOptionPane.YES_NO_OPTION) == JOptionPane.YES_OPTION) {
System.exit(0); // 退出
}
}
});
// 點關閉按鈕事件
frame.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
String str = "是否要退出遊戲?";
// 添加消息對話框
if (JOptionPane.showConfirmDialog(null, str, "退出遊戲",
JOptionPane.YES_NO_OPTION) == JOptionPane.YES_OPTION) {
System.exit(0); // 退出
}
}
});
}
/**
* 縱向找
*/
protected boolean find(int x, int y) {
int i, num = 1;
char temp = player ? 'b' : 'w';
for (i = x + 1; i < 15; i++) {// 向下找
if (board[i][y] == temp) {
num++;
if (num == 5) {
return true;
}
} else {
break;
}
}
for (i = x - 1; i >= 0; i--) {// 向上找
if (board[i][y] == temp) {
num++;
if (num == 5) {
return true;
}
} else {
break;
}
}
return false;
}
/**
* 橫向找
*/
protected boolean find2(int x, int y) {
int i, num = 1;
char temp = player ? 'b' : 'w';
for (i = y + 1; i < 15; i++) { // 向右找
if (board[x][i] == temp) {
num++;
if (num == 5) {
return true;
}
} else {
break;
}
}
for (i = y - 1; i >= 0; i--) {// 向左找
if (board[x][i] == temp) {
num++;
if (num == 5) {
return true;
}
} else {
break;
}
}
return false;
}
/**
* \方向
*/
protected boolean find3(int x, int y) {
int i, j, num = 1;
char temp = player ? 'b' : 'w';
for (i = x + 1, j = y + 1; i < 15 && j < 15; i++, j++) {// 向下方
if (board[i][j] == temp) {
num++;
if (num == 5) {
return true;
}
} else {
break;
}
}
for (i = x - 1, j = y - 1; i >= 0 && j >= 0; i--, j--) {// 向上方
if (board[i][j] == temp) {
num++;
if (num == 5) {
return true;
}
} else {
break;
}
}
return false;
}
/**
* /方向
*/
protected boolean find4(int x, int y) {
int i, j, num = 1;
char temp = player ? 'b' : 'w';
for (i = x + 1, j = y - 1; i < 15 && j >= 0; i++, j--) {// 向下
if (board[i][j] == temp) {
num++;
if (num == 5) {
return true;
}
} else {
break;
}
}
for (i = x - 1, j = y + 1; i >= 0 && j < 15; i--, j++) { // 向上
if (board[i][j] == temp) {
num++;
if (num == 5) {
return true;
}
} else {
break;
}
}
return false;
}
/**
*判斷勝負
*/
protected boolean isWin(int x, int y) {
return (find(x, y) || find2(x, y) || find3(x, y) || find4(x, y));
}
/**
* 內部容器類,用於實現圖像處理
*/
private class GameMap extends JPanel {
private static final long serialVersionUID = 16578987565248L;
public void paintComponent(Graphics g) {
super.paintComponent(g);
// 棋盤
g.setColor(new Color(200, 100, 50)); // 設為桔黃色
g.fillRect(0, 0, ROW_WIDTH * (BOARD_SIZE + 1), ROW_WIDTH
* (BOARD_SIZE + 1)); // 填充棋盤
g.setColor(Color.black); // 設為黑色
for (int i = 0; i < BOARD_SIZE; i++) {// 畫豎線
g.drawLine(SPACE + ROW_WIDTH * i, SPACE, SPACE + ROW_WIDTH * i,
SPACE + ROW_WIDTH * (BOARD_SIZE - 1));
}
for (int i = 0; i < BOARD_SIZE; i++) {// 畫橫線
g.drawLine(SPACE, SPACE + ROW_WIDTH * i, SPACE + ROW_WIDTH
* (BOARD_SIZE - 1), SPACE + ROW_WIDTH * i);
}
// 畫點
g.fillOval(SPACE + 3 * ROW_WIDTH - 3, SPACE + 3 * ROW_WIDTH - 3, 7, 7);
g.fillOval(SPACE + 11 * ROW_WIDTH - 3, SPACE + 3 * ROW_WIDTH - 3, 7, 7);
g.fillOval(SPACE + 3 * ROW_WIDTH - 3, SPACE + 11 * ROW_WIDTH - 3, 7, 7);
g.fillOval(SPACE + 7 * ROW_WIDTH - 3, SPACE + 7 * ROW_WIDTH - 3, 7, 7);
g.fillOval(SPACE + 11 * ROW_WIDTH - 3, SPACE + 11 * ROW_WIDTH - 3, 7, 7);
// 棋子
// 遍歷數組,繪製棋子。
for (int i = 0; i < BOARD_SIZE; i++) {
for (int j = 0; j < BOARD_SIZE; j++) {
if (board[i][j] == 'b') {// 繪製黑棋
g.setColor(Color.black);
g.fillOval(SPACE + i * ROW_WIDTH - ROW_WIDTH / 2, SPACE
+ j * ROW_WIDTH - ROW_WIDTH / 2, ROW_WIDTH,
ROW_WIDTH);
}
if (board[i][j] == 'w') {// 繪製白棋
g.setColor(Color.white);
g.fillOval(SPACE + i * ROW_WIDTH - ROW_WIDTH / 2, SPACE
+ j * ROW_WIDTH - ROW_WIDTH / 2, ROW_WIDTH,
ROW_WIDTH);
}
}
}
}
}
public static void main(String[] args) {
FiveChessGame game = new FiveChessGame();
game.start();
System.out.println("測試成功");
}
}
運行效果: