最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

JS+Canvas實(shí)現(xiàn)五子棋游戲

 更新時(shí)間:2020年08月26日 09:54:50   作者:小時(shí)俞  
這篇文章主要為大家詳細(xì)介紹了原生JS+Canvas實(shí)現(xiàn)五子棋游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下

本文實(shí)例為大家分享了JS+Canvas實(shí)現(xiàn)五子棋游戲的具體代碼,供大家參考,具體內(nèi)容如下

布局+樣式部分代碼 :

<style type='text/css'>
 canvas {
  display: block;
  margin: 50px auto;
  box-shadow: -2px -2px 2px #efefef, 5px 5px 5px #b9b9b9;
  cursor: pointer;
 }

 .btn-wrap {
  display: flex;
  flex-direction: row;
  justify-content: center;
 }

 .btn-wrap div {
  margin: 0 10px;
 }

 div>span {
  display: inline-block;
  padding: 10px 20px;
  color: #fff;
  background-color: #EE82EE;
  border-radius: 5px;
  cursor: pointer;
 }
 
 div.unable span {
  background: #D6D6D4;
  color: #adacaa;
 }
 
 #result-wrap {
  text-align: center;
 }
 </style>
 
 <h3 id="result-wrap">--五子棋--</h3>
 <canvas id="chess" width="450px" height="450px"></canvas>
 <div class="btn-wrap">
 <div id='restart' class="restart">
 <span>重新開(kāi)始</span>
 </div>
 <div id='goback' class="goback unable">
 <span>悔棋</span>
 </div>
 <div id='return' class="return unable">
 <span>撤銷悔棋</span>
 </div>
</div>

js部分代碼:

