2012-05-09 75 views
0

我做了一個TicTacToe遊戲!只是爲了好玩。它可以工作,所有,但一旦有人贏了就無法辨別。我使用.inArray在當前主板上尋找獲勝的解決方案。這個想法是一旦在棋盤上出現了正方形的勝利組合,就會彈出一個提示(「你贏了布魯」)。也許inArray比較win數組和選擇的元素相對於win數組的元素與選定的元素?我很難過。如果你感興趣的話,請查看jsfiddle,如果你知道了,請留下回復。謝謝。 http://jsfiddle.net/QH6W9/7/如何使用inArray並使用jQuery製作精美的TicTacToe(Noughts and Crosses)

// UPDATE

我結束了使用幻方和檢查,如果3的組合加入到15,並使用可能的組合和一個MySQL數據庫中實現自我的教學和基本AI。我使用了第二個腳本來讓電腦自行播放並構建數據庫。這不是最完美的代碼,但看到自己..

//---//--//--//--//--//--//---//--//--//--//--//---// 
// TIC-TAC-TOE:         // 
//Good Old game. This version is meant to be a self// 
//teaching system as a means to utilise and master // 
//exchange between web-page, server and database. // 
//---//--//--//--//--//--//---//--//--//--//--//---// 

// Author: Dylan Madisetti 
// Date: I don't remember? 


$(document).ready(function(){ 

    var magiclist = [8,3,4,1,5,9,6,7,2]; //for humans   
    var squares = [8,3,4,1,5,9,6,7,2]; //Le Magic Square\\ 
    var xs = [];       //------------// 
    var os = [];       // 8 | 3 | 4 // 
    var x = 0;       //----+---+---// 
    var o = 0;       // 1 | 5 | 9 // 
    var gameover = -1;     //----+---+---// 
    var FirstMoves = [];     // 6 | 7 | 2 // 
    var SecondMoves = [];    //------------// 
    var ThirdMoves = []; //All Diagonals,rows and Columns add to 15\\    
    var moves = []; 
    var i = 0; 
    win = false; 
    end = false; 
    // I have a radio button for whether the human plays as x or o  
      if(document.getElementById('human').checked) { 
       humanmove("x",x,xs,moves,squares,gameover,i,magiclist,"o",o,os); //human move  
      }else{ 
       ajaxmove("x",x,xs,moves,squares,gameover,i,magiclist,"o",o,os); //computer move 
      x++; 
      i++;    
      humanmove("o",o,os,moves,squares,gameover,i,magiclist,"x",x,xs); //human move 
      };     
}); 

//---//--//--//--//--//--//--//--//--//--//--//---// 
// AjaxMove Desc. Checks if can win or block if it// 
//can't, Sends data to MYSQLtest which in turn // 
//queries xos database and returns best move is // 
//then used.          // 
//---//--//--//--//--//--//--//--//--//--//--//---// 

function ajaxmove(status,counter,turn,moves,squares,gameover,i,magiclist,otherturn){ 

bestmove = 0; 
if (turn.length >= 2){ //goes through each possibility 
    FirstMoves = turn.slice(0); 
    while (FirstMoves.length > 1){       
      FirstX = FirstMoves[0]; 
      SecondMoves = FirstMoves.slice(1); 
      ThirdMoves = squares.slice(0); 
      $.each (SecondMoves,function(){ 
       if (ThirdMoves.length > 0){ 
            SecondX = this; 
         $.each (ThirdMoves,function(){ 
          ThirdX = this; 
          if (FirstX + SecondX + ThirdX == 15){ 
          bestmove = this; 
          }; 
         }); 
         ThirdMoves = ThirdMoves.slice(1);         
       }; 
      }); 
      FirstMoves = FirstMoves.slice(1); 
    } 
}; 
if ((bestmove == 0) && (otherturn.length >= 2)){ 
    FirstMoves = otherturn.slice(0); 
    while (FirstMoves.length > 1){ 
      FirstX = FirstMoves[0]; 
      SecondMoves = FirstMoves.slice(1); 
      ThirdMoves = squares.slice(0); 
      $.each (SecondMoves,function(){ 
       if (ThirdMoves.length > 0){ 
         SecondX = this; 
         $.each (ThirdMoves,function(){ 
          ThirdX = this; 
          if (FirstX + SecondX + ThirdX == 15){ 
           bestmove = this; 
          }; 
         }); 
         ThirdMoves = ThirdMoves.slice(1);         
       }; 
      }); 
      FirstMoves = FirstMoves.slice(1); 
    } 
}; 
if (bestmove == 0){ 
    $.ajax({type:'POST', 
     async: false, 
     url:'/XOsAI/MYSQLtest.php', 
     data:{ 
      status: status, 
      moves: moves, 
      remaining: squares, 
      gameover: gameover 
     }, 
     success: 
      function(data){ 
       bestmove = data;           
      } 
    }); 
}; 
bestmove = Number(bestmove); 
index = squares.indexOf(bestmove); 
    turn[counter] = bestmove; 
select = magiclist.indexOf(bestmove); 
    $('.square').eq(select).addClass(status); 
    $('.square').eq(select).addClass('clicked'); 
    squares.splice(index,1); 
    moves[i] = turn[counter];   
    gamecheck(turn,squares,moves); //game check (see below) 
    if (win) { 
     alert ("You Lose!"); 
     while (i <= 9){       
       i++; 
       moves[i] = "'" + status + "'";      
     };         
     $.ajax({type:'POST', 
       async: false, 
       url:'/XOsAI/MYSQLtest.php', 
       data:{ 
        status: status, 
        moves: moves, 
        remaining: squares, 
        gameover: gameover 
       }      
     }); 
    }; 
}; 

