Bitboard for Tic-Tac-Toe in Kotlin
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* TicTacToe bitboard | |
*/ | |
class Board( | |
val map: LongArray = longArrayOf( | |
0b000_000_000, // X = player 1 | |
0b000_000_000 // O = player -1 | |
) | |
) { | |
companion object { | |
/** | |
* Rotate the given [board] by 90° clockwise | |
* @param [board] to rotate | |
* @return rotated board | |
*/ | |
private fun rotatePlayerBoard90(board: Long): Long { | |
var rotated = board shl 2 and 0b010_000_100 // 0 -> 2, 5 -> 7 | |
rotated = rotated or (board shr 2 and 0b001_000_010) // 3 -> 1, 8 -> 6 | |
rotated = rotated or (board shl 4 and 0b000_100_000) // 1 -> 5 | |
rotated = rotated or (board shl 6 and 0b100_000_000) // 2 -> 8 | |
rotated = rotated or (board shr 6 and 0b000_000_001) // 6 -> 0 | |
rotated = rotated or (board shr 4 and 0b000_001_000) // 7 -> 3 | |
rotated = rotated or (board and 0b000_010_000) // 4 -> 4 | |
return rotated | |
} | |
} | |
/** | |
* Rotate board 90° clockwise. | |
* @return rotated board | |
*/ | |
private fun rotate90(): Board { | |
return Board(longArrayOf(rotatePlayerBoard90(map[0]), rotatePlayerBoard90(map[1]))) | |
} | |
/** | |
* Get board of given [player]. | |
* @param [player] the player number | |
* @return player board | |
*/ | |
fun getPlayerBoard(player: Int) = when (player) { | |
1 -> getPlayer1Board() | |
else -> getPlayer2Board() | |
} | |
/** | |
* Set [player] board to a given [board]. | |
* @param [player] | |
* @param [board] | |
*/ | |
fun setPlayerBoard(player: Int, board: Long) = when (player) { | |
1 -> Board(longArrayOf(board, getPlayer2Board())) | |
else -> Board(longArrayOf(getPlayer1Board(), board)) | |
} | |
/** | |
* Get board of player 1. | |
* @return board | |
*/ | |
fun getPlayer1Board(): Long = map[0] | |
/** | |
* Get board of player 2. | |
* @return board | |
*/ | |
fun getPlayer2Board(): Long = map[1] | |
/** | |
* Inverse the board (switch player 1 board with player 2 board). | |
* @return inversed board | |
*/ | |
fun inverse(): Board { | |
return Board( | |
longArrayOf( | |
getPlayer2Board(), | |
getPlayer1Board() | |
) | |
) | |
} | |
/** | |
* Rotate the board [n] times 90° clockwise. | |
* @param [n] number of rotations | |
* @return rotated board | |
*/ | |
fun rotateN(n: Int): Board { | |
var board = this | |
for (i in 0 until n) board = board.rotate90() | |
return board | |
} | |
override fun toString(): String { | |
val str = StringBuilder() | |
for (i in 0..2) { | |
for (k in 0..2) { | |
val bitShifted = 1L shl (i * 3 + k) | |
str.append(if (bitShifted and map[0] != 0L) "X " else if (bitShifted and map[1] != 0L) "O " else ". ") | |
} | |
str.append("\n") | |
} | |
return str.toString(); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment