五子棋
- 功能分析
-
- 功能实现
-
- Code
-
- Fivechess
- FivechessLisenter
- Fiveface
- Fivepreserve
- Fiveshape
- FivechessLisenter
- FivechessUI
- IsWin
功能分析
轮流下棋
- 下棋:
- 将棋子放置在棋盘线上的交叉点上
- 轮流下棋
悔棋
功能实现
界面绘制与更新
- 界面绘制:
- 可用JPanel将其分为下棋区域和按钮区域
- 重写paint方法,使得每次拖动棋盘都会更新一次
悔棋
Code
Fivechess
public void showUI(){
JFrame jf=new JFrame();
jf.setTitle("五子棋");
jf.setSize(800,800); jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel jbupl=new JPanel();
jf.add(jbupl,BorderLayout.EAST);
Fiveshape fiveshape=new Fiveshape();
jf.add(fiveshape,BorderLayout.CENTER);
fiveshape.setBackground(Color.WHITE);
FivechessLisenter fivechessLisenter=new FivechessLisenter();
- 设置一个初始化按钮面板的方法,给按钮面板设置大小、颜色、排布的位置、按钮名
public void initjbu(ActionListener actionListener,JPanel jPanel){
Dimension dimension=new Dimension(125,300);
jPanel.setLayout(new BorderLayout());
JPanel njp=new JPanel();
JPanel sjp=new JPanel();
njp.setBackground(Color.PINK);
sjp.setBackground(Color.orange);
njp.setPreferredSize(dimension);
sjp.setPreferredSize(dimension);
jPanel.add(njp,BorderLayout.NORTH);
jPanel.add(sjp,BorderLayout.SOUTH);
Dimension dimension1=new Dimension(120,45);
String name[]={"开始游戏","悔棋","暂停","结束游戏"};
String name1[]={"白棋","黑棋"};
for (int i = 0; i < name.length; i++) { jbuchess(fivechessLisenter,dimension1,Color.pink,name[i],njp );
}
for (int i = 0; i < name1.length; i++) { jbuchess(fivechessLisenter,dimension1,Color.ORANGE,name1[i],sjp );
}
}
public void jbuchess(ActionListener actionListener,Dimension dimension,Color color,String string,JPanel jPanel){
JButton jButton=new JButton(string);
jButton.addActionListener(actionListener);
jButton.setBackground(color);
jButton.setPreferredSize(dimension );
jPanel.add(jButton);
}
initjbu(fivechessLisenter,jbupl);
jf.setVisible(true);
FivechessLisenter
- 监听器继承鼠标监听器、动作监听器,在属性栏设置:重绘棋子类对象、画笔对象、二维数组范围、创建一个公共类对象、int 对象初始化的值
public class FivechessLisenter implements MouseListener, ActionListener,Fiveface {
Graphics g;
Fiveshape fiveshape;
int [][]chessArr=new int[L+1][R+1];
ArrayListfivepreserveArrayList=new ArrayList<>();
int count=1;
- 在按下的方法中,直接运用,判断为“开始游戏”时开始下棋,执行封装的判断输赢的方法
public void mousePressed(MouseEvent e) {
int x = e.getX();
int y = e.getY();
if(str.equals("开始游戏")){
chess(x, y);
IsWin.isWin(chessArr,ChessL,ChessR,chessFlag);
chessFlag=3-chessFlag;
}
}
- 将轮流下棋设置成一个封装方法,设置x、y矫正的位置及还原的坐标点,
- 判断数组长度等于0时,在判断矫正点是否为1,为1时话黑棋数组对象chessArr的长度赋值给int 对象,创建一个棋子类对象(矫正位置及判定条件),将保存的棋子类对象调用添加到公共类中
- 画3D棋子、画完黑棋接着画白棋,白棋方法与黑棋方法一致
-可将上述判断条件
public void chess(int x,int y){
int ChessL = (x - X + Size / 2) / Size;
int ChessR = (y - Y + Size / 2) / Size;
int ChessX = ChessL * Size + X - Size / 2;
int ChessY = ChessR * Size + Y - Size / 2;
if(chessArr[ChessL][ChessR]==0){
if (chessFlag==1) {
chessArr[ChessL][ChessR]=chessFlag;
Fivepreserve black=new Fivepreserve(ChessR,ChessL,chessFlag);
fivepreserveArrayList.add(black);
for (int i = 0; i < Size; i++) {
g.setColor(new Color(i * 3, i * 3, i * 3));
g.fillOval(ChessX + i / 2, ChessY + i / 2, Size - i, Size - i);
chessFlag = 2;
}
} else if (chessFlag == 2) {
chessArr[ChessL][ChessR] = chessFlag;
Fivepreserve white = new Fivepreserve(ChessR, ChessL, chessFlag);
fivepreserveArrayList.add(white);
for (int i = 0; i < Size; i++) {
g.setColor(new Color(i + 205, i + 205, i + 205));
g.fillOval(ChessX + i / 2, ChessY + i / 2, Size - i, Size - i);
chessFlag = 1;
}
}
}else {
return;
}
}
Fiveface
- 单独创建一个接口,写其需要用到的常量属性,方便后面被用到
int X=100;
int Y=100;
int L=10;
int R=10;
int Size=50;
Fivepreserve
- 创建一个保存棋子的类,写其属性及保存的方法,当前类调用申明的变量 赋值给参数(为了保存)
public class Fivepreserve {
int chessR;
int chessL;
int chessNum;
int chessFlag;
public Fivepreserve( int chessR,int chessL,int chessNum,int chessFlag){
this.chessR=chessR;
this.chessL=chessL;
this.chessNum=chessNum;
this.chessFlag=chessFlag;
}
}
Fiveshape
- 创建一个重绘棋子的类,继承JPanel、接口,申明一个二位数组对象,继承JPanel中的paint重绘方法,画棋盘线,画棋子
public class Fiveshape extends JPanel implements Fiveface{
int [][]chessArr;
public void paint(Graphics g) {
super.paint(g);
drawline(g);
drawchess(g);
System.out.println("A");
}
public void drawline(Graphics g){
for (int i = 0; i <11 ; i++) {
g.drawLine(X,Y+i*Size,X+Size*L,Y+i*Size);
g.drawLine(X+i*Size,Y+Size*L,X+i*Size,Y);
}
}
- 设置画棋子的封装方法,for循环二维数组中的一位数组的长度,再for循环一维数组中的长度,申明一个变量赋值给二维数组对象,判定下白棋还是黑棋
public void drawchess(Graphics g){
for (int i = 0; i
FivechessLisenter
- 在监听器中设置一个悔棋的方法,申明一个int对象赋值给公共类保存棋子类对象调用得到的
- 申明一个保存类对象赋值给公共类对象调用得到值,且在此基础上逐一递减1
- 数组对象长度赋值为0,判断size-1不为0时,执行size-1,否则无法悔棋,重绘
public void huiqi() {
int size = fivepreserveArrayList.size();
Fivepreserve fivepreserve = fivepreserveArrayList.get(size - 1);
chessArr[fivepreserve.chessL][fivepreserve.chessR] = 0;
if (size - 1 != 0) {
fivepreserveArrayList.remove(size - 1);
} else {
System.out.println("无法悔棋");
}
chessFlag = fivepreserve.chessFlag;
fiveshape.repaint();
}
- 动作监听器方法中判断是否为“悔棋”,为“悔棋”执行悔棋的封装方法
public void actionPerformed(ActionEvent e) {
String str=e.getActionCommand();
if( str.equals("悔棋")){
huiqi();
}
}
FivechessUI
- 申明画笔对象赋值为重绘的棋子类对象调用得到的画笔对象,将监听器对象添加到重绘棋子类对象中
- 监听器对象调用画笔对象、重绘的棋子类对象,赋值给申明的画笔对象、重绘的棋子类对象,重绘的棋子类对象调用数组对象赋值给监听器调用数组对象
Graphics g=fiveshape.getGraphics();
fiveshape.addMouseListener(fivechessLisenter);
fivechessLisenter.g=g;
fivechessLisenter.fiveshape=fiveshape;
fiveshape.chessArr= fivechessLisenter.chessArr;
IsWin
- while:多次循环结构,while计算的的表达式必须是boolean值,直至ture(执行{}中所有的代码)/false(否则false),用while是为了多次执行
- 写四个方位的判断输赢,分别为横向、纵向、以及两个斜方向的
public class IsWin {
//(横向)
static int winL_R(int[][] chessArr, int m, int n) {
int count = 0;
for (int i = n; i < chessArr.length-1; i++) {
if (chessArr[m][n] == chessArr[m][i]) {
count++;
} else {
break;
}
}
for (int i = n-1; i > 0; i--) {
if (chessArr[m][n] == chessArr[m][i]) {
count++;
} else {
break;
}
}
// System.out.println("count:"+count);
return count;
}
//纵向
static int winU_D(int[][] chessArr, int m, int n) {
int count = 0;
for (int i = m; i < chessArr.length-1; i++) {
if (chessArr[m][n] == chessArr[i][n]) {
count++;
} else {
break;
}
}
for (int i = m-1; i >0; i--) { if (chessArr[m][n] == chessArr[i ][n]) {
count++;
} else {
break;
}
}
// System.out.println("count:"+count);
return count;
}
// 斜方向(左下右上)的方向
static int winLD_RU(int[][] chessArr, int m, int n) {
int count = 0;
int i = m;
int j = n;
while (i >0 && j < chessArr.length-1) {
if (chessArr[m][n] == chessArr[i ][j ]) {
count++;
i--;
j++;
} else {
break;
}
}
i = m;
j = n;
while (i < chessArr.length-1 && j >0) {
if (chessArr[m][n] == chessArr[i+1 ][j-1 ]) {
count++;
i++;
j--;
} else {
break;
}
}
System.out.println("count:"+count);
return count;
}
// 斜方向(左上右下)的方向
static int winLU_RD(int[][] chessArr, int m, int n) {
int count = 0;
int i = m;
int j = n;
while (i < chessArr.length-1 && j < chessArr.length-1) {
if (chessArr[m][n] == chessArr[i+1][j+1]) {
count++;
i++;
j++;
} else {
break;
}
}
i = m;
j = n;
while (i > 0 && j > 0) {
if (chessArr[m][n] == chessArr[i ][j ]) {
count++;
i--;
j--;
} else {
break;
}
}
System.out.println("count:"+count);
return count;
}
//判断输赢的静态方法
static void isWin(int[][] chessarr,int m,int n,int chessFlag) {
System.out.println("chessFlag"+chessFlag);
if(winL_R ( chessarr,m,n)>=5|winU_D ( chessarr,m,n)>=5|winLD_RU( chessarr,m,n)>=5|winLU_RD( chessarr,m,n)>=5){
if(chessFlag==1){
System.out.println( "黑棋赢了");
}else if(chessFlag==2){
System.out.println( "白棋赢了");
}
}else {
return;
}
}
}