Robots/Kotlin
< Robots
Code
<lang scala>// version 1.1.51
import java.util.Random import java.awt.* import java.awt.BasicStroke.* import java.awt.event.* import javax.swing.JFrame import javax.swing.JPanel import javax.swing.SwingUtilities
val rand = Random()
val dirs = listOf(
-1 to 1, 0 to 1, 1 to 1, -1 to 0, 1 to 0, -1 to -1, 0 to -1, 1 to -1
)
class Robots : JPanel() {
val nRows = 38 val nCols = 50 val dash = BasicStroke(2.0f, CAP_BUTT, JOIN_MITER, 10.0f, floatArrayOf(5.0f), 0.0f)
var playerRow = 0 var playerCol = 0 var score = 0 var hiScore = 0 var level = 0 var gameOver = true
enum class Grid(val symbol: String) { Player("@"), Robot("+"), Scrap("*"), Mark("~") }
lateinit var grid: Array<Array<Grid?>>
init { preferredSize = Dimension(800, 650) background = Color.white foreground = Color.lightGray font = Font("SansSerif", Font.PLAIN, 18) isFocusable = true
addMouseListener(object : MouseAdapter() { override fun mousePressed(e: MouseEvent) { if (gameOver) { startNewGame() repaint() } } })
addKeyListener(object : KeyAdapter() { override fun keyPressed(e: KeyEvent) { if (gameOver) return // disable keystrokes until game starts val keyCode = e.keyCode if (keyCode == KeyEvent.VK_NUMPAD5) { teleport() } else { var k = keyCode - KeyEvent.VK_NUMPAD1 if (k in 0..8) move(if (k > 4) --k else k) } repaint() } }) }
fun startNewGame() { level = 1 if (score > hiScore) hiScore = score score = 0 initGrid() gameOver = false }
fun initGrid() { grid = Array(nRows) { arrayOfNulls<Grid>(nCols) } teleport() val numRobots = 7 * level var i = 0 while (i < numRobots) { val r = rand.nextInt(nRows) val c = rand.nextInt(nCols) if (grid[r][c] == null) { grid[r][c] = Grid.Robot i++ } } }
fun movePlayer(r: Int, c: Int): Boolean { if (grid[r][c] != null) { gameOver = true } else { grid[playerRow][playerCol] = null playerRow = r playerCol = c grid[r][c] = Grid.Player } return !gameOver }
fun move(d: Int) { val c = playerCol + dirs[d].first val r = playerRow + dirs[d].second
if (!withinBounds(r, c)) return if (!movePlayer(r, c)) return
for (rr in 0 until nRows) { for (cc in 0 until nCols) { if (grid[rr][cc] == Grid.Robot) { // calc new r and c based on dx + cc and dy + rr val nc = (if (c == cc) 0 else (c - cc) / Math.abs(c - cc)) + cc val nr = (if (r == rr) 0 else (r - rr) / Math.abs(r - rr)) + rr if (!withinBounds(nr, nc)) continue grid[rr][cc] = null
if (grid[nr][nc] == Grid.Player) { gameOver = true return /* EARLY RETURN */ } else if (grid[nr][nc] != null) { score++ if (grid[nr][nc] != Grid.Scrap) score++ grid[nr][nc] = Grid.Scrap } else { // avoid processing the same robot twice grid[nr][nc] = Grid.Mark } } } }
var robotsLeft = 0 for (rr in 0 until nRows) { for (cc in 0 until nCols) { if (grid[rr][cc] == Grid.Mark) grid[rr][cc] = Grid.Robot if (grid[rr][cc] == Grid.Robot) robotsLeft++ } } if (robotsLeft == 0) { level++ initGrid() } }
fun teleport() { movePlayer(rand.nextInt(nRows), rand.nextInt(nCols)) }
fun drawBorder(g: Graphics2D) { g.stroke = dash g.color = foreground g.drawRect(22, 20, width - 41, height - 72) }
fun drawGrid(g: Graphics2D) { for (r in 0 until nRows) { for (c in 0 until nCols) { if (grid[r][c] != null) g.drawString(grid[r][c]!!.symbol, 24 + c * 15, 36 + r * 15) } } }
fun drawStartScreen(g: Graphics2D) { g.color = Color.gray g.font = Font("SansSerif", Font.BOLD, 48) g.drawString("robots", 315, 280)
g.font = this.font g.drawString("(use numpad to move player)", 270, 350) g.drawString("(teleport is numpad 5)", 300, 380) g.drawString("(click to start)", 328, 410) }
fun drawScore(g: Graphics2D) { g.color = Color.gray g.font = this.font val s = String.format("hiscore %s score %s", hiScore, score) g.drawString(s, 30, height - 17) }
fun withinBounds(r: Int, c: Int) = (c in 0 until nCols) && (r in 0 until nRows)
override fun paintComponent(gg: Graphics) { super.paintComponent(gg) val g = gg as Graphics2D g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON) drawBorder(g) drawScore(g) if (gameOver) drawStartScreen(g) else drawGrid(g) }
}
fun main(args: Array<String>) {
SwingUtilities.invokeLater { val f = JFrame() with (f) { defaultCloseOperation = JFrame.EXIT_ON_CLOSE title = "Robots" isResizable = false add(Robots(), BorderLayout.CENTER) pack() setLocationRelativeTo(null) isVisible = true } }
}</lang>