mirror of
https://github.com/cmclark00/mintris.git
synced 2025-05-18 20:05:20 +01:00
Remove Tetris references and rename to generic game pieces
This commit is contained in:
parent
df9957580e
commit
e26c6ebd8c
10 changed files with 358 additions and 336 deletions
|
@ -17,18 +17,18 @@ class GameBoard(
|
|||
// True = occupied, False = empty
|
||||
private val grid = Array(height) { BooleanArray(width) { false } }
|
||||
|
||||
// Current active tetromino
|
||||
private var currentPiece: Tetromino? = null
|
||||
// Current active piece
|
||||
private var currentPiece: GamePiece? = null
|
||||
|
||||
// Next tetromino to be played
|
||||
private var nextPiece: Tetromino? = null
|
||||
// Next piece to be played
|
||||
private var nextPiece: GamePiece? = null
|
||||
|
||||
// Hold piece
|
||||
private var holdPiece: Tetromino? = null
|
||||
private var holdPiece: GamePiece? = null
|
||||
private var canHold = true
|
||||
|
||||
// 7-bag randomizer
|
||||
private val bag = mutableListOf<TetrominoType>()
|
||||
private val bag = mutableListOf<GamePieceType>()
|
||||
|
||||
// Game state
|
||||
var score = 0
|
||||
|
@ -43,7 +43,7 @@ class GameBoard(
|
|||
|
||||
// Scoring state
|
||||
private var combo = 0
|
||||
private var lastClearWasTetris = false
|
||||
private var lastClearWasQuad = false
|
||||
private var lastClearWasPerfect = false
|
||||
private var lastClearWasAllClear = false
|
||||
private var lastPieceClearedLines = false // Track if the last piece placed cleared lines
|
||||
|
@ -80,12 +80,12 @@ class GameBoard(
|
|||
private fun spawnNextPiece() {
|
||||
// If bag is empty, refill it with all piece types
|
||||
if (bag.isEmpty()) {
|
||||
bag.addAll(TetrominoType.entries.toTypedArray())
|
||||
bag.addAll(GamePieceType.entries.toTypedArray())
|
||||
bag.shuffle()
|
||||
}
|
||||
|
||||
// Take the next piece from the bag
|
||||
nextPiece = Tetromino(bag.removeAt(0))
|
||||
nextPiece = GamePiece(bag.removeAt(0))
|
||||
onNextPieceChanged?.invoke()
|
||||
}
|
||||
|
||||
|
@ -122,12 +122,12 @@ class GameBoard(
|
|||
/**
|
||||
* Get the currently held piece
|
||||
*/
|
||||
fun getHoldPiece(): Tetromino? = holdPiece
|
||||
fun getHoldPiece(): GamePiece? = holdPiece
|
||||
|
||||
/**
|
||||
* Get the next piece that will be spawned
|
||||
*/
|
||||
fun getNextPiece(): Tetromino? = nextPiece
|
||||
fun getNextPiece(): GamePiece? = nextPiece
|
||||
|
||||
/**
|
||||
* Spawns the current tetromino at the top of the board
|
||||
|
@ -541,8 +541,8 @@ class GameBoard(
|
|||
}
|
||||
} else 1.0
|
||||
|
||||
// Calculate back-to-back Tetris bonus
|
||||
val backToBackMultiplier = if (clearedLines == 4 && lastClearWasTetris) 1.5 else 1.0
|
||||
// Calculate back-to-back quad bonus
|
||||
val backToBackMultiplier = if (clearedLines == 4 && lastClearWasQuad) 1.5 else 1.0
|
||||
|
||||
// Calculate perfect clear bonus
|
||||
val perfectClearMultiplier = if (isPerfectClear) {
|
||||
|
@ -579,7 +579,7 @@ class GameBoard(
|
|||
}.start()
|
||||
|
||||
// Update line clear state
|
||||
lastClearWasTetris = clearedLines == 4
|
||||
lastClearWasQuad = clearedLines == 4
|
||||
lastClearWasPerfect = isPerfectClear
|
||||
lastClearWasAllClear = isAllClear
|
||||
|
||||
|
@ -597,7 +597,7 @@ class GameBoard(
|
|||
*/
|
||||
private fun isTSpin(): Boolean {
|
||||
val piece = currentPiece ?: return false
|
||||
if (piece.type != TetrominoType.T) return false
|
||||
if (piece.type != GamePieceType.T) return false
|
||||
|
||||
// Count occupied corners around the T piece
|
||||
var occupiedCorners = 0
|
||||
|
@ -637,7 +637,7 @@ class GameBoard(
|
|||
/**
|
||||
* Get the current tetromino
|
||||
*/
|
||||
fun getCurrentPiece(): Tetromino? = currentPiece
|
||||
fun getCurrentPiece(): GamePiece? = currentPiece
|
||||
|
||||
/**
|
||||
* Check if a cell in the grid is occupied
|
||||
|
@ -702,7 +702,7 @@ class GameBoard(
|
|||
|
||||
// Reset scoring state
|
||||
combo = 0
|
||||
lastClearWasTetris = false
|
||||
lastClearWasQuad = false
|
||||
lastClearWasPerfect = false
|
||||
lastClearWasAllClear = false
|
||||
lastPieceClearedLines = false
|
||||
|
|
214
app/src/main/java/com/pixelmintdrop/model/GamePiece.kt
Normal file
214
app/src/main/java/com/pixelmintdrop/model/GamePiece.kt
Normal file
|
@ -0,0 +1,214 @@
|
|||
package com.pixelmintdrop.model
|
||||
|
||||
/**
|
||||
* Represents a game piece
|
||||
*/
|
||||
enum class GamePieceType {
|
||||
I, J, L, O, S, T, Z
|
||||
}
|
||||
|
||||
class GamePiece(val type: GamePieceType) {
|
||||
private var rotation = 0
|
||||
|
||||
// Each piece has 4 rotations (0, 90, 180, 270 degrees)
|
||||
private val blocks: Array<Array<BooleanArray>> = getBlocks(type)
|
||||
|
||||
/**
|
||||
* Get the current shape of the piece based on rotation
|
||||
*/
|
||||
fun getShape(): Array<BooleanArray> = blocks[rotation]
|
||||
|
||||
/**
|
||||
* Get the width of the current piece shape
|
||||
*/
|
||||
fun getWidth(): Int = blocks[rotation][0].size
|
||||
|
||||
/**
|
||||
* Get the height of the current piece shape
|
||||
*/
|
||||
fun getHeight(): Int = blocks[rotation].size
|
||||
|
||||
/**
|
||||
* Rotate the piece clockwise
|
||||
*/
|
||||
fun rotateClockwise() {
|
||||
rotation = (rotation + 1) % 4
|
||||
}
|
||||
|
||||
/**
|
||||
* Rotate the piece counter-clockwise
|
||||
*/
|
||||
fun rotateCounterClockwise() {
|
||||
rotation = (rotation + 3) % 4
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the piece's block exists at the given coordinates
|
||||
*/
|
||||
fun hasBlock(x: Int, y: Int): Boolean {
|
||||
if (x < 0 || x >= getWidth() || y < 0 || y >= getHeight()) return false
|
||||
return blocks[rotation][y][x]
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the block patterns for each piece type and all its rotations
|
||||
*/
|
||||
private fun getBlocks(type: GamePieceType): Array<Array<BooleanArray>> {
|
||||
return when (type) {
|
||||
GamePieceType.I -> arrayOf(
|
||||
arrayOf(
|
||||
booleanArrayOf(false, false, false, false),
|
||||
booleanArrayOf(true, true, true, true),
|
||||
booleanArrayOf(false, false, false, false),
|
||||
booleanArrayOf(false, false, false, false)
|
||||
),
|
||||
arrayOf(
|
||||
booleanArrayOf(false, false, true, false),
|
||||
booleanArrayOf(false, false, true, false),
|
||||
booleanArrayOf(false, false, true, false),
|
||||
booleanArrayOf(false, false, true, false)
|
||||
),
|
||||
arrayOf(
|
||||
booleanArrayOf(false, false, false, false),
|
||||
booleanArrayOf(false, false, false, false),
|
||||
booleanArrayOf(true, true, true, true),
|
||||
booleanArrayOf(false, false, false, false)
|
||||
),
|
||||
arrayOf(
|
||||
booleanArrayOf(false, true, false, false),
|
||||
booleanArrayOf(false, true, false, false),
|
||||
booleanArrayOf(false, true, false, false),
|
||||
booleanArrayOf(false, true, false, false)
|
||||
)
|
||||
),
|
||||
GamePieceType.J -> arrayOf(
|
||||
arrayOf(
|
||||
booleanArrayOf(true, false, false),
|
||||
booleanArrayOf(true, true, true),
|
||||
booleanArrayOf(false, false, false)
|
||||
),
|
||||
arrayOf(
|
||||
booleanArrayOf(false, true, true),
|
||||
booleanArrayOf(false, true, false),
|
||||
booleanArrayOf(false, true, false)
|
||||
),
|
||||
arrayOf(
|
||||
booleanArrayOf(false, false, false),
|
||||
booleanArrayOf(true, true, true),
|
||||
booleanArrayOf(false, false, true)
|
||||
),
|
||||
arrayOf(
|
||||
booleanArrayOf(false, true, false),
|
||||
booleanArrayOf(false, true, false),
|
||||
booleanArrayOf(true, true, false)
|
||||
)
|
||||
),
|
||||
GamePieceType.L -> arrayOf(
|
||||
arrayOf(
|
||||
booleanArrayOf(false, false, true),
|
||||
booleanArrayOf(true, true, true),
|
||||
booleanArrayOf(false, false, false)
|
||||
),
|
||||
arrayOf(
|
||||
booleanArrayOf(false, true, false),
|
||||
booleanArrayOf(false, true, false),
|
||||
booleanArrayOf(false, true, true)
|
||||
),
|
||||
arrayOf(
|
||||
booleanArrayOf(false, false, false),
|
||||
booleanArrayOf(true, true, true),
|
||||
booleanArrayOf(true, false, false)
|
||||
),
|
||||
arrayOf(
|
||||
booleanArrayOf(true, true, false),
|
||||
booleanArrayOf(false, true, false),
|
||||
booleanArrayOf(false, true, false)
|
||||
)
|
||||
),
|
||||
GamePieceType.O -> arrayOf(
|
||||
arrayOf(
|
||||
booleanArrayOf(true, true),
|
||||
booleanArrayOf(true, true)
|
||||
),
|
||||
arrayOf(
|
||||
booleanArrayOf(true, true),
|
||||
booleanArrayOf(true, true)
|
||||
),
|
||||
arrayOf(
|
||||
booleanArrayOf(true, true),
|
||||
booleanArrayOf(true, true)
|
||||
),
|
||||
arrayOf(
|
||||
booleanArrayOf(true, true),
|
||||
booleanArrayOf(true, true)
|
||||
)
|
||||
),
|
||||
GamePieceType.S -> arrayOf(
|
||||
arrayOf(
|
||||
booleanArrayOf(false, true, true),
|
||||
booleanArrayOf(true, true, false),
|
||||
booleanArrayOf(false, false, false)
|
||||
),
|
||||
arrayOf(
|
||||
booleanArrayOf(false, true, false),
|
||||
booleanArrayOf(false, true, true),
|
||||
booleanArrayOf(false, false, true)
|
||||
),
|
||||
arrayOf(
|
||||
booleanArrayOf(false, false, false),
|
||||
booleanArrayOf(false, true, true),
|
||||
booleanArrayOf(true, true, false)
|
||||
),
|
||||
arrayOf(
|
||||
booleanArrayOf(true, false, false),
|
||||
booleanArrayOf(true, true, false),
|
||||
booleanArrayOf(false, true, false)
|
||||
)
|
||||
),
|
||||
GamePieceType.T -> arrayOf(
|
||||
arrayOf(
|
||||
booleanArrayOf(false, true, false),
|
||||
booleanArrayOf(true, true, true),
|
||||
booleanArrayOf(false, false, false)
|
||||
),
|
||||
arrayOf(
|
||||
booleanArrayOf(false, true, false),
|
||||
booleanArrayOf(false, true, true),
|
||||
booleanArrayOf(false, true, false)
|
||||
),
|
||||
arrayOf(
|
||||
booleanArrayOf(false, false, false),
|
||||
booleanArrayOf(true, true, true),
|
||||
booleanArrayOf(false, true, false)
|
||||
),
|
||||
arrayOf(
|
||||
booleanArrayOf(false, true, false),
|
||||
booleanArrayOf(true, true, false),
|
||||
booleanArrayOf(false, true, false)
|
||||
)
|
||||
),
|
||||
GamePieceType.Z -> arrayOf(
|
||||
arrayOf(
|
||||
booleanArrayOf(true, true, false),
|
||||
booleanArrayOf(false, true, true),
|
||||
booleanArrayOf(false, false, false)
|
||||
),
|
||||
arrayOf(
|
||||
booleanArrayOf(false, false, true),
|
||||
booleanArrayOf(false, true, true),
|
||||
booleanArrayOf(false, true, false)
|
||||
),
|
||||
arrayOf(
|
||||
booleanArrayOf(false, false, false),
|
||||
booleanArrayOf(true, true, false),
|
||||
booleanArrayOf(false, true, true)
|
||||
),
|
||||
arrayOf(
|
||||
booleanArrayOf(false, true, false),
|
||||
booleanArrayOf(true, true, false),
|
||||
booleanArrayOf(true, false, false)
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,260 +0,0 @@
|
|||
package com.pixelmintdrop.model
|
||||
|
||||
/**
|
||||
* Represents a Tetris piece (Tetromino)
|
||||
*/
|
||||
enum class TetrominoType {
|
||||
I, J, L, O, S, T, Z
|
||||
}
|
||||
|
||||
class Tetromino(val type: TetrominoType) {
|
||||
|
||||
// Each tetromino has 4 rotations (0, 90, 180, 270 degrees)
|
||||
private val blocks: Array<Array<BooleanArray>> = getBlocks(type)
|
||||
private var currentRotation = 0
|
||||
|
||||
// Current position in the game grid
|
||||
var x = 0
|
||||
var y = 0
|
||||
|
||||
/**
|
||||
* Get the current shape of the tetromino based on rotation
|
||||
*/
|
||||
fun getCurrentShape(): Array<BooleanArray> {
|
||||
return blocks[currentRotation]
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the width of the current tetromino shape
|
||||
*/
|
||||
fun getWidth(): Int {
|
||||
return blocks[currentRotation][0].size
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the height of the current tetromino shape
|
||||
*/
|
||||
fun getHeight(): Int {
|
||||
return blocks[currentRotation].size
|
||||
}
|
||||
|
||||
/**
|
||||
* Rotate the tetromino clockwise
|
||||
*/
|
||||
fun rotateClockwise() {
|
||||
currentRotation = (currentRotation + 1) % 4
|
||||
}
|
||||
|
||||
/**
|
||||
* Rotate the tetromino counter-clockwise
|
||||
*/
|
||||
fun rotateCounterClockwise() {
|
||||
currentRotation = (currentRotation + 3) % 4
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the tetromino's block exists at the given coordinates
|
||||
*/
|
||||
fun isBlockAt(blockX: Int, blockY: Int): Boolean {
|
||||
val shape = blocks[currentRotation]
|
||||
return if (blockY >= 0 && blockY < shape.size &&
|
||||
blockX >= 0 && blockX < shape[blockY].size) {
|
||||
shape[blockY][blockX]
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
/**
|
||||
* Get the block patterns for each tetromino type and all its rotations
|
||||
*/
|
||||
private fun getBlocks(type: TetrominoType): Array<Array<BooleanArray>> {
|
||||
return when (type) {
|
||||
TetrominoType.I -> arrayOf(
|
||||
// Rotation 0°
|
||||
arrayOf(
|
||||
booleanArrayOf(false, false, false, false),
|
||||
booleanArrayOf(true, true, true, true),
|
||||
booleanArrayOf(false, false, false, false),
|
||||
booleanArrayOf(false, false, false, false)
|
||||
),
|
||||
// Rotation 90°
|
||||
arrayOf(
|
||||
booleanArrayOf(false, false, true, false),
|
||||
booleanArrayOf(false, false, true, false),
|
||||
booleanArrayOf(false, false, true, false),
|
||||
booleanArrayOf(false, false, true, false)
|
||||
),
|
||||
// Rotation 180°
|
||||
arrayOf(
|
||||
booleanArrayOf(false, false, false, false),
|
||||
booleanArrayOf(false, false, false, false),
|
||||
booleanArrayOf(true, true, true, true),
|
||||
booleanArrayOf(false, false, false, false)
|
||||
),
|
||||
// Rotation 270°
|
||||
arrayOf(
|
||||
booleanArrayOf(false, true, false, false),
|
||||
booleanArrayOf(false, true, false, false),
|
||||
booleanArrayOf(false, true, false, false),
|
||||
booleanArrayOf(false, true, false, false)
|
||||
)
|
||||
)
|
||||
TetrominoType.J -> arrayOf(
|
||||
// Rotation 0°
|
||||
arrayOf(
|
||||
booleanArrayOf(true, false, false),
|
||||
booleanArrayOf(true, true, true),
|
||||
booleanArrayOf(false, false, false)
|
||||
),
|
||||
// Rotation 90°
|
||||
arrayOf(
|
||||
booleanArrayOf(false, true, true),
|
||||
booleanArrayOf(false, true, false),
|
||||
booleanArrayOf(false, true, false)
|
||||
),
|
||||
// Rotation 180°
|
||||
arrayOf(
|
||||
booleanArrayOf(false, false, false),
|
||||
booleanArrayOf(true, true, true),
|
||||
booleanArrayOf(false, false, true)
|
||||
),
|
||||
// Rotation 270°
|
||||
arrayOf(
|
||||
booleanArrayOf(false, true, false),
|
||||
booleanArrayOf(false, true, false),
|
||||
booleanArrayOf(true, true, false)
|
||||
)
|
||||
)
|
||||
TetrominoType.L -> arrayOf(
|
||||
// Rotation 0°
|
||||
arrayOf(
|
||||
booleanArrayOf(false, false, true),
|
||||
booleanArrayOf(true, true, true),
|
||||
booleanArrayOf(false, false, false)
|
||||
),
|
||||
// Rotation 90°
|
||||
arrayOf(
|
||||
booleanArrayOf(false, true, false),
|
||||
booleanArrayOf(false, true, false),
|
||||
booleanArrayOf(false, true, true)
|
||||
),
|
||||
// Rotation 180°
|
||||
arrayOf(
|
||||
booleanArrayOf(false, false, false),
|
||||
booleanArrayOf(true, true, true),
|
||||
booleanArrayOf(true, false, false)
|
||||
),
|
||||
// Rotation 270°
|
||||
arrayOf(
|
||||
booleanArrayOf(true, true, false),
|
||||
booleanArrayOf(false, true, false),
|
||||
booleanArrayOf(false, true, false)
|
||||
)
|
||||
)
|
||||
TetrominoType.O -> arrayOf(
|
||||
// All rotations are the same for O
|
||||
arrayOf(
|
||||
booleanArrayOf(false, true, true, false),
|
||||
booleanArrayOf(false, true, true, false),
|
||||
booleanArrayOf(false, false, false, false)
|
||||
),
|
||||
arrayOf(
|
||||
booleanArrayOf(false, true, true, false),
|
||||
booleanArrayOf(false, true, true, false),
|
||||
booleanArrayOf(false, false, false, false)
|
||||
),
|
||||
arrayOf(
|
||||
booleanArrayOf(false, true, true, false),
|
||||
booleanArrayOf(false, true, true, false),
|
||||
booleanArrayOf(false, false, false, false)
|
||||
),
|
||||
arrayOf(
|
||||
booleanArrayOf(false, true, true, false),
|
||||
booleanArrayOf(false, true, true, false),
|
||||
booleanArrayOf(false, false, false, false)
|
||||
)
|
||||
)
|
||||
TetrominoType.S -> arrayOf(
|
||||
// Rotation 0°
|
||||
arrayOf(
|
||||
booleanArrayOf(false, true, true),
|
||||
booleanArrayOf(true, true, false),
|
||||
booleanArrayOf(false, false, false)
|
||||
),
|
||||
// Rotation 90°
|
||||
arrayOf(
|
||||
booleanArrayOf(false, true, false),
|
||||
booleanArrayOf(false, true, true),
|
||||
booleanArrayOf(false, false, true)
|
||||
),
|
||||
// Rotation 180°
|
||||
arrayOf(
|
||||
booleanArrayOf(false, false, false),
|
||||
booleanArrayOf(false, true, true),
|
||||
booleanArrayOf(true, true, false)
|
||||
),
|
||||
// Rotation 270°
|
||||
arrayOf(
|
||||
booleanArrayOf(true, false, false),
|
||||
booleanArrayOf(true, true, false),
|
||||
booleanArrayOf(false, true, false)
|
||||
)
|
||||
)
|
||||
TetrominoType.T -> arrayOf(
|
||||
// Rotation 0°
|
||||
arrayOf(
|
||||
booleanArrayOf(false, true, false),
|
||||
booleanArrayOf(true, true, true),
|
||||
booleanArrayOf(false, false, false)
|
||||
),
|
||||
// Rotation 90°
|
||||
arrayOf(
|
||||
booleanArrayOf(false, true, false),
|
||||
booleanArrayOf(false, true, true),
|
||||
booleanArrayOf(false, true, false)
|
||||
),
|
||||
// Rotation 180°
|
||||
arrayOf(
|
||||
booleanArrayOf(false, false, false),
|
||||
booleanArrayOf(true, true, true),
|
||||
booleanArrayOf(false, true, false)
|
||||
),
|
||||
// Rotation 270°
|
||||
arrayOf(
|
||||
booleanArrayOf(false, true, false),
|
||||
booleanArrayOf(true, true, false),
|
||||
booleanArrayOf(false, true, false)
|
||||
)
|
||||
)
|
||||
TetrominoType.Z -> arrayOf(
|
||||
// Rotation 0°
|
||||
arrayOf(
|
||||
booleanArrayOf(true, true, false),
|
||||
booleanArrayOf(false, true, true),
|
||||
booleanArrayOf(false, false, false)
|
||||
),
|
||||
// Rotation 90°
|
||||
arrayOf(
|
||||
booleanArrayOf(false, false, true),
|
||||
booleanArrayOf(false, true, true),
|
||||
booleanArrayOf(false, true, false)
|
||||
),
|
||||
// Rotation 180°
|
||||
arrayOf(
|
||||
booleanArrayOf(false, false, false),
|
||||
booleanArrayOf(true, true, false),
|
||||
booleanArrayOf(false, true, true)
|
||||
),
|
||||
// Rotation 270°
|
||||
arrayOf(
|
||||
booleanArrayOf(false, true, false),
|
||||
booleanArrayOf(true, true, false),
|
||||
booleanArrayOf(true, false, false)
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue