JavaScript寫的一個帶AI的井字棋

来源:https://www.cnblogs.com/phdeblog/archive/2018/05/20/9062432.html
-Advertisement-
Play Games

最近有一門課結束了,需要做一個井字棋的游戲,我用JavaScript寫了一個。首先界面應該問題不大,用html稍微寫一下就可以。主要是人機對弈時的ai演算法,如何使電腦方聰明起來,是值得思考一下的。開始游戲後,由玩家先行。那麼站在電腦的角度,可以對多種情況進行分析,並按照重要程度賦予權值。情況如下: ...


       最近有一門課結束了,需要做一個井字棋的游戲,我用JavaScript寫了一個。首先界面應該問題不大,用html稍微寫一下就可以。主要是人機對弈時的ai演算法,如何使電腦方聰明起來,是值得思考一下的。開始游戲後,由玩家先行。那麼站在電腦的角度,可以對多種情況進行分析,並按照重要程度賦予權值。
情況如下:

1、同一排(行。列。對角線)有且只有兩個棋子,並且都是自己的,只要再進一步就能獲勝,那麼剩下的那個位置權值最高,優先順序最大。賦予一級權值。

2、同一排(行。列。對角線)有且只有兩個棋子,並且都是對方的(也就是玩家的),只要再進一步,玩家就會成功,所以“我”要堵住,剩下的那個位置賦予二級權值。

3、因為電腦方後行,如果聰明點,需要一直堵玩家方,所以當一排只有一個棋,且是玩家的棋子,那麼該排其他位置的權值設為三級。

4、四級權值:一排只有己方(電腦方)的棋子。

5、五級許可權:同排沒有棋子,包括對方和己方。

       實現的時候,每個位置的棋子,可以用二維數組full表示,每個位置的權值大小也用一個二維數組val來表示。玩家方下完後,調用AI方的函數,AI方行棋前,先更新一下權值,然後選出權值最大的位置落子(最優解)。無論是ai還是玩家方,每次落子後都要判斷有沒有產生輸贏。用alert()函數輸出結果。

       為了表示權值的大小,規定按照一級到五級順序,依次加  10000、1000、10、5、3

       註:由於可能要提交源碼,我沒有分離出css樣式和js文件,不過最好還是分開寫更規範。如有不足之處,歡迎批評指正。

源碼如下:

<html>
<head>
<meta charset="utf-8">
<title>井字棋</title>
<script>
//定義全局變數
var full=[[0,0,0],[0,0,0],[0,0,0]];//0表示null,1表示我下的,2表示電腦下的
var val=[[1,1,1],[1,1,1],[1,1,1]];//表示每個位置的權值
function judge(){
      //檢測是否有人贏
      //
      for(var i=0;i<3;i++){
          if(full[i][0]==full[i][1]&&full[i][1]==full[i][2]&&full[i][0]!=0){
                          if(full[i][0]==1){
                               window.alert("you win!");
                                return true;
                          }
                          else {
                                window.alert("you lose");
                                return true;
                          }                                
          }
      }
      //
      for(var i=0;i<3;i++){
          if(full[0][i]==full[1][i]&&full[1][i]==full[2][i]&&full[0][i]!=0){
                          if(full[0][i]==1){
                               window.alert("you win!"); 
                               return true;
                          }
                          else {
                               window.alert("you lose");    
                               return true;
                          }                               
          }
      }
      //主對角線
      if(full[0][0]==full[1][1]&&full[1][1]==full[2][2]&&full[0][0]!=0){
                          if(full[0][0]==1){
                               window.alert("you win!");
                               return true;
                        }
                          else {
                               window.alert("you lose");
                               return true;
                        }                               
      }
      if(full[0][2]==full[1][1]&&full[2][0]==full[1][1]&&full[0][2]!=0){
                          if(full[0][2]==1){
                               window.alert("you win!");
                               return true;
                        }
                          else {
                              window.alert("you lose");
                              return true;
                        }
      }
      for(var i=0;i<3;i++){
         for(var j=0;j<3;j++){
            if(full[i][j]==0)
               return false;//說明還沒結束
             if(i==2&&j==2)
               {window.alert("平局!");    
                return true;
               }                
         }
      }
      return false;//無結果
}
function bn(i,j){
     //如果已經下過,則無效
      if(full[i][j]!=0){
           return 0;
      }else{
           //沒下過
           full[i][j]=1;
           num1=(i*3+j+1)+"";
           document.getElementById(num1).value="X";
           if(judge()==true){
               return;
           }
           ai();//切換
      }
}
//重置權值:
function resetValue(){

      for(var i=0;i<3;i++){
           for(var j=0;j<3;j++){
               if(full[i][j]!=0)
                   val[i][j]=0;
               else{
            //看行和列:   
                  //最高權值
                  if(((full[0][j]+full[1][j]+full[2][j])==4)&&(full[0][j]*full[1][j]*full[2][j])==0
                  &&((full[0][j]-1)*(full[1][j]-1)*(full[2][j]-1))==-1)
                        val[i][j]=val[i][j]+10000;
                  if(((full[i][0]+full[i][1]+full[i][2])==4)&&(full[i][0]*full[i][1]*full[i][2])==0
                  &&((full[i][0]-1)*(full[i][1]-1)*(full[i][2]-1))==-1)
                        val[i][j]=val[i][j]+10000;
                  //次級權值
                  if(((full[0][j]+full[1][j]+full[2][j])==2)&&(full[0][j]*full[1][j]*full[2][j])==0
                  &&((full[0][j]-1)*(full[1][j]-1)*(full[2][j]-1))==0)
                        val[i][j]=val[i][j]+1000;
                  if(((full[i][0]+full[i][1]+full[i][2])==2)&&(full[i][0]*full[i][1]*full[i][2])==0
                  &&((full[i][0]-1)*(full[i][1]-1)*(full[i][2]-1))==0)
                        val[i][j]=val[i][j]+1000;
                  //三級權值(一排只有一個X)
                  if(((full[0][j]+full[1][j]+full[2][j])==1)&&(full[0][j]*full[1][j]*full[2][j])==0
                  &&((full[0][j]-1)*(full[1][j]-1)*(full[2][j]-1))==0)
                        val[i][j]=val[i][j]+10;
                  if(((full[i][0]+full[i][1]+full[i][2])==1)&&(full[i][0]*full[i][1]*full[i][2])==0
                  &&((full[i][0]-1)*(full[i][1]-1)*(full[i][2]-1))==0)
                        val[i][j]=val[i][j]+10;
                  //四級權值(一排只有一個O)
                  if(((full[0][j]+full[1][j]+full[2][j])==2)&&(full[0][j]*full[1][j]*full[2][j])==0
                  &&((full[0][j]-1)*(full[1][j]-1)*(full[2][j]-1))==1)
                        val[i][j]=val[i][j]+5;
                  if(((full[i][0]+full[i][1]+full[i][2])==2)&&(full[i][0]*full[i][1]*full[i][2])==0
                  &&((full[i][0]-1)*(full[i][1]-1)*(full[i][2]-1))==1)
                        val[i][j]=val[i][j]+	   

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 什麼是瀏覽器同源策略 同源策略(Same origin policy)是一種約定,它是瀏覽器最核心也最基本的安全功能,如果缺少了同源策略,則瀏覽器的正常功能可能都會受到影響。可以說 Web 是構建在同源策略基礎之上的,瀏覽器只是針對同源策略的一種實現。 它的核心就在於它認為自任何站點裝載的信賴內容是 ...
  • 內容:為什麼開始學習node.js,需要安裝哪些東西,及其安裝過程 node.js的學習是按照菜鳥教程的node.js教程學習,學習這項技術主要是因為需要使用。需要安裝的東西:解釋器,IDE(集成開發環境),後期應該還有資料庫mongodb,暫時學習前面的知識,先不安裝資料庫。主要是學習,所以在Wi ...
  • 電商m站的首頁,有一個需求是配一張大的banner圖,然後指定某些區域是熱區,點擊之後跳轉到不同的活動頁。 聽起來簡單明瞭,實現也比較容易,立刻就想起來有個map標簽,簡直就是為這個需求量身定做。 簡單說下做法: 我們首先會和後臺約定一些規則,定義一個json對象。比如: 我們可以約定,type為1 ...
  • 這兩天不知道咋了,迷迷糊糊的,突然知道今天是520的我,急急忙忙趕出個程式(新手,代碼有點亂),發出來大家一起研究下(參考百度的)。 ...
  • 最近突然想做一些好玩的東西,找來找去,想到了之前曾經在網上看到過有人用box-shadow畫了一副蒙娜麗莎出來感覺這個挺有意思,正好趁著周末,自己也搞一波 前言 線上地址: 優化前的版本優化後的版本源碼倉庫地址 不建議上傳大圖片。。喜歡聽電腦引擎聲的除外 首先,並不打算單純的實現某一張圖片(這樣太沒 ...
  • 命名捕獲 語法 : ?<name> 一:舉個慄子 我們要把從2018-05-20取出年月日 1:普通方法 1 let str = '2018-05-20'; 2 let reg1 = /(\d{4})-(\d{2})-(\d{2})/; 3 let arr = str.match(reg1); 4 ...
  • 思考與總結 1.模塊化 曾看到某大牛說:模塊化和組件化是前端開發的一大趨勢。所謂的模塊化一般是指為了實現一個特定的功能而將所有的代碼(對象)封裝成一個模塊。而AMD就是requireJS為指定模塊規範化的一個產出,它具有非同步載入、依賴前置、提前執行的特點。CMD則是針對淘寶提技術團隊sea.js的一 ...
  • vue2.0 實現導航守衛(路由守衛) 路由跳轉前做一些驗證,比如登錄驗證,是網站中的普遍需求。 對此,vue-route 提供的 beforeRouteUpdate 可以方便地實現導航守衛(navigation-guards)。 導航守衛(navigation-guards)這個名字,聽起來怪怪的 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...