mirror of
https://github.com/coding-horror/basic-computer-games.git
synced 2026-01-04 17:17:59 -08:00
Merge pull request #767 from Gryzor/add_32_diamonds_kotlin
Add Kotlin port of 32_Diamonds
This commit is contained in:
@@ -1,3 +1,12 @@
|
||||
Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
|
||||
|
||||
Conversion to [Kotlin](https://kotlinlang.org/)
|
||||
Conversion to [Kotlin](https://kotlinlang.org/), structure inspired from [the Java port](https://github.com/coding-horror/basic-computer-games/blob/main/32_Diamond/java/Diamond.java).
|
||||
|
||||
### How to Run
|
||||
1. Install [kotlin command line](https://kotlinlang.org/docs/command-line.html) compiler from JetBrains.
|
||||
2. Compile with `kotlinc diamond.kt -include-runtime -d diamond.jar`
|
||||
3. Run with `java -jar diamond.jar`
|
||||
|
||||
### Changes from Original
|
||||
This version validates that user input is correct.
|
||||
|
||||
|
||||
154
32_Diamond/kotlin/diamond.kt
Normal file
154
32_Diamond/kotlin/diamond.kt
Normal file
@@ -0,0 +1,154 @@
|
||||
|
||||
/**
|
||||
* Game of Diamond
|
||||
* <p>
|
||||
* Based on the BASIC game of Diamond
|
||||
* https://github.com/coding-horror/basic-computer-games/blob/main/32%20Diamond/diamond.bas
|
||||
* <p>
|
||||
*
|
||||
* Changes From Original: Input is validated.
|
||||
*
|
||||
* Converted from BASIC to Kotlin by Martin Marconcini (@Gryzor)
|
||||
* Inspired in the Java code written by Darren Cardenas.
|
||||
*/
|
||||
|
||||
|
||||
fun main() {
|
||||
Diamond().startGame()
|
||||
}
|
||||
|
||||
class Diamond {
|
||||
init {
|
||||
printIntro()
|
||||
}
|
||||
|
||||
fun startGame() {
|
||||
var body: Int
|
||||
var end: Int
|
||||
var start: Int = 1
|
||||
var row: Int = 1
|
||||
var numPerRow: Int
|
||||
var increment: Int = 2
|
||||
var lineContent: String
|
||||
var prefixIndex: Int
|
||||
|
||||
printPrompt()
|
||||
|
||||
// Read the user input
|
||||
val input = readLine()
|
||||
|
||||
// Validate input
|
||||
val userInput: Int = try {
|
||||
input?.toInt() ?: -1
|
||||
} catch (e: NumberFormatException) {
|
||||
-1
|
||||
}
|
||||
if (!isValid(userInput)) {
|
||||
printInvalidInput()
|
||||
return
|
||||
}
|
||||
|
||||
// Calculate how many diamonds can horizontally fit in the given space
|
||||
numPerRow = calculateDiamondsPerRow(userInput)
|
||||
end = userInput
|
||||
|
||||
// Loop throw rows of Diamonds
|
||||
while (row <= numPerRow) {
|
||||
body = start
|
||||
while (canLoop(increment, body, end)) {
|
||||
lineContent = ""
|
||||
|
||||
// Add white spaces to the "left" of the leftmost diamond.
|
||||
while (lineContent.length < ((userInput - body) / 2)) {
|
||||
lineContent += " "
|
||||
}
|
||||
|
||||
// Begin loop through each column of diamonds
|
||||
for (col in 1..numPerRow) {
|
||||
prefixIndex = 1
|
||||
|
||||
// Begin loop that fills each diamond with characters (not whitespace)
|
||||
for (fill in 1..body) {
|
||||
// Right side of diamond, if the index is greater than the prefix, put a Symbol.
|
||||
if (prefixIndex > PREFIX.length) {
|
||||
lineContent += SYMBOL
|
||||
}
|
||||
// Left side of diamond, pick a Prefix character (-1 since it starts at 0)
|
||||
else {
|
||||
lineContent += PREFIX[prefixIndex - 1]
|
||||
prefixIndex++
|
||||
}
|
||||
}// End loop that fills each diamond with characters
|
||||
|
||||
// Is Column finished?
|
||||
if (col == numPerRow) {
|
||||
break
|
||||
}
|
||||
// Column is not finished...
|
||||
else {
|
||||
// Add whitespace on the "right" side of the current diamond, and fill the "left" side of the
|
||||
// next; doesn't fill the space to the right of the rightmost diamond.
|
||||
while (lineContent.length < (userInput * col + (userInput - body) / 2)) {
|
||||
lineContent += " "
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}// End loop through each column of diamonds
|
||||
|
||||
// Print the current Line
|
||||
println(lineContent)
|
||||
|
||||
// Increment the body that moves
|
||||
body += increment
|
||||
} //end While Loop throw rows of Diamonds
|
||||
|
||||
// Increment the current Row of diamonds.
|
||||
row++
|
||||
|
||||
if (start != 1) {
|
||||
start = 1
|
||||
end = userInput
|
||||
increment = 2
|
||||
} else {
|
||||
// We're rendering the "bottom half" of the total rendering.
|
||||
// Alter the parameters, and decrease the row number so the logic can loop again.
|
||||
start = userInput - 2
|
||||
end = 1
|
||||
increment = -2
|
||||
row--
|
||||
}
|
||||
} // End loop through each row of diamonds
|
||||
}
|
||||
|
||||
private fun canLoop(increment: Int, body: Int, end: Int): Boolean = if (increment < 0) body >= end else body <= end
|
||||
|
||||
private fun calculateDiamondsPerRow(totalDiamonds: Int): Int = LINE_WIDTH / totalDiamonds
|
||||
|
||||
private fun isValid(input: Int): Boolean = (input in 5..21) && (input % 2 != 0)
|
||||
|
||||
private fun printInvalidInput() = println("Invalid input")
|
||||
|
||||
private fun printPrompt() {
|
||||
println(
|
||||
"""
|
||||
FOR A PRETTY DIAMOND PATTERN
|
||||
TYPE IN AN ODD NUMBER BETWEEN 5 AND 21?
|
||||
""".trimIndent()
|
||||
)
|
||||
println()
|
||||
}
|
||||
|
||||
private fun printIntro() {
|
||||
println(" ".repeat(32) + "DIAMOND")
|
||||
println(" ".repeat(14) + "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY")
|
||||
println()
|
||||
println()
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val LINE_WIDTH = 60
|
||||
const val PREFIX = "CC"
|
||||
const val SYMBOL = "!"
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user