diff --git a/.gitignore b/.gitignore index 51e6d0ca5..b73ba19e4 100644 --- a/.gitignore +++ b/.gitignore @@ -452,3 +452,9 @@ screenlog.* node_modules /dist + + +#################### +## Intellij Idea ## +#################### +.idea/ diff --git a/airesources/Kotlin/LANGUAGE b/airesources/Kotlin/LANGUAGE new file mode 100644 index 000000000..a34f6fd82 --- /dev/null +++ b/airesources/Kotlin/LANGUAGE @@ -0,0 +1 @@ +Kotlin diff --git a/airesources/Kotlin/Model.kt b/airesources/Kotlin/Model.kt new file mode 100644 index 000000000..130c27b47 --- /dev/null +++ b/airesources/Kotlin/Model.kt @@ -0,0 +1,140 @@ +import java.util.* + +class Networking { + + val SIZE_OF_INTEGER_PREFIX = 4 + val CHAR_SIZE = 1 + var width : Int = 0 + var height : Int = 0 + + val productions : MutableList> = arrayListOf() + + fun deserializeGameMapSize(inputString: String) { + inputString.split(" ") + .map { Integer.parseInt(it) } + .forEachIndexed { index, size -> + if (index == 0) width = size else height = size} + } + + fun deserializeProductions(input: String) { + val inputs = input.split(" ").map { Integer.parseInt(it) } + (0 until height).mapTo(productions) { inputs.subList(it * width, (it + 1) * width).toMutableList() } + } + + fun serializeMoveList(moves: ArrayList): String { + val builder = StringBuilder() + for ((loc, dir) in moves) builder.append(loc.x.toString() + " " + loc.y + " " + dir.ordinal + " ") + return builder.toString() + } + + fun deserializeGameMap(input: String): GameMap { + val inputs = input.split(" ").map { Integer.parseInt(it) } + + val map = GameMap(width, height) + + var y = 0 + var x = 0 + var currentIndex = 0 + while (y < map.height) { + val counter = inputs[currentIndex++] + val owner = inputs[currentIndex++] + (0 until counter).forEach { + map.contents[y][x].owner = owner + ++x + if (x == map.width) { + x = 0 + ++y + } + } + } + + for (x in 0 until map.contents.size) { + for (y in 0 until map.contents[x].size) { + map.contents[x][y].strength = inputs[currentIndex++] + map.contents[x][y].production = productions[x][y] + } + } + + return map + } + + fun sendString(sendString: String) { + println(sendString) + System.out.flush() + } + + fun getInit(): InitPackage { + val myID = Integer.parseInt(readLine()?.trim()) + deserializeGameMapSize(readLine()!!.trim()) + deserializeProductions(readLine()!!.trim()) + val map = deserializeGameMap(readLine()!!.trim()) + + return InitPackage(myID, map) + } + + fun sendInit(name: String) { + sendString(name) + } + + fun getFrame(): GameMap { + return deserializeGameMap(readLine()!!.trim()) + } + + fun sendFrame(moves: ArrayList) { + sendString(serializeMoveList(moves)) + } +} + +data class Site(var owner: Int, var strength : Int, var production: Int) +data class Location(var x: Int, var y: Int) +data class InitPackage(var myID: Int, var map: GameMap) +data class Move(var loc: Location, var dir: Direction) + +enum class Direction { + STILL, NORTH, EAST, SOUTH, WEST; + + companion object { + val DIRECTIONS = arrayOf(STILL, NORTH, EAST, SOUTH, WEST) + val CARDINALS = arrayOf(NORTH, EAST, SOUTH, WEST) + + fun random() : Direction { + return DIRECTIONS[Random().nextInt(DIRECTIONS.size)] + } + } +} + +class GameMap(val width: Int, val height: Int) { + + val contents : MutableList> = arrayListOf() + + init { + (0 until height).forEach { + contents.add(Array(width, {Site(0, 0, 0)}).toMutableList()) + } + } + + fun inBounds(location: Location) : Boolean { + return location.x < width && location.x >= 0 && location.y < height && location.y >= 0 + } + + fun getLocation(loc: Location, dir: Direction): Location { + val l = loc.copy() + when(dir) { + Direction.STILL -> return l + Direction.NORTH -> if (l.y == 0) l.y = height - 1 else l.y-- + Direction.EAST -> if (l.x == width - 1) l.x = 0 else l.x++ + Direction.SOUTH -> if (l.y == height - 1) l.y = 0 else l.y++ + Direction.WEST -> if (l.x == 0) l.x = width - 1 else l.x-- + } + return l + } + + fun getSite(loc: Location, dir: Direction): Site { + val (x, y) = getLocation(loc, dir) + return contents[y][x] + } + + fun getSite(loc: Location): Site { + return contents[loc.y][loc.x] + } +} \ No newline at end of file diff --git a/airesources/Kotlin/MyBot.kt b/airesources/Kotlin/MyBot.kt new file mode 100644 index 000000000..d2c5aba90 --- /dev/null +++ b/airesources/Kotlin/MyBot.kt @@ -0,0 +1,34 @@ +import java.util.* + +fun main(args : Array) { + MyBot().start() +} + +class MyBot { + + fun start() { + val network = Networking() + val iPackage = network.getInit() + val myID = iPackage.myID + var gameMap = iPackage.map + + network.sendInit("MyKotlinBot") + + while (true) { + val moves = ArrayList() + + gameMap = network.getFrame() + + for (y in 0..gameMap.height - 1) { + for (x in 0..gameMap.width - 1) { + val site = gameMap.getSite(Location(x, y)) + if (site.owner == myID) { + val dir = Direction.random() + moves.add(Move(Location(x, y), dir)) + } + } + } + network.sendFrame(moves) + } + } +} \ No newline at end of file diff --git a/airesources/Kotlin/RandomBot.kt b/airesources/Kotlin/RandomBot.kt new file mode 100644 index 000000000..1dd52a943 --- /dev/null +++ b/airesources/Kotlin/RandomBot.kt @@ -0,0 +1,34 @@ +import java.util.* + +fun main(args : Array) { + RandomBot().start() +} + +class RandomBot { + + fun start() { + val network = Networking() + val iPackage = network.getInit() + val myID = iPackage.myID + var gameMap = iPackage.map + + network.sendInit("RandomKotlinBot") + + while (true) { + val moves = ArrayList() + + gameMap = network.getFrame() + + for (y in 0..gameMap.height - 1) { + for (x in 0..gameMap.width - 1) { + val site = gameMap.getSite(Location(x, y)) + if (site.owner == myID) { + val dir = Direction.random() + moves.add(Move(Location(x, y), dir)) + } + } + } + network.sendFrame(moves) + } + } +} \ No newline at end of file diff --git a/airesources/Kotlin/runGame.bat b/airesources/Kotlin/runGame.bat new file mode 100644 index 000000000..a8bcc5b59 --- /dev/null +++ b/airesources/Kotlin/runGame.bat @@ -0,0 +1,3 @@ +kotlinc.bat *.kt -d mybot.jar +kotlinc.bat *.kt -d randombot.jar +.\halite.exe -d "30 30" "kotlin -classpath mybot.jar MyBotKt" "kotlin -classpath randombot.jar RandomBotKt" diff --git a/airesources/Kotlin/runGame.sh b/airesources/Kotlin/runGame.sh new file mode 100755 index 000000000..4995bd935 --- /dev/null +++ b/airesources/Kotlin/runGame.sh @@ -0,0 +1,5 @@ +#!/bin/bash + +kotlinc *.kt -d mybot.jar +kotlinc *.kt -d randombot.jar +./halite -d "30 30" "kotlin -classpath mybot.jar MyBotKt" "kotlin -classpath randombot.jar RandomBotKt" \ No newline at end of file diff --git a/airesources/Kotlin/runGameExecutable.bat b/airesources/Kotlin/runGameExecutable.bat new file mode 100644 index 000000000..2862919d4 --- /dev/null +++ b/airesources/Kotlin/runGameExecutable.bat @@ -0,0 +1,5 @@ +kotlinc.bat *.kt -include-runtime -d mybot.jar +jar ufe mybot.jar MyBotKt +kotlinc.bat *.kt -include-runtime -d randombot.jar +jar ufe randombot.jar RandomBotKt +.\halite.exe -d "30 30" "java -jar mybot.jar" "java -jar randombot.jar" diff --git a/airesources/Kotlin/runGameExecutable.sh b/airesources/Kotlin/runGameExecutable.sh new file mode 100644 index 000000000..b3f96f326 --- /dev/null +++ b/airesources/Kotlin/runGameExecutable.sh @@ -0,0 +1,7 @@ +#!/bin/bash + +kotlinc *.kt -include-runtime -d mybot.jar +jar ufe mybot.jar MyBotKt +kotlinc *.kt -include-runtime -d randombot.jar +jar ufe randombot.jar RandomBotKt +./halite -d "30 30" "java -jar mybot.jar" "java -jar randombot.jar" diff --git a/website/archiveStarterPackages.sh b/website/archiveStarterPackages.sh index d8050303e..2dda646cf 100755 --- a/website/archiveStarterPackages.sh +++ b/website/archiveStarterPackages.sh @@ -16,7 +16,8 @@ mkdir Halite-Python-Starter-Package \ Halite-JavaScript-Starter-Package \ Halite-OCaml-Starter-Package \ Halite-Clojure-Starter-Package \ - Halite-C-Starter-Package + Halite-C-Starter-Package \ + Halite-Kotlin-Starter-Package cp -r Python/* Halite-Python-Starter-Package/ cp -r Java/* Halite-Java-Starter-Package/ @@ -31,6 +32,7 @@ cp -r JavaScript/* Halite-JavaScript-Starter-Package/ cp -r OCaml/* Halite-OCaml-Starter-Package/ cp -r Clojure/* Halite-Clojure-Starter-Package/ cp -r C/* Halite-C-Starter-Package/ +cp -r Kotlin/* Halite-Kotlin-Starter-Package/ cp -r Scala/* Halite-Scala-Starter-Package/ rm Halite-Scala-Starter-Package/MyBot.java @@ -48,6 +50,7 @@ zip -r Halite-JavaScript-Starter-Package.zip Halite-JavaScript-Starter-Package/ zip -r Halite-OCaml-Starter-Package.zip Halite-OCaml-Starter-Package/ zip -r Halite-Clojure-Starter-Package.zip Halite-Clojure-Starter-Package/ zip -r Halite-C-Starter-Package.zip Halite-C-Starter-Package/ +zip -r Halite-Kotlin-Starter-Package.zip Halite-Kotlin-Starter-Package/ mkdir -p ../website/downloads/starterpackages mv *.zip ../website/downloads/starterpackages diff --git a/website/downloads.php b/website/downloads.php index 4e02a1b1e..0bffa417d 100644 --- a/website/downloads.php +++ b/website/downloads.php @@ -36,6 +36,7 @@
  • OCaml 4.01.0
  • Clojure 1.8.0
  • C
  • +
  • Kotlin