//---//--//--//--//--//--//--//--//--//--//--//---// 
// HumanMove Desc. Allows human to make a move and// 
//checks if they have won.Updates Database if so. // 
//Also Triggers computer move.     // 
//---//--//--//--//--//--//--//--//--//--//--//---// 

function humanmove(status,counter,turn, 
       moves,squares,gameover, 
       i,magiclist,otherstatus, 
       othercounter,otherturn){  
    $(".XOs").on('click', '.square:not(.clicked)', function() { 
     if (gameover == -1){ 
     if (!$(this).hasClass("clicked")) { 
       $(this).addClass('clicked'); 
       $(this).addClass(status); 
       data = magiclist[$('.square').index(this)]; 
       turn[counter] = data; 
       index = squares.indexOf(data); 
       squares.splice(index,1); 
       moves[i] = turn[counter]; 
       gamecheck(turn,squares,moves); //game check (see below) 
       if (!(end)){ 
       if (win) { 
         alert ("You Win!"); 
         gameover = 1; 
         while (i <= 9){       
          i++; 
          moves[i] = "'" + status + "'";      
         };         
         $.ajax({type:'POST', 
          async: false, 
          url:'/XOsAI/MYSQLtest.php', 
          data:{ 
           status: status, 
           moves: moves, 
           remaining: squares, 
           gameover: gameover 
          }      
         }); 
         $('.squares').addClass('clicked'); 
       }; 
       counter++; 
       i++; 
       if (gameover == -1){ 
       ajaxmove(otherstatus,othercounter,otherturn,moves,squares,gameover,i,magiclist,turn); //computer move   
       othercounter++; 
       i++; 
       if (win) {gameover = 1;}; 
       }; 
       }; 
     }; 
    }; 
    }); 
}; 

//---//--//--//--//--//--//--//--//--//--//--//---// 
// GameCheck Desc. Runs through each possibility.// 
//As data locations of divs are arranged in magic // 
//square, checks if any three add to 15. Checks // 
//for cat game as well.       // 
//---//--//--//--//--//--//--//--//--//--//--//---// 

function gamecheck(turn,squares,moves){ 
    if (turn.length >= 3){ 
     FirstMoves = turn.slice(0); 
     while (FirstMoves.length >= 3){       
      FirstX = FirstMoves[0]; 
      SecondMoves = FirstMoves.slice(1); 
      ThirdMoves = SecondMoves.slice(1); 
      $.each (SecondMoves,function(){ 
       if (ThirdMoves.length > 0){ 
         SecondX = this; 
         $.each (ThirdMoves,function(){ 
          ThirdX = this; 
          if (FirstX + SecondX + ThirdX == 15){ 
           win = true; 
          }; 
         }); 
         ThirdMoves = ThirdMoves.slice(1);         
       }; 
      }); 
      FirstMoves = FirstMoves.slice(1); 
     } 
    }; 

    if (!(squares.length > 0) && win == false) { //if any remain  
     alert ("You Draw!"); 
     gameover = 1; 
     moves[9] = "'c'";                
     $.ajax({type:'POST', //ajax to tell server Cat Game 
       async: false, 
       url:'/XOsAI/MYSQLtest.php', 
       data:{ 
        status: "c", 
        moves: moves, 
        remaining: squares, 
        gameover: gameover 
       }      
     }); 
     end = true; 
    }; 
}; 

