Location.java 该部分是棋子类 public class Location { private int x;//棋盘上x坐标 private int y;//棋盘上y坐标 private int owner;//1代表黑棋,2代表白棋 public Location(int x, int y, int owner) { this.x = x; this.y = y; this.owner = owner; } public int getX() { return x; } public void setX(int x) { this.x = x; } public int getY() { return y; } public void setY(int y) { this.y = y; } public int getOwner() { return owner; } public void setOwner(int owner) { this.owner = owner; } }
Chessboard.java 该部分是棋盘类,主要实现的功能是画棋盘,画棋子,实现落子,以及实现输赢判断的功能。 import javax.swing.*; import java.awt.*; import java.util.ArrayList; import java.util.List; //棋盘类,负责格子的绘制 public class Chessboard extends JPanel { //规定棋盘横竖线各15条 private static final int CHESSBOARD_SIZE=15;//常量的写法,规定15条线 private int margin=20;//外边距 //创建一个容器来保存棋子对象 private List<Location> locationList=new ArrayList<>(); //创建一个数组表示棋盘上被占用的位置 private int[][] location=new int[CHESSBOARD_SIZE][CHESSBOARD_SIZE]; //绘图工具 g就是画笔工具 @Override public void paint(Graphics g){ super.paint(g); //调用画棋盘的方法 drawChessBoard(g); //调用画棋子的功能 drawChess(g); } private void drawChessBoard(Graphics g){ //每条线之间的距离,即小格子的边长 int cellsize=(getWidth()-2*margin)/(CHESSBOARD_SIZE-1);//(总的宽度-2个外边距)/14个小格子 for (int i = 0; i < CHESSBOARD_SIZE; i++) { //画横线 g.drawLine(margin,margin+cellsize*i,getWidth()-margin,margin+cellsize*i); //画竖线 g.drawLine(margin+cellsize*i,margin,margin+cellsize*i,getHeight()-margin); } } //画棋子 public void drawChess(Graphics g){ for(int i = 0; i < locationList.size(); i++) { //如何辨别棋子的颜色 Location loc=locationList.get(i); if(loc.getOwner()==1){ //棋子黑色 g.setColor(Color.BLACK); }else { g.setColor(Color.WHITE); } //先求出格子的大小 int cellsize=(getWidth()-2*margin)/(CHESSBOARD_SIZE-1); //转为棋盘的坐标画棋子 g.fillOval(loc.getX()*cellsize+margin-cellsize/2,loc.getY()*cellsize+margin-cellsize/2,cellsize,cellsize); } } //落子的方法 public void addChess(Location location){ locationList.add(location); repaint(); } //获取格子的大小的方法 public int getCellSize() { return (getWidth() - 2 * margin) / (CHESSBOARD_SIZE - 1); } //判断是否可以落子 public boolean isLegal(int x,int y){ System.out.println(x+":"+y); if(x>=0&&x<=CHESSBOARD_SIZE&&y>=0&&y<=CHESSBOARD_SIZE&&location[x][y]==0){ //System.out.println(x,y); return true; } return false; } //落子后占用棋盘的位置 public void addLocation(int x,int y,int owner){ location[x][y]=owner; } //判断输赢 public boolean isWin(int x,int y,int owner){ //创建一个变量来记录同一个方向上的相同棋子的个数 int sum=0; //判断水平,垂直,主对角线,副对角线 //水平:左+右 //左 for (int i = x-1; i>=0 ; i--) { if(location[i][y]==owner){ sum++; } else{ break; } } //右 for (int i = x+1; i <=CHESSBOARD_SIZE; i++) { if(location[i][y]==owner){ sum++; }else { break; } } if(sum>=4){ return true; } sum=0;//另外的方向上sum置零 //垂直方法 //上 for (int i = y-1; i>=0 ; i--) { if(location[x][i]==owner){ sum++; } else{ break; } } ///下 for (int i = y+1; i <=CHESSBOARD_SIZE; i++) { if(location[x][i]==owner){ sum++; }else { break; } } if(sum>=4){ return true; } sum=0; //主对角线方向 //左上 for (int i = x-1, j=y-1; i>=0&&j>=0; i--,j--) { if(location[i][j]==owner){ sum++; } else{ break; } } //右下 for (int i = x+1,j=y+1; i <=CHESSBOARD_SIZE&&j<=CHESSBOARD_SIZE; i++,j++) { if(location[i][j]==owner){ sum++; }else { break; } } if(sum>=4){ return true; } //副对角线 //左下 for (int i = x-1, j=y+1; i>=0&&j<=CHESSBOARD_SIZE; i--,j++) { if(location[i][j]==owner){ sum++; } else{ break; } } //右上 for (int i = x+1,j=y-1; i <=CHESSBOARD_SIZE&&j>=0; i++,j--) { if(location[i][j]==owner){ sum++; }else { break; } } if(sum>=4){ return true; } return false; } }
Ui.java
该部分的主要对人机交互界面的设置,但是有一些bug,是我问了不少人也没有解决的,就是在Ui.java里面,while(true)这部分,我每一次点击棋盘,棋子的坐标是不会变的。希望有更多能力强的程序员可以帮忙看看。
import javax.swing.*; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; public class Ui { private final JFrame frame = new JFrame(); private final Chessboard chessboard = new Chessboard(); /*制作五子棋的窗体 */ public void init() { //给窗体设置标题 frame.setTitle("五子棋小游戏"); //设置窗体的大小 frame.setSize(518, 540); //设置位置居中 frame.setLocationRelativeTo(null); //默认关闭 frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); //让棋盘添加进来 frame.add(chessboard); //让窗体显示 frame.setVisible(true); System.out.println("1111111"); //实现点击鼠标落子的功能 //1.给棋盘添加鼠标监听事件---鼠标点击事件 chessboard.addMouseListener(new MouseAdapter() { @Override public void mouseClicked(MouseEvent e) { super.mouseClicked(e); System.out.println("22222222"); //调用画棋子的方法 play(e); } }); } //鼠标点击生成棋子 private void play(MouseEvent e) { System.out.println(""); //先把格子的大小求出来 int cellsize = chessboard.getCellSize(); //将鼠标的位置转成棋盘坐标的位置 int x = (e.getX() - 5) / cellsize; int y = (e.getY() - 5) / cellsize;//-5是为了在没有点击交汇的正中间时也能落在中间 //什么情况可以落子:1.落子的位置不能有其他棋子2.不能超过棋盘边界 int player = 1; // 用于判断当前玩家是黑方(1)还是白方(2) // 用于判断当前玩家是黑方(1)还是白方(2) while (true) { // 获取玩家输入的x和y值 if (chessboard.isLegal(x, y)) { System.out.println("位置合法"); // 如果该位置合法,让当前玩家下棋 chessboard.addChess(new Location(x, y, player)); chessboard.addLocation(x,y, player); if (chessboard.isWin(x,y, player)) { // 如果该玩家获胜,弹出提示框并结束游戏 if (player == 1) { JOptionPane.showMessageDialog(frame, "黑棋获胜", "游戏结束", JOptionPane.PLAIN_MESSAGE); } else { JOptionPane.showMessageDialog(frame, "白棋获胜", "游戏结束", JOptionPane.PLAIN_MESSAGE); } //break; } else { // 如果该玩家没有获胜,切换到另一个玩家 player = (player == 1) ? 2 : 1; } } else { System.out.println(chessboard.isLegal(x, y)); System.out.println("位置不合法"); //System.out.println(x,y); } } } public static void main(String[] args) { new Ui().init(); } }