我正在将俄罗斯方块作为一个有趣的侧面项目(不是家庭作业),并希望实现AI,以便计算机可以自己玩。我听说这样做的方法是使用BFS搜索可用的位置,然后创建最合理的放置位置的总分...
但我无法理解算法。到目前为止,我理解的方式是:
1)将节点添加到ArrayList
nodeList.add(n nodes)
2)连接节点
adjMatrix[sizeOfNodeList][sizeOfNodeList]
传递节点进行连接:例如connectNode(nodeA, nodeB);
,其中调用:connectNode(Node from, Node to)
:
int fromNode=nodesList.indexOf(from);
int toNode=nodesList.indexOf(to);
//connect node A to B and B to A, set that i,j position = 1
adjMatrix[fromNode][toNode]=1;
adjMatrix[toNode][fromNode]=1;
在邻接矩阵中连接节点后......
3)循环遍历节点队列,并将访问者添加到队列
Queue q = new LinkedList();
rootNode
添加到队列:q.add(rootNode)
rootNode.visited(true)
这是我不理解的部分......
Node n = (Node)q.remove()
但是如果您要向其添加节点q.add(rootNode)
和q.add(child)
,那么什么时候它会变空?
while((child=getUnvisitedChildNode(n))!=null)
,您应该更改子访问状态= true
,然后将其添加到队列{{1} } ...但你不是在做这一切q.add(child)
吗?那么,如果您要添加while(!q.isEmpty())
,那么它什么时候会为空呢?我的队列q
的目的是什么?是结果队列吗?
由于
答案 0 :(得分:3)
您的队列q
包含您尚未访问过的节点。您应该只添加尚未访问过的队列q
节点。这样它就会变空,你已经探索过的节点不会重新进入列表。
以图片为例,您只能使用节点q
启动A
。您将A
标记为已访问。这就是你的开始。
您的循环将包括删除队列q
上的第一个节点,在本例中为A
,并添加所有连接到A
且尚未连接的节点访问了。换句话说,您将遍历A
矩阵的行,并发现B
,C
和D
已连接到A
。对于每个人,如果visited()
返回false,则会将其添加到q
并标记为已访问。在此次传递中,q
将B
,C
和D
,而A-D
的所有q
都将被访问过()为真。
在下一次迭代中,B
上的第一个节点将为A
。您将对其进行出列,并将其与E
,F
和A
相关联。由于true
在您致电visited()
时会返回q
,因此您不会将其添加到E
。将添加F
和C
并将其标记为已访问。
如果您继续,则会将D
,E
,F
和q
出列,而不会向q.isEmpty()
添加任何内容,因为所有节点都已经被访问过。之后,true
将返回{{1}}并且您的循环结束。
答案 1 :(得分:1)
队列是您的待办事项列表。它是接下来要处理的节点列表。
当您在树/图的叶子上处理完要处理的子项时,队列将变为空。