cg85-v2/Sources/Np85Snake/Board/Snake.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
}
}