<script>
 var over = false;
 var me = true; //我 
 var _nowi = 0, _nowj = 0; //記錄自己下棋的坐標(biāo) 
 var _compi = 0, _compj = 0; //記錄計(jì)算機(jī)當(dāng)前下棋的坐標(biāo) 
 var _myWin = [], _compWin = []; //記錄我,計(jì)算機(jī)贏的情況 
 var backAble = false, returnAble = false;
 var resultTxt = document.getElementById('result-wrap');
 var chressBord = [];//棋盤(pán) 
 for (var i = 0; i < 15; i++) {
  chressBord[i] = [];
  for (var j = 0; j < 15; j++) {
  chressBord[i][j] = 0;
  }
 }
 //贏法的統(tǒng)計(jì)數(shù)組 
 var myWin = [];
 var computerWin = [];
 //贏法數(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ù) 
 //橫線贏法 
 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++;
  }
 }
 //豎線贏法 
 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++;
  }
 }
 //正斜線贏法 
 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++;
  }
 }
 //反斜線贏法 
 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++;
  }
 }
 // debugger; 
 for (var i = 0; i < count; i++) {
  myWin[i] = 0;
  _myWin[i] = 0;
  computerWin[i] = 0;
  _compWin[i] = 0;
 }
 var chess = document.getElementById("chess");
 var context = chess.getContext('2d');
 context.strokeStyle = '#bfbfbf'; //邊框顏色 
 var backbtn = document.getElementById("goback");
 var returnbtn = document.getElementById("return");
 window.onload = function () {
  drawChessBoard(); // 畫(huà)棋盤(pán) 
 }
 document.getElementById("restart").onclick = function () {
  window.location.reload();
 }
 // 我,下棋 
 chess.onclick = function (e) {
  if (over) {
  return;
  }
  if (!me) {
  return;
  }
  // 悔棋功能可用 
  backbtn.className = backbtn.className.replace(new RegExp("(\\s|^)unable(\\s|$)"), " ");
  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]) {
   // debugger; 
   myWin[k]++;
   _compWin[k] = computerWin[k];
   computerWin[k] = 6;//這個(gè)位置對(duì)方不可能贏了 
   if (myWin[k] == 5) {
    // window.alert('你贏了'); 
    resultTxt.innerHTML = '恭喜,你贏了!';
    over = true;
   }
   }
  }
  if (!over) {
   me = !me;
   computerAI();
  }
  }
 }
 // 悔棋 
 backbtn.onclick = function (e) {
  if (!backAble) { return; }
  over = false;
  me = true;
  // resultTxt.innerHTML = 'o(╯□╰)o,悔棋中'; 
  // 撤銷悔棋功能可用 
  returnbtn.className = returnbtn.className.replace(new RegExp("(\\s|^)unable(\\s|$)"), " ");
  // 我,悔棋 
  chressBord[_nowi][_nowj] = 0; //我,已占位置 還原 
  minusStep(_nowi, _nowj); //銷毀棋子 
  for (var k = 0; k < count; k++) { // 將可能贏的情況都減1 
  if (wins[_nowi][_nowj][k]) {
   myWin[k]--;
   computerWin[k] = _compWin[k];//這個(gè)位置對(duì)方可能贏 
  }
  }
  // 計(jì)算機(jī)相應(yīng)的悔棋 
  chressBord[_compi][_compj] = 0; //計(jì)算機(jī),已占位置 還原 
  minusStep(_compi, _compj); //銷毀棋子 
  for (var k = 0; k < count; k++) { // 將可能贏的情況都減1 
  if (wins[_compi][_compj][k]) {
   computerWin[k]--;
   myWin[k] = _myWin[i];//這個(gè)位置對(duì)方可能贏 
  }
  }
  resultTxt.innerHTML = '益智五子棋';
  returnAble = true;
  backAble = false;
 }
 // 撤銷悔棋 
 returnbtn.onclick = function (e) {
  if (!returnAble) { return; }
  // 我,撤銷悔棋 
  chressBord[_nowi][_nowj] = 1; //我,已占位置 
  oneStep(_nowi, _nowj, me);
  for (var k = 0; k < count; k++) {
  if (wins[_nowi][_nowj][k]) {
   myWin[k]++;
   _compWin[k] = computerWin[k];
   computerWin[k] = 6;//這個(gè)位置對(duì)方不可能贏 
  }
  if (myWin[k] == 5) {
   resultTxt.innerHTML = '恭喜,你贏了!';
   over = true;
  }
  }
  // 計(jì)算機(jī)撤銷相應(yīng)的悔棋 
  chressBord[_compi][_compj] = 2; //計(jì)算機(jī),已占位置 
  oneStep(_compi, _compj, false);
  for (var k = 0; k < count; k++) { // 將可能贏的情況都減1 
  if (wins[_compi][_compj][k]) {
   computerWin[k]++;
   _myWin[k] = myWin[k];
   myWin[k] = 6;//這個(gè)位置對(duì)方不可能贏 
  }
  if (computerWin[k] == 5) {
   resultTxt.innerHTML = '計(jì)算機(jī)贏了,繼續(xù)加油哦!';
   over = true;
  }
  }
  returnbtn.className += ' ' + 'unable';
  returnAble = false;
  backAble = true;
 }
 // 計(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 = '計(jì)算機(jī)贏了,繼續(xù)加油哦!';
   over = true;
   }
  }
  }
  if (!over) {
  me = !me;
  }
  backAble = true;
  returnAble = false;
  var hasClass = new RegExp('unable').test(' ' + returnbtn.className + ' ');
  if (!hasClass) {
  returnbtn.className += ' ' + 'unable';
  }
 }
 //繪畫(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();
  }
 }
 //畫(huà)棋子 
 var oneStep = function (i, j, me) {
  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();
 }
 //銷毀棋子 
 var minusStep = function (i, j) {
  //擦除該圓 
  context.clearRect((i) * 30, (j) * 30, 30, 30);
  // 重畫(huà)該圓周圍的格子 
  context.beginPath();
  context.moveTo(15 + i * 30, j * 30);
  context.lineTo(15 + i * 30, j * 30 + 30);
  context.moveTo(i * 30, j * 30 + 15);
  context.lineTo((i + 1) * 30, j * 30 + 15);

  context.stroke();
 } 
</script>

更多有趣的經(jīng)典小游戲?qū)崿F(xiàn)專題,分享給大家:

C++經(jīng)典小游戲匯總

python經(jīng)典小游戲匯總

python俄羅斯方塊游戲集合

JavaScript經(jīng)典游戲 玩不停

