我需要帮助理解这部分代码与javascript中的Snake冲突,我标记了部分我不完全理解它们是如何工作的: 完整代码: https://codeincomplete.com/posts/starting-snakes/
// do not understand this function
function occupies(a, b) {
return a && b && (a.x == b.x) && (a.y == b.y);
};
//do not understand this function
function snakeOccupies(pos, ignoreHead) {
var segment = ignoreHead ? head.next : head;
do {
if (occupies(segment, pos))
return true;
} while (segment = segment.next);
return false;
};
function unoccupied() {
var pos = {};
do {
//understand this part but i do not understand what does while do
pos.x = Math.round(random(0, nx-1));
pos.y = Math.round(random(0, ny-1));
} while (foodOccupies(pos) || snakeOccupies(pos));
return pos;
};
答案 0 :(得分:1)
在此代码中,游戏区域上的位置由具有属性x
和y
的对象表示。
occupies
检查两个这样的对象是否代表相同的位置。仅仅return a == b;
或return a === b;
是不够的,因为单独的对象可以是彼此的副本并代表相同的位置。例如,表达式{ x: 1, y: 1 } === { x: 1, y: 1 }
将评估为false
。
a && b &&
部分用于处理a
和b
中的一个/两个是undefined
或null
或其他内容的情况。如果a
是假的,occupies
将返回a
。如果a
是真实的,但b
是假的,则会返回b
。 (在javascript中,值false
,undefined
,null
,0
,''
和NaN
是假的;所有其他都是真实的。)由于返回值仅在if(...)
内使用,因此任何虚假值都会被视为false
,任何真实值都会被视为true
。
unoccupied
中的do-while循环运行块的内容,然后评估foodOccupies(pos) || snakeOccupies(pos)
。如果它的计算结果为true
(或其他条件),它将再次运行该块;否则会停止。它将继续运行循环,直到条件为假。这个和没有do
的while循环之间的唯一区别是,这个循环在循环的第一次迭代之前不会检查条件(所以它保证至少运行一次块)。
snakeOccupies
中的循环略有异常:条件(segment = segment.next
)不仅返回一个检查真实性的值,还会更改变量的值。
head
是蛇头的位置。它具有属性x
和y
,就像其他位置一样,除了它还包含一个名为next
的属性。这个属性的值是另一个位置,代表蛇头之后的下一个方块,它有自己的next
属性引用蛇的下一个位置,依此类推。这就是Bergi对“链表”的意思:它是(x
,y
)对的序列,可以作为数组实现,但它是由元素之间的链接实现的。
所以do-while循环遍历snake中的位置(可能忽略head
)。如果它到达位于pos
的位置,则snakeOccupies
会返回true
。否则,循环将最终到达蛇的末尾,segment
将设置为假的(可能是undefined
或null
),循环将退出并snakeOccupies
将返回false
。