Skip to content

Instantly share code, notes, and snippets.

@akwasiio
Created October 10, 2023 03:45
Show Gist options
  • Save akwasiio/0dc4959264cc47ff8bfa2fd6425ecf94 to your computer and use it in GitHub Desktop.
Save akwasiio/0dc4959264cc47ff8bfa2fd6425ecf94 to your computer and use it in GitHub Desktop.
Simple Tic Tac Toe Game between two players
enum class Player {
X, O
}
class Board {
private val slots = "1,2,3,4,5,6,7,8,9".split(",").toTypedArray()
fun show() {
for ((index, item) in slots.withIndex()) {
print(item)
if (index == 2 || index == 5) {
println()
println("——————————")
} else if (index < 2 || index < 5 || index < 8)
print(" | ")
}
}
fun isPlayerWinner(player: Player): Boolean {
return (slots[0] == player.name && slots[1] == player.name && slots[2] == player.name) || // top row
(slots[3] == player.name && slots[4] == player.name && slots[5] == player.name) || // middle row
(slots[6] == player.name && slots[7] == player.name && slots[8] == player.name) || // bottom row
// diagonals
(slots[0] == player.name && slots[4] == player.name && slots[8] == player.name) ||
(slots[2] == player.name && slots[4] == player.name && slots[6] == player.name) ||
// columns
(slots[0] == player.name && slots[3] == player.name && slots[6] == player.name) ||
(slots[1] == player.name && slots[4] == player.name && slots[7] == player.name) ||
(slots[2] == player.name && slots[5] == player.name && slots[8] == player.name)
}
fun insertPlayerMove(player: Player, selectedSlot: Int) {
slots[selectedSlot] = player.name
}
fun isSlotTaken(index: Int): Boolean {
return slots[index] == Player.X.name || slots[index] == Player.O.name
}
fun areAllSlotsTaken(): Boolean = slots.all { it == Player.X.name || it == Player.O.name }
fun reset() {
for (index in slots.indices) {
slots[index] = "${index + 1}"
}
}
}
class TicTacToeGame {
private var currentPlayer: Player = Player.X
private var xScore = 0
private var oScore = 0
private val board = Board()
private var isPlaying = true
fun play() {
board.show()
while (isPlaying) {
print("\n\n${currentPlayer.name}'s turn(1-9): ")
var input: Int
do {
try {
input = readln().toInt()
if (board.isSlotTaken(input - 1)) print("Slot is occupied, try again(1 - 9): ")
else
break
} catch (e: NumberFormatException) {
print("Unexpected character entered, try again (1 - 9): ")
}
} while (true)
board.insertPlayerMove(currentPlayer, input - 1)
println()
board.show()
when {
board.isPlayerWinner(currentPlayer) -> {
println("\n\n${currentPlayer.name} won!")
updateScore(winner = currentPlayer)
showLeaderBoard()
checkIfPlayAgain()
}
board.areAllSlotsTaken() -> {
println("\n\nTie game!")
checkIfPlayAgain()
}
else -> {
currentPlayer = if (currentPlayer == Player.X) Player.O else Player.X
}
}
}
}
private fun updateScore(winner: Player) {
if (winner == Player.X) {
xScore += 10
} else {
oScore += 10
}
}
private fun showLeaderBoard() {
println("----Game leaderboard----")
println("Player ${Player.X.name}'s score: $xScore")
println("Player ${Player.O.name}'s score: $oScore")
}
private fun checkIfPlayAgain() {
print("\nPress \"r\" if you want to play again, any character to quit: ")
val r = readln()
if (r == "r") {
println()
board.reset()
board.show()
} else {
println("Thanks for playing!!")
isPlaying = false
}
}
}
fun main() {
val game = TicTacToeGame()
game.play()
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment