///|
/// One expansion event produced by a search algorithm.
pub(all) struct SearchStep {
order : Int
point : Point
cost : Int
score : Int
} derive(Eq, Debug)
///|
pub fn SearchStep::new(
order : Int,
point : Point,
cost : Int,
score : Int
) -> SearchStep {
{ order, point, cost, score }
}
///|
pub fn Point::to_json(self : Point) -> String {
"{\"x\":\{self.x},\"y\":\{self.y}}"
}
///|
pub fn SearchStep::to_json(self : SearchStep) -> String {
"{\"order\":\{self.order},\"point\":\{self.point.to_json()},\"cost\":\{self.cost},\"score\":\{self.score}}"
}
///|
/// Search trace is kept as data so it can feed JSON, SVG, HTML, or tests.
pub(all) struct SearchTrace {
steps : Array[SearchStep]
} derive(Eq, Debug)
///|
pub fn SearchTrace::new() -> SearchTrace {
{ steps: [] }
}
///|
pub fn SearchTrace::length(self : SearchTrace) -> Int {
self.steps.length()
}
///|
pub fn SearchTrace::push_step(
self : SearchTrace,
order : Int,
point : Point,
cost : Int,
score : Int
) -> Unit {
self.steps.push(SearchStep::new(order, point, cost, score))
}
///|
pub fn SearchTrace::to_json(self : SearchTrace) -> String {
let buf = StringBuilder(size_hint=32 + self.steps.length() * 64)
buf.write_string("{\"steps\":[")
for i = 0; i < self.steps.length(); i = i + 1 {
if i > 0 {
buf.write_string(",")
}
buf.write_string(self.steps[i].to_json())
}
buf.write_string("]}")
buf.to_string()
}
///|
fn write_points_json(buf : StringBuilder, points : Array[Point]) -> Unit {
buf.write_string("[")
for i = 0; i < points.length(); i = i + 1 {
if i > 0 {
buf.write_string(",")
}
buf.write_string(points[i].to_json())
}
buf.write_string("]")
}
///|
pub fn PathResult::to_json(self : PathResult) -> String {
let buf = StringBuilder(size_hint=128 + self.path.length() * 24 + self.trace.length() * 64)
buf.write_string("{\"found\":")
buf.write_string(if self.found { "true" } else { "false" })
buf.write_string(",\"cost\":\{self.cost},\"visited_count\":\{self.visited_count},\"path\":")
write_points_json(buf, self.path)
buf.write_string(",\"trace\":")
buf.write_string(self.trace.to_json())
buf.write_string("}")
buf.to_string()
}
///|
fn write_ints_json(buf : StringBuilder, values : Array[Int]) -> Unit {
buf.write_string("[")
for i = 0; i < values.length(); i = i + 1 {
if i > 0 {
buf.write_string(",")
}
buf.write_string(values[i].to_string())
}
buf.write_string("]")
}
///|
pub fn GraphPathResult::to_json(self : GraphPathResult) -> String {
let buf = StringBuilder(size_hint=128 + self.points.length() * 24 + self.trace.length() * 64)
buf.write_string("{\"found\":")
buf.write_string(if self.found { "true" } else { "false" })
buf.write_string(",\"cost\":\{self.cost},\"visited_count\":\{self.visited_count},\"nodes\":")
write_ints_json(buf, self.nodes)
buf.write_string(",\"points\":")
write_points_json(buf, self.points)
buf.write_string(",\"trace\":")
buf.write_string(self.trace.to_json())
buf.write_string("}")
buf.to_string()
}