国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁(yè) > 編程 > JavaScript > 正文

原生JS+Canvas實(shí)現(xiàn)五子棋游戲?qū)嵗?/h1>
2019-11-19 16:18:37
字體:
來(lái)源:轉(zhuǎn)載
供稿:網(wǎng)友

一、功能模塊

先看下現(xiàn)在做完的效果:

線(xiàn)上體驗(yàn):https://wj704.github.io/five_game.html

主要功能模塊為:

1.人機(jī)對(duì)戰(zhàn)功能
2.悔棋功能
3.撤銷(xiāo)悔棋功能

二、代碼詳解

2.1 人機(jī)對(duì)戰(zhàn)功能實(shí)現(xiàn)

從效果圖可以看到,棋盤(pán)的橫豎可以放的位置為15*15,通過(guò)canvas畫(huà)棋盤(pán):

    //繪畫(huà)棋盤(pán)    var drawChessBoard = function(){      for(var i = 0; i < 15; i++){        context.moveTo(15 + i * 30 , 15);        context.lineTo(15 + i * 30 , 435);        context.stroke();        context.moveTo(15 , 15 + i * 30);        context.lineTo(435 , 15 + i * 30);        context.stroke();      }    }

知道格子數(shù)后,我們先看五子棋有多少種贏法:

       //贏法數(shù)組      var wins = [];      for(var i = 0; i < 15; i++){        wins[i] = [];        for(var j = 0; j < 15; j++){          wins[i][j] = [];        }      }      var count = 0; //贏法總數(shù)      //橫線(xiàn)贏法      for(var i = 0; i < 15; i++){        for(var j = 0; j < 11; j++){          for(var k = 0; k < 5; k++){            wins[i][j+k][count] = true;          }          count++;        }      }      //豎線(xiàn)贏法      for(var i = 0; i < 15; i++){        for(var j = 0; j < 11; j++){          for(var k = 0; k < 5; k++){            wins[j+k][i][count] = true;          }          count++;        }      }      //正斜線(xiàn)贏法      for(var i = 0; i < 11; i++){        for(var j = 0; j < 11; j++){          for(var k = 0; k < 5; k++){            wins[i+k][j+k][count] = true;          }          count++;        }      }      //反斜線(xiàn)贏法      for(var i = 0; i < 11; i++){         for(var j = 14; j > 3; j--){          for(var k = 0; k < 5; k++){            wins[i+k][j-k][count] = true;          }          count++;        }      }

根據(jù)贏法總數(shù)定義分別保存計(jì)算機(jī)和人贏法的數(shù)組:

  for(var i = 0; i < count; i++){        myWin[i] = 0;        _myWin[i] = 0;        computerWin[i] = 0;        _compWin[i] = 0;   }

然后就是人開(kāi)始下棋:

 

  // 我,下棋  chess.onclick = function(e){    if(over){ // 游戲結(jié)束      return;    }    if(!me){      return;    }    var x = e.offsetX;    var y = e.offsetY;    var i = Math.floor(x / 30);    var j = Math.floor(y / 30);    _nowi = i;    _nowj = j;    if(chressBord[i][j] == 0){      oneStep(i,j,me);      chressBord[i][j] = 1; //我,已占位置          for(var k = 0; k < count; k++){ // 將可能贏的情況都加1        if(wins[i][j][k]){          myWin[k]++;          _compWin[k] = computerWin[k]; // 為悔棋做準(zhǔn)備          computerWin[k] = 6;//這個(gè)位置對(duì)方不可能贏了          if(myWin[k] == 5){            resultTxt.innerHTML = '恭喜,你贏了!';            over = true;          }        }      }      if(!over){        me = !me;        computerAI();      }    }    // 悔棋功能可用    backbtn.className = backbtn.className.replace( new RegExp( "(//s|^)unable(//s|$)" )," " );       }

oneStep() 方法為落子,要在棋盤(pán)上畫(huà)一個(gè)棋子:

    //畫(huà)棋子    var oneStep = function(i,j,me){      // debugger;      context.beginPath();      context.arc(15 + i * 30, 15 + j * 30, 13, 0, 2 * Math.PI);//畫(huà)圓      context.closePath();      //漸變      var gradient = context.createRadialGradient(15 + i * 30 + 2, 15 + j * 30 - 2, 13, 15 + i * 30 + 2, 15 + j * 30 - 2, 0);      if(me){        gradient.addColorStop(0,'#0a0a0a');        gradient.addColorStop(1,'#636766');      }else{        gradient.addColorStop(0,'#d1d1d1');        gradient.addColorStop(1,'#f9f9f9');      }      context.fillStyle = gradient;      context.fill();    }

接著看計(jì)算機(jī)怎么下棋,具體看computerAI()方法:

    // 計(jì)算機(jī)下棋    var computerAI = function (){      var myScore = [];      var computerScore = [];      var max = 0;      var u = 0, v = 0;      for(var i = 0; i < 15; i++){        myScore[i] = [];        computerScore[i] = [];        for(var j = 0; j < 15; j++){          myScore[i][j] = 0;          computerScore[i][j] = 0;        }      }      for(var i = 0; i < 15; i++){        for(var j = 0; j < 15; j++){          if(chressBord[i][j] == 0){            for(var k = 0; k < count; k++){              if(wins[i][j][k]){                if(myWin[k] == 1){                  myScore[i][j] += 200;                }else if(myWin[k] == 2){                  myScore[i][j] += 400;                }else if(myWin[k] == 3){                  myScore[i][j] += 2000;                }else if(myWin[k] == 4){                  myScore[i][j] += 10000;                }                if(computerWin[k] == 1){                  computerScore[i][j] += 220;                }else if(computerWin[k] == 2){                  computerScore[i][j] += 420;                }else if(computerWin[k] == 3){                  computerScore[i][j] += 2100;                }else if(computerWin[k] == 4){                  computerScore[i][j] += 20000;                }                          }            }            if(myScore[i][j] > max){              max = myScore[i][j];              u = i;              v = j;            }else if(myScore[i][j] == max){              if(computerScore[i][j] > computerScore[u][v]){                u = i;                v = j;                }            }            if(computerScore[i][j] > max){              max = computerScore[i][j];              u = i;              v = j;            }else if(computerScore[i][j] == max){              if(myScore[i][j] > myScore[u][v]){                u = i;                v = j;                }            }          }        }      }      _compi = u;      _compj = v;      oneStep(u,v,false);      chressBord[u][v] = 2; //計(jì)算機(jī)占據(jù)位置      for(var k = 0; k < count; k++){        if(wins[u][v][k]){          computerWin[k]++;          _myWin[k] = myWin[k];          myWin[k] = 6;//這個(gè)位置對(duì)方不可能贏了          if(computerWin[k] == 5){            resultTxt.innerHTML = 'o(

主站蜘蛛池模板:
临桂县|
马山县|
南皮县|
汕头市|
龙江县|
鹰潭市|
孝感市|
昌都县|
徐水县|
利辛县|
塘沽区|
昆明市|
九江县|
英超|
屯留县|
庄浪县|
文成县|
江都市|
吉隆县|
都兰县|
信丰县|
红原县|
托克逊县|
恩施市|
商城县|
兴安县|
民县|
长泰县|
慈溪市|
布尔津县|
佛学|
洞口县|
嘉禾县|
阳曲县|
浦县|
商都县|
巴东县|
洞头县|
商都县|
陇川县|
乐昌市|