Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
javascript中的connect4算法_Javascript_Algorithm_Pseudocode - Fatal编程技术网

javascript中的connect4算法

javascript中的connect4算法,javascript,algorithm,pseudocode,Javascript,Algorithm,Pseudocode,在connect 4中检查一行中的4的最佳方法是什么 我不会复制数组的代码,但它基本上是一个长度为42的数组。每个数组元素都保留绘图的X、Y位置和颜色 var board_array = [{x:60, y:55, c:"Red"}, // ... and so on 看起来是这样的: 最初我采取了这种方法。这里是所有可能的不同方式,一个人可以赢得比赛。这并不是所有可能的4连胜位置,而是一个人可以垂直、水平和垂直获胜的所有不同方式——你仍然需要使用某种嵌套for循环进行检查 // Winni

在connect 4中检查一行中的4的最佳方法是什么

我不会复制数组的代码,但它基本上是一个长度为42的数组。每个数组元素都保留绘图的X、Y位置和颜色

var board_array = [{x:60, y:55, c:"Red"}, // ... and so on
看起来是这样的:

最初我采取了这种方法。这里是所有可能的不同方式,一个人可以赢得比赛。这并不是所有可能的4连胜位置,而是一个人可以垂直、水平和垂直获胜的所有不同方式——你仍然需要使用某种嵌套for循环进行检查

// Winning vertically
wins[0]  = new Array(0, 7,  14, 21, 28, 35);
wins[1]  = new Array(1, 8,  15, 22, 29, 36);
wins[2]  = new Array(2, 9,  16, 23, 30, 37);
wins[3]  = new Array(3, 10, 17, 24, 31, 38);
wins[4]  = new Array(4, 11, 18, 25, 32, 39);
wins[5]  = new Array(5, 12, 19, 26, 33, 40);
wins[6]  = new Array(6, 13, 20, 27, 34, 41);
// Winning horizontally
wins[7]  = new Array(0,   1,  2,  3,  4,  5,  6);
wins[8]  = new Array(7,   8,  9, 10, 11, 12, 13);
wins[9]  = new Array(14, 15, 16, 17, 18, 19, 20);
wins[10] = new Array(21, 22, 23, 24, 25, 26, 27);
wins[11] = new Array(28, 29, 30, 31, 32, 33, 34);
wins[12] = new Array(35, 36, 37, 38, 39, 40, 41);
// Winning diagonally, left to right
wins[13] = new Array(14, 22, 30, 38);
wins[14] = new Array(7, 15, 23, 31, 39);
wins[15] = new Array(0, 8, 16, 24, 32, 40);
wins[16] = new Array(1, 9, 17, 25, 33, 41);
wins[17] = new Array(2, 10, 18, 26, 34);
wins[18] = new Array(3, 11, 19, 27);
//Winning diagonally, right to left
wins[19] = new Array(20, 26, 32, 38);
wins[20] = new Array(13, 19, 25, 31, 37);
wins[21] = new Array(6,  12, 18, 24, 30, 36);
wins[22] = new Array(5,  11, 17, 23, 29, 35);
wins[23] = new Array(4,  10, 16, 22, 28);
wins[24] = new Array(3,   9, 15, 21);
如果您认为board_阵列是这样的:

//0  1  2  3  4  5  6
//7  8  9  10 11 12 13
//14 15 16 17 18 19 20
//21 22 23 24 25 26 27
//28 29 30 31 32 33 34
//35 36 37 38 39 40 41

我使用了一个3层for循环和一个计数器来检查wins阵列和board_阵列,但没有用。我只是想知道是否有更简单的方法。

有很多方法可以做到这一点。如果您想摆脱循环,可以使用动态规划算法,每次添加硬币时计算结果

为此,每个字段必须保存4个值:水平值、垂直值、对角左值和对角右值

class Field {
       int horiz;
       int vert;
       int diagLeft;
       int diagRight;
}
开始时,所有字段都初始化为0(字段的所有值)。 如果向字段中添加硬币,则可以计算如下值:

fields[i][j].horiz = fields[i][j+1].horiz + fields[i][j-1].horiz + 1;
fields[i][j].vert = fields[i+1][j].vert + fields[i-1][j].vert + 1;
fields[i][j].diagLeft = fields[i+1][j+1].diagLeft + fields[i-1][j-1].diagLeft +1;
fields[i][j].diagRight = fields[i-1][j-1].diagRight + fields[i+1][j+1]
如果四个计算值中的一个大于等于4,则为赢家

要处理两个玩家,您可以为每个玩家创建一个字段数组,也可以使用正值和负值

如果您不想一直检查边界(i和j),可以在字段中添加边界(这样您就可以在左侧和右侧增加一列,在顶部和底部增加一行)

“在connect 4中检查一行中的4的最佳方法是什么?” 我不会说这是“最好的方式”,但这是一种方式

大多数情况下忽略UI gubbins,该过程(在某种程度上)只是在每次在动态创建的条带搜索模式(可能包含四个连接)中删除计数器时读取网格

每一行、每一列以及前后倾斜的对角线条都是一个字符串,由沿其每一点的颜色值连接而成。
用一个简单的正则表达式测试这些条带,看看是否连续提到了相同的四种计数器颜色(红色或黄色)

虽然它非常循环,但对象非常短,
check4Winner()
(读取网格)中的第一个嵌套循环整理了完成检查所需的所有数据,同时检查行以获得连接。
下面的循环循环仅在未找到赢家的情况下检查柱状和对角条

一个未包含的优化(老实说,几乎不值得额外的代码)可能是删除12条对角线(每个角有三条),因为它们太短,不需要检查

如果需要导出或导入游戏数据,可以轻松使用字符串数组的临时对象(即
console.log
ged用于演示)

用户界面gubbins虽然对于寻找赢家的算法并不十分重要,但在设计时考虑了算法,因此DOM的状态是读取数据的来源。
我特意关闭了代码段中的
控制台
输出,但是您可以在浏览器的控制台中看到通过读取DOM(以这种特定方式)生成的数据

var player=“red”;
常量玩家={“红色”:“黄色”,“黄色”:“红色”},
输出=document.querySelector(“输出”),
tbody=document.querySelector(“tbody”),
rows=tbody.querySelectorAll(“tr”),
准备就绪=(n)=>{
返回数组(n),填充(“”);
},
连接4=(带)=>{
常量rslt=/(?:(红色){4}|(黄色){4}/.exec(条带);
如果(!!rslt){
output.classList.add(rslt[1]| | rslt[2]);
返回true;
}
返回false;
},
check4Winner=()=>{
var条带={
h:[],
五:预备雷(七),,
f:prepArray(12),
b:准备就绪(12)
},
条带,颜色,获胜者,目录;
rows.forEach((row,ri)=>{
strip=“”;
row.querySelectorAll(“td”).forEach((单元格,ci)=>{
color=cell.getAttribute(“类”)| |“”;
strips.b[ci-ri+rows.length-1]+=颜色;
条带.f[ci+ri]+=颜色;
条带.v[ci]+=颜色;
条纹+=颜色;
} );
条。h.推(条);
赢家=赢家| |连接4(带);
} );
console.log(strips);//游戏数据对象
用于(条状目录){
if(!winner&&strips.hasOwnProperty(dir)){
条带[dir].forEach((s)=>{
获胜者=获胜者| |连接4个;
} );
}
}
},
dropCounter=(ci)=>{
var电池;
rows.forEach((row)=>{
if(!(pc=row.childNodes[ci]).getAttribute(“类”)){
cell=pc;
}
} );
如果(单元){
cell.classList.add(player=players[player]);
check4Winner();
}
};
output.addEventListener(“单击”,()=>{
output.removeAttribute(“类”);
t body.queryselectoral(“td”).forEach((c)=>{
c、 删除属性(“类别”);
} );
},假);
tbody.addEventListener(“单击”,(evt)=>{
const trg=evt.target;
如果(!output.getAttribute(“class”)和&trg.tagName.toLowerCase()=“td”){
滴落计数器(trg.cellIndex);
}
},假)
表格,
输出{
盒影:5vh.5vh.2vh.5vh rgba(0,0,0,5);
}
桌子{
宽度:90vh;
边界塌陷:塌陷;
边框:2vh纯蓝色;
}
运输署{
宽度:计算(90vh/7);
背景:皇家蓝;
游标:默认值;
用户选择:无;
}
td:之前{
内容:“;
显示:块;
宽度:计算(90vh/7);
高度:计算(90vh/7);
边界半径:50%;
盒影:插图5vh.5VH2VH.5VHRGBA(0,0,0,5);
背景:白色;
}
运输署署长:之前,{
背景:红色;
}
黄道光:之前,{
背景:黄色;
}
输出{
P
"100000,212121,212000,121211,212100,000000,200000"