⚠️ Warning: This is a draft ⚠️

This means it might contain formatting issues, incorrect code, conceptual problems, or other severe issues.

If you want to help to improve and eventually enable this page, please fork RosettaGit's repository and open a merge request on GitHub.

==Code== {{trans|Java}}

// 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
        }
    }
}