和PHP如果有人有興趣

//-------------------------------------------------------------------------- 
// 1) Connect to mysql database 
//-------------------------------------------------------------------------- 
$con = mysqli_connect($host,$user,$pass,$databaseName); 
$dbs = mysqli_select_db($con,$databaseName); 

//-------------------------------------------------------------------------- 
// 2) Query database for bestmove or insert data if gameover 
//-------------------------------------------------------------------------- 
$gameover = 0; 
$col = 0; 
$status = $_POST['status']; 
$moves = $_POST['moves']; 
$gameover = $_POST['gameover']; 
$remaining = $_POST['remaining']; 
$bestresult = 0; 
if ($gameover < 0){ 
    $required = (count($remaining) * 50); //seemed large enough to make a smart move 
    if (count($moves) > 0){ 
    foreach ($moves as $move){ 
     $columns[$col].=' AND '; 
     $columns[$col].= '`'; 
     $columns[$col].= ($col + 1); 
     $columns[$col].= '`='; 
     $columns[$col].= $move; 
     $col++; 
    };  
    $moves = implode(' ',$columns); 
    }; 
    $sql = ' 
      SELECT * 
      FROM xos 
      WHERE status=\''; 
    $sql .= $status; 
    $sql .= '\' '; 
    if (count($moves) > 0){ 
    $sql .= $moves ; 
    }; 
    $results = mysqli_query($con,$sql); //fetch result 
    $results = $results->num_rows; 
    echo $con->error; 
if ($results > $required){ 
     if (count($moves) == 0){ 
      $col = 1; 
     }; 
     $reset = $sql; 
     foreach ($remaining as $bestmove){ 
      $sql .=' AND '; 
      $sql .= '`'; 
      $sql .= $col;    
      $sql .= '`='; 
      $sql .= $bestmove; 
      $sql .= ' '; 
      $results = mysqli_query($con,$sql); 
      $results = $results->num_rows; 
      if ($con->error){ 
       echo $con->error ."\n"; 
       echo $sql .":"; 
       echo $results ."\n \n"; 
      } 
      if ($results >= $bestresult){ 
       $bestresult = $results; 
       $bestplay = $bestmove; 
      }; 
      $sql = $reset; 
     }; 
}else{ 
    $sql = ' 
      SELECT * 
      FROM xos 
      WHERE status=\'c\''; 
    if (count($moves) > 0){ 
     $sql .=' AND '; 
     $sql .= $moves ; 
    }; 
    $results = mysqli_query($con,$sql); //fetch result 
    $results = $results->num_rows; 
    if ($results > $required){ 
      if (count($moves) == 0){ 
      $col = 1; 
     }; 
     $reset = $sql; 
     foreach ($remaining as $bestmove){ 
      $sql .=' AND '; 
      $sql .= '`'; 
      $sql .= $col;    
      $sql .= '`='; 
      $sql .= $bestmove; 
      $sql .= ' '; 
      $results = mysqli_query($con,$sql); 
      $results = $results->num_rows; 
      if ($con->error){ 
       echo $con->error ."\n"; 
       echo $sql .":"; 
       echo $results ."\n \n"; 
      } 
      if ($results >= $bestresult){ 
       $bestresult = $results; 
       $bestplay = $bestmove; 
      }; 
      $sql = $reset; 
     }; 
    }else{ 
    $max = count($remaining) - 1; 
    $bestplay = rand(0,$max); 
    $bestplay= $remaining[$bestplay]; 
    }; 
    };echo $bestplay; 
}else{ 
$sql = "INSERT INTO `xos`(`1`, `2`, `3`, `4`, `5`, `6`, `7`, `8`, `9`, `Status`) VALUES ("; 
     for ($i = 0; $i <= 8; $i++) { 
      $sql .= $moves[$i]; 
      $sql .= ","; 
     }; 
     $sql .= ""; 
     $sql .= $moves[9]; 
     $sql .= ")"; 
     if ($con->query($sql) === false){ 
      echo $con->error; 
      echo $sql; 
     };  
};       

