常识可得,一个玩家获胜肯定是当前的一颗棋子,和之前的棋子组成了连续的五个棋子。
所以只要从当前棋子出发,从四个方向分别找到最边界的棋子,然后往后数相同颜色的棋子个数即可判断输赢。
例:如下图所示,现在有四个白棋:
然后现在再下一个白棋,我们从刚下的位置开始向左上方移动,找到最左上的白棋,然后从最左上的白棋,向右下移动。在途径都是白棋的情况下,开始计数,超过五个即可得白棋获胜。
代码实现如下图所示:
首先声明一个二维数组,存储五子棋的位置
private int [][]broadChess= new int[broadScale][broadScale];
//0表示无棋,1表示白棋,2表示黑棋
sidePosX=posX;sidePosY=posY;tempMaxChess=0;
//这里的sidePosX与sidePosY表示边界棋子(最左上的棋子在数组中的位置)
//tempMaxChess即这个方向的有多少个连续且相同颜色的棋子和刚下的棋子相连
//posX,posY是刚下的棋子在二维数组的坐标
for(i =posX-1,j=posY-1;i>=0 && j>=0;i--,j--){//查找行最上边同色棋子
if(broadChess[i][j] == broadChess[posX][posY]){
sidePosX -=1;
sidePosY -=1;
}
else
break;
}
for(i =sidePosX,j=sidePosY;i<broadScale && j<broadScale;i++,j++){//查找斜行\
if(broadChess[i][j] == broadChess[posX][posY]){
tempMaxChess +=1;
}
else
break;//查找到不同颜色就突出
}
maxChess = Math.max(tempMaxChess, maxChess);//与之前的方向得到的最大数据进行比较
一共四个方向(—,|,\,/)
这四个方向的代码实现:
private int [][]broadChess= new int[broadScale][broadScale];//0表示无棋,1表示白棋,2表示黑棋
public int keepPlaying(int posX,int posY){//输入为1查找白棋,输入为2查找黑棋
if(broadChess[posX][posY] == 0)//需要输入刚下的棋子在二维数组的序号
return 0;
int tempMaxChess;
int maxChess=0;
int sidePosX;
int sidePosY;
int i,j;
sidePosX=posX;sidePosY=posY;tempMaxChess=0;
for(i =posX-1;i>=0;i--){//查找行
if(broadChess[i][posY] == broadChess[posX][posY]){
sidePosX -=1;
}
else
break;
}
for(i =sidePosX;i<broadScale;i++){
if(broadChess[i][posY] == broadChess[posX][posY]){
tempMaxChess +=1;
}
else
break;
}
maxChess = Math.max(tempMaxChess, maxChess);
sidePosX=posX;sidePosY=posY;tempMaxChess=0;
for(i =posY-1;i>=0;i--){//查找列
if(broadChess[posX][i] == broadChess[posX][posY]){
sidePosY -=1;
}
else
break;
}
for(i =sidePosY;i<broadScale;i++){
if(broadChess[posX][i] == broadChess[posX][posY]){
tempMaxChess +=1;
}
else
break;
}
maxChess = Math.max(tempMaxChess, maxChess);
sidePosX=posX;sidePosY=posY;tempMaxChess=0;
for(i =posX-1,j=posY-1;i>=0 && j>=0;i--,j--){//查找斜率-1的斜行\
if(broadChess[i][j] == broadChess[posX][posY]){
sidePosX -=1;
sidePosY -=1;
}
else
break;
}
for(i =sidePosX,j=sidePosY;i<broadScale && j<broadScale;i++,j++){
if(broadChess[i][j] == broadChess[posX][posY]){
tempMaxChess +=1;
}
else
break;
}
maxChess = Math.max(tempMaxChess, maxChess);
sidePosX=posX;sidePosY=posY;tempMaxChess=0;
for(i =posX+1,j=posY-1;i<broadScale && j>=0;i++,j--){//查找斜率为1的斜行/
if(broadChess[i][j] == broadChess[posX][posY]){
sidePosX +=1;
sidePosY -=1;
}
else
break;
}
for(i =sidePosX,j=sidePosY;i>=0 && j<broadScale;i--,j++){
if(broadChess[i][j] == broadChess[posX][posY]){
tempMaxChess +=1;
}
else
break;
}
maxChess = Math.max(tempMaxChess, maxChess);
return maxChess>=5?broadChess[posX][posY]:0;//返回是否胜利,若有胜者则返回胜者棋子颜色
}
都写到这个,就给个五子棋游戏的实现:
import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
public class BroadGame {
BufferedImage broad ;
BufferedImage whiteChess;
BufferedImage blackChess;
BufferedImage choiceChess ;
Frame frame = new Frame("五子棋游戏");
Panel p1 = new Panel();
private int broadWidth = 535;//broad.getWidth();
private int broadHeight = 536;//broad.getHeight();
private final int broadScale=15;
private final int heightExc=6;
private final int widthExc=5;
//0表示无棋,1表示白棋,2表示黑棋
private int [][]broadChess= new int[broadScale][broadScale];
Button buttonWhite = new Button("white");
Button buttonBlack= new Button("black");
Button buttonRetract = new Button("retract");
private int firstOne=1;//0表示悔棋,1表示白棋,2表示黑棋
private int choiceX=-1;
private int choiceY=-1;
private final int RATE = broadHeight/broadScale;
private int is_end = 0;
int x1,y1,x2,y2;
int xPos,yPos;
private class ChessPaint extends JPanel {
public void not_end(Graphics g){
//画图板
g.drawImage(broad, 0, 0, null);
//画选择红框
if (choiceX > 0 && choiceY > 0) {
g.drawImage(choiceChess, choiceX * RATE + widthExc, choiceY * RATE + heightExc, null);
}
for (int i = 0; i < broadScale; ++i) {
for (int j = 0; j < broadScale; ++j) {
if (broadChess[i][j] == 1) {
g.drawImage(whiteChess, i * RATE + widthExc, j * RATE + heightExc, null);
} else if (broadChess[i][j] == 2) {
g.drawImage(blackChess, i * RATE + widthExc, j * RATE + heightExc, null);
}
}
}//二维循环
}
@Override
public void paint(Graphics g) {
not_end(g);
if(is_end != 0) {
//设置颜色并绘制小球
//g.setColor(Color.RED);
//g.drawLine(x1 * RATE + widthExc,y1 * RATE + heightExc,x2 * RATE + widthExc,y2 * RATE + widthExc);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
g.setColor(Color.WHITE);
g.fillRect(0,0,broadWidth,broadHeight);
g.setColor(Color.BLACK);
g.setFont(new Font("Times",Font.BOLD,30));
if(is_end == 1)
g.drawString("游戏结束!"+"白棋胜利",broadWidth/2-120,200);
else if(is_end == 2)
g.drawString("游戏结束!"+"黑棋胜利",broadWidth/2-120,200);
}
}//paint重写
}//类定义
public void updateBtnColor(Color whiteBtnColor,Color blackBtnColor,Color clearBtnColor){
buttonWhite.setBackground(whiteBtnColor);
buttonBlack.setBackground(blackBtnColor);
buttonRetract.setBackground(clearBtnColor);
}
public int keepPlaying(int posX,int posY){//输入为1查找白棋,输入为2查找黑棋
if(broadChess[posX][posY] == 0)
return 0;
int tempMaxChess;
int maxChess=0;
int sidePosX;
int sidePosY;
sidePosX=posX;sidePosY=posY;tempMaxChess=0;
int i,j;
for(i =posX-1;i>=0;i--){//查找行最左边同色棋子
if(broadChess[i][posY] == broadChess[posX][posY]){
sidePosX -=1;
}
else
break;
}
for(i =sidePosX;i<broadScale;i++){//查找行
if(broadChess[i][posY] == broadChess[posX][posY]){
tempMaxChess +=1;
}
else
break;
}
maxChess = Math.max(tempMaxChess, maxChess);
if(maxChess == tempMaxChess){
x1=sidePosX;y1=sidePosY;x2=i-1;y2=sidePosY;
}
sidePosX=posX;sidePosY=posY;tempMaxChess=0;
for(i =posY-1;i>=0;i--){//查找行最上边同色棋子
if(broadChess[posX][i] == broadChess[posX][posY]){
sidePosY -=1;
}
else
break;
}
for(i =sidePosY;i<broadScale;i++){//查找列
if(broadChess[posX][i] == broadChess[posX][posY]){
tempMaxChess +=1;
}
else
break;
}
maxChess = Math.max(tempMaxChess, maxChess);
if(maxChess == tempMaxChess){
x1=sidePosX;y1=sidePosY;x2=sidePosX;y2=i-1;
}
sidePosX=posX;sidePosY=posY;tempMaxChess=0;
for(i =posX-1,j=posY-1;i>=0 && j>=0;i--,j--){//查找行最上边同色棋子
if(broadChess[i][j] == broadChess[posX][posY]){
sidePosX -=1;
sidePosY -=1;
}
else
break;
}
for(i =sidePosX,j=sidePosY;i<broadScale && j<broadScale;i++,j++){//查找斜行\
if(broadChess[i][j] == broadChess[posX][posY]){
tempMaxChess +=1;
}
else
break;
}
maxChess = Math.max(tempMaxChess, maxChess);
if(maxChess == tempMaxChess){
x1=sidePosX;y1=sidePosY;x2=i-1;y2=j-1;
}
sidePosX=posX;sidePosY=posY;tempMaxChess=0;
for(i =posX+1,j=posY-1;i<broadScale && j>=0;i++,j--){//查找行最上边同色棋子
if(broadChess[i][j] == broadChess[posX][posY]){
sidePosX +=1;
sidePosY -=1;
}
else
break;
}
for(i =sidePosX,j=sidePosY;i>=0 && j<broadScale;i--,j++){//查找斜行/
if(broadChess[i][j] == broadChess[posX][posY]){
tempMaxChess +=1;
}
else
break;
}
maxChess = Math.max(tempMaxChess, maxChess);
if(maxChess == tempMaxChess){
x1=sidePosX;y1=sidePosY;x2=i+1;y2=j-1;
}
return maxChess>=5?broadChess[posX][posY]:0;
}
//按钮添加监听
public void init() throws IOException {
updateBtnColor(Color.BLUE,Color.GRAY,Color.GRAY);
ActionListener listener=(e) -> {
String actionCommand=e.getActionCommand();
switch (actionCommand){
case "white":firstOne=1;updateBtnColor(Color.BLUE,Color.GRAY,Color.GRAY);
break;
case "black":firstOne=2;updateBtnColor(Color.GRAY,Color.BLUE,Color.GRAY);
break;
case "retract":firstOne=0;updateBtnColor(Color.GRAY,Color.GRAY,Color.BLUE);
break;
}
};
buttonWhite.addActionListener(listener);
buttonBlack.addActionListener(listener);
buttonRetract.addActionListener(listener);
p1.add(buttonWhite);
p1.add(buttonBlack);
p1.add(buttonRetract);
frame.add(p1,BorderLayout.SOUTH);
ChessPaint chessPaint = new ChessPaint();
//初始化黑棋,白棋,棋盘,选中框
broad = ImageIO.read(new File("..\\img\\board.jpg"));
whiteChess = ImageIO.read(new File("..\\img\\white.gif"));
blackChess = ImageIO.read(new File("..\\img\\black.gif"));
choiceChess = ImageIO.read(new File("..\\img\\selected.gif"));
//初始化二维数组,默认情况下,所有位置处都没有棋子
//设置chessPaint的最佳大小
chessPaint.setPreferredSize(new Dimension(broadWidth,broadHeight));
//给chessPaint注册鼠标监听器
chessPaint.addMouseListener(new MouseAdapter() {
//鼠标单击会触发
@Override
public void mouseClicked(MouseEvent e) {
//将用户鼠标的坐标,转换成棋子的坐标
xPos = (e.getX()-heightExc)/RATE;
yPos = (e.getY()-widthExc)/RATE;
broadChess[xPos][yPos] = firstOne;
if(firstOne == 1)
firstOne=2;
else
firstOne=1;
//重绘chessPaint
chessPaint.repaint();
is_end=keepPlaying(xPos,yPos);
}
//当鼠标退出棋盘区域后,复位选中坐标,重绘chessPaint,要保证红色选中框显示正确
@Override
public void mouseExited(MouseEvent e) {
choiceX=-1;
choiceY=-1;
chessPaint.repaint();
}
});
//给chessPaint注册鼠标移动监听器
chessPaint.addMouseMotionListener(new MouseMotionAdapter() {
//当鼠标移动时,修正choiceX和choicetY,重绘chessPaint,要保证红色选中框显示正确
@Override
public void mouseMoved(MouseEvent e) {
//将鼠标的坐标,转换成棋子的索引
choiceX = (e.getX()-widthExc)/RATE;
choiceY = (e.getY()-heightExc)/RATE;
chessPaint.repaint();
}
});
//把chessPaint添加到frame中
frame.add(chessPaint);
//设置frame最佳大小并可见
frame.pack();
frame.setVisible(true);
frame.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
}
public static void main(String[] args) throws IOException {
new BroadGame().init();
}
}
其中的图片元素:
记得把File类参数填完喔
图片是B站一个UP @黑马程序员 提供的,五子棋的实现也是基于其改进的