Android UI
Having an algorithm to calculate the next step of a game is nice, but we need a UI in order to show the game playing.
We start with the Android implementation. We create a custom view which draws a gray rectangle for each living cell.
class BoardView : View {
private val paint = Paint().apply {
color = Color.GRAY
style = Paint.Style.FILL
strokeWidth = 0.0f
}
…
override fun onDraw(canvas: Canvas) {
super.onDraw(canvas)
val board = board ?: return
for (rowIdx in 0 until board.rows) {
for (columnIdx in 0 until board.columns) {
if (board.cellAt(column = columnIdx, row = rowIdx).alive) {
canvas.drawRect(rectFor(rowIdx, columnIdx), paint)
}
}
}
}
private fun rectFor(rowIdx: Int, columnIdx: Int): RectF {
val left = (columnIdx * cellSize) + cellPadding
val right = (left + cellSize) - cellPadding
val top = (rowIdx * cellSize) + cellPadding
val bottom = (top + cellSize) - cellPadding
return RectF(left, top, right, bottom)
}
}
The main activity uses a timer as a game loop and calculates a new step every half a second and then updates the UI drawing the new board.
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val columns = 30
val rows = 50
val board = Board(columns, rows)
board.setCells(
"""
***_*
*____
___**
_**_*
*_*_*
""".trimIndent().cells().translatedTo(columns / 2 - 2, rows / 2 - 2))
boardView.cellSize = 14.0f * resources.displayMetrics.density
boardView.board = board
fixedRateTimer("GameLoop", false, period = 500L) {
board.calculateNextGeneration()
boardView.invalidate()
}
}
}