如何使用排序类型函数有效更新对象中的特定键/值
我正在创建井字游戏的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;
}
};
你可以这样做做某事(使用一些迭代...):
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
}
});
我想评论,但我不能。所以这里是我的评论作为答案...
如果你使每个“领域”的对象,你可以引用它在不同的数组。所以你可以做一个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()
为你做所有的工作。
这是小提琴的链接,我不认为以前的作品。 (https://jsfiddle.net/1hup5195/#&togetherjs=i67M4LaRnw) –