再读《悟透javascript》之五、五子棋

前言

      五子棋是个很有趣的游戏,在用javascript开发之后,我发现其实ai算法才是最难的,这里的ai算法是直接借鉴自其它的ai算法。

 

 

代码如下:

<html xmlns="http://www.w3.org/1999/xhtml">

<head runat="server">

    <title>五子棋</title>

    <script type="text/javascript">

    var chess = {

        //-----------------构造函数-----------------------------------------

        create:function(x, y){

            var newDiv = document.createElement("div");

            document.body.appendChild(newDiv);

           

            newDiv.style.position = "absolute";

            newDiv.style.width = "23px";

            newDiv.style.height = "23px";

            newDiv.style.top = 100 + 23*y + "px";

            newDiv.style.left = document.body.clientWidth/2-23*9+23*x+"px";

           

            newDiv.x = x;

            newDiv.y = y;

            

            newDiv.fill = this.fill;

            newDiv.manPlay = this.manPlay;

            newDiv.pcPlay = this.pcPlay;

            newDiv.setVal = this.setVal;

            newDiv.isWin = this.isWin;

            newDiv.wink = this.wink;

            

            var n;

            var borderline = chess.getChessWidth() - 1;

            if(x==0&&y==0)

                n=0;

            else if(x==borderline && y==0)

                n=2;

            else if(x==0 && y==borderline)

                n=6;

            else if(x==borderline && y==borderline)

                n=8;

            else if(x>0 && x<borderline && y==0)

                n=1;

            else if(x>0 && x<borderline && y==borderline)

                n=7;

            else if(x==0 && y>0 && y<borderline)

                n=3;

            else if(x==borderline && y>0 && y<borderline)

                n=5;

            else

                n=4;

           

            (function(){

                var _newDiv = newDiv;

                var _n = n;

                var _y = y;

               

                setTimeout(function(){

                    _newDiv.style.backgroundImage = "url(images/b"+_n+".gif)";

                    _newDiv._backImage = _newDiv.style.backgroundImage;

                }, _y*69);

            })();

           

            return newDiv;

        },

       

       

        //-----------------处理函数-----------------------------------------

        fill:function(flag){

            this.style.backgroundImage = flag == undefined ? this._backImage : "url(images/d"+flag+".gif)"; //白:0,黑:1

            this.flag = flag;

            this.setVal(flag);

            

            return this.isWin();

        },

       

        setVal:function(flag){

            for(var i=0; i<winCount; i++){

                if(flag==0){

                    if(pcTab[this.x][this.y][i] && win[0][i]!=9){

                        win[0][i]++;

                    }

                    if(manTab[this.x][this.y][i]){

                        manTab[this.x][this.y][i] = false;

                        win[1][i] = 9;

                    }

                }

                if(flag==1){

                    if(manTab[this.x][this.y][i] && win[1][i]!=9){

                        win[1][i]++;

                    }

                    if(pcTab[this.x][this.y][i]){

                        pcTab[this.x][this.y][i] = false;

                        win[0][i] = 9;

                    }

                }

            }

        },

       

        manPlay:function(){

            if(this.flag == undefined){

                var isWin = this.fill(1);

                if(isWin) return;

                this.pcPlay(0);

            }

        },

       

        pcPlay:function(){

            if(this.flag == undefined && arguments.length==0){

                this.fill(0);

                return;

            }

           

            var chessWidth = chess.getChessWidth();

            //计算玩家、电脑在每个格子上的分数

            for(var x=0; x<chessWidth; x++){

                for(var y=0; y<chessWidth; y++){

                    manScore[x][y] = 0;

                    pcScore[x][y] = 0;

                    if(board[x][y].flag == undefined){

                        for(var z=0; z<winCount; z++){

                            //计算玩家在每个格子上的分数

                            if(manTab[x][y][z]){

                                switch(win[1][z]){

                                    case 1 : manScore[x][y] += 5; break;

                                    case 2 : manScore[x][y] += 50; break;

                                    case 3 : manScore[x][y] += 100; break;

                                    case 4 : manScore[x][y] += 500; break;

                                }

                            }

                           

                            //计算电脑在每个格子上的分数

                            if(pcTab[x][y][z]){

                                switch(win[0][z]){

                                    case 1 : pcScore[x][y] += 5; break;

                                    case 2 : pcScore[x][y] += 50; break;

                                    case 3 : pcScore[x][y] += 100; break;

                                    case 4 : pcScore[x][y] += 500; break;

                                }

                            }

                        }

                    }

                }

            }

           

            //比较哪个空格子上的分数最高

            var menMax = { x:-1, y:-1, val:-1 }

            var pcMax =  { x:-1, y:-1, val:-1 }

           

            for(var x=0; x<chessWidth; x++){

                for(var y=0; y<chessWidth; y++){

                    if(board[x][y].flag == undefined){

                        if(manScore[x][y] >= menMax.val){

                            menMax.val = manScore[x][y];

                            menMax.x = x;

                            menMax.y = y;

                        }

                        if(pcScore[x][y] >= pcMax.val){

                            pcMax.val = pcScore[x][y];

                            pcMax.x = x;

                            pcMax.y = y;

                        }

                    }

                }

            }

           

            //进攻or防守

            var nextX = 0;

            var nextY = 0;

           

            if(menMax.val>=pcMax.val && menMax.val>=100){   //防守

                nextX = menMax.x;

                nextY = menMax.y;

            }

            else if(pcMax.val==0){

                nextX = menMax.x;

                nextY = menMax.y;

            }

            else{

                nextX = pcMax.x;

                nextY = pcMax.y;

            }

           

            chess.fill.call(board[nextX][nextY], 0);

        },

       

        isWin:function(){

            for(var i=0; i<winCount; i++){

                if(win[0][i] == chess.getWinLength()){

                    this.wink(i, 0);

                    alert("电脑赢了");

                    return true;

                }

                if(win[1][i] == chess.getWinLength()){

                    this.wink(i, 1);

                    alert("恭喜,您赢了");

                    return true;

                }

            }

            

            return false;

        },

       

        wink:function(winIndex, flag){

            var chessWidth = chess.getChessWidth();

            for(var x=0; x<chessWidth; x++){

                for(var y=0; y<chessWidth; y++){

                    if(flag == 0){

                        if(pcTab[x][y][winIndex]){

                            board[x][y].style.zIndex = 100;

                            board[x][y].style.border = "solid 3px red";

                        }

                    }

                    

                    if(flag == 1){

                        if(manTab[x][y][winIndex]){

                            board[x][y].style.zIndex = 100;

                            board[x][y].style.border = "solid 3px red";

                        }

                    }

                   

                    board[x][y].onclick = function(){

                        if(confirm("是否重新开始")){

                            window.location = window.location;

                        }

                    }

                }

            }

        },

       

        //-----------------常量-----------------------------------------

        getChessWidth:function(){

            return 15;

        },

        getWinLength:function(){

            return document.getElementById("rdo5").checked ? 5 : 6;

        }

    }

   

    var board = new Array(chess.getChessWidth());

    var manTab = new Array(chess.getChessWidth());      //用户获胜组合

    var pcTab = new Array(chess.getChessWidth());

    var manScore = new Array(chess.getChessWidth());    //用户获取的分数

    var pcScore = new Array(chess.getChessWidth());

    var win = new Array(2);     //

    var winCount = 0;

   

    function main(){

        close();

       

        var winLength = chess.getWinLength();

        var chessWidth = chess.getChessWidth();

       

        //计算可能赢的组合个数

        for(var x=0; x<chessWidth; x++){

            for(var y=0; y<chessWidth; y++){

                if((x+winLength-1)<chessWidth) winCount++;

                if((y+winLength-1)<chessWidth) winCount++;

                if((x+winLength-1)<chessWidth && (y+winLength-1)<chessWidth) winCount++;

                if((x+winLength-1)<chessWidth && (y-winLength+1)>=0) winCount++;

            }

        }

           

        //画棋盘,初始化数据结构

        for(var x=0; x<chessWidth; x++){

            board[x] = new Array(chessWidth);

            manTab[x] = new Array(chessWidth);

            pcTab[x] = new Array(chessWidth);

            manScore[x] = new Array(chessWidth);

            pcScore[x] = new Array(chessWidth);

           

            for(var y=0; y<chessWidth; y++){

                board[x][y] = chess.create(x,y);

                manTab[x][y] = new Array(winCount);

                pcTab[x][y] = new Array(winCount);

            }

           

            win[0] = new Array(winCount);

            win[1] = new Array(winCount);

        }

       

        //初始化

        for(var i=0; i<win.length; i++)

            for(var j=0; j<win[i].length; j++)

                win[i][j] = 0;

        

        //计算可赢的可能的组合

        winCount = 0;

        var disable = winLength - 1;

        //横向组合

        for(var x=0; x<chessWidth-disable; x++){

            for(var y=0; y<chessWidth; y++){

                for(var z=0; z<winLength; z++){

                    manTab[x+z][y][winCount] = true;

                    pcTab[x+z][y][winCount] = true;

                }

                winCount++;

            }

        }

        //纵向组合

        for(var x=0; x<chessWidth; x++){

            for(var y=0; y<chessWidth-disable; y++){

                for(var z=0; z<winLength; z++){

                    manTab[x][y+z][winCount] = true;

                    pcTab[x][y+z][winCount] = true;

                }

                winCount++;

            }

        }

        //斜向下组合

        for(var x=0; x<chessWidth-disable; x++){

            for(var y=0; y<chessWidth-disable; y++){

                for(var z=0; z<winLength; z++){

                    manTab[x+z][y+z][winCount] = true;

                    pcTab[x+z][y+z][winCount] = true;

                }

                winCount++;

            }

        }

        //斜向上组合

        for(var x=0; x<chessWidth-disable; x++){

            for(var y=winLength-1; y<chessWidth; y++){

                for(var z=0; z<winLength; z++){

                    manTab[x+z][y-z][winCount] = true;

                    pcTab[x+z][y-z][winCount] = true;

                }

                winCount++;

            }

        }

       

        //选项

        var level = document.getElementById("radio");

        level.style.position = "absolute";

        level.style.top = "100px";

        level.style.left = document.body.clientWidth/2+23*chessWidth/2+"px";

       

        if(document.getElementById("rdoHard").checked){

            setTimeout(function(){

                open();

                chess.pcPlay.call(board[chessWidth/2][chessWidth/2]);

                alert("可以开始啦!!!");

            }, 2*1000);

        }

        else{

            open();

        }

       

        function open(){

            for(var x=0; x<chessWidth; x++){

                for(var y=0; y<chessWidth; y++){

                    board[x][y].onclick = chess.manPlay

                }

            }

        }

        function close(){

            for(var x=0; x<chessWidth; x++){

                for(var y=0; y<chessWidth; y++){

                    board[x][y].onclick = function(){alert("还不能开始,请稍等...");}

                }

            }

        }

    }

   

    window.onload = main;

    </script>

</head>

<body>

    <form id="form1" runat="server">

    <div id="radio">

        容易:<input id="rdoEasy" checked="checked" name="onlyOne" onclick="main()" type="radio" /><br />

        较难:<input id="rdoHard" name="onlyOne" onclick="main()" type="radio" /><br /><br />

        五子棋:<input id="rdo5" checked="checked" onclick="main()" name="only" type="radio" /><br />

        六子棋: <input id="rdo6" onclick="main()" name="only" type="radio" />

    </div>

    </form>

</body>

</html>

 

 

 

图片:

   

   

   

   

请对照下面的图片命名上面的图片

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值