简单五子棋实现
基本思路:
- 编写需要公共静态变量的接口类
package com.drj.game;
import java.util.HashMap;
/**
*
* @ClassName: Goconfig
* @Description:TODO(公用的变量)
* @author: drj
* @date: 2018年9月8日 下午7:49:11
*
* @Copyright: 2018
*
*/
public interface Goconfig {
public static final String TITLE = "简单五子棋";
public static final String PC_TYPE="人机对战";
public static final String PP_TYPE = "人人对站";
public static final String START_GAME = "开始游戏";
public static final String RETURN_GO = "悔棋";
public static final String LOSER = "认输";
public static final String WHITE_WIN = "白棋胜利!";
public static final String BLACK_WIN = "黑棋胜利!";
public static final String WARING_INFO = "请点击在棋盘内";
public static final String DEUCE = "恭喜你们打成平手";
public static final int ROW=6; //棋谱行数
public static final int COLUMN = 6; //棋谱列数
public static final int SQUARE_SIZE=35; //棋谱每个方格的大小
public static final int RADIUS=12; //棋子的半径长度
public static Piece go[][]=new Piece[ROW][ROW]; //存放棋谱上棋子的颜色
public static int weightarr[][]=new int[ROW][ROW]; //存放棋子的权重,也就是权重越大 优先级越高
public static HashMap<String,Integer> map = new HashMap<String,Integer>(); //存放 白旗或是黑棋 存在的路线组合举个例子: 0 代表空位 1 白色 棋子 2 黑色棋子 010 表示 只有一个白色棋子两边都是空位 0110 代表两个棋子相连两头是空位的
}
- 搭建swing 窗体
package com.drj.game;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JPanel;
/**
*
* @ClassName: GameMain
* @Description:TODO(启动主类、初始化窗体)
* @author: drj
* @date: 2018年9月8日 下午7:48:17
* qq:3343217807
* @Copyright: 2018
*
*/
public class GameMain extends JPanel implements Goconfig {
/**
*
*/
private static final long serialVersionUID = 1L;
/**
* 存放棋子可能的组合 活一连 两头都是空位 就是活几连 有几个一起相连的就是几 活二连 眠一连 一头是对方棋子 一头是空位
*
*/
static {
map.put("01", 20);
map.put("02", 20);
map.put("010", 42);
map.put("020", 42);
map.put("011", 300);
map.put("022", 300);
map.put("0110", 400);
map.put("0220", 400);
map.put("0111", 400);
map.put("0222", 400);
map.put("01111", 3000);
map.put("02222", 3000);
map.put("01110", 3000);
map.put("02220", 3000);
map.put("011110", 10000);
map.put("022220", 10000);
map.put("012", 23);
map.put("021", 23);
map.put("0112", 200);
map.put("0221", 200);
map.put("01112", 500);
map.put("02221", 500);
map.put("022221", 3000);
map.put("011112", 3000);
}
JButton buttonStart = new JButton(START_GAME);
JButton buttonregret = new JButton(RETURN_GO);
JButton buttonlose = new JButton(LOSER);
public static void main(String[] args) {
// TODO Auto-generated method stub
GameMain main = new GameMain();
main.Init();
main.PieceInit();
main.setButton(false);
}
/**
* 初始化窗体 1窗体大小 2窗体中布局 3按钮、下拉框 4添加事件监听
*/
public void Init() {
JFrame jf = new JFrame();
jf.setTitle(TITLE);
jf.setSize(650, 580);
jf.setLocationRelativeTo(null);
jf.setResizable(true);
jf.setDefaultCloseOperation(3);
jf.setLayout(new BorderLayout());
jf.add(this);
JPanel eastp = new JPanel();
eastp.setPreferredSize(new Dimension(100, 0));
String[] itemArray = { PP_TYPE, PC_TYPE };
JComboBox<String> cbItem = new JComboBox<String>(itemArray);
buttonStart.setPreferredSize(new Dimension(90, 40));
buttonregret.setPreferredSize(new Dimension(90, 40));
buttonlose.setPreferredSize(new Dimension(90, 40));
cbItem.setPreferredSize(new Dimension(90, 40));
JPanel eastp_tmp = new JPanel();
eastp_tmp.setPreferredSize(new Dimension(90, 30));
eastp.add(eastp_tmp);
eastp.add(buttonStart);
eastp.add(buttonregret);
eastp.add(buttonlose);
eastp.add(cbItem);
jf.add(eastp, BorderLayout.EAST);
jf.setVisible(true);
GameListener cl = new GameListener(this, cbItem);
buttonStart.addActionListener(cl);
buttonregret.addActionListener(cl);
buttonlose.addActionListener(cl);
cbItem.addActionListener(cl);
}
/**
* 存放棋子的数组 开始都是空位
*/
private void PieceInit() {
for (int i = 0; i < ROW; i++) {
for (int j = 0; j < ROW; j++) {
go[i][j] = new Piece(0);
}
}
}
/**
* 画棋谱格子
*/
public void paint(Graphics g) {
super.paint(g);
for (int i = 0; i < ROW; i++) {
g.drawLine(30, 30 + i * SQUARE_SIZE, 30 + SQUARE_SIZE * (ROW - 1), 30 + i * SQUARE_SIZE);
g.drawLine(30 + i * SQUARE_SIZE, 30, 30 + i * SQUARE_SIZE, 30 + SQUARE_SIZE * (ROW - 1));
}
for (int i = 0; i < ROW; i++) {
for (int j = 0; j < ROW; j++) {
if (go[i][j].color != 0) {
int x = 30 + i * SQUARE_SIZE;
int y = 30 + j * SQUARE_SIZE;
if (go[i][j].color == 1)
g.setColor(Color.BLACK);
else
g.setColor(Color.WHITE);
g.fillOval(x - 12, y - 12, 24, 24);
}
}
}
}
public void setButton(boolean flag) {
buttonregret.setEnabled(flag);
buttonlose.setEnabled(flag);
}
}
- 棋子对象 Chess
package com.drj.game;
/**
*
* @ClassName: Chess
* @Description:TODO(棋子类 存放棋子 xy 坐标)
* @author: drj
* @date: 2018年9月8日 下午7:45:52
*
* @Copyright: 2018
* */
public class Chess {
public int x,y;
public Chess(int x,int y) {
this.x=x;
this.y=y;
}
}
- 监听窗体事件类GameListene
package com.drj.game;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import javax.swing.JComboBox;
import javax.swing.JOptionPane;
/**
-
- @ClassName: GameListener
- @Description:TODO(监听窗体事件)
- @author: drj
- @date: 2018年9月8日 下午7:47:16
-
- @Copyright: 2018
- */
public class GameListener extends MouseAdapter implements ActionListener, Goconfig {
private GameMain main;// 窗体对象
private Graphics2D g;// 画图对象
private String gameModel = PP_TYPE;// 游戏模式
private boolean flag = true;// 默认 黑棋
private JComboBox<String> cbItem;// 存放游戏选择 人人 还是人机 数组对象
private ArrayList<Chess> list = new ArrayList<Chess>();
public GameListener(GameMain main, JComboBox<String> cbItem) {
this.main = main;
this.cbItem = cbItem;
}
/**
* 鼠标点击事件
*/
public void mouseClicked(MouseEvent e) {
if (g == null) {// 获取 画棋子的对象
g = (Graphics2D) main.getGraphics();
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
}
int x = e.getX() - 30;// 获取鼠标点击的x 坐标
int y = e.getY() - 30;// 获取鼠标点击的y 坐标
int length = (ROW - 1) * SQUARE_SIZE + 30;
if (x < 0 || y < 0 || x > length || y > length) {
System.out.println(555);
JOptionPane.showMessageDialog(main, WARING_INFO);
} else {
int cx = x - (x / SQUARE_SIZE) * SQUARE_SIZE;
int cy = y - (y / SQUARE_SIZE) * SQUARE_SIZE;
// 当 点击 x在方格中间 位置 按离他最近的点 放置
if (cx > (SQUARE_SIZE / 2)) {
x = (x / SQUARE_SIZE + 1) * SQUARE_SIZE;
} else {
x = (x / SQUARE_SIZE) * SQUARE_SIZE;
}
// 当 点击在 y 在方格中间 位置 按离他最近的点 放置
if (cy > (SQUARE_SIZE / 2)) {
y = (y / SQUARE_SIZE + 1) * SQUARE_SIZE;
} else {
y = (y / SQUARE_SIZE) * SQUARE_SIZE;
}
int zx = x / SQUARE_SIZE;
int zy = y / SQUARE_SIZE;
System.out.println(zx + "===" + zy);
Chess tmpchess = new Chess(zx, zy);
if (go[zx][zy].color == 0) {// 是空位就是画棋子
draw(tmpchess);
if (list.size() == Math.pow(ROW, 2)) {
gameOverClear(main, cbItem);
JOptionPane.showMessageDialog(main, DEUCE);
return;
}
if (PC_TYPE.equals(gameModel)) {// 人机模式
Piece.weightReset();
tmpchess = Piece.weight();
draw(tmpchess); // 画出该子,并判断输赢
}
}
}
}
/**
* 绘画黑白棋子
*
* @param tmpchess
*/
public void draw(Chess tmpchess) {
int zx = tmpchess.x;
int zy = tmpchess.y;
int x = zx * SQUARE_SIZE + 30;
int y = zy * SQUARE_SIZE + 30;
if (flag) {
g.setColor(Color.BLACK);
} else {
g.setColor(Color.WHITE);
}
g.fillOval(x - RADIUS, y - RADIUS, RADIUS * 2, RADIUS * 2);
Color col = g.getColor();
if (col == Color.BLACK) {
go[zx][zy].color = 1;
} else if (col == Color.WHITE) {
go[zx][zy].color = 2;
}
if (go[zx][zy].judge(zx, zy) != 0) {
if (flag) {
JOptionPane.showMessageDialog(main, BLACK_WIN);
} else {
JOptionPane.showMessageDialog(main, WHITE_WIN);
}
gameOverClear(main, cbItem);
return;
}
flag = !flag;
list.add(tmpchess);
}
/**
* 针对窗体上事件的拦截
*/
@Override
public void actionPerformed(ActionEvent e) {
if (e.getActionCommand().equals(START_GAME)) {
for (int i = 0; i < ROW; i++) {
for (int j = 0; j < COLUMN; j++) {
go[i][j].color = 0;
}
}
Piece.weightReset(); // 开始前重置棋盘的权重
flag = true; // 黑色 定义为 true
cbItem.setEnabled(false);// 下拉框 置为不可选
list.clear(); // 清空棋子数组
main.repaint();// 窗体重绘
// main.removeMouseListener(this); //移除监听对象
main.addMouseListener(this);// 添加监听对象
main.setButton(true); // 设置悔棋、认输可点
} else if (e.getActionCommand().equals(RETURN_GO)) {
if (list.size() >= 1) {
Chess chess = list.remove(list.size() - 1);// 删除最后加入的棋子对象
go[chess.x][chess.y].color = 0;// 将最后棋子 位置 颜色置为 0
flag = !flag;// 悔棋后 需要是悔棋重新下
main.repaint();// 棋谱重新画
}
} else if (e.getActionCommand().equals(LOSER)) {
if (flag) {
JOptionPane.showMessageDialog(main, WHITE_WIN);
} else {
JOptionPane.showMessageDialog(main, BLACK_WIN);
}
gameOverClear(main, cbItem);
} else if (e.getSource() instanceof JComboBox) {
@SuppressWarnings("unchecked")
JComboBox<String> cbItem = (JComboBox<String>) e.getSource();// 获取事件源对象
gameModel = cbItem.getSelectedItem().toString(); // 获取选择的对战模式
System.out.println("select is" + gameModel);
}
}
/**
* 游戏结束 处理公共代码
*
* @param main
* @param cbItem
*/
public void gameOverClear(GameMain main, JComboBox<String> cbItem) {
main.removeMouseListener(this); // 移除棋盘面板上的鼠标动作监听方法和事件处理类对象
cbItem.setEnabled(true); // 游戏模式可以操作
main.setButton(false); // 悔棋 禁止操作
} }
- 棋子的颜色、判断是否成功、计算ai权值
- package com.drj.game;
/**
*
* @ClassName: Piece
* @Description:TODO(描述棋子的颜色、判断是否成功、计算ai权值 )
* @author: drj
* @date: 2018年9月8日 下午7:45:01
*
* @Copyright: 2018
*
*/
class Piece implements Goconfig {
public Piece(int color) {
this.color = 0;
}
public int color = 0;// 0 代表空位
// 权值重置
public static void weightReset() {
for (int i = 0; i < weightarr.length; i++) {
for (int j = 0; j < weightarr[i].length; j++) {
weightarr[i][j] = 0;
}
}
}
/**
* 计算权重
*
* @return
*/
public static Chess weight() {
int maxWeight = 0;
int x = 0, y = 0;
for (int i = 0; i < go.length; i++) {
for (int j = 0; j < go[i].length; j++) {
if (go[i][j].color == 0) {// 只有空位的 才去计算权值
String key1 = "0";
String key2 = "0";
int upx = i, upy = j, downx = i, downy = j;
// 左斜方向判断 西北方
int first1 = 0, first2 = 0;
while ((upx - 1) >= 0 && (upy - 1) >= 0) {
int first = go[i - 1][j - 1].color;
first1 = first;
if (first == 0)
break;
else {
--upx;
--upy;
if (go[upx][upy].color == first) {
key1 += go[upx][upy].color;
} else {
key1 += go[upx][upy].color;
break;
}
}
}
// 东南方
while ((downx + 1) <= (ROW - 1) && (downy + 1) <= (ROW - 1)) {
int first = go[i + 1][j + 1].color;
first2 = first;
if (first == 0)
break;
else {
++downx;
++downy;
if (go[downx][downy].color == first) {
key2 += go[downx][downy].color;
} else {
key2 += go[downx][downy].color;
break;
}
}
}
System.out.println("one" + key1 + "===" + key2);
Integer res1 = map.get(key1);
Integer res2 = map.get(key2);
int value1 = 0, value2 = 0;
if (res1 != null)
value1 = res1.intValue();
if (res2 != null)
value2 = res2.intValue();
int value = value1 + value2;
if ((first1 == first2) && first1 != 0) {
value *= 2;
}
key1 = "0";
key2 = "0";
upx = i;
upy = j;
downx = i;
downy = j;
// 绔栫洿鏂瑰悜鍒ゆ柇
first1 = 0;
first2 = 0;
while ((upy - 1) >= 0) {
int first = go[i][j - 1].color;
first1 = first;
if (first == 0)
break;
else {
--upy;
if (go[upx][upy].color == first) {
key1 += go[upx][upy].color;
} else {
key1 += go[upx][upy].color;
break;
}
}
}
while ((downy + 1) <= (ROW - 1)) {
int first = go[i][j + 1].color;
first2 = first;
if (first == 0)
break;
else {
++downy;
if (go[downx][downy].color == first) {
key2 += go[downx][downy].color;
} else {
key2 += go[downx][downy].color;
break;
}
}
}
System.out.println("tow" + key1 + "===" + key2);
res1 = map.get(key1);
res2 = map.get(key2);
value1 = 0;
value2 = 0;
if (res1 != null)
value1 = res1.intValue();
if (res2 != null)
value2 = res2.intValue();
value += value1 + value2;
if ((first1 == first2) && first1 != 0) {
value *= 2;
}
key1 = "0";
key2 = "0";
upx = i;
upy = j;
downx = i;
downy = j;
first1 = 0;
first2 = 0;
while ((upx - 1) >= 0) {
int first = go[i - 1][j].color;
first1 = first;
if (first == 0)
break;
else {
--upx;
if (go[upx][upy].color == first) {
key1 += go[upx][upy].color;
} else {
key1 += go[upx][upy].color;
break;
}
}
}
while ((downx + 1) <= (ROW - 1)) {
int first = go[i + 1][j].color;
first2 = first;
if (first == 0)
break;
else {
++downx;
if (go[downx][downy].color == first) {
key2 += go[downx][downy].color;
} else {
key2 += go[downx][downy].color;
break;
}
}
}
System.out.println("three" + key1 + "===" + key2);
res1 = map.get(key1);
res2 = map.get(key2);
value1 = 0;
value2 = 0;
if (res1 != null)
value1 = res1.intValue();
if (res2 != null)
value2 = res2.intValue();
value += value1 + value2;
if ((first1 == first2) && first1 != 0)
value *= 2;
key1 = "0";
key2 = "0";
upx = i;
upy = j;
downx = i;
downy = j;
first1 = 0;
first2 = 0;
while ((upx + 1) <= (ROW - 1) && (upy - 1) >= 0) {
int first = go[i + 1][j - 1].color;
first1 = first;
if (first == 0)
break;
else {
++upx;
--upy;
if (go[upx][upy].color == first) {
key1 += go[upx][upy].color;
} else {
key1 += go[upx][upy].color;
break;
}
}
}
while ((downx - 1) >= 0 && (downy + 1) <= (ROW - 1)) {
int first = go[i - 1][j + 1].color;
first2 = first;
if (first == 0)
break;
else {
--downx;
++downy;
if (go[downx][downy].color == first) {
key2 += go[downx][downy].color;
} else {
key2 += go[downx][downy].color;
break;
}
}
}
System.out.println("four" + key1 + "===" + key2);
res1 = map.get(key1);
res2 = map.get(key2);
value1 = 0;
value2 = 0;
if (res1 != null)
value1 = res1.intValue();
if (res2 != null)
value2 = res2.intValue();
value += value1 + value2;
if ((first1 == first2) && first1 != 0)
value *= 2;
weightarr[i][j] += value;
if (weightarr[i][j] >= maxWeight) {
maxWeight = weightarr[i][j];
x = i;
y = j;
}
}
}
}
System.out.println(maxWeight);
return new Chess(x, y);
}
/**
* 判断是否五子连接成功
*
* @param x
* @param y
* @return
*/
public int judge(int x, int y) {
for (int i = 0; i < 4; i++) {
int upx = x, upy = y, downx = x, downy = y;
int count = 1;
if (i == 0) {
while ((upx - 1) >= 0 && (upy - 1) >= 0) {
if (go[--upx][--upy].color == this.color)
count++;
else
break;
}
while ((downx + 1) <= (ROW - 1) && (downy + 1) <= (ROW - 1)) {
if (go[++downx][++downy].color == this.color)
count++;
else
break;
}
if (count >= 5) {
System.out.print(this.color + "胜利");
return this.color;
}
} else if (i == 1) {
while ((upy - 1) >= 0) {
if (go[upx][--upy].color == this.color)
count++;
else
break;
}
while ((downy + 1) <= (ROW - 1)) {
if (go[downx][++downy].color == this.color)
count++;
else
break;
}
if (count >= 5) {
System.out.print(this.color + "胜利");
return this.color;
}
} else if (i == 2) {
while ((upx + 1) <= (ROW - 1) && (upy - 1) >= 0) {
if (go[++upx][--upy].color == this.color)
count++;
else
break;
}
while ((downx - 1) >= 0 && (downy + 1) <= (ROW - 1)) {
if (go[--downx][++downy].color == this.color)
count++;
else
break;
}
if (count >= 5) {
System.out.print(this.color + "胜利");
return this.color;
}
} else if (i == 3) {
while ((downx - 1) >= 0) {
if (go[--downx][downy].color == this.color)
count++;
else
break;
}
while ((upx + 1) <= (ROW - 1)) {
if (go[++upx][upy].color == this.color)
count++;
else
break;
}
if (count >= 5) {
System.out.print(this.color + "胜利");
return this.color;
}
}
}
return 0;
}
}