目录
构思
书接上回
让我们来构思一下如何设计悔棋,这里就要用到java中面向对象的思想了,一种比较方便的做法是直接创建一个类,取名为Chess,针对悔棋这个环节来做。
实际操作——悔棋
- 另定义一个类,取名为chess,来把棋子对象化
- 用this调用行-r,列-c,棋子标识-chessFlag
public class Chess { int r,c,chessFlag; public Chess(int r,int c,int chessFlag){ this.r=r; this.c=c; this.chessFlag=chessFlag; } }
- 并在GoListener类中,我们之前将chessFlag存入二维数组的代码下面初始化chess对象
Chess chess=new Chess(r,c,chessFlag);
这时候我们先思考一下,悔棋要用到什么工具方便操作,棋子落子我们用到的是二维数组,但是悔棋操作是有顺序的,而且一般来说,我们不需要在意黑棋白棋的悔棋,点击悔棋只需要返回当前状态的上一个状态即可,所以其实只需要一维数组就可以解决,而且一维数组还天然的有顺序,这样还可以确保悔棋的准确性。
- 初始化一个叫chessList的一维数组,同时定义一个变量,来标记棋子的顺序下标
private Chess[] chessList=new Chess[ROWS*COLS]; private int chessIndex=0;//棋子的顺序下标
- 在mousePressed方法中,把棋子对象存入顺序数组chessList,通过
public void mousePressed(MouseEvent e){ int x=e.getX(); int y=e.getY(); System.out.println("x:"+x+"y:"+y); int r=(y-Y+SIZE/2)/SIZE; int c=(x-X+SIZE/2)/SIZE; System.out.println("r"+r+"c"+c); if(chessFlag==0){ JOptionPane.showMessageDialog(null,"请点击开始游戏按钮"); return; } //判断下棋的范围,要在0-14 if(x<=X-SIZE/2||y<=Y-SIZE/2||r<0||r>=ROWS||c<0||c>=COLS){ JOptionPane.showMessageDialog(null,"此处不能下棋"); return; } //判断不能重复下棋 if(chessArray[r][c]!=0){ JOptionPane.showMessageDialog(null,"此处已经有棋子了"); return; } //将棋子的标识存入二维数粗 chessArray[r][c]=chessFlag; Chess chess=new Chess(r,c,chessFlag); //把棋子对象存入顺序数组 chessList[chessIndex]=chess; chessIndex++; if(chessFlag==1){ g.setColor(Color.BLACK); chessFlag=2; }else if(chessFlag==2){ g.setColor(Color.WHITE); chessFlag=1; } //让棋子准确落子 int cx=c*SIZE+X-SIZE/2; int cy=r*SIZE+Y-SIZE/2; g.fillOval(cx,cy,SIZE,SIZE); //每次下棋之后判断输赢 boolean isWin=GoWinUtils.isWin(chessArray,chess.r,chess.c); if(isWin) { JOptionPane.showMessageDialog(null, chess.chessFlag == 1 ? "黑棋胜利" : "白棋胜利"); chessFlag = 0; chessIndex = 0; } printChessArray(); }
- 同时要确保最后一个棋子是无法悔棋的,在GoListener类中创建一个方法,取名rchess
public void rChess(){ //下面是关于如何设置悔棋的操作 //1.判断ChessIndex是否等于1 if(chessIndex<=1){ JOptionPane.showMessageDialog(null,"不能继续悔棋了"); return; } //2.根据chessIndex获取棋子对象的信息 Chess chess=chessList[chessIndex-1]; //3.根据棋子对象的行列值,删除二维数组对应位置的1或者2,变成0 chessArray[chess.r][chess.c]=0; //4.将chessFlag的值设置为被撤回的棋子的chessFlag的值 chessFlag=chess.chessFlag; //5.删除棋子顺序数组中最后一颗棋子 chessList[chessIndex-1]=null; //6.把棋子的顺序下标减去1 chessIndex--; //7.刷新棋盘,实现重绘棋盘和棋子 chessPanel.paint(g); }
- 并在actionPerformed的方法中,在之前退出游戏判断语句和开始结束游戏判断语句中插入用于悔棋的else语句,用this关键字调用rChess
public void actionPerformed(ActionEvent e) { //获取按钮上的字符串 String action=e.getActionCommand(); //获取按钮对象 Object source=e.getSource(); //转型成按钮对象 JButton btn=(JButton) source; if(action.equals("开始游戏")){ chessFlag=1; //把按钮的文本修改为:结束游戏 btn.setText("结束游戏"); }else if(action.equals("结束游戏")){ chessFlag=0; btn.setText("开始游戏"); /*接下来要做的是清空棋盘 1.删除二维数组中的数据 2.刷新面板 */ this.clearChessArray(); chessPanel.paint(g); }else if(action.equals("悔棋")){ this.rChess(); }else if(action.equals("退出游戏")){ System.exit(0); } }
-
这样我们就实现了悔棋
启发
基于此项目,其实有一定基础的读者也可以想想有什么更好的办法来实现这个操作,比如采用链表