目录
简介
Hello,I'm Shendi
继上次写完象棋后又花了一天时间写了个五子棋,比较简单
拥有大概如下功能
- 五子棋的基本功能
- 棋盘大小的自由设置
- 胜利棋数的自由设置
- 人机对战
游戏思路
五子棋相比其他棋牌游戏比较简单
我们判断胜负只需要在玩家/人机下棋处循环遍历
- 上下是不是连起来到了指定点数
- 左右...
- 左斜
- 右斜
源码
github: https://github.com/1711680493/Application#gobang
效果视频
Java制作五子棋/连珠棋+简单AI
代码片段
棋盘,棋子绘制代码
/**
* 重新绘制棋盘.
* @author Shendi <a href='tencent://AddContact/?fromId=45&fromSubId=1&subcmd=all&uin=1711680493'>QQ</a>
* @param chessBoardNum 棋盘大小
*/
public void repaint(int chessBoardNum) {
BufferedImage img = new BufferedImage(getWidth(), getHeight(), BufferedImage.TYPE_INT_ARGB);
Graphics g = img.getGraphics();
size = 380 / chessBoardNum;
first = size >> 1;
// 棋子大小初始化
Game.getGame().getChesses().forEach((chess) -> chess.setSize(size,size));
// 将棋盘上所有位置初始化
positions.clear();
for (int i = 0;i < chessBoardNum;i++) {
positions.put(i, first + size * i);
}
// 绘制棋盘
for (int i = 1;i < chessBoardNum;i++) {
// 横线
g.drawLine(size, size * i, 380, size * i);
// 竖线
g.drawLine(size * i, size, size * i, 380);
}
g.drawLine(size, 380 , 380, 380);
g.drawLine(380, size, 380, 380);
g.dispose();
background.setIcon(new ImageIcon(img));
invalidate();
repaint();
// 白色黑色棋子图
int imgPos = (size - size / 2) >> 1;
int imgSize = size >> 1;
BufferedImage whiteChessImg = new BufferedImage(size,size,BufferedImage.TYPE_INT_ARGB);
g = whiteChessImg.getGraphics();
g.setColor(Color.WHITE);
g.fillRoundRect(imgPos, imgPos, imgSize, imgSize, 180, 180);
g.dispose();
BufferedImage blackChessImg = new BufferedImage(size,size,BufferedImage.TYPE_INT_ARGB);
g = blackChessImg.getGraphics();
g.setColor(Color.BLACK);
g.fillRoundRect(imgPos, imgPos, imgSize, imgSize, 180, 180);
g.dispose();
whiteChessIcon = new ImageIcon(whiteChessImg);
blackChessIcon = new ImageIcon(blackChessImg);
}
判断游戏逻辑代码
/**
* 执行下棋操作.
* @author Shendi <a href='tencent://AddContact/?fromId=45&fromSubId=1&subcmd=all&uin=1711680493'>QQ</a>
* @param chess 棋子
* @param whiteBlack 白棋还是黑棋.
*/
public void exec(JLabel chess,boolean whiteBlack) {
// 指定位置是否有棋子,有不做操作
int x = chessBoard.getScenePos(chess.getX());
int y = chessBoard.getScenePos(chess.getY());
if (scene[y][x] != 0) { return; }
// 下棋
int team = whiteBlack ? 1 : 2;
scene[y][x] = team;
// for (int[] xScene : scene) System.out.println(Arrays.toString(xScene));
if (whiteBlack) chess.setIcon(chessBoard.whiteChessIcon);
else chess.setIcon(chessBoard.blackChessIcon);
// 判断胜负,横竖斜有指定数量棋子则胜利,对方失败
int h = 1,v = 1,ld = 1,rd = 1;
// 横,左右
int posX,posY;
for (int i = 1;i < chessBoardNum;i++) {
posX = x - i;
if (posX < 0) break;
if (scene[y][posX] == team) h++; else break;
}
for (int i = 1;i < chessBoardNum;i++) {
posX = x + i;
if (posX >= chessBoardNum) break;
if (scene[y][posX] == team) h++; else break;
}
// 竖,上下
for (int i = 1;i < chessBoardNum;i++) {
posY = y - i;
if (posY < 0) break;
if (scene[posY][x] == team) v++; else break;
}
for (int i = 1;i < chessBoardNum;i++) {
posY = y + i;
if (posY >= chessBoardNum) break;
if (scene[posY][x] == team) v++; else break;
}
// 左斜,上左下右 \
for (int i = 1;i < chessBoardNum;i++) {
posX = x - i;
posY = y - i;
if (posX < 0 || posY < 0) break;
if (scene[posY][posX] == team) ld++; else break;
}
for (int i = 1;i < chessBoardNum;i++) {
posX = x + i;
posY = y + i;
if (posX >= chessBoardNum || posY >= chessBoardNum) break;
if (scene[posY][posX] == team) ld++; else break;
}
// 右斜,上右下左 /
for (int i = 1;i < chessBoardNum;i++) {
posX = x + i;
posY = y - i;
if (posX >= chessBoardNum || posY < 0) break;
if (scene[posY][posX] == team) rd++; else break;
}
for (int i = 1;i < chessBoardNum;i++) {
posX = x - i;
posY = y + i;
if (posX < 0 || posY >= chessBoardNum) break;
if (scene[posY][posX] == team) rd++; else break;
}
if (h >= vectoryNum || v >= vectoryNum || ld >= vectoryNum || rd >= vectoryNum) {
stop(whiteBlack);
return;
}
// 当前角色下棋完成,换一边
currentTeam = !currentTeam;
if (!currentTeam) AI.getAI().play();
}