1 Gobang game

Posted by eranwein on Wed, 29 Dec 2021 07:21:16 +0100

Let me explain the development of a simple game: Gobang.

To realize Gobang, the first thing to do is to create a two-dimensional array and a chessboard. Maybe someone else's chessboard is created with canvas , but my chessboard is created with div element, because the label element can put a lot of data. For example, I put a div on the chess position of the chessboard, which can put user-defined attributes.

The border style of div needs to be fine tuned, or it can't be painted as neatly as canvas labels.

 for(let y=0;y<13;y++){
            chessboard[y]=new Array(y);
            for (let x=0;x<13;x++){
                chessboard[y][x]=0; //At first, all are set to 0, which means there are no pieces on the chessboard
               // While generating a two-dimensional array, create the coordinate position of the chess pieces on the chessboard
      if(y == 0){
        if (x == 0) {
            $(".box").append("<div class='Piece special-top special-left' x-index=" + x + " y-index=" + y + "></div>");
        } else if (x == 12) {
            $(".box").append("<div class='Piece special-top special-right' x-index=" + x + " y-index=" + y + "></div>");
        } else {
            $(".box").append("<div class='Piece special-top' x-index=" + x + " y-index=" + y + "></div>");
        }
    } else if (x == 0) {
        if (y != 12) {
            $(".box").append("<div class='Piece special-left' x-index=" + x + " y-index=" + y + "></div>");
        } else {
            $(".box").append("<div class='Piece special-left special-bottom' x-index=" + x + " y-index=" + y + "></div>");
        }
    } else if (x == 12) {
        if (y != 12) {
            $(".box").append("<div class='Piece special-right' x-index=" + x + " y-index=" + y + "></div>");
        } else {
            $(".box").append("<div class='Piece special-right special-bottom' x-index=" + x + " y-index=" + y + "></div>");
        }
    } else if (y == 12) {
        $(".box").append("<div class='Piece special-bottom' x-index=" + x + " y-index=" + y + "></div>");
    } else {
        $(".box").append("<div class='Piece' x-index=" + x + " y-index=" + y + "></div>");
    }
            }
        }

As shown in the figure above: it is the code to create a chessboard. First, you need to create a two-dimensional array. You can see that the two-dimensional array is a two-dimensional array corresponding to a 13 * 13 chessboard. While creating the array, a chessboard is also created. Each chess position corresponds to the values of x and y. the user-defined attribute of div is used to add value. The judgment in double for is used to fine tune the border of Div, Without these judgments, it would look ugly. The code is very simple and doesn't need to be talked about. There is also the creation of sparse arrays. Sparse arrays are used to simplify data judgment and the number of code execution. There is also the function of using sparse arrays when pausing saving explained later.

 

After the chessboard is generated, click the chess position to generate pieces

$(".box").on("click",".Piece",function(){
           //judge
          if($(this).children(".qizi").length>0){
               return; //Judge that there can be no more than one chess piece in the current position
           }
            let x=parseInt($(this).attr("x-index"));
            let y=parseInt($(this).attr("y-index"));
           let WchessOrBchess=1;
          let len=$(".box").children(".Piece").children(".qizi").length;
           if(len%2==0){ //Sunspot go
               $(this).append("<div class='qizi Bchess' data-qizi="+1+"></div>"); //0 is a sunspot
               $("#showQiZi").removeClass("Bchess").addClass("Wchess");
               $("#text").text(" white go ");
               WchessOrBchess=1;
           }else{ //Baizi go
               $(this).append("<div class='qizi Wchess' data-qizi="+2+"></div>"); //1 is Baizi
               $("#showQiZi").removeClass("Wchess").addClass("Bchess");
               $("#Text). Text ("black chess go");
               WchessOrBchess=2;
           }
            isNotReset=true;// This is used to judge that you can only regret one step at a time.
           tempPiece=$(this);//The function of this is to facilitate repentance and assign the parent of the clicked chess piece to a temporary variable
           isNotWin(WchessOrBchess,x,y);
       })

As shown in the code in the figure, because my chessboard is dynamically generated, I need to use jq's on to dynamically obtain. When I click, I will generate Gobang sunspots or whites on the corresponding chess position. How to judge? Because my setting is always black first, I only need to judge the number of pieces, and obtain the values of x-index and y-index attributes of the current chess position at the same time, Simultaneous changeThe style and text of this thing, and then set the global variable of repentance chess to true, that is, when you click repentance chess next time, call the isNotWin() method and pass in three parameters. The first parameter is used to judge whether it is white flag or black chess, and then pass in the corresponding index of x coordinate and y coordinate.

 

 

Let's look at the code of this method

        function isNotWin(WchessOrBchess,x,y){
            let len=$(".box").children(".Piece").children().length;

            //The operation here is to assign to a two-dimensional array
                  chessboard[y][x]=WchessOrBchess;
            //Add sparse array
                  sparseArr[len]=new Array();
                  sparseArr[0][2]=len;
                  sparseArr[len][0]=x;
                  sparseArr[len][1]=y;
                  sparseArr[len][2]=WchessOrBchess;
                
               // Judge when the pieces on the chessboard are greater than or equal to 9, which can save code execution
           if(len>=9){
         ergodicity(WchessOrBchess);
           }
}

In fact, this method is very simple, that is, assign the two-dimensional array to 1 or 2 corresponding to the two-dimensional array at the position of each click. 1 is a black chess, 2 is a white chess, and then a sparse array. Each click will increase the length of the sparse array. When the number of chess pieces is greater than or equal to 9, it will enter the function ergodicity to judge whether it is a winner or loser, You only need to pass in a parameter that is white or black,

 // This is to traverse the sparse array to judge the existing pieces
        function ergodicity(WchessOrBchess){
             let flag=false; 
              for (let i=1;i<sparseArr.length;i++){
                  // Wchessorb chesss is the round to judge sunspots or whites
                      if(sparseArr[i][2]==WchessOrBchess){
                     let x=sparseArr[i][0];
                     let y=sparseArr[i][1];
                   // Judge the position of the current chess piece and call four methods. If the method under one of the chess pieces extends to true, it will be returned and assigned flag=true;
                     if(Crosswise(x,y,WchessOrBchess)||
                        Lengthways(x,y,WchessOrBchess)||
                        InclinedUp(x,y,WchessOrBchess)||
                        InclinedDown(x,y,WchessOrBchess)){
                          flag=true;
                           break;
                        }
                      }
              }
             //The current flag ==true proves that it has won
             if(flag){
                 let qizi="";
                 let aft="";
                 if(WchessOrBchess==1){
                     qizi="Bchess";
                     aft="Black chess wins";
                 }else{
                     qizi="Wchess";
                     aft="White chess wins";
                 }
                layer.open({
                       title: 'The outcome is divided'
                       ,content:aft
                      ,btn: ['One more game']
                      ,skin: 'demo-class'
                      ,icon:6
                      ,success:function(){ //Pop up successful callback
        $("#layui-layer1").children(".layui-layer-content").append("<div class="+qizi+" ></div>");
                       }
                      ,yes: function(index, layero){
                        $("#layui-layer2")
                        $("#anew").click(); / / click restart to finish, which improves the reusability of the code
                        layer.close(index);  
                      }
                      ,cancel: function(){
                        $("#anew").click();
                      }
                    });
                }
              }

When calling this method, you only need to traverse the sparse array, take the passed parameters as the white or black chess existing in the sparse array, and judge whether it has the condition of victory. The main purpose is to call four methods to judge whether it has won. The four methods are the four victory modes of Gobang: 1, horizontal, 2 vertical, 3 oblique up and 4 oblique down. The code is as follows

        //First, judge the horizontal
        function(x,y,WchessOrBchess){
            //This judgment can prevent the index from crossing the boundary and reporting errors, and can also save code execution time
         if(x>=9){ //If x > = 9, it is not necessary to judge whether the horizontal wins or not, and return false directly
            return false;                
           }else{
               if(chessboard[y][x+1]==WchessOrBchess&&chessboard[y][x+2]==WchessOrBchess&&chessboard[y][x+3]==WchessOrBchess&&chessboard[y][x+4]==WchessOrBchess){
                   return true;
               }else{
                   return false;
               }
           }
        }
        //Judge whether it is vertical
        function Lengthways(x,y,WchessOrBchess){
            //x doesn't have to move, y doesn't
            if(y>=9){//This judgment can prevent the index from crossing the boundary and reporting errors, and can also save code execution time
               return false;     
            }else{
                if(chessboard[y+1][x]==WchessOrBchess&&chessboard[y+2][x]==WchessOrBchess&&chessboard[y+3][x]==WchessOrBchess&&chessboard[y+4][x]==WchessOrBchess){
                   return true;
               }else{
                   return false;
               }
            }
        }
        //Judge whether it is inclined upward 
        function InclinedUp(x,y,WchessOrBchess){
            // The x-axis must be greater than 3 and the y-axis must be less than 9. If it cannot be followed, return directly
            if(!(x>3&&y<9)){//This judgment can prevent the index from crossing the boundary and reporting errors, and can also save code execution time
             return false;        
            }
                 if(chessboard[y+1][x-1]==WchessOrBchess&&chessboard[y+2][x-2]==WchessOrBchess&&chessboard[y+3][x-3]==WchessOrBchess&&chessboard[y+4][x-4]==WchessOrBchess){
                   return true;
               }else{
                   return false;
               }
            }
        //Judge whether it is inclined downward
        function InclinedDown(x,y,WchessOrBchess){
            if(!(x<9&&y<9)){ //This judgment can prevent the index from crossing the boundary and reporting errors, and can also save code execution time
             return false;        
            }
                 if(chessboard[y+1][x+1]==WchessOrBchess&&chessboard[y+2][x+2]==WchessOrBchess&&chessboard[y+3][x+3]==WchessOrBchess&&chessboard[y+4][x+4]==WchessOrBchess){
                   return true;
               }else{
                   return false;
               }
        }

The judgment of the four methods shown in the figure should not be too simple. It is to predict whether the remaining four chess pieces under a specific rule are in this direction according to the current position of the first chess piece. It is necessary to judge whether the value is the same. If all pass, true will be returned. If true, for in the ergodicity method will directly return the victory signal.

I won't say much about the three methods defined at last. They are clearing chess pieces, clearing two-dimensional arrays and clearing sparse arrays. I won't say much. I directly go to all the code and add the plug-in of layui. If necessary, I can download and import it from the official website of layui

<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Gobang 1</title>
    <link rel="stylesheet" href="layuiDoc Offline manual/layui/dist/css/layui.css">
</head>
<style> 
    *{
        margin: 0;
        padding: 0;
    }
    .box{
    margin: 50px auto;
    margin-bottom: 0px;
    height: 600px;
    width: 600px;
    background: #F7E6B7;
    border: 1px solid #9E9E9E;
    overflow: hidden;
    border-radius: 8px;
    box-shadow: 0px 0px 5px 0px #9e9e9ed9;
    padding: 20px;
    }
    .btn{
        margin: 10px auto;
        width: 600px;
    }
    #button, #anew, #state, #winner,#suspend {
    margin-left: 10px;
    float: right;
    display: block;
    width: 50px;
    height: 50px;
    border-radius: 30px;
    outline: none;
    font-size: 13px;
    font-weight: 500;
    box-sizing: border-box;
    color: #00BCD4;
    background: #fff;
    border: none;
    box-shadow: 1px 1px 3px 1px #9e9e9e5e;
    user-select: none;
    }
    html, body {
    width: 100%;
    height: 100%;
    margin: 0;
    padding: 0;
    overflow: hidden;
    background: #e6e7ec;
}
    #state {
    width: 130px;
    float: right;
    display: flex;
    align-content: center;
    
}

 .chessName, #winner {
    width: 60px;
    height: 30px;
    text-align: center;
    line-height: 30px;
    font-size: 18px;
}
    .chessName{
         margin: auto 0px;
        font-weight: 600;
    }
    .Wchess{
    width: 35px;
    height: 35px;
    border-radius: 50%;
    background: radial-gradient( #e4e4e4 10%,#b7aaaa);
    box-shadow: 1px 1px 2px 0px #0000006e;
    font-size: 10px;
    line-height: 27px;
    text-align: center;
    color: #000000;
    margin: auto 10px;
}
   .Bchess{
    width: 35px;
    height: 35px;
    border-radius: 50%;
    background: radial-gradient(#9E9E9E -100%, #000000 100%);
    box-shadow: 1px 1px 2px 0px #0000006e;
    font-size: 12px;
    font-weight: 500;
    line-height: 27px;
    text-align: center;
    color: #fff;
    margin: auto 10px;
    }
    #anew:hover {
    transition: 1s all;
    background: #1bb556;
    color: #fff;
}
    #button:hover{
    transition: 1s all;
    background: #01BCFF;
    color: #fff;
}
    .Piece .qizi{
    width: 37px;
    height: 37px;
    margin: 3.3px;

}
    .Piece{
        width: 7.33%;
        float: left;
        height: 7.33%;
        border: 1px solid rgba(199,167,130,1.00);
    }
    /*bottom right  top*/
    .special-left{
         border-left: 2px solid rgba(199,167,130,1.00);
    }
    .special-bottom{
           border-bottom: 2px solid rgba(199,167,130,1.00);
     }
    .special-right{
          border-right: 2px solid rgba(199,167,130,1.00);
}
    .special-top{
        border-top: 2px solid rgba(199,167,130,1.00);
    }
    body .demo-class .layui-layer-title{background:rgba(71,173,237,1.00); color:#fff; border: none;}
body .demo-class .layui-layer-btn{border-top:1px solid #E9E7E7}
body .demo-class .layui-layer-btn a{background:rgba(240,149,69,1.00);}
body .demo-class .layui-layer-btn .layui-layer-btn1{background:#999;}
    .layui-layer-content .Bchess{
        margin: 0px;
        position: absolute;
     top: 15px;
    left: 15px;
    }
     .layui-layer-content .Wchess{
    margin: 0px;
    position: absolute;
    top: 15px;
    left: 15px;
    }
    </style>
<body>
    <!-- Making Gobang-->
    <div class="box">
        <!-- Make a 13*13 Chessboard-->
            <!--<div class="Piece"></div>-->
    </div>
    <div class="btn">
                <div id="state">
		<div class="Bchess" id="showQiZi" ></div>
		<div class="chessName" id="text">Black chess go</div>
	</div>
    <button id="button">Repentance chess</button>
    <button id="anew">Reopen</button>
    <button id="suspend" class="layui-btn layui-btn-radius layui-btn-warm">Pause save</button>
    </div>
</body>
    <script src="Application and attempt/jq/jquery-3.2.1.min.js"></script>
    <script src="layuiDoc Offline manual/layui/dist/layui.js"></script>
    <script>
    $(function(){
        var layer;
        var isNotReset=false; // The initial global variable is false, indicating
        var tempPiece;
        layui.use(["layer"],function(){
            layer=layui.layer;
        })
        //Repentance chess

        //Create a 2D array
        let chessboard=Array();
        //Create sparse array
        let sparseArr=new Array();
           sparseArr[0]=new Array();
                  sparseArr[0][0]=13;
                  sparseArr[0][1]=13;
                  sparseArr[0][2]=0;
         //Generate a two-dimensional array and generate a chessboard
        for(let y=0;y<13;y++){
            chessboard[y]=new Array(y);
            for (let x=0;x<13;x++){
                chessboard[y][x]=0; //At first, all are set to 0, which means there are no pieces on the chessboard
               // While generating a two-dimensional array, create the coordinate position of the chess pieces on the chessboard
      if(y == 0){
        if (x == 0) {
            $(".box").append("<div class='Piece special-top special-left' x-index=" + x + " y-index=" + y + "></div>");
        } else if (x == 12) {
            $(".box").append("<div class='Piece special-top special-right' x-index=" + x + " y-index=" + y + "></div>");
        } else {
            $(".box").append("<div class='Piece special-top' x-index=" + x + " y-index=" + y + "></div>");
        }
    } else if (x == 0) {
        if (y != 12) {
            $(".box").append("<div class='Piece special-left' x-index=" + x + " y-index=" + y + "></div>");
        } else {
            $(".box").append("<div class='Piece special-left special-bottom' x-index=" + x + " y-index=" + y + "></div>");
        }
    } else if (x == 12) {
        if (y != 12) {
            $(".box").append("<div class='Piece special-right' x-index=" + x + " y-index=" + y + "></div>");
        } else {
            $(".box").append("<div class='Piece special-right special-bottom' x-index=" + x + " y-index=" + y + "></div>");
        }
    } else if (y == 12) {
        $(".box").append("<div class='Piece special-bottom' x-index=" + x + " y-index=" + y + "></div>");
    } else {
        $(".box").append("<div class='Piece' x-index=" + x + " y-index=" + y + "></div>");
    }
            }
        }
        
       
        //When I click on a chess position on the chessboard, the corresponding chess pieces are generated
       $(".box").on("click",".Piece",function(){
           //judge
          if($(this).children(".qizi").length>0){
               return; //Judge that there can be no more than one chess piece in the current position
           }
            let x=parseInt($(this).attr("x-index"));
            let y=parseInt($(this).attr("y-index"));
           let WchessOrBchess=1;
          let len=$(".box").children(".Piece").children(".qizi").length;
           if(len%2==0){ //Sunspot go
               $(this).append("<div class='qizi Bchess' data-qizi="+1+"></div>"); //0 is a sunspot
               $("#showQiZi").removeClass("Bchess").addClass("Wchess");
               $("#text").text(" white go ");
               WchessOrBchess=1;
           }else{ //Baizi go
               $(this).append("<div class='qizi Wchess' data-qizi="+2+"></div>"); //1 is Baizi
               $("#showQiZi").removeClass("Wchess").addClass("Bchess");
               $("#Text). Text ("black chess go");
               WchessOrBchess=2;
           }
            isNotReset=true;// This is used to judge that you can only regret one step at a time.
           tempPiece=$(this);//The function of this is to facilitate repentance and assign the parent of the clicked chess piece to a temporary variable
           isNotWin(WchessOrBchess,x,y);
       })
        
        
        //Repentance chess can only retreat one space, and repentance chess can only be played once each time
        $("#button").click(function(){
            if(isNotReset){
                 //Start with sparse arrays
            let num=sparseArr[0][2];
                 //Delete the element first
                tempPiece.empty();
                 //Then set the 2D array to 0
            let x=sparseArr[num][0];//x coordinate of chess piece
            let y=sparseArr[num][1];//y coordinate of chess pieces
            let val=sparseArr[num][2];//y coordinate of chess pieces
                chessboard[y][x]=0;
            // Then the sparse array deletes the last element
               sparseArr.pop();
                //Finally, judge who withdrew
                if(val==1){
               $("#showQiZi").removeClass("Wchess").addClass("Bchess");
               $("#Text). Text ("black chess go");
                }else{
               $("#showQiZi").removeClass("Bchess").addClass("Wchess");
               $("#text").text(" white go "); 
                }
                //Check whether the data is aligned
                sparseArr[0][2]=num-1;
                console.log(chessboard);
                console.log(sparseArr);
            }else{
              alert("I can't repent");
                return;
            }
            isNotReset=false;
        })
        
        function isNotWin(WchessOrBchess,x,y){
            let len=$(".box").children(".Piece").children().length;

            //The operation here is to assign to a two-dimensional array
                  chessboard[y][x]=WchessOrBchess;
            //Add sparse array
                  sparseArr[len]=new Array();
                  sparseArr[0][2]=len;
                  sparseArr[len][0]=x;
                  sparseArr[len][1]=y;
                  sparseArr[len][2]=WchessOrBchess;
                
               // Judge when the pieces on the chessboard are greater than or equal to 9, which can save code execution
           if(len>=9){
         ergodicity(WchessOrBchess);
           }
}
        
        
        // This is to traverse the sparse array to judge the existing pieces
        function ergodicity(WchessOrBchess){
             let flag=false; 
              for (let i=1;i<sparseArr.length;i++){
                  // Wchessorb chesss is the round to judge sunspots or whites
                      if(sparseArr[i][2]==WchessOrBchess){
                     let x=sparseArr[i][0];
                     let y=sparseArr[i][1];
                   // Judge the position of the current chess piece and call four methods. If the method under one of the chess pieces extends to true, it will be returned and assigned flag=true;
                     if(Crosswise(x,y,WchessOrBchess)||
                        Lengthways(x,y,WchessOrBchess)||
                        InclinedUp(x,y,WchessOrBchess)||
                        InclinedDown(x,y,WchessOrBchess)){
                          flag=true;
                           break;
                        }
                      }
              }
             //The current flag ==true proves that it has won
             if(flag){
                 let qizi="";
                 let aft="";
                 if(WchessOrBchess==1){
                     qizi="Bchess";
                     aft="Black chess wins";
                 }else{
                     qizi="Wchess";
                     aft="White chess wins";
                 }
                layer.open({
                       title: 'The outcome is divided'
                       ,content:aft
                      ,btn: ['One more game']
                      ,skin: 'demo-class'
                      ,icon:6
                      ,success:function(){ //Pop up successful callback
        $("#layui-layer1").children(".layui-layer-content").append("<div class="+qizi+" ></div>");
                       }
                      ,yes: function(index, layero){
                        $("#layui-layer2")
                        $("#anew").click(); / / click restart to finish, which improves the reusability of the code
                        layer.close(index);  
                      }
                      ,cancel: function(){
                        $("#anew").click();
                      }
                    });
                }
              }
        
        //First, judge the horizontal
        function(x,y,WchessOrBchess){
            //This judgment can prevent the index from crossing the boundary and reporting errors, and can also save code execution time
         if(x>=9){ //If x > = 9, it is not necessary to judge whether the horizontal wins or not, and return false directly
            return false;                
           }else{
               if(chessboard[y][x+1]==WchessOrBchess&&chessboard[y][x+2]==WchessOrBchess&&chessboard[y][x+3]==WchessOrBchess&&chessboard[y][x+4]==WchessOrBchess){
                   return true;
               }else{
                   return false;
               }
           }
        }
        //Judge whether it is vertical
        function Lengthways(x,y,WchessOrBchess){
            //x doesn't have to move, y doesn't
            if(y>=9){//This judgment can prevent the index from crossing the boundary and reporting errors, and can also save code execution time
               return false;     
            }else{
                if(chessboard[y+1][x]==WchessOrBchess&&chessboard[y+2][x]==WchessOrBchess&&chessboard[y+3][x]==WchessOrBchess&&chessboard[y+4][x]==WchessOrBchess){
                   return true;
               }else{
                   return false;
               }
            }
        }
        //Judge whether it is inclined upward 
        function InclinedUp(x,y,WchessOrBchess){
            // The x-axis must be greater than 3 and the y-axis must be less than 9. If it cannot be followed, return directly
            if(!(x>3&&y<9)){//This judgment can prevent the index from crossing the boundary and reporting errors, and can also save code execution time
             return false;        
            }
                 if(chessboard[y+1][x-1]==WchessOrBchess&&chessboard[y+2][x-2]==WchessOrBchess&&chessboard[y+3][x-3]==WchessOrBchess&&chessboard[y+4][x-4]==WchessOrBchess){
                   return true;
               }else{
                   return false;
               }
            }
        //Judge whether it is inclined downward
        function InclinedDown(x,y,WchessOrBchess){
            if(!(x<9&&y<9)){ //This judgment can prevent the index from crossing the boundary and reporting errors, and can also save code execution time
             return false;        
            }
                 if(chessboard[y+1][x+1]==WchessOrBchess&&chessboard[y+2][x+2]==WchessOrBchess&&chessboard[y+3][x+3]==WchessOrBchess&&chessboard[y+4][x+4]==WchessOrBchess){
                   return true;
               }else{
                   return false;
               }
        }
        //Empty two-dimensional array method
        function EmptyArr(){
                      for(let y=0;y<13;y++){
                    chessboard[y]=new Array(y);
                    for (let x=0;x<13;x++){
                      chessboard[y][x]=0; 
                      }
                     }
        }
        //Clear sparse array method
        function EmptySparseArr(){
            // Empty the sparse array with previous values
            sparseArr=new Array();
           sparseArr[0]=new Array();
                  sparseArr[0][0]=13;
                  sparseArr[0][1]=13;
                  sparseArr[0][2]=0;
        }
        //Click restart
        $("#anew").click(function(){
                        $(".box").children(".Piece").empty();
                        //Empty the value of the array
                        EmptyArr();
                          //Empty sparse array
                        EmptySparseArr();
                        $("#Text). Text ("black chess go");
                        $("#showQiZi").removeClass("Wchess").addClass("Bchess");
            
        })
        
    })
        
    </script>
</html>

Topics: Javascript html5 html