Advertisement
Guest User

A*

a guest
Jan 16th, 2019
125
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Kotlin 3.54 KB | None | 0 0
  1. class AStar2(val size: Int) {
  2.  
  3.     enum class Data {
  4.  
  5.         WALL,
  6.         NONE,
  7.         PATH,
  8.  
  9.     }
  10.  
  11.     enum class Move(private val dX: Int, private val dY: Int) {
  12.  
  13.         N(-1, 0),
  14.         S(1, 0),
  15.         E(0, 1),
  16.         W(0, -1),
  17.  
  18.         NW(-1, -1),
  19.         NE(-1, 1),
  20.         SW(1, -1),
  21.         SE(1, 1);
  22.  
  23.  
  24.         fun move(node: Node, grid: Grid): Node? {
  25.             return try {
  26.                 grid[node.x + dX, node.y + dY]
  27.             } catch (ex: Exception) {
  28.                 null
  29.             }
  30.         }
  31.  
  32.     }
  33.  
  34.     data class Node(val x: Int, val y: Int) {
  35.  
  36.         var f = 0
  37.         var g = 0
  38.         var h = 0
  39.  
  40.         var d: Data = Data.NONE
  41.         var p: Node? = null
  42.  
  43.     }
  44.  
  45.     data class Grid(val size: Int) {
  46.  
  47.         private val nodes = Array(size) { x ->
  48.             Array(size) { y ->
  49.                 Node(x, y)
  50.             }
  51.         }
  52.  
  53.  
  54.         operator fun get(x: Int, y: Int): Node {
  55.             return nodes[x][y]
  56.         }
  57.  
  58.  
  59.         fun getRow(y: Int): List<Node> {
  60.             return nodes.map { it[y] }
  61.         }
  62.  
  63.         fun getCol(x: Int): List<Node> {
  64.             return nodes[x].toList()
  65.         }
  66.  
  67.     }
  68.  
  69.     val s: Node
  70.     val e: Node
  71.  
  72.     val grid = Grid(size)
  73.  
  74.     init {
  75.         grid.getRow(0).forEach {
  76.             it.d = Data.WALL
  77.         }
  78.         grid.getCol(0).forEach {
  79.             it.d = Data.WALL
  80.         }
  81.  
  82.         grid.getRow(size - 1).forEach {
  83.             it.d = Data.WALL
  84.         }
  85.         grid.getCol(size - 1).forEach {
  86.             it.d = Data.WALL
  87.         }
  88.  
  89.  
  90.         val rS = (random() * size).toInt()
  91.         val rE = (random() * size).toInt()
  92.  
  93.         s = grid[0, rS]
  94.         e = grid[size - 1, rE]
  95.  
  96.         s.d = Data.NONE
  97.         e.d = Data.NONE
  98.  
  99.  
  100.         for (x in 1 until size - 1) {
  101.             for (y in 1 until size - 1) {
  102.                 if (random() >= 0.30) continue
  103.                 grid[x, y].d = Data.WALL
  104.             }
  105.         }
  106.     }
  107.  
  108.     fun exec() {
  109.  
  110.         val o = sortedSetOf<Node>(compareBy { it.f })
  111.         val c = mutableSetOf<Node>()
  112.  
  113.         o += s
  114.  
  115.         while (o.isNotEmpty()) {
  116.             val n = o.first()
  117.  
  118.             o -= n
  119.             c += n
  120.  
  121.             if (n == e) {
  122.                 return println("Found path, next")
  123.             }
  124.  
  125.             val next = Move.values().mapNotNull { it.move(n, grid) }.filter { it.d == Data.NONE && it !in c }
  126.  
  127.             next.forEach {
  128.  
  129.                 it.g = n.g + 1
  130.                 it.h = dist(it, e)
  131.                 it.f = it.g + it.h
  132.                 it.p = n
  133.  
  134.                 o += it
  135.             }
  136.         }
  137.     }
  138.  
  139.     fun show() {
  140.         println()
  141.         for (y in 0 until size) {
  142.             for (x in 0 until size) {
  143.                 val char = when (grid[x, y].d) {
  144.                     Data.NONE -> '░'
  145.                     Data.PATH -> '▒'
  146.                     Data.WALL -> '▓'
  147.                 }
  148.                 print(char)
  149.             }
  150.             print("\n")
  151.         }
  152.         println()
  153.     }
  154.  
  155.     fun path(): List<Node> {
  156.         var p: Node? = e
  157.         return generateSequence { p?.let { p = it.p; it } }.toList().reversed()
  158.     }
  159.  
  160.     fun dist(a: Node, b: Node): Int {
  161.         return abs(a.x - b.x) + abs(a.y - b.y)
  162.     }
  163.    
  164.     companion object {
  165.  
  166.         @JvmStatic
  167.         fun main(args: Array<String>) {
  168.             val star = AStar2(20)
  169.             star.show()
  170.             star.exec()
  171.  
  172.             star.path().forEach { it.d = Data.PATH }
  173.  
  174.             star.show()
  175.         }
  176.  
  177.     }
  178.  
  179. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement