闲来无事,简单整理了一下以前做的Java课设。当时是借鉴学习了大佬的代码,然后稍稍改动了一些东西。比较普通,可以再加些功能。
百度网盘链接:https://pan.baidu.com/s/106ifjqCVSHsoNyDs7gGdJQ?pwd=hikq
使用的是Eclipse,源码可以参考视频里的操作,正常应该是没啥问题的,注解也比较详细。
效果展示:
ButtonListener类
//实现对JPanel的监听接口处理 public class ButtonListener implements GoBangconfig,ActionListener{ public GoBangframe gf; static int q=0; public ButtonListener(GoBangframe gf) { this.gf=gf;//获取左半部分的画板 } //当界面发生操作时进行处理 public void actionPerformed(ActionEvent e) { //获取当前被点击按钮的内容,判断是不是"开始新游戏"这个按钮 if(e.getActionCommand().equals("开始新游戏")) { //如果是开始新游戏的按钮,再为左半部分设置监听方法 q++; gf.textA.setText(" 开始新游戏!"); frameListener fl=new frameListener(); fl.setGraphics(gf);//获取画笔对象 gf.addMouseListener(fl); } //判断当前点击的按钮是不是悔棋 else if(e.getActionCommand().equals("悔棋")) { if(gf.ChessPositonList.size()>1) { //把棋子数组相应的位置置为0; ChessPosition l=new ChessPosition(); //获取最后一个棋子的对象信息 l=gf.ChessPositonList.remove(gf.ChessPositonList.size()-1); //把相应的数组位置置为0 gf.isAvail[l.Listi][l.Listj]=0; //把玩家还原为上一步的玩家 if(gf.turn==1) gf.turn++; else gf.turn--; gf.textA.setText(" "); //直接调用gf的重绘方法,重绘方法的画笔应该是在棋盘页面还没生成的时候就要获取 //调用repaint会自动调用paint方法,而且不用给参数 gf.repaint(); //gf.paint(gf.getGraphics()); } else { gf.textA.setText(" 不能悔棋!"); //System.out.println("不能悔棋!"); } } else if(e.getActionCommand().equals("认输")) { if(gf.turn==1) gf.textA.setText(" 白方赢!");//System.out.println("白方赢"); else gf.textA.setText(" 黑方赢!"); //System.out.println("黑方赢"); } } }
ChessPosition类
//新建一个棋子类ChessPosition保存每一步棋子所在的位置 public class ChessPosition { public int Listi,Listj; public ChessPosition() { } public ChessPosition(int Listi,int Listj) { this.Listi=Listi; this.Listj=Listj; } }
frameListener类
//实现对GoBangframe下棋界面的监听接口处理 public class frameListener implements GoBangconfig,MouseListener{ public GoBangframe gf; //public int turn;//判断当前轮到谁了,1表示黑方,2表示白方 //动态数组对象的实例化 //public ArrayList<ChessPosition>ChessPositonList=new ArrayList<ChessPosition>(); public void setGraphics(GoBangframe gf) { this.gf=gf; //清除棋盘的全部信息 for(int i=0;i<row;i++) for(int j=0;j<column;j++) { gf.isAvail[i][j]=0; } gf.ChessPositonList.clear(); gf.turn=1; gf.repaint(); } public void mouseClicked(java.awt.event.MouseEvent e) { int x=e.getX(); int y=e.getY(); //计算棋子要落在棋盘的哪个交叉点上 int countx=(x/40)*40+20; int county=(y/40)*40+20; Graphics g=gf.getGraphics(); // System.out.println(gf.isAvail[0][0]); if(gf.isAvail[(countx-20)/40][(county-20)/40]!=0) { if(ButtonListener.q>1) { return; } gf.textA.setText("此处已经有棋子了,请下在其它地方"); //System.out.println("此处已经有棋子了,请下在其它地方"); } else { //计算棋盘上棋子在数组中相应的位置 int colu=(countx-20)/40; int ro=(county-20)/40; if(gf.turn==1) { //先获取要落的地方 g.setColor(Color.black); //落子 g.fillOval(countx-size/2, county-size/2, size, size); //设置当前位置已经有棋子了,棋子为黑子 gf.isAvail[colu][ro]=1; //把当前所下的棋子位置保存在动态数组中 gf.ChessPositonList.add(new ChessPosition(colu,ro)); gf.turn++; gf.textA.setText("黑方已下:白方手"); //判断是否已经出现五颗棋子了 //列判断 //首先界定数组范围,防止越界 int imin=colu-4,imax=colu+4; if(imin<0) imin=0; if(imax>18) imax=18; int count1=0;//判断相连的黑棋子数 for(int i=imin;i<=imax;i++) { if(gf.isAvail[i][ro]==1) count1++; //如果出现了其他棋子,或者是没有棋子时,就重新开始计数 else count1=0; if(count1==5) { gf.textA.setText(" 黑方赢!"); return; } } //行判断 //首先界定数组范围,防止越界 int jmin=ro-4,jmax=ro+4; if(jmin<0) jmin=0; if(jmax>18) jmax=18; int count2=0;//判断相连的棋子数 for(int j=jmin;j<=jmax;j++) { if(gf.isAvail[colu][j]==1) count2++; else count2=0; if(count2==5) { gf.textA.setText(" 黑方赢!"); return; } //如果出现了其他棋子,或者是没有棋子时,就重新开始计数 } //左对角线判断 //首先界定数组范围,防止越界 int count3=0;//判断相连的棋子数 for(int i=-4;i<=4;i++) { if((colu+i>=0)&&(ro+i>=0)&&(colu+i<=18)&&(ro+i<=18)) { if(gf.isAvail[colu+i][ro+i]==1) count3++; //如果出现了其他棋子,或者是没有棋子时,就重新开始计数 else count3=0; if(count3==5) { gf.textA.setText(" 黑方赢!"); return; } } } //右对角线判断 int count4=0;//判断相连的棋子数 for(int i=-4;i<=4;i++) { if((colu+i>=0)&&(ro-i>=0)&&(colu+i<=18)&&(ro-i<=18)) { //System.out.print("count4:"+count4); if(gf.isAvail[colu+i][ro-i]==1) count4++; //如果出现了其他棋子,或者是没有棋子时,就重新开始计数 else count4=0; if(count4==5) { gf.textA.setText(" 黑方赢!"); return; } } } } else { g.setColor(Color.white); g.fillOval(countx-size/2, county-size/2, size, size); //设置当前位置已经有棋子了,棋子为白子 gf.ChessPositonList.add(new ChessPosition(colu,ro)); gf.isAvail[colu][ro]=2; gf.turn--; gf.textA.setText("白方已下:黑方手"); //列判断 //首先界定数组范围,防止越界 int imin=colu-4,imax=colu+4; if(imin<0) imin=0; if(imax>18) imax=18; int count1=0;//判断相连的白棋子数 for(int i=imin;i<=imax;i++) { if(gf.isAvail[i][ro]==2) count1++; //如果出现了其他棋子,或者是没有棋子时,就重新开始计数 else count1=0; if(count1==5) { gf.textA.setText(" 白方赢!"); return; } } //行判断 //首先界定数组范围,防止越界 int jmin=ro-4,jmax=ro+4; if(jmin<0) jmin=0; if(jmax>18) jmax=18; int count2=0;//判断相连的棋子数 for(int j=jmin;j<=jmax;j++) { if(gf.isAvail[colu][j]==2) count2++; //如果出现了其他棋子,或者是没有棋子时,就重新开始计数 else count2=0; if(count2==5) { gf.textA.setText(" 白方赢!"); return; } } //左对角线判断 //首先界定数组范围,防止越界 int count3=0;//判断相连的棋子数 for(int i=-4;i<=4;i++) { if((colu+i>=0)&&(ro+i>=0)&&(colu+i<=18)&&(ro+i<=18)) { if(gf.isAvail[colu+i][ro+i]==2) count3++; //如果出现了其他棋子,或者是没有棋子时,就重新开始计数 else count3=0; if(count3==5) { gf.textA.setText(" 白方赢!"); return; } } } //右对角线判断 int count4=0;//判断相连的棋子数 for(int i=-4;i<=4;i++) { if((colu+i>=0)&&(ro-i>=0)&&(colu+i<=18)&&(ro-i<=18)) { if(gf.isAvail[colu+i][ro-i]==2) count4++; //如果出现了其他棋子,或者是没有棋子时,就重新开始计数 else count4=0; if(count4==5) { gf.textA.setText(" 白方赢!"); return; } } } } } } public void mousePressed(java.awt.event.MouseEvent e) { } public void mouseReleased(java.awt.event.MouseEvent e) { } public void mouseEntered(java.awt.event.MouseEvent e) { } public void mouseExited(java.awt.event.MouseEvent e) { } }
GoBangconfig类
//定义GoBangconfig接口 //定义与棋盘数据相关的接口,保存棋盘的起点,格子大小,行数列数等信息 public interface GoBangconfig { int x=20,y=20,size=40,row=19,column=19; }
GoBangframe类
public class GoBangframe extends JPanel implements GoBangconfig{ public Graphics g;//定义一支画笔 public int[][] isAvail=new int [19][19];//定义一个二维数组来储存棋盘的落子情况 public ArrayList<ChessPosition>ChessPositonList=new ArrayList<ChessPosition>();//保存每一步的落子情况 public int turn=1; JTextArea textA = new JTextArea("点击:开始新游戏(才能开始!!!)",10,15); JTextArea textB = new JTextArea(" 设计人:xxx",0,15); Font f1= new Font("宋体",Font.BOLD,15); Font f2= new Font("宋体",Font.BOLD,15); //主函数入口 public static void main(String args[]) { GoBangframe gf=new GoBangframe();//初始化一个五子棋界面的对象 gf.initUI();//调用方法进行界面的初始化 } public void initUI() { //初始化一个界面,并设置标题大小等属性 JFrame jf=new JFrame(); jf.setTitle("五子棋"); jf.setSize(927,800); jf.setLocationRelativeTo(null); jf.setDefaultCloseOperation(3); jf.setLayout(new BorderLayout());//设置顶级容器JFrame为框架布局 Dimension dim1=new Dimension(150,0);//设置右半部分的大小 Dimension dim3=new Dimension(800,0);//设置左半部分的大小 Dimension dim2=new Dimension(140,40);//设置右边按钮组件的大小 //实现左边的界面,把GoBangframe的对象添加到框架布局的中间部分 this.setPreferredSize(dim3);//设置下棋界面的大小 this.setBackground(Color.GRAY);//设置下棋界面的颜色 //这里的话直接把左边的画板添加上去,指明是在框架布局的中间版块 //若放在其他版块会有一些小问题 jf.add(this,BorderLayout.CENTER);//添加到框架布局的中间部分 //实现右边的JPanel容器界面 JPanel jp=new JPanel(); jp.setPreferredSize(dim1);//设置JPanel的大小 jp.setBackground(Color.white);//设置右边的界面颜色为白色 jf.add(jp,BorderLayout.EAST);//添加到框架布局的东边部分 jp.setLayout(new FlowLayout());//设置JPanel为流式布局 //添加作者 textB.setFont(f2); jp.add(textB); //接下来我们需要把按钮等组件依次加到那个JPanel上面 //设置按钮数组 String[] butname= {"开始新游戏","悔棋","认输"}; JButton[] button=new JButton[3]; //依次把三个按钮组件加上去 for(int i=0;i<butname.length;i++) { button[i]=new JButton(butname[i]); button[i].setPreferredSize(dim2); jp.add(button[i]); } //添加文本框 textA.setFont(f1); textA.setLineWrap(true);//设置自动换行 jp.add(textA); //按钮监控类 ButtonListener butListen=new ButtonListener(this); //对每一个按钮都添加状态事件的监听处理机制 for(int i=0;i<butname.length;i++) { button[i].addActionListener(butListen);//添加发生操作的监听方法 } jf.setVisible(true); } //重写重绘方法,这里重写的是第一个大的JPanel的方法 public void paint(Graphics g) { super.paint(g); //重绘出棋盘 g.setColor(Color.black); for(int i=0;i<row;i++) { g.drawLine(x, y+size*i, x+size*(column-1), y+size*i); } for(int j=0;j<column;j++) { g.drawLine(x+size*j, y, x+size*j, y+size*(row-1)); } //重绘出棋子 for(int i=0;i<row;i++) { for(int j=0;j<column;j++) { if(isAvail[i][j]==1) { int countx=size*i+20; int county=size*j+20; g.setColor(Color.black); g.fillOval(countx-size/2, county-size/2, size, size); } else if(isAvail[i][j]==2) { int countx=size*i+20; int county=size*j+20; g.setColor(Color.white); g.fillOval(countx-size/2, county-size/2, size, size); } } } } }