freecodecamp项目---tictactoe

来源:互联网 发布:php取数组中的最大值 编辑:程序博客网 时间:2024/06/05 15:09

一:介绍

这个项目是做一个人机对战的井字棋,一开始,完全不知道如何下手,不知道该怎么完成这个功能,最后再github上找了个项目跟着看,一看js代码,各种函数,作者也没有什么注释,看着还是头疼,但是没有办法,只有硬着头皮一个个函数的看过去,分析这个函数时做什么的,看着看着突然觉得还是挺简单的~但是大多数的时候我们都被自己吓怕了,所以不管多难,都要尝试去做,说不定就做出来了呢。当然这个作者的js代码只有三百多行,所以也不算多,只是一个小项目~

该项目在codepen上的地址:https://codepen.io/lightforme/full/JJLGwq/

二:知识点

  • 1.confirm(message):该方法用于显示一个带有指定消息和OK、取消按钮的对话框;
  • 2.window.location:对象用于获得当前页面的地址 (URL),window.location.reload可以将页面重新加载;
  • 3.z-index:只有当position为非默认值时,该值才有效,只越大越层叠在上面,并且被覆盖的部分不能被点击到;
  • 4.e.preventDefault:取消和事件相关联的默认动作;
  • 5.原生js中可以直接重新设置事件方法进行覆盖,但是jQuery中不行,jQuery中需要取消事件方法需要使用.unbind()方法,不加参数是移出所有的事件方法,加参数指定移出事件方法;
  • 6.在codepen中window.location对象被禁用了,所以重载页面可以使用location = location;来替代;

三:代码
html:

<!DOCTYPE html><html>    <head>        <meta charset="utf-8" />        <title>tictoctie game</title>        <link rel="stylesheet" href="http://cdn.bootcss.com/bootstrap/3.3.5/css/bootstrap.min.css">        <link rel="stylesheet" href="css/tictoctie.css" />    </head>    <body>        <div class="container">            <div class="gameboard">                <ul class="grid-list">                    <li class="grid grid-0"></li>                    <li class="grid grid-1"></li>                    <li class="grid grid-2"></li>                    <li class="grid grid-3"></li>                    <li class="grid grid-4"></li>                    <li class="grid grid-5"></li>                    <li class="grid grid-6"></li>                    <li class="grid grid-7"></li>                    <li class="grid grid-8"></li>                </ul>            </div>        </div>        <div class="bg">        </div>        <div class="choose-panel">            <div class="choose-player">                <p>选择角色:X OR O?</p>                <div class="choose-btn">                    <button class="btn btn-default xobtn" id="x-btn">X</button><button class="btn btn-default xobtn" id="o-btn">O</button>                </div>            </div>            <div class="choose-first">                <p>设置先手:</p>                <div class="choose-btn">                    <button class="btn btn-default firstbtn" id="computer">电脑</button><button class="btn btn-default firstbtn" id="user">玩家</button>                </div>            </div>        </div>        <script src="https://cdn.bootcss.com/jquery/3.2.1/jquery.min.js"></script>        <script src="js/tictpctie.js"></script>    </body></html>

css:

* {    margin: 0px;    padding: 0px;}.gameboard {    width: 480px;    height: 450px;    margin-left: auto;    margin-right: auto;    margin-top: 200px;    background-color: #000;}.gameboard ul {    list-style: none;    height: 480px;    padding: 15px;}.grid {    width: 32.4%;    height: 30.5%;    float: left;    border: 1px solid #E1F5A9;}.gameboard li {    cursor: pointer;    color: #F9F9F9;    text-align: center;    line-height: 138px;    font-size: 2em;}.grid-0, .grid-3, .grid-6 {    border-left: none;}.grid-0, .grid-1, .grid-2 {    border-top: none;   }.grid-2, .grid-5, .grid-8 {    border-right: none;}.grid-6, .grid-7, .grid-8 {    border-bottom: none;}.bg {    /*display: none;*/    position: absolute;    top: 0%;    left: 0%;    width: 100%;    height: 100%;    background-color: black;    z-index:1001;    -moz-opacity: 0.7;    opacity:.70;    filter: alpha(opacity=70);}.choose-panel {    position: absolute;    top: 0;    left: 0;    bottom: 0;    right: 0;    width: 560px;    height: 200px;    margin: auto;    background-color: #FFF;    margin-top: 200px;    z-index: 1002;    border-radius: 25px;}.choose-panel p {    font-size: 2em;    text-align: center;    padding-top: 30px;}.choose-btn {    text-align: center;}.btn {    margin: 5px;    padding:5px;}.choose-first {    display: none;}

javascript:

/*game逻辑分析 *      新建一个game的构造函数,并给该构造函数的原型对象prototype添加两个属性:init/play *  *      1.点击选择角色按钮,选择角色,关闭选择角色面板,打开选择先手面板; *      2.选择先手,若是电脑先手,调用对象的play()函数; *      3.设置点击棋盘位置的点击事件,每次点击玩更新棋盘相应处的棋子,并调用play()函数,让电脑落子; *      4.play()函数逻辑:判断是否下一手即可获胜,若能找到落子位置落子 *                      否则,判断下一手player是否将要获胜,若是,找到落子位置落子; *                      否则,判断是否是第一手,若是,落子棋盘正中间; *                      否则,收集棋盘其余未落子的位置,并随机选择落子位置落子 */$(function(){    var running = false,                computerVal = -1,                playerVal = 1,                   computer,player,        copEnd = false,        winResult = [[0,1,2],[3,4,5],[6,7,8],[0,3,6],[1,4,7],[2,5,8],[0,4,8],[2,4,6]],        panel = [0,0,0,0,0,0,0,0,0];    //设置角色    function setPlayer(val){        computer = val === 'O' ? 'X' : 'O';        $(".choose-player").css("display","none");        $(".choose-first").css("display","block");    };    //通过类名获得位置    function getPos(val){        return val.split(" ")[1].split("-")[1];    };    //判断玩家是否胜利    function playerWin(){        for(var i = 0;i <winResult.length;i++){            var winCount = 0;            for(var j = 0;j < winResult[i].length;j++){                if(panel[winResult[i][j]] == 1){                    winCount++;                };            };            if(winCount == 3){                return true;            };        };        return false;    };    //判断电脑是否胜利    function computerWin(){        for(var i = 0;i <winResult.length;i++){            var winCount = 0;            for(var j = 0;j < winResult[i].length;j++){                if(panel[winResult[i][j]] == (-1)){                    winCount++;                };            };            if(winCount == 3){                return true;            };        };        return false;    };    //判断棋盘是否下满    function end(){        var count = 0;        for(var i = 0;i < panel.length;i++){            if(panel[i] != 0){                count++;            };        };        return (count == 9);    };    //更新棋盘棋子    function updateRole(pos,val){        var targetClass = '.grid-' + pos;        var who = val == 1 ? player : computer;        $(targetClass).html(who);        $(targetClass).unbind("click");        panel[pos] = val;        if(playerWin()){            copEnd = true;            if(confirm("玩家胜利,是否重开一局?")){                window.location.reload();            };        }else if(computerWin()){            copEnd = true;            if(confirm("电脑胜利 ,是否重开一局?")){                window.location.reload();            };        }else if(end()){            copEnd = true;            if(confirm("平局,是否重开一局?")){                window.location.reload();            };        };    };    function compOneEmp(arr){        var empCount = 0;        var compCount = 0;        for(var i = 0;i < arr.length;i++){            if(panel[arr[i]] == 0){                empCount++;            };            if(panel[arr[i]] == (-1)){                compCount++;            };        };        if(compCount == 2){            return (empCount == 1);        };    };    //电脑是否可以攻击    function canAttack(){        for(var i = 0;i < winResult.length;i++){            if(compOneEmp(winResult[i])){                return true;            };        };        return false;    };    function findAttackPos(){        for(var i = 0;i<winResult.length;i++){            if(compOneEmp(winResult[i])){                for(var j=0;j<winResult[i].length;j++){                    if(panel[winResult[i][j]] == 0){                        return winResult[i][j];                     };                };            };        };        return false;    };    //电脑是否需要防守    function canDefend(){        for(var i = 0;i < winResult.length;i++){            if(playOneEmp(winResult[i])){                return true;            };        };        return false;    };    function playOneEmp(arr){        var empCount = 0;        var playCount = 0;        for(var i = 0;i < arr.length;i++){            if(panel[arr[i]] == 0){                empCount++;            };            if(panel[arr[i]] == 1){                playCount++;            };        };        if(playCount == 2){            return (empCount == 1);        };    };    function findDefendPos(){        for(var i = 0;i<winResult.length;i++){            if(playOneEmp(winResult[i])){                for(var j=0;j<winResult[i].length;j++){                    if(panel[winResult[i][j]] == 0){                        return winResult[i][j];                     };                };            };        };        return false;    };    function firstStep(){        return !running;    };    function specialPos(){        if(panel[4] == 0){            return true;        };        return false;    };    function collectEmp(){        var arr = [];        for(var i = 0;i < panel.length;i++){            if(panel[i] == 0){                arr.push(i);            };        };        return arr;    };    //建立构造器函数    var ticToctie = function(){};    //给构造函数原型添加方法    ticToctie.prototype = {        init: function(){            var self = this;            $(".choose-player .btn").click(function(){                player = $(this).html();                setPlayer(player);            });            $(".choose-first .btn").click(function(){                $(".bg").css('display', 'none');                $(".choose-panel").css("display","none");                var whoFirst = $(this).attr("id");                //若不是,将running置为true,防止影响后面电脑落子                if(whoFirst == 'computer'){                    self.play();                }else{                    running = true;                };            });            $(".grid").click(function(){                var pos = getPos($(this).attr('class'));                updateRole(pos,playerVal);                if(!copEnd){                    self.play();                };                //并取消此处可点击            });        },        play: function(){            if(canAttack()){                let pos = findAttackPos();                updateRole(pos,computerVal);                return;            };            if(canDefend()){                let pos = findDefendPos();                updateRole(pos,computerVal);                return;            };            if(firstStep()){                running = true;                updateRole(4,computerVal);                return;            };            if(specialPos()){                updateRole(4,computerVal);                return;            };            var arr = collectEmp();            var pos = Math.floor(Math.random() * arr.length);            updateRole(arr[pos],computerVal);            return;        }    };    //创建一个构造函数实例    var competition = new ticToctie();    competition.init();});

如果有发现问题或者有好的建议,请在评论中指出

原创粉丝点击