Lesson 4
Journey through 2D Arrays in Kotlin: Finding Ideal Positions for Game Pieces
Introduction

Hello, and welcome, code explorer! Today's journey takes us through the intricate paths within a 2-dimensional array, often likened to a game board. Our mission is to identify ideal spots for game piece placement. Sounds like an adventure, doesn't it? Let's embark!

Task Statement

Visualize a chessboard in the form of a 2D array, where each cell could be marked E for empty or P for a piece. Our quest involves creating a Kotlin function named findPositions(). Upon examining this 2D array, this function identifies all the spots where a new piece could be placed so that it can move to another empty cell in one move. The catch is that a piece can move only to an immediately neighboring cell directly above, below, to the left, or right, but not diagonally.

Consider this 4x4 board, for instance:

1P E E P 2E P E P 3P E P P 4P E P E

The function should output the following pairs representing positions: (0, 1), (0, 2), (1, 2), (2, 1), (3, 1). This output represents the positions where a new piece can fit perfectly and then be able to move in the next turn.

Solution Building: Step 1

Let's step right into action by starting with an empty positions list to help us log the sought positions. Understanding the dimensions of our "board" is key to defining boundaries in our exploration mission. In Kotlin, we determine the size of a 2D array using the size property.

Using a list is crucial here because we don't know beforehand how many positions will be found. A MutableList in Kotlin is dynamic and can resize itself to accommodate any number of elements, making it a perfect choice for storing an unknown number of positions.

Kotlin
1fun findPositions(board: Array<CharArray>): MutableList<IntArray> { 2 val positions = mutableListOf<IntArray>() 3 4 val rows = board.size 5 val cols = board[0].size 6 // Further exploration follows
Solution Building: Step 2

With our boundary map, we begin our expedition across the board using two nested for loops to do this, traversing the entire board one cell at a time.

Kotlin
1fun findPositions(board: Array<CharArray>): MutableList<IntArray> { 2 val positions = mutableListOf<IntArray>() 3 4 val rows = board.size 5 val cols = board[0].size 6 7 for (i in 0 until rows) { 8 for (j in 0 until cols) { 9 // ensuing exploration
Solution Building: Step 3

What's the plan for each cell, you ask? While exploring each cell, our trusty Kotlin code inspects if the cell is empty. If confirmed, it then peeks into the neighbors in the up, down, left, and right directions. If another vacant cell (E) is spotted, we jot down the main cell's position in our positions list.

Kotlin
1fun findPositions(board: Array<CharArray>): MutableList<IntArray> { 2 val positions = mutableListOf<IntArray>() 3 4 val rows = board.size 5 val cols = board[0].size 6 7 for (i in 0 until rows) { 8 for (j in 0 until cols) { 9 if (board[i][j] == 'E') { 10 if ((i > 0 && board[i - 1][j] == 'E') || 11 (i < rows - 1 && board[i + 1][j] == 'E') || 12 (j > 0 && board[i][j - 1] == 'E') || 13 (j < cols - 1 && board[i][j + 1] == 'E')) { 14 positions.add(intArrayOf(i, j)) 15 } 16 } 17 } 18 } 19 return positions 20} 21 22fun main() { 23 val board = arrayOf( 24 charArrayOf('P', 'E', 'E', 'P'), 25 charArrayOf('E', 'P', 'E', 'P'), 26 charArrayOf('P', 'E', 'P', 'P'), 27 charArrayOf('P', 'E', 'P', 'E') 28 ) 29 30 val positions = findPositions(board) 31 32 for (pos in positions) { 33 println("(${pos[0]}, ${pos[1]})") 34 } 35} 36 37// The output will be: 38// (0, 1) 39// (0, 2) 40// (1, 2) 41// (2, 1) 42// (3, 1)
Lesson Summary

Neatly wrapped up, haven't we? Today we engaged in a thrilling treasure hunt and emerged victorious with the positions list. This journey revealed the importance of understanding 2D arrays and effectively maneuvering through them using Kotlin. We cleverly avoided unwanted recursion while harnessing the power of conditional statements to devise an efficient blueprint for our code.

Now that we've mastered the theory, we step into the realm of application — the practice field. Venture forth and make your mark by solving correlated challenges. And remember, persistence is the best companion for a coder. Happy coding with Kotlin!

Enjoy this lesson? Now it's time to practice with Cosmo!
Practice is how you turn knowledge into actual skills.