50 lines
1.3 KiB
Swift
50 lines
1.3 KiB
Swift
public struct Snake {
|
|
public let body: [BoardNode]
|
|
public let isMine: Bool
|
|
|
|
init(size: Vertex, nodes: [[BoardNode]], origin: BoardNode) throws {
|
|
isMine = origin.part == .legalHead
|
|
|
|
var body: [BoardNode] = [origin]
|
|
body.reserveCapacity(size.x * size.y)
|
|
|
|
var prev: BoardNode? = nil
|
|
var current = origin
|
|
|
|
var directions = [Vertex.up, Vertex.down, Vertex.right, Vertex.left]
|
|
while true {
|
|
var next: BoardNode? = nil
|
|
|
|
for dir in directions {
|
|
let nextVertex = (current.vertex + dir) % size
|
|
let candidate = nodes[nextVertex.y][nextVertex.x]
|
|
|
|
if prev?.vertex == candidate.vertex { continue }
|
|
if current.part.isHead && !candidate.part.isNeck { continue }
|
|
|
|
guard current.part.connects(to: candidate.part, in: dir * -1) else {
|
|
continue
|
|
}
|
|
|
|
next = candidate
|
|
if candidate.part.isJunction
|
|
|| candidate.part.normalize() == .rightLeft
|
|
|| candidate.part.normalize() == .upDown
|
|
{
|
|
directions = [dir]
|
|
} else {
|
|
directions = Vertex.cardinals
|
|
}
|
|
break
|
|
}
|
|
|
|
guard let nextNode = next else { break }
|
|
body.append(nextNode)
|
|
prev = current
|
|
current = nextNode
|
|
}
|
|
|
|
self.body = body
|
|
}
|
|
}
|