Data commit
This commit is contained in:
parent
7387c8f97b
commit
cb5bb5e222
199093 changed files with 3378972 additions and 0 deletions
170
Task/2048/Kotlin/2048.kotlin
Normal file
170
Task/2048/Kotlin/2048.kotlin
Normal file
|
|
@ -0,0 +1,170 @@
|
|||
import java.io.BufferedReader
|
||||
import java.io.InputStreamReader
|
||||
|
||||
const val positiveGameOverMessage = "So sorry, but you won the game."
|
||||
const val negativeGameOverMessage = "So sorry, but you lost the game."
|
||||
|
||||
fun main(args: Array<String>) {
|
||||
val grid = arrayOf(
|
||||
arrayOf(0, 0, 0, 0),
|
||||
arrayOf(0, 0, 0, 0),
|
||||
arrayOf(0, 0, 0, 0),
|
||||
arrayOf(0, 0, 0, 0)
|
||||
)
|
||||
|
||||
val gameOverMessage = run2048(grid)
|
||||
println(gameOverMessage)
|
||||
}
|
||||
|
||||
fun run2048(grid: Array<Array<Int>>): String {
|
||||
if (isGridSolved(grid)) return positiveGameOverMessage
|
||||
else if (isGridFull(grid)) return negativeGameOverMessage
|
||||
|
||||
val populatedGrid = spawnNumber(grid)
|
||||
display(populatedGrid)
|
||||
|
||||
return run2048(manipulateGrid(populatedGrid, waitForValidInput()))
|
||||
}
|
||||
|
||||
fun isGridSolved(grid: Array<Array<Int>>): Boolean = grid.any { row -> row.contains(2048) }
|
||||
fun isGridFull(grid: Array<Array<Int>>): Boolean = grid.all { row -> !row.contains(0) }
|
||||
|
||||
fun spawnNumber(grid: Array<Array<Int>>): Array<Array<Int>> {
|
||||
val coordinates = locateSpawnCoordinates(grid)
|
||||
val number = generateNumber()
|
||||
|
||||
return updateGrid(grid, coordinates, number)
|
||||
}
|
||||
|
||||
fun locateSpawnCoordinates(grid: Array<Array<Int>>): Pair<Int, Int> {
|
||||
val emptyCells = arrayListOf<Pair<Int, Int>>()
|
||||
grid.forEachIndexed { x, row ->
|
||||
row.forEachIndexed { y, cell ->
|
||||
if (cell == 0) emptyCells.add(Pair(x, y))
|
||||
}
|
||||
}
|
||||
|
||||
return emptyCells[(Math.random() * (emptyCells.size - 1)).toInt()]
|
||||
}
|
||||
|
||||
fun generateNumber(): Int = if (Math.random() > 0.10) 2 else 4
|
||||
|
||||
fun updateGrid(grid: Array<Array<Int>>, at: Pair<Int, Int>, value: Int): Array<Array<Int>> {
|
||||
val updatedGrid = grid.copyOf()
|
||||
updatedGrid[at.first][at.second] = value
|
||||
return updatedGrid
|
||||
}
|
||||
|
||||
fun waitForValidInput(): String {
|
||||
val input = waitForInput()
|
||||
return if (isValidInput(input)) input else waitForValidInput()
|
||||
}
|
||||
|
||||
fun isValidInput(input: String): Boolean = arrayOf("a", "s", "d", "w").contains(input)
|
||||
|
||||
fun waitForInput(): String {
|
||||
val reader = BufferedReader(InputStreamReader(System.`in`))
|
||||
println("Direction? ")
|
||||
return reader.readLine()
|
||||
}
|
||||
|
||||
fun manipulateGrid(grid: Array<Array<Int>>, input: String): Array<Array<Int>> = when (input) {
|
||||
"a" -> shiftCellsLeft(grid)
|
||||
"s" -> shiftCellsDown(grid)
|
||||
"d" -> shiftCellsRight(grid)
|
||||
"w" -> shiftCellsUp(grid)
|
||||
else -> throw IllegalArgumentException("Expected one of [a, s, d, w]")
|
||||
}
|
||||
|
||||
fun shiftCellsLeft(grid: Array<Array<Int>>): Array<Array<Int>> =
|
||||
grid.map(::mergeAndOrganizeCells).toTypedArray()
|
||||
|
||||
fun shiftCellsRight(grid: Array<Array<Int>>): Array<Array<Int>> =
|
||||
grid.map { row -> mergeAndOrganizeCells(row.reversed().toTypedArray()).reversed().toTypedArray() }.toTypedArray()
|
||||
|
||||
fun shiftCellsUp(grid: Array<Array<Int>>): Array<Array<Int>> {
|
||||
val rows: Array<Array<Int>> = arrayOf(
|
||||
arrayOf(grid[0][0], grid[1][0], grid[2][0], grid[3][0]),
|
||||
arrayOf(grid[0][1], grid[1][1], grid[2][1], grid[3][1]),
|
||||
arrayOf(grid[0][2], grid[1][2], grid[2][2], grid[3][2]),
|
||||
arrayOf(grid[0][3], grid[1][3], grid[2][3], grid[3][3])
|
||||
)
|
||||
|
||||
val updatedGrid = grid.copyOf()
|
||||
|
||||
rows.map(::mergeAndOrganizeCells).forEachIndexed { rowIdx, row ->
|
||||
updatedGrid[0][rowIdx] = row[0]
|
||||
updatedGrid[1][rowIdx] = row[1]
|
||||
updatedGrid[2][rowIdx] = row[2]
|
||||
updatedGrid[3][rowIdx] = row[3]
|
||||
}
|
||||
|
||||
return updatedGrid
|
||||
}
|
||||
|
||||
fun shiftCellsDown(grid: Array<Array<Int>>): Array<Array<Int>> {
|
||||
val rows: Array<Array<Int>> = arrayOf(
|
||||
arrayOf(grid[3][0], grid[2][0], grid[1][0], grid[0][0]),
|
||||
arrayOf(grid[3][1], grid[2][1], grid[1][1], grid[0][1]),
|
||||
arrayOf(grid[3][2], grid[2][2], grid[1][2], grid[0][2]),
|
||||
arrayOf(grid[3][3], grid[2][3], grid[1][3], grid[0][3])
|
||||
)
|
||||
|
||||
val updatedGrid = grid.copyOf()
|
||||
|
||||
rows.map(::mergeAndOrganizeCells).forEachIndexed { rowIdx, row ->
|
||||
updatedGrid[3][rowIdx] = row[0]
|
||||
updatedGrid[2][rowIdx] = row[1]
|
||||
updatedGrid[1][rowIdx] = row[2]
|
||||
updatedGrid[0][rowIdx] = row[3]
|
||||
}
|
||||
|
||||
return updatedGrid
|
||||
}
|
||||
|
||||
fun mergeAndOrganizeCells(row: Array<Int>): Array<Int> = organize(merge(row.copyOf()))
|
||||
|
||||
fun merge(row: Array<Int>, idxToMatch: Int = 0, idxToCompare: Int = 1): Array<Int> {
|
||||
if (idxToMatch >= row.size) return row
|
||||
if (idxToCompare >= row.size) return merge(row, idxToMatch + 1, idxToMatch + 2)
|
||||
if (row[idxToMatch] == 0) return merge(row, idxToMatch + 1, idxToMatch + 2)
|
||||
|
||||
return if (row[idxToMatch] == row[idxToCompare]) {
|
||||
row[idxToMatch] *= 2
|
||||
row[idxToCompare] = 0
|
||||
merge(row, idxToMatch + 1, idxToMatch + 2)
|
||||
} else {
|
||||
if (row[idxToCompare] != 0) merge(row, idxToMatch + 1, idxToMatch + 2)
|
||||
else merge(row, idxToMatch, idxToCompare + 1)
|
||||
}
|
||||
}
|
||||
|
||||
fun organize(row: Array<Int>, idxToMatch: Int = 0, idxToCompare: Int = 1): Array<Int> {
|
||||
if (idxToMatch >= row.size) return row
|
||||
if (idxToCompare >= row.size) return organize(row, idxToMatch + 1, idxToMatch + 2)
|
||||
if (row[idxToMatch] != 0) return organize(row, idxToMatch + 1, idxToMatch + 2)
|
||||
|
||||
return if (row[idxToCompare] != 0) {
|
||||
row[idxToMatch] = row[idxToCompare]
|
||||
row[idxToCompare] = 0
|
||||
organize(row, idxToMatch + 1, idxToMatch + 2)
|
||||
} else {
|
||||
organize(row, idxToMatch, idxToCompare + 1)
|
||||
}
|
||||
}
|
||||
|
||||
fun display(grid: Array<Array<Int>>) {
|
||||
val prettyPrintableGrid = grid.map { row ->
|
||||
row.map { cell ->
|
||||
if (cell == 0) " " else java.lang.String.format("%4d", cell)
|
||||
}
|
||||
}
|
||||
|
||||
println("New Grid:")
|
||||
prettyPrintableGrid.forEach { row ->
|
||||
println("+----+----+----+----+")
|
||||
row.forEach { print("|$it") }
|
||||
println("|")
|
||||
}
|
||||
println("+----+----+----+----+")
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue