Java五子棋(2)

一、简述      

  上一期讲了五子棋主界面的布局和棋盘绘制,以及按钮就功能的实现,本期来讲解棋子绘制以及棋子连珠判断。

二、棋子绘制

        1、坐标获取

                为了能够绘制出棋子,首先需要知道鼠标点击时的坐标。因此这里需要使用鼠标监听器中的mouseClicked方法。

public void mouseClicked(MouseEvent e) {

        x = e.getX();
        y = e.getY();
}

        2、坐标处理    

            接下来是坐标处理,将获取到的鼠标坐标进行变换,目的是为了后续能够保存和画出棋子。

                首先是使棋子能够落在网格的交点上,实现思路如下:以第一个交点为圆心,两个交点之间一半的距离为半径划定一个圆形区域,如果鼠标在该区域内点击,就需要将点击的坐标矫正到圆心的坐标。具体实现效果如下:

 public void mouseClicked(MouseEvent e) {
        //x矫正
        //x在前一个交点附近
        if ((x - X0) % SIZE > SIZE / 2) {
            setX = (x - X0) / SIZE + 1;
        } else {
            //x在后一个交点附近
            setX = (x - X0) / SIZE;
        }
        //y矫正
        if ((y - Y0) % SIZE > SIZE / 2) {
            setY = (y - Y0) / SIZE ;
        } else {
            setY = (y - Y0) / SIZE - 1;
        }
}

经过上述处理后,setX和setY将会返回一个以左上角为顶点的一个坐标系数。方便后续将棋子存入二维数组。

        3、棋子绘制

                接下来是落子的功能。这里需要将坐标转换为窗体的相对坐标

 public void mouseClicked(MouseEvent e) {
       DropChessX = setX * SIZE + X0;
       DropChessY = (setY + 1) * SIZE + Y0;
       //使棋子中心正对光标
       locationX = DropChessX - CHESS / 2 + 9;
       locationY = DropChessY - CHESS / 2 ;


 }

                创建画笔并画出棋子

  public void DrawChess(){
        Graphics g = this.getGraphics();
        //定义新对象实现画笔功能
        setColor1 = new GameMouse();
        setColor1.setColor = g;
        this.addMouseListener(setColor1);
    }

   public void mouseClicked(MouseEvent e) {

       //设置画笔颜色
       setColor.setColor(Color.BLACK);
       //绘制棋子
       setColor.fillOval(locationX, locationY, CHESS, CHESS);
    }

                运行效果如下

         4、交替下棋

                为了能够实现黑白交替下棋的效果,可以使用switch循环实现。而黑棋白棋的绘制和上述一样,将绘制功能的语句放入switch中即可

public void mouseClicked(MouseEvent e) {
        //设置循环判断参数
        int turn = 0;

        x = e.getX();
        y = e.getY();
        if ((x - X0) % SIZE > SIZE / 2) {
            setX = (x - X0) / SIZE + 1;
        } else {
            setX = (x - X0) / SIZE;
        }
        if ((y - Y0) % SIZE > SIZE / 2) {
            setY = (y - Y0) / SIZE ;
        } else {
            setY = (y - Y0) / SIZE - 1;
        }

        //循环判断处理,1为黑棋 , 2为白棋
        int NewTurn = turn % 2;
        DropChessX = setX * SIZE + X0;
        DropChessY = (setY + 1) * SIZE + Y0;
        locationX = DropChessX - CHESS / 2 + 9;
        locationY = DropChessY - CHESS / 2 ;
           
            
        switch (NewTurn){
           case 0:                 
             setColor.setColor(Color.BLACK);
             setColor.fillOval(locationX, locationY, CHESS, CHESS);
             turn += 1;
             break;
           case 1:
             setColor.setColor(Color.WHITE);
             setColor.fillOval(locationX, locationY, CHESS, CHESS);
             turn += 1;
                               
             break;
                 }
       }

运行效果如下

 三、棋局判断

        判断棋局首先要扫描棋盘,并将相同颜色的棋子转化为数值进行累加,最后判断是否相连,因此首先要实现的是将棋局存入二维数组中。

        1、棋局存储

                首先以棋盘的大小创建一个二维数组,之后在每次落子后将当前棋子的颜色存入数组中的对应位置即可

//定义一个二维数组,LINE为棋盘大小
public static int chessArr[][] = new int[LINE][LINE]; 

public void mouseClicked(MouseEvent e) {

        x = e.getX();
        y = e.getY();
        if ((x - X0) % SIZE > SIZE / 2) {
            setX = (x - X0) / SIZE + 1;
        } else {
            setX = (x - X0) / SIZE;
        }
        if ((y - Y0) % SIZE > SIZE / 2) {
            setY = (y - Y0) / SIZE ;
        } else {
            setY = (y - Y0) / SIZE - 1;
        }


      
        int NewTurn = turn % 2;
        DropChessX = setX * SIZE + X0;
        DropChessY = (setY + 1) * SIZE + Y0;
        locationX = DropChessX - CHESS / 2 + 9;
        locationY = DropChessY - CHESS / 2 ;
         
        switch (NewTurn){
          case 0:
                               
            setColor.setColor(Color.BLACK);
            setColor.fillOval(locationX, locationY, CHESS, CHESS);
            //记录棋局
            chessArr[setY][setX] = 1; // 1、为黑色 2、为白色
            turn += 1;
            break;
          case 1:
            setColor.setColor(Color.WHITE);
            setColor.fillOval(locationX, locationY, CHESS, CHESS);
            chessArr[setY][setX] = 2; // 1、为黑色 2、为白色
            turn += 1;
                              
            break;
                        }
                    }

        2、棋盘扫描

                棋盘扫描一共有八个方向,大致思想是从当前棋子开始向该棋子四周进行扫描,并将相同颜色的棋子进行累加。接下来将判断棋局进行分解

                水平方向

public int JudgeFlat(int r , int c){//r , c为当前棋子所在的行和列
        int count  = 1;

        //向右
        for (int i = c + 1 ; i < arr[r].length; i++) {
            if(arr[r][i] == arr[r][c]){
                count++;
            }else {
                break;
            }
        }

        //向左
        for(int i = c - 1 ; i >= 0 ; i --){
            if(arr[r][i] == arr[r][c]){
                count++;
            }else {
                break;
            }
        }
        return count;
    }

                竖直方向

public int JudgeVertical(int r , int c){
        int count = 1;
        //向下
        for (int i = r + 1 ; i < arr.length; i++) {
            if(arr[r][c] == arr[i][c]){
                count ++;
            }else {
                break;
            }
        }
        //向上
        for(int i = r - 1 ; i >= 0 ; i --){
            if(arr[r][c] == arr[i][c]){
                count ++;
            }else {
                break;
            }
        }
        return count;
    }

                对角线

public int JudgeTilt1(int r , int c){
        int count = 1;
        //右上角
        for (int i = c + 1 , a = r - 1 ; i < arr.length && a >= 0 ; i++ , a--) {
            if(arr[a][i] == arr[r][c]){
                count ++;
            }else {
                break;
            }
        }
        //左下角
        for (int j = r + 1 , b = c - 1 ; j < arr.length && b >= 0 ; j++ , b--) {
            if(arr[j][b] == arr[r][c]){
                count ++;
            }else {
                break;
            }
        }
        return count;
    }

    public int JudgeTilt2(int r , int c){
        int count = 1;
        //左上角
        for(int i = c - 1 , a = r - 1 ; i >= 0 && a >= 0 ; i -- , a --){
            if(arr[a][i] == arr[r][c]){
                count ++;
            }else {
                break;
            }
        }
        //右下角
        for (int j = c + 1 , b = r + 1 ; j < arr.length && b < arr.length ; j++ , b ++){
            if(arr[b][j] == arr[r][c]){
                count ++;
            }else {
                break;
            }
        }
        return count;
    }

本期为简单的人人对战的五子棋,下一期讲解如何让电脑下棋

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值