Advertisement
jules0707

game2048.kt

Nov 26th, 2021
1,372
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Kotlin 3.26 KB | None | 0 0
  1. package games.game2048
  2.  
  3. import board.Cell
  4. import board.Direction
  5. import board.Direction.*
  6. import board.GameBoard
  7. import board.createGameBoard
  8. import games.game.Game
  9.  
  10. /*
  11.  * Your task is to implement the game 2048 https://en.wikipedia.org/wiki/2048_(video_game).
  12.  * Implement the utility methods below.
  13.  *
  14.  * After implementing it you can try to play the game running 'PlayGame2048'.
  15.  */
  16. fun newGame2048(initializer: Game2048Initializer<Int> = RandomGame2048Initializer): Game =
  17.     Game2048(initializer)
  18.  
  19. class Game2048(private val initializer: Game2048Initializer<Int>) : Game {
  20.     private val board = createGameBoard<Int?>(4)
  21.  
  22.     override fun initialize() {
  23.         repeat(2) {
  24.             board.addNewValue(initializer)
  25.         }
  26.     }
  27.  
  28.     override fun canMove() = board.any { it == null }
  29.  
  30.     override fun hasWon() = board.any { it == 2048 }
  31.  
  32.     override fun processMove(direction: Direction) {
  33.         if (board.moveValues(direction)) {
  34.             board.addNewValue(initializer)
  35.         }
  36.     }
  37.  
  38.     override fun get(i: Int, j: Int): Int? = board.run { get(getCell(i, j)) }
  39. }
  40.  
  41. /*
  42.  * Add a new value produced by 'initializer' to a specified cell in a board.
  43.  */
  44. fun GameBoard<Int?>.addNewValue(initializer: Game2048Initializer<Int>) {
  45.     val (c, i) = initializer.nextValue(this)!!
  46.     this[c] = i
  47. }
  48.  
  49. /*
  50.  * Update the values stored in a board,
  51.  * so that the values were "moved" in a specified rowOrColumn only.
  52.  * Use the helper function 'moveAndMergeEqual' (in Game2048Helper.kt).
  53.  * The values should be moved to the beginning of the row (or column),
  54.  * in the same manner as in the function 'moveAndMergeEqual'.
  55.  * Return 'true' if the values were moved and 'false' otherwise.
  56.  */
  57. @OptIn(ExperimentalStdlibApi::class)
  58. fun GameBoard<Int?>.moveValuesInRowOrColumn(rowOrColumn: List<Cell>): Boolean {
  59.     val c1 = rowOrColumn.size
  60.     val values = mutableListOf<Int?>()
  61.     for (c in rowOrColumn) {
  62.         values.add(this[c]) // build the current values list of rowOrColumn cells list
  63.     }
  64.     val res = values.moveAndMergeEqual { it*2 }.toMutableList<Int?>()
  65.     val c2 = res.size
  66.     val i = res.iterator()
  67.     for (c in rowOrColumn){
  68.         if (i.hasNext()){
  69.             this[c]=res.removeFirst() // override the current values with the move and merged values
  70.         } else this[c]=null // add null to fill it up
  71.     }
  72.     return c2!=c1 // have the values been changed
  73. }
  74.  
  75. /*
  76.  * Update the values stored in a board,
  77.  * so that the values were "moved" to the specified direction
  78.  * following the rules of the /////2048 game .
  79.  * Use the 'moveValuesInRowOrColumn' function above.
  80.  * Return 'true' if the values were moved and 'false' otherwise.
  81.  */
  82. fun GameBoard<Int?>.moveValues(direction: Direction): Boolean { // thanks mook2_y2
  83.         fun getRowOrColumn(direction: Direction, index:Int):List<Cell>{
  84.         return when(direction){
  85.             UP -> this.getColumn(1.. this.width, index)
  86.             DOWN -> this.getColumn(this.width downTo 1, index)
  87.             RIGHT -> this.getRow(index, this.width downTo 1)
  88.             LEFT -> this.getRow(index, 1..this.width)
  89.         }
  90.     }
  91.     return (1 .. this.width).fold(false){ isMoved, idx ->
  92.         this.moveValuesInRowOrColumn(getRowOrColumn(direction, idx))||isMoved
  93.     }
  94. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement