欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

五子棋总结

程序员文章站 2022-06-14 10:58:03
...
[size=large]五子棋总结
五子棋对我来说是第一个有关于算法的项目,也是第一个自己开始独立完成的项目。五子棋分为人人和人机两种版本。
但是在做之前都先要画棋盘,这个因为有前面画图板的经验,所以还相对于较容易实现,只要画直线就好,值得注意到是,我们可以先定义一个接口,将所以需要用到是数据都放在接口中,便于修改,而不需要在界面中进行修改:[/size]
public interface config {
public static final int X0=50,Y0=50;//定义初始点位置
public static final int ROWS=13,COLUMNS=13;//定义横线和竖线的条数
public static final int SIZE=50;//定义棋盘单元格的大小
public static final int CHESS_SIZE=40;//定义棋子大小
public static final int[][] CHESS=new int[13][13];//定义一个数组来标记棋子
}

[size=large]只要主界面接这个接口就可以了。主界面中根据这些变量来画棋盘。在画棋子时,用鼠标监听器来监听点击的坐标。但是要计算好点击的是哪一个范围内就算哪一个点上落子。具体代码实现如下:
在鼠标监听器中,注意也要实现棋盘的重绘。[/size]
public void mouseReleased(MouseEvent e) {
// 画棋子
// 得到所点击处的坐标
int x1 = e.getX();
int y1 = e.getY();
// 计算所应摆放棋子的位置的单元格
int j = (x1 - X0) / SIZE;
int i = (y1 - Y0) / SIZE;
rules ru = new rules();
// 判断是否可以摆棋子
if (count == 1) {
for (int k = 0; k < CHESS.length; k++) {
for (int h = 0; h < CHESS[k].length; h++) {
if (CHESS[k][h] == -1) {
count2++;
}
}
}

} else {
for (int k = 0; k < CHESS.length; k++) {
for (int h = 0; h < CHESS.length; h++) {
if (CHESS[k][h] == 1) {
count1++;
}
}
}

}
if (a || b == 1) {
b++;

// 判断此处是否可以摆放棋子
if (CHESS[i][j] == 0) {

// 得到单元格的左上角坐标
int x2 = X0 + j * SIZE;
int y2 = Y0 + i * SIZE;
// 得到单元格的中心点坐标
int x3 = x2 + SIZE / 2;
int y3 = y2 + SIZE / 2;
a = ru.check(i, j, count);
if (a) {
if (count == 1) {
g.setColor(Color.black);
CHESS[i][j] = 1;
count = -1;
} else {
g.setColor(Color.white);
CHESS[i][j] = -1;
count = 1;
}
// 绘制棋子
g.fillOval(x3 - CHESS_SIZE / 2, y3 - CHESS_SIZE / 2,
CHESS_SIZE, CHESS_SIZE);
javax.swing.SwingUtilities.updateComponentTreeUI(UI);
}

}

} else {
for (int k = 0; k < CHESS.length; k++) {
for (int h = 0; h < CHESS.length; h++) {
if (CHESS[k][h] == 1) {
count1++;
a = overt.chesstraver(k, h, count);
}
}
}
if (a) {
if (CHESS[i][j] == 0) {

// 得到单元格的左上角坐标
int x2 = X0 + j * SIZE;
int y2 = Y0 + i * SIZE;
// 得到单元格的中心点坐标
int x3 = x2 + SIZE / 2;
int y3 = y2 + SIZE / 2;
a = ru.check(i, j, count);
if (a) {
if (count == 1) {
g.setColor(Color.black);
CHESS[i][j] = 1;
count = -1;
} else {
g.setColor(Color.white);
CHESS[i][j] = -1;
count = 1;
}
// 绘制棋子
g.fillOval(x3 - CHESS_SIZE / 2, y3 - CHESS_SIZE / 2,
CHESS_SIZE, CHESS_SIZE);
javax.swing.SwingUtilities.updateComponentTreeUI(UI);
}
}
}
}
}

[size=large]人人版显然相对较容易实现,只要实现判断落下棋子后是否有连成5个就可以了,相对来说只要遍历相对于这步棋的周围5步,看是否有连成5个即可以得到。
至于人机版,就需要有一个算法来计算当前游戏者落子后对于另一方比较有利的地方。因此可以考虑将整个棋盘可以下子的地方附上权值,每下一步并根据算法来更改棋盘上未落子的地方的权值,由此得到权值最大的地方就是最有利的下子地方,从而下子。这个算法便显的至关重要了,不仅要考虑下子后将周围的棋子的权值变大,还要考虑断三,活三等各种情况。因此分为进攻和防守两个算法。具体实行如下:[/size]
// 横向判断是否有5个棋子
public int checkROW(int x, int y, int color) {

// 定义一个计数器
int count = 0;
int i = y + 1;
// 往右走
for (; i < CHESS.length; i++) {
if ((CHESS[x][i] == CHESS[x][y]) && (CHESS[x][i] == color)) {
count++;

} else {
break;// 只要有一颗棋子不同就退出循环
}
}

if (i < CHESS.length && count == 2)
if ((CHESS[x][i] == CHESS[x][y]) && (CHESS[x][i] == color))

// 断3的处理方法

if ((CHESS[x][i - 1] != 1) && (CHESS[x][i - 1] != 1)) {
CHESS[x][i - 1] = 10000;
}

// 往左走
for (i = y; i >= 0; i--) {
if ((CHESS[x][i] == CHESS[x][y]) && (CHESS[x][i] == color)) {
count++;
} else {
break;
}
}

if (i >= 0 && count == 2)
if ((CHESS[x][i] == CHESS[x][y]) && (CHESS[x][i] == color))

// 断3的处理方法

if ((CHESS[x][i + 1] != 1) && (CHESS[x][i + 1] != 1)) {
CHESS[x][i + 1] = 10000;
}

// 连3的处理方法

if (count == 3) {
if ((CHESS[x][y - 1] != 1) && (CHESS[x][y - 1] != -1)
&& (CHESS[x][y + 3] != -color)) {
CHESS[x][y - 1] = 2000;
}
if ((CHESS[x][y + 1] != 1) && (CHESS[x][y + 1] != -1)
&& (CHESS[x][y - 3] != -color)) {
CHESS[x][y + 1] = 2000;
}
}
if (count == 4) {
if ((CHESS[x][y - 1] != 1) && (CHESS[x][y - 1] != -1)) {
CHESS[x][y - 1] = 100000;
}
if ((CHESS[x][y + 1] != 1) && (CHESS[x][y + 1] != -1)) {
CHESS[x][y + 1] = 100000;
}

}

return count;// 返回所数的个数
}

// 纵向判断是否有5颗棋子
public int checkCOLUMNS(int x, int y, int color) {
// 定义一个计数器
int count = 0;
int i = x + 1;
// 向上
for (; i < CHESS.length; i++) {
if ((CHESS[i][y] == CHESS[x][y]) && (CHESS[i][y] == color)) {
count++;

}

else {
break;
}
}

if (i < CHESS.length && count == 2)

if ((CHESS[i][y] == CHESS[x][y]) && (CHESS[i][y] == color))
// 断3的处理方法
if ((CHESS[i - 1][y] != 1) && (CHESS[i - 1][y] != 1)) {
CHESS[i - 1][y] = 100000;
}

// 向下
for (i = x; i >= 0; i--) {
if ((CHESS[i][y] == CHESS[x][y]) && (CHESS[i][y] == color))
count++;
else {
break;
}

}

if (i >= 0 && count == 2)
if ((CHESS[i][y] == CHESS[x][y]) && (CHESS[i][y] == color))
// 断3的处理方法
if ((CHESS[i + 1][y] != 1) && (CHESS[i + 1][y] != 1)) {
CHESS[i + 1][y] = 100000;
}

// 连3的处理方法

if (count == 3) {
if ((CHESS[x - 1][y] != 1) && (CHESS[x - 1][y] != -1)
&& (CHESS[x + 3][y] != -color)) {
CHESS[x - 1][y] = 2000;
}
if ((CHESS[x + 1][y] != 1) && (CHESS[x + 1][y] != -1)
&& (CHESS[x - 3][y] != -color)) {
CHESS[x + 1][y] = 2000;
}
}
if (count == 4) {
if ((CHESS[x + 1][y] != 1) && (CHESS[x + 1][y] != -1)) {
CHESS[x + 1][y] = 100000;
}
if ((CHESS[x - 1][y] != 1) && (CHESS[x - 1][y] != -1)) {
CHESS[x - 1][y] = 100000;
}

}
return count;
}

// 右斜
public int checkrighttop(int x, int y, int color) {
// 定义一个计数器
int count = 0;
int i = x - 1, j = y + 1;
// 斜向上
for (; j < CHESS.length && i > 0; i--, j++) {
if ((CHESS[x][y] == CHESS[i][j]) && (CHESS[i][j] == color)) {
count++;
} else {
break;
}
}
if (i >= 0 && j < CHESS.length && count == 2)
if ((CHESS[i][j] == CHESS[x][y]) && (CHESS[i][j] == color))
// 断3的处理方法

if ((CHESS[i + 1][y - 1] != 1) && (CHESS[i + 1][y - 1] != 1)) {
CHESS[i + 1][y - 1] = 10000;
}

// 斜向下
for (i = x, j = y; i < CHESS.length && j > 0; i++, j--)
if ((CHESS[x][y] == CHESS[i][j]) && (CHESS[i][j] == color)) {
count++;
} else {
break;
}
if (i < CHESS.length && j > 0 && count == 2)
if ((CHESS[i][j] == CHESS[x][y]) && (CHESS[i][j] == color))
// 断3的处理方法

if ((CHESS[i - 1][y + 1] != 1) && (CHESS[i - 1][y + 1] != 1)) {
CHESS[i - 1][y + 1] = 10000;
}

if (count == 3) {
if ((CHESS[x - 1][y + 1] != 1) && (CHESS[x - 1][y + 1] != -1)
&& (CHESS[x + 3][y - 3] != -color)) {
CHESS[x - 1][y + 1] = 2000;
}
if ((CHESS[x + 1][y - 1] != 1) && (CHESS[x + 1][y - 1] != -1)
&& (CHESS[x - 3][y + 3] != -color)) {
CHESS[x + 1][y - 1] = 2000;
}
}
if (count == 4) {
if ((CHESS[x - 1][y + 1] != 1) && (CHESS[x - 1][y + 1] != -1)) {
CHESS[x - 1][y + 1] = 100000;
}
if ((CHESS[x + 1][y - 1] != 1) && (CHESS[x + 1][y - 1] != -1)) {
CHESS[x + 1][y - 1] = 100000;
}

}

return count;
}

// 左斜
public int checklefttop(int x, int y, int color) {
// 定义一个计数器
int count = 0;
int i = x, j = y;
// 斜向上
for (; i >= 0 && j >= 0; i--, j--) {
if ((CHESS[x][y] == CHESS[i][j]) && (CHESS[i][j] == color))
count++;
else {
break;

}

}
if (i > 0 && j > 0 && count == 2)
if ((CHESS[i][j] == CHESS[x][y]) && (CHESS[i][j] == color))
// 断3的处理方法

if ((CHESS[i + 1][y + 1] != 1) && (CHESS[i + 1][y + 1] != 1)) {
CHESS[i + 1][y + 1] = 10000;
}

// 斜向下
for (i = x + 1, j = y + 1; i < CHESS.length && j < CHESS.length; i++, j++) {
if ((CHESS[x][y] == CHESS[i][j]) && (CHESS[i][j] == color))
count++;
else
break;
}
if (i < CHESS.length && j < CHESS.length && count == 2)
if ((CHESS[i][j] == CHESS[x][y]) && (CHESS[i][j] == color))
// 断3的处理方法

if ((CHESS[i - 1][y - 1] != 1) && (CHESS[i - 1][y - 1] != 1)) {
CHESS[i - 1][y - 1] = 10000;
}

if (count == 3) {
if ((CHESS[x + 1][y + 1] != 1) && (CHESS[x + 1][y + 1] != -1)
&& (CHESS[x -3 ][y - 3] != -color)) {
CHESS[x + 1][y + 1] = 2000;
}
if ((CHESS[x - 1][y - 1] != 1) && (CHESS[x - 1][y - 1] != -1)
&& (CHESS[x + 3][y + 3] != -color)) {
CHESS[x - 1][y - 1] = 2000;
}
}
if (count == 4) {
if ((CHESS[x + 1][y + 1] != 1) && (CHESS[x + 1][y + 1] != -1)) {
CHESS[x + 1][y + 1] = 100000;
}
if ((CHESS[x - 1][y - 1] != 1) && (CHESS[x - 1][y - 1] != -1)) {
CHESS[x - 1][y - 1] = 100000;
}

}

return count;
}

}


// 横向判断是否有5个棋子
public int checkROW(int x, int y, int color) {

// 定义一个计数器
int count = 0;
// 往右走
for (int i = y + 1; i < CHESS.length; i++) {
if ((CHESS[x][i] == CHESS[x][y]) && (CHESS[x][i] == color)) {
count++;

} else
break;
// 只要有一颗棋子不同就退出循环
}
// 往左走
for (int i = y; i >= 0; i--) {
if ((CHESS[x][i] == CHESS[x][y]) && (CHESS[x][i] == color)) {
count++;
} else
break;
// 只要有一颗棋子不同就退出循环

}
//攻击,下活3
if(count==2){
if ((CHESS[x][y - 1] != 1) && (CHESS[x][y - 1] != -1)
&& (CHESS[x ][y + 2] != -color)) {
CHESS[x][y - 1] = 700;
}
if ((CHESS[x][y + 1] != 1) && (CHESS[x][y + 1] != -1)
&& (CHESS[x ][y - 2] != -color)) {
CHESS[x][y + 1] = 700;
}

}
//攻击,连4颗
if (count == 3) {
if ((CHESS[x][y - 1] != 1) && (CHESS[x][y - 1] != -1)) {
CHESS[x][y - 1] = 500;
}
if ((CHESS[x][y + 1] != 1) && (CHESS[x][y + 1] != -1)) {
CHESS[x][y + 1] = 500;
}
}
if (count == 4) {
if ((CHESS[x][y - 1] != 1) && (CHESS[x][y - 1] != -1)) {
CHESS[x][y - 1] = 5000;
}
if ((CHESS[x][y + 1] != 1) && (CHESS[x][y + 1] != -1)) {
CHESS[x][y + 1] = 5000;
}

}

return count;// 返回所数的个数

}

// 纵向判断是否有5颗棋子
public int checkCOLUMNS(int x, int y, int color) {
// 定义一个计数器
int count = 0;
// 向上
for (int i = x + 1; i < CHESS.length; i++) {
if ((CHESS[i][y] == CHESS[x][y]) && (CHESS[i][y] == color)) {
count++;

}

else
break;
}
for (int i = x; i >= 0; i--) {
if ((CHESS[i][y] == CHESS[x][y]) && (CHESS[i][y] == color))
count++;
else
break;
}
if (count == 2) {
if ((CHESS[x - 1][y] != 1) && (CHESS[x - 1][y] != -1)
&& (CHESS[x + 1][y] != -color)) {
CHESS[x + 2][y] = 700;
}
if ((CHESS[x + 1][y] != 1) && (CHESS[x + 1][y] != -1)
&& (CHESS[x - 2][y] != -color)) {
CHESS[x + 1][y] = 700;
}
}
if (count == 3) {
if ((CHESS[x - 1][y] != 1) && (CHESS[x - 1][y] != -1)) {
CHESS[x - 1][y] = 800;
}
if ((CHESS[x + 1][y] != 1) && (CHESS[x + 1][y] != -1)) {
CHESS[x + 1][y] = 800;
}
}
if (count == 4) {
if ((CHESS[x + 1][y] != 1) && (CHESS[x + 1][y] != -1)) {
CHESS[x + 1][y] = 5000;
}
if ((CHESS[x - 1][y] != 1) && (CHESS[x - 1][y] != -1)) {
CHESS[x - 1][y] = 5000;
}

}
return count;
}

// 右斜
public int checkrighttop(int x, int y, int color) {
// 定义一个计数器
int count = 0;
//斜向上
for (int i = x - 1, j = y + 1; j < CHESS.length && i > 0; i--, j++) {
if ((CHESS[x][y] == CHESS[i][j]) && (CHESS[i][j] == color)) {
count++;
} else {
break;
}
}
//斜向下
for (int i = x, j = y; i < CHESS.length && j > 0; i++, j--)
if ((CHESS[x][y] == CHESS[i][j]) && (CHESS[i][j] == color)) {
count++;
} else {
break;
}
if (count == 2) {
if ((CHESS[x - 1][y + 1] != 1) && (CHESS[x - 1][y + 1] != -1)
&& (CHESS[x + 2][y-2] != -color)) {
CHESS[x-1][y + 1] = 700;
}
if ((CHESS[x + 1][y - 1] != 1) && (CHESS[x + 1][y - 1] != -1)
&& (CHESS[x - 2][y + 2] != -color) ){
CHESS[x + 1][y - 1] = 700;
}
}
if (count == 3) {
if ((CHESS[x - 1][y + 1] != 1) && (CHESS[x - 1][y + 1] != -1)) {
CHESS[x-1][y + 1] = 800;
}
if ((CHESS[x + 1][y - 1] != 1) && (CHESS[x + 1][y - 1] != -1)) {
CHESS[x + 1][y - 1] = 800;
}
}
if (count == 4) {
if ((CHESS[x - 1][y + 1] != 1) && (CHESS[x - 1][y + 1] != -1)) {
CHESS[x-1][y + 1] = 5000;
}
if ((CHESS[x + 1][y - 1] != 1) && (CHESS[x + 1][y - 1] != -1)) {
CHESS[x + 1][y - 1] = 5000;
}

}

return count;
}

// 左斜
public int checklefttop(int x, int y, int color) {
// 定义一个计数器
int count = 0;
// 斜向上
for (int i = x, j = y; i >= 0 && j >= 0; i--, j--) {
if ((CHESS[x][y] == CHESS[i][j]) && (CHESS[i][j] == color))
count++;
else
break;

}
// 斜向下
for (int i = x + 1, j = y + 1; i < CHESS.length && j < CHESS.length; i++, j++) {
if ((CHESS[x][y] == CHESS[i][j]) && (CHESS[i][j] == color))
count++;
else
break;
}
if (count == 2) {
if ((CHESS[x + 1][y + 1] != 1) && (CHESS[x + 1][y + 1] != -1)&&(CHESS[x - 2][y - 2] != -color) ){
CHESS[x + 1][y + 1] = 700;
}
if ((CHESS[x - 1][y - 1] != 1) && (CHESS[x - 1][y - 1] != -1)&&(CHESS[x + 2][y + 2] != -color) ) {
CHESS[x - 1][y - 1] = 700;
}
}
if (count == 3) {
if ((CHESS[x + 1][y + 1] != 1) && (CHESS[x + 1][y + 1] != -1)) {
CHESS[x + 1][y + 1] = 800;
}
if ((CHESS[x - 1][y - 1] != 1) && (CHESS[x - 1][y - 1] != -1)) {
CHESS[x - 1][y - 1] = 800;
}
}
if (count == 4) {
if ((CHESS[x + 1][y + 1] != 1) && (CHESS[x + 1][y + 1] != -1)) {
CHESS[x + 1][y + 1] = 5000;
}
if ((CHESS[x - 1][y - 1] != 1) && (CHESS[x - 1][y - 1] != -1)) {
CHESS[x - 1][y - 1] = 5000;
}

}

return count;
}

}
相关标签: java 算法