javascript經(jīng)典小游戲匯總

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • javascript中的delete使用詳解

    javascript中的delete使用詳解

    在這篇文章中作者從《JavaScript面向?qū)ο缶幊讨改稀芬粫?shū)中關(guān)于 delete 的錯(cuò)誤講起,詳細(xì)講述了關(guān)于 delete 操作的實(shí)現(xiàn), 局限以及在不同瀏覽器和插件(這里指 firebug)中的表現(xiàn)
    2013-04-04
  • ie 7/8不支持trim的屬性的解決方案

    ie 7/8不支持trim的屬性的解決方案

    在ie 7 8瀏覽器中,如果使用trim()屬性去除空格的話,則會(huì)導(dǎo)致報(bào)錯(cuò),下面有幾種不錯(cuò)的解決方法
    2014-05-05
  • JS帶你深入領(lǐng)略Proxy的世界

    JS帶你深入領(lǐng)略Proxy的世界

    Proxy是es2015 標(biāo)準(zhǔn)規(guī)范加入的語(yǔ)法,很可能你只是聽(tīng)說(shuō)過(guò),但并沒(méi)有用過(guò),畢竟考慮到兼容的問(wèn)題,不能輕易地使用Proxy特性。但現(xiàn)在隨著各個(gè)瀏覽器的更新迭代,Proxy的支持度也越來(lái)越高:而且使用Proxy進(jìn)行代理和劫持,也漸漸成為了趨勢(shì)。
    2021-05-05
  • bootstrap-table.js擴(kuò)展分頁(yè)工具欄(增加跳轉(zhuǎn)到xx頁(yè))功能

    bootstrap-table.js擴(kuò)展分頁(yè)工具欄(增加跳轉(zhuǎn)到xx頁(yè))功能

    這篇文章主要介紹了bootstrap-table.js擴(kuò)展分頁(yè)工具欄,增加跳轉(zhuǎn)到xx頁(yè)功能,由于小編的水平停留在dom級(jí),此次擴(kuò)展只支持頁(yè)面上的表格,如果大家有好的建議歡迎提出
    2017-12-12
  • 基于substring()和substr()的使用以及區(qū)別(實(shí)例講解)

    基于substring()和substr()的使用以及區(qū)別(實(shí)例講解)

    下面小編就為大家分享一篇基于substring()和substr()的使用以及區(qū)別實(shí)例講解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2017-12-12
  • webpack獨(dú)立打包和緩存處理詳解

    webpack獨(dú)立打包和緩存處理詳解

    這篇文章主要介紹了webpack獨(dú)立打包和緩存處理的相關(guān)資料,文中介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)webpack具有一定的參考價(jià)值,需要的朋友們下面來(lái)一起看看吧。
    2017-04-04
  • javascript offsetX與layerX區(qū)別

    javascript offsetX與layerX區(qū)別

    FF沒(méi)有offsetX屬性,有個(gè)layerX屬性,只要將事件源的位置設(shè)置成相對(duì)定位(position:relative)或絕對(duì)定位(position:absolute),兩者結(jié)果就相等,表示事件源相對(duì)于父元素的X坐標(biāo)。
    2010-03-03
  • js實(shí)現(xiàn)點(diǎn)擊按鈕隨機(jī)生成背景顏色

    js實(shí)現(xiàn)點(diǎn)擊按鈕隨機(jī)生成背景顏色

    這篇文章主要為大家詳細(xì)介紹了js實(shí)現(xiàn)點(diǎn)擊按鈕隨機(jī)生成背景顏色,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-09-09
  • JavaScript設(shè)計(jì)模式之代理模式詳解

    JavaScript設(shè)計(jì)模式之代理模式詳解

    這篇文章主要為大家詳細(xì)介紹了JavaScript設(shè)計(jì)模式之代理模式,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-06-06
  • js+html5通過(guò)canvas指定開(kāi)始和結(jié)束點(diǎn)繪制線條的方法

    js+html5通過(guò)canvas指定開(kāi)始和結(jié)束點(diǎn)繪制線條的方法

    這篇文章主要介紹了js+html5通過(guò)canvas指定開(kāi)始和結(jié)束點(diǎn)繪制線條的方法,涉及html5屬性的操作技巧,需要的朋友可以參考下
    2015-06-06

最新評(píng)論

嘉善县| 天门市| 台东县| 河东区| 长葛市| 金沙县| 阜城县| 永登县| 张家港市| 鱼台县| 五家渠市| 乃东县| 土默特左旗| 乌兰察布市| 黑山县| 平凉市| 类乌齐县| 读书| 仪征市| 长岭县| 香格里拉县| 神农架林区| 洛阳市| 图片| 庆云县| 湘潭县| 克东县| 固安县| 贺兰县| 广元市| 濮阳市| 仁怀市| 彭泽县| 新绛县| 台南市| 大石桥市| 黑水县| 景德镇市| 五家渠市| 彭泽县| 山阳县|