commonMain.ru.casperix.path.util.PathDrawer.kt Maven / Gradle / Ivy
package ru.casperix.path.util
import ru.casperix.math.array.CustomMap2D
import ru.casperix.math.array.Map2D
import ru.casperix.math.vector.int32.Vector2i
import ru.casperix.path.api.Path
import ru.casperix.path.custom.PathFactory
enum class PathType {
NONE,
START,
FINISH,
POINT,
}
fun drawPathInfo(info: PathFactory, path: Path, edgeProjection: (Vector2i) -> Vector2i, hasObstacle: (Vector2i) -> Boolean) {
val (first, map) = createLocalPathMap(path, edgeProjection)
val start = path.start
val finish = path.finish
var result = ""
result += "dist: ${start.distTo(finish)}\n"
result += "weight: ${info.weight}\n"
result += "steps: ${info.searchSteps}\n"
result += "map: ${info.searchMap?.size}\n"
result += drawPathMap(info, first, map, hasObstacle)
println(result)
}
fun drawPathMap(info: PathFactory, first: Vector2i, map: Map2D, hasObstacle: (Vector2i) -> Boolean): String {
var result = ""
for (y in 0 until map.dimension.y) {
for (x in 0 until map.dimension.x) {
val localPosition = Vector2i(x, y)
val path = map.get(localPosition)
val obstacle = hasObstacle(localPosition + first)
val inSearchMap = info.searchMap.containsKey(localPosition + first) ?: false
result += getSymbol(path, obstacle, inSearchMap)
}
result += "\n"
}
return result
}
fun getSymbol(path: PathType, obstacle: Boolean, inSearchMap: Boolean): String {
if (inSearchMap) {
return getSymbol2(path, obstacle)
}
return getSymbol(path, obstacle)
}
fun getSymbol(path: PathType, obstacle: Boolean): String {
return when (path) {
PathType.NONE -> {
if (obstacle) {
"██"
} else {
"░░"
}
}
PathType.START -> "O "
PathType.POINT -> "+ "
PathType.FINISH -> "X "
}
}
fun getSymbol2(path: PathType, obstacle: Boolean): String {
return when (path) {
PathType.NONE -> {
if (obstacle) {
"▓▓"
} else {
"▒▒"
}
}
PathType.START -> "OO"
PathType.POINT -> "[]"
PathType.FINISH -> "XX"
}
}
fun createLocalPathMap(path: Path, edgeProjection: (Node) -> Vector2i): Pair> {
var min = Vector2i(Int.MAX_VALUE)
var max = Vector2i(Int.MIN_VALUE)
path.nodes.forEach {
val position = edgeProjection(it)
min = min.lower(position)
max = max.upper(position)
}
min -= Vector2i.ONE * 4
max += Vector2i.ONE * 4
val localMap = CustomMap2D.create(max - min + Vector2i.ONE) { PathType.NONE }
path.nodes.forEach {
val globalPosition = edgeProjection(it)
val localPosition = globalPosition - min
if (it == path.start) {
localMap.set(localPosition, PathType.START)
} else if (it == path.finish) {
localMap.set(localPosition, PathType.FINISH)
} else {
localMap.set(localPosition, PathType.POINT)
}
}
return Pair(min, localMap)
}