回答

1

你有幾個問題。

首先,您將.x的所有位置放入數組中,然後查看該數組是否在wins陣列中。

不幸的是,$.inArray()只會返回一個索引,如果這些項目是相同的項目,如果它們具有匹配的值,則不會返回索引。

$.inArray([4,5,6], [[1,2,3], [4,5,6]]) // returns -1 

var ary1 = [1,2,3]; 
var ary2 = [4,5,6]; 
$.inArray(ary2, [ary1, ary2]); // returns 1 

$.inArray(ary2, [ary1, [4,5,6]]); // returns -1 

其次,如果你是在哪裏,你有3次以上X的遊戲的狀態,你永遠不會匹配一個成功的位置:

X O _ 
X X O 
X O _ 

在這種情況下xs將等於[1,4,5,7]。這是一個勝利的位置,但不會匹配你的任何陣列。

還有很多其他方法可以解決這個問題。考慮到您的wins陣列,最簡單的方法是遍歷每個陣列,並檢查陣列中每個位置的div是否爲X。如果是這樣,停止並宣佈勝利。

演示:http://jsfiddle.net/jtbowden/4BDwt/1/

注意,我在這個例子中清理了一些其他的代碼。

  • 被移去的冗餘clickable類,並使用 .square:not(.clicked)
  • 代替.click().on()
  • 刪除了.square的ID,只是使用div的訂單XOs作爲位置,使用.eq()與數組的位置。 ID不應以數字開頭,最好將數據存儲在jQuery數據屬性中,如<div data-location="1">,並使用.data('location')檢索它。但是,在這種情況下,它不是必需的,因爲div命令告訴我們它在哪裏。
  • $.each(array, function(){})代替$(array).each(function(){})。這是迭代不是jQuery對象的普通數組的正確方法。
+0

感謝您的建議和.eq()的建議。我在一段時間後完成了AI的程序,但是剛剛發佈了我最終做的事情。出於安全原因,我不會發布該鏈接,但它始終如一地繪製或獲勝。 –

2

乍一看,它看起來像在

$(wins).each(function(){ 
    var maybe = $.inArray(this,xs); //if Xs match combos win 
    ... 
} 

如果array xs在當前籤成功的組合找到您正在檢查,而不是僅僅比較thisxs(包括一維數組) 。 [試過$.inArray(wins, xs)但是不行。]

難道這是它嗎?

UPDATE:這個版本的作品:http://jsfiddle.net/QH6W9/9/

我定你的代碼與該檢索X'ed領域的ID:

var xs = $(".x").map(function(i, el) { 
      return parseInt($(el).attr('id')) 
     }).get(); // get ids as array 

而且還檢測的雙贏局面:

$(wins).each(function() { 
    var found = true; 
    for(var i =0; i<this.length; i++) { 
     found &= ($.inArray(this[i], xs) > -1); 
    } 
    if (!found) return; 
    alert("You Won Bruh"); 
    var all = $(".square"); 
    $(all).addclass('clicked'); //stops more turns 
    return; 
}); 
1

你必須在你的程序的兩個問題:

首先,你有以下幾點:

parseInt(number); xs [i] = number;

xs[i]仍然收到一個字符串,因爲parseInt()不修改其參數。相反,它會返回數字值。所以我改變了代碼,以更緊湊:

xs[i] = parseInt(number); 

其次,在你的$(wins).each()循環,你正在使用$.inArray(),但你已經個別陣列,讓你真正想做的數組子集比較有。由於使用Javascript/jQuery有沒有內置陣列子功能,我只是比較陣列中的每個元素:

$(wins).each(function(){ 
    console.log('template: ' + this); 
    var allIn = true; 
    for(var i=0; i<this.length; i++) { 
     console.log(this[i]); 
     if($.inArray(this[i], xs) == -1) allIn = false; 
    } 
if (allIn){ 
    alert("You Won Bruh"); 

而現在它的工作原理。我只爲X的,而不是O的......我會把它留給你!你可以看到我在這裏的jsfiddle解決方案:

http://jsfiddle.net/HxGZE/2/

編輯:我的解決方案,現在的作品。看到j​​sfiddle的證明。

+0

我注意到了。仍然是一個很好的鏡頭,尷尬我沒有注意到我的parseint沒有分配任何東西 –