如何使用排序类型函数有效更新对象中的特定键/值

问题描述:

我正在创建井字游戏的JavaScript游戏,并尝试使其足够聪明,以基于*文章中列出的策略制定明智的举动。 IE,如果有一行或两列中有两个X或两个O,请抽空。因此,考虑到键值对的行或列,可以说该值可能是: OBJ { 键1: “X”, KEY2: “”, KEY3: “X”, }如何使用排序类型函数有效更新对象中的特定键/值

我有一直在努力一段时间来做这件事,并且好奇是否有办法做到这一点,而不是一系列的循环。我的第一个尝试是尝试按字母顺序对项目进行排序,以便可以隔离空白值:var =“”,“X”,“X”

在这种情况下,我可以轻松地调用第一项并更新它,但我不能将其逆转为原来的状态,并将其更新为其在对象中的原始位置。但是,我似乎无法弄清楚如何以不会产生大量浪费代码的方式来实现这一点。分成多个循环可能会更好吗?一个隔离行和列(有8个)有一个空白点?

我的另一个想法是给网格中的每个值为1,然后通过网格查看,如果一行等于3(创建var,加入它们并使用.eval()方法) ,然后使每个项目等于1,因此将空白点更新为1,并更新已经为1的其他两个点。

我试图尽可能具体,但我并不擅长解释这个特定问题,我承认。

这里是一个JS提琴我提出: https://jsfiddle.net/1hup5195/

下面是一些我的脚本供参考:

$(document).ready(function(){  
var playerTurn = true; 
var buttonStatus = "allowclick"; // Change to inactive once game starts 
var player = ""; 
var machine = ""; 
var test = ""; 
var emptyObj = {1: "", 2: "", 3: "", 
       4: "", 5: "", 6: "", 
       7: "", 8: "", 9: ""}; 
var gridObj = {1: "", 2: "", 3: "", 
       4: "", 5: "", 6: "", 
       7: "", 8: "", 9: ""}; 
var winningObj = [[1,2,3], [4,5,6], [7,8,9], [1,4,7], [2,5,8], [3,6,9], [1,5,9], [3,5,7]]; 




// Check if player is holding a corner 
function machineFunction() { 
    // Loop through winningObj and check if there are rows/columns with 2/3 taken 
    // for(i = 0; i < winningObj.length; i++) { 
     var i = 3; 
     var alpha = winningObj[i][0]; 
     var bravo = winningObj[i][1]; 
     var charlie = winningObj[i][2]; 
     console.log(alpha); 
     console.log(bravo); 
     console.log(charlie); 
     // After defining alpha/bravo/charlie, fire the fxn 
     testFxn(alpha, bravo, charlie); 
     // This is my function to sort the 3 different spots within the grid 
     function testFxn(a,b,c) { 
      // Test would be equal to ["", "X", "X"] or something similar 
      var test = [gridObj[a], gridObj[b], gridObj[c]].sort(); 
      console.log(test); 
      console.log(gridObj); 
      // If 2/3 spots taken by either X or O, take this spot 
      if (test[0] === "" && test[1] === "X" && test[2] === "X") { 
       console.log("#" + alpha + "") 
       $('#' + alpha + '').html(machine); 
       gridObj[alpha] = machine; 
       console.log(gridObj); 
       $(this).html(machine); // Sends player over to html 
       gridObj[this.id] = machine; // Update gridObj object 
       playerTurn = true; 
      } 
      if (test[0] === "" && test[1] === "O" && test[2] === "O") { 
       // How do I get the ID I need?? 
       $('#' + test[0] + '').html(machine); 
       playerTurn = true; 
      } 
     }; 
+0

这是小提琴的链接,我不认为以前的作品。 (https://jsfiddle.net/1hup5195/#&togetherjs=i67M4LaRnw) –

你可以这样做做某事(使用一些迭代...):

var rows = [[1,2,3], [4,5,6], [7,8,9], [1,4,7], [2,5,8], [3,6,9], [1,5,9], [3,5,7]]; 
var gridObj = {1: "", 2: "", 3: "", 
      4: "", 5: "", 6: "", 
      7: "", 8: "", 9: ""}; 

rows.some(function(row){//iterate over all rows 
    var values=row.map(key=>gridObj[key]);//get the rows values 
    if(values.filter(el=>el==="X").length===2){//check if there are two Xses 
     gridObj[rows[values.indexOf("")]]="O";//get the field id and add O to the blank field 
     return true;//stop iterating the rows 
    } 
}); 

http://jsbin.com/miriwuhuce/edit?console

我想评论,但我不能。所以这里是我的评论作为答案...

如果你使每个“领域”的对象,你可以引用它在不同的数组。所以你可以做一个array.copy,排序一个,然后改变对象的值。

这也将设置其他数组中保存相同对象的值。

祝你好运!

JavaScript有一个很棒的功能叫做map,可以用在数组上。 Here is documentation

提供了一个回调函数,它将对数组中的每个元素执行一些定义的函数(可能根据当前状态检查获胜状态),并返回一个具有更改或未更改值的新数组。例如,你可以有中奖的状态就像你现在要做的数组,并做

var winner = winningObj.map((item) => { //()=>{} is ES6 syntax. Same as function(){} 
    var token = {} 
    if currentState[item[0]] != empty 
     token.1st = X 

    if currentState[item[1]] != empty 
     token.2nd = X 
    if currentState[item[2]] != empty 
     token.3rd = X 

    if all tokens are X 
     return X  // winner! 
    else if all tokens are O 
     return O  // check the other winning conditions, or keep playing 
    else 
     return false 
); 

if winner.containsValue(X) 
    X wins 
else if winner.containsValue(O) 
    O wins 
else 
    keep playing 

我知道这并没有真正回答你的问题的更好的效率方面,但这种方式,你可以避免写摆脱任何循环,让map()为你做所有的工作。