• 安卓项目五子棋代码详解(四)


    前几期介绍完了各种方法,就是可以实现下棋的功能了,但是,还无法判断输赢,这一期就是讲解判断输赢的方法

    正文开始———

    首先,我们得声明两个boolean类型的变量

    private boolean IsGameOver; //判断游戏是否结束
    private boolean IsWhitewin; //判断白棋是否胜利

    两个变量的作用已经注释了,这里便不解释了

    之后,定义一个方法来实现判断输赢,在这个方法之中还加入了弹出对话框与Toast提示,具体的之后详解

    private void checkGameover() {
            boolean whitewin = checkFiveInline(Whitearray);
            boolean blackwin = checkFiveInline(Blackarray);
            boolean textflag = false;
            if(whitewin){
                IsGameOver = true;
                IsWhitewin = true;
                textflag = true;
                showDlog("白棋胜利");
            }
            if(blackwin){
                IsGameOver = true;
                IsWhitewin = false;
                textflag = true;
                showDlog("黑棋胜利");
            }
            if(textflag){
            String text = IsWhitewin?"白棋胜利":"黑棋胜利";
            Toast.makeText(getContext(), text, Toast.LENGTH_SHORT).show();
            }
        }

    这里代码有点多,我一个个解释。

    首先,我定义了两个两个boolean变量用来判断游戏中是白棋胜利还是黑棋胜利,这两个boolean的值由checkFiveInLine()方法返回可得

    checkFiveInLine()中传入的参数就是白棋坐标和黑棋坐标

    private boolean checkFiveInline(List<Point> myarray) {
            for(Point p:myarray){
                int x = p.x;
                int y = p.y;
                boolean flag = checkHorizontal(x , y ,myarray)||checkVertical(x,y,myarray)||checkLeftDiagonal(x,y,myarray)||checkRightDiagonal(x,y,myarray);
                if(flag){
                    return true;
                }
            }
                return false;
        }

     这里中,for(Point p:myarray)这一个循环其实是相当于for(Point p=0;p<myarray.length();p++),用来遍历Point型数组myarray的,每一次访问数组myarray的时候读取的数据放入Point型的p中

    得到的横坐标与纵坐标给x与y,之后再是声明一个boolean类型的flag变量,将x与y作为参数传入到横向,纵向,斜向是否有五子方法中,之后由检查横向,纵向,斜向是否有五子方法的返回值经过逻辑与的逻辑计算得到数值

    逻辑与计算,只要有一个为真,结果都是为真

    flag有数值之后,再用一个if语句判断并返回boolean数值

    检查横向,纵向,斜向是否有五子方法代码如下,具体的都有注释了,这里需要注意的是,x和y坐标原点是在屏幕左上角,也就是说,x+是往右边,y+是往下边,这里应该不难,理解一个就是能举一反三了

    //水平方向检查是否五子
        private boolean checkHorizontal(int x,int y,List<Point> myarray){
            int count=1;
            //右边检查是否五子
            for(int i = 1;i < 5; i++){
                if (myarray.contains(new Point(x+i,y))) {
                   count++;
                 }else {
                    break;
                }
           }
           if (count == 5) {
               return true;
           }
           //左边检查是否五子
           for(int i = 1;i < 5; i++){
               if (myarray.contains(new Point(x-i,y))) {
                   count++;
               }else {
                    break;
               }
           }
           if (count == 5) {
               return true;
           }
    
            return false;
        }
        
        //垂直方向检查五子
        private boolean checkVertical(int x,int y,List<Point> myarray){
            int count=1;
            //下边检查是否五子
            for(int i = 1;i < 5; i++){
                if (myarray.contains(new Point(x,y+i))) {
                   count++;
                 }else {
                    break;
                }
           }
           if (count == 5) {
               return true;
           }
           //上边检查是否五子
           for(int i = 1;i < 5; i++){
               if (myarray.contains(new Point(x,y-i))) {
                   count++;
               }else {
                    break;
               }
           }
           if (count == 5) {
               return true;
           }
            return false;
        }
        
        //左斜方向检查是否五子
        private boolean checkLeftDiagonal(int x,int y,List<Point> myarray){
            int count=1;
            //左上角向右下角检查是否五子
            for(int i = 1;i < 5; i++){
                if (myarray.contains(new Point(x+i,y+i))) {
                   count++;
                 }else {
                    break;
                }
           }
           if (count == 5) {
               return true;
           }
           //右下角向左上角检查是否五子
           for(int i = 1;i < 5; i++){
               if (myarray.contains(new Point(x-i,y-i))) {
                   count++;
               }else {
                    break;
               }
           }
           if (count == 5) {
               return true;
           }
    
            return false;
        }
        //右斜方向检查是否五子
        private boolean checkRightDiagonal(int x,int y,List<Point> myarray){
            int count=1;
            //左下角向右上角检查是否五子
            for(int i = 1;i < 5; i++){
                if (myarray.contains(new Point(x+i,y-i))) {
                   count++;
                 }else {
                    break;
                }
           }
           if (count == 5) {
               return true;
           }
           //右上角想左下角检查是否五子
           for(int i = 1;i < 5; i++){
               if (myarray.contains(new Point(x-i,y+i))) {
                   count++;
               }else {
                    break;
               }
           }
           if (count == 5) {
               return true;
           }
    
            return false;
        }

    回到checkGameOver()这个方法中来,先忽略掉textflag这个boolean变量,前面的两个boolean变量已经获得了数值,之后便是由两个if语句判断,之后给相应的全局变量赋值其实赋值的话可以提取出来放在两个if语句之后,或者作为一个方法,这样的话可以省一些代码,不过,为了方便理解,我就是写进了if语句之中),到这一步是可以判断输赢了,但是还是可以画棋子的,我们还需要在onTouchEvent事件中加入一个if判断,如果IsGameOver这个boolean变量数值为true的话,就返回一个false,不执行下面的触摸事件,也就是不能再画棋子

    if(IsGameOver){
                return false;
            }
    private void checkGameover() {
            boolean whitewin = checkFiveInline(Whitearray);
            boolean blackwin = checkFiveInline(Blackarray);
            boolean textflag = false;
            if(whitewin){
                IsGameOver = true;
                IsWhitewin = true;
                textflag = true;
                showDlog("白棋胜利");
            }
            if(blackwin){
                IsGameOver = true;
                IsWhitewin = false;
                textflag = true;
                showDlog("黑棋胜利");
            }
            if(textflag){
            String text = IsWhitewin?"白棋胜利":"黑棋胜利";
            Toast.makeText(getContext(), text, Toast.LENGTH_SHORT).show();
            }
        }

     虽然上面所说可以判断一个游戏的输赢,但是没有提示玩家怎么知道谁输谁赢,所以我们就得弄一个Toast提示,个人觉得加了一个Toast体验还不够好,于是就是再多加了一个对话框提示,在游戏结束的时候弹出。

    在这里就先说Toast,首先声明了一个textflag的boolean变量,用来判断状态,由最后一个if语句判断,由textflag的数值我们可以知道,最后一个的if语句中的代码一定会执行

    解释一下

    String text = IsWhitewin?"白棋胜利":"黑棋胜利";

    上面的代码相当于下面

    if(IsWhitewin==true){
      String text = "白棋胜利";
    }else{
      String text = "黑棋胜利";
    }

     之后调用Toast的makeTex()t的show()方法弹出Toast

    getContext()是View提供的一个获取View显示的当前的activity方法

    我自己写了一个对话框,那个showDlog就是我自己定义的用来实现弹出对话框的方法

    showDlog()方法如下

    //弹出对话框
        private void showDlog(String winner) {
            AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
            builder.setTitle("对战结果");
            builder.setMessage(winner);
    
            builder.setPositiveButton("确定", new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    dialog.cancel();
                }
            }).setNegativeButton("再来一局", new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    dialog.cancel();
                    restart();
                }
            });
            builder.create().show();
    
        }

     在游戏结束的时候弹出对话框,提示胜利的一方,之后下面有着两个按钮,一个是确定,另外一个是再来一局,我为这两个按钮设置了监听器,当用户点击确定按钮的时候,就会取消对话框,当用户点击再来一局按钮的时候,就会取消对话框,同时再来一局,可以看到,再来一局按钮的onClick()方法中有一个定义的方法restart()方法,这个方法就是用来实现再来一局的功能

    代码如下

     

    public void restart(){//重新开始
            Whitearray.clear();
            Blackarray.clear();
            IsGameOver = false;
            IsWhitewin = false;
            invalidate();
            
        }

    清除数组里的坐标,改变两个boolean变量的数值,之后用invalidate()方法刷新界面

     

    到这里,一个能玩的五子棋安卓项目就是弄好了,详解正式完结了~撒花~~撒花~~

     

    众人:喂,你更换背景的功能还没有讲呢?

     

    (⊙o⊙)哦,差点忘了,还有我自定义的个性功能啊,嗯,那就多加一期,下一期见了!!

     

  • 相关阅读:
    POJ3889Fractal Streets
    POJ3263 Tallest Cow
    tyvjP1288 飘飘乎居士取能量块
    洛谷P3369 【模板】普通平衡树(Treap/SBT)
    洛谷P1063 能量项链 [2006NOIP提高组]
    洛谷P1541 乌龟棋 [2010NOIP提高组]
    POJ3322 Bloxorz I
    BZOJ1218:[HNOI2003]激光炸弹
    TyvjP1266 费解的开关
    洛谷P3070 [USACO13JAN]岛游记Island Travels
  • 原文地址:https://www.cnblogs.com/stars-one/p/7413565.html
Copyright © 2020-2023  润新知