All Downloads are FREE. Search and download functionalities are using the official Maven repository.
Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
com.neko233.skilltree.game.grid.impl.Grid2DByMap.kt Maven / Gradle / Ivy
package com.neko233.skilltree.game.grid.impl
import com.neko233.skilltree.game.grid.Grid2D
import com.example.kotlinplayground.spaceMath.Vector2D
import java.util.*
import kotlin.collections.ArrayDeque
import kotlin.math.abs
/**
* 2D 地图格子 by Map 实现 (稀疏矩阵)
*/
class Grid2DByMap(
val width: Int,
val height: Int,
val fillValue: T? = null,
) : Grid2D {
// Map
private val grid: MutableMap = mutableMapOf()
init {
clear()
fill(fillValue)
}
override fun get(
x: Int,
y: Int,
): T? {
return grid[Vector2D(x, y)]
}
override fun set(
x: Int,
y: Int,
value: T?,
) {
grid[Vector2D(x, y)] = value
}
override fun clear() {
for (x in 0 until width) {
for (y in 0 until height) {
grid[Vector2D(x, y)] = null
}
}
}
override fun fill(value: T?) {
for (x in 0 until width) {
for (y in 0 until height) {
grid[Vector2D(x, y)] = value
}
}
}
override fun forEach(
handleGrid: (x: Int, y: Int, value: T?) -> Unit,
) {
for (x in 0 until width) {
for (y in 0 until height) {
handleGrid(x, y, grid[Vector2D(x, y)])
}
}
}
/**
* 广度优先搜索
*/
override fun bfs(start: Vector2D, target: Vector2D): List {
val queue = ArrayDeque()
val visited = mutableSetOf()
val parentMap = mutableMapOf()
queue.add(start)
visited.add(start)
while (queue.isNotEmpty()) {
val current = queue.removeFirst()
if (current == target) {
return reconstructPath(start, target, parentMap)
}
val neighbors = getNeighbors(current)
for (neighbor in neighbors) {
if (neighbor !in visited) {
queue.add(neighbor)
visited.add(neighbor)
parentMap[neighbor] = current
}
}
visited.add(current) // 将当前节点标记为已访问
}
return emptyList()
}
override fun dfs(start: Vector2D, target: Vector2D): List {
val stack = Stack()
val visited = mutableSetOf()
val parentMap = mutableMapOf()
stack.push(start)
visited.add(start)
while (stack.isNotEmpty()) {
val current = stack.pop()
if (current == target) {
return reconstructPath(start, target, parentMap)
}
val neighbors = getNeighbors(current)
for (neighbor in neighbors) {
if (neighbor !in visited) {
stack.push(neighbor)
visited.add(neighbor)
parentMap[neighbor] = current
}
}
}
return emptyList()
}
private fun reconstructPath(
start: Vector2D,
target: Vector2D,
parentMap: Map,
): List {
val path = mutableListOf()
var current = target
while (current != start) {
path.add(current)
current = parentMap[current] ?: break
}
path.add(start)
path.reverse()
return path
}
override fun aStar(
start: Vector2D,
target: Vector2D,
targetScoreMap: MutableMap,
targetCostMap: MutableMap,
): List {
val toTryGridList = mutableListOf(start)
val cameFrom = mutableMapOf()
while (toTryGridList.isNotEmpty()) {
val current = toTryGridList.minByOrNull { targetCostMap.getOrDefault(it, Double.MAX_VALUE) }!!
if (current == target) {
return reconstructPath(start, target, cameFrom)
}
toTryGridList.remove(current)
// 获取当前节点的邻居节点
val neighbors = getNeighbors(current)
for (neighbor in neighbors) {
val defaultScore = targetScoreMap.getOrDefault(current, Int.MAX_VALUE)
// 计算 tentativeGScore
val tentativeGScore = defaultScore + 1
// 比较 tentativeGScore 和邻居节点的得分
if (tentativeGScore < targetScoreMap.getOrDefault(neighbor, Int.MAX_VALUE)) {
cameFrom[neighbor] = current
targetScoreMap[neighbor] = tentativeGScore
targetCostMap[neighbor] = tentativeGScore + heuristic(neighbor, target)
// 将邻居节点加入到待尝试的节点列表
if (neighbor !in toTryGridList) {
toTryGridList.add(neighbor)
}
}
}
}
// 若没有找到路径,则返回空列表
return emptyList()
}
override fun heuristic(start: Vector2D, target: Vector2D): Double {
val xPrice = abs(start.x - target.x)
val yPrice = abs(start.y - target.y).toDouble()
return xPrice + yPrice
}
}