### 设计思路
为了满足在CodeArts IDE for Cangjie环境下实现一个三四百行的俄罗斯方块小游戏的目标,以下是详细的实现方案:
#### 1. **游戏结构**
- 游戏分为以下几个主要部分:棋盘管理、方块生成与控制、碰撞检测、分数计算以及界面渲染。
- 使用面向对象的思想来组织代码,便于维护和扩展。
---
### 完整代码实现
```cangjie
package tetrisGame
const BOARD_WIDTH: Int64 = 10
const BOARD_HEIGHT: Int64 = 20
var board: Array<Array<String>> = []
type Piece struct {
shape: Array<Array<Int64>>
color: String
x: Int64
y: Int64
}
func main(): Int64 {
initGame()
startGameLoop()
return 0
}
// 初始化游戏
func initGame() {
board = createEmptyBoard(BOARD_WIDTH, BOARD_HEIGHT)
renderBoard(board)
currentPiece := generateRandomPiece()
placePieceOnBoard(currentPiece)
}
// 创建空白棋盘
func createEmptyBoard(width: Int64, height: Int64): Array<Array<String>> {
var emptyBoard: Array<Array<String>> = []
for _ in range(height) {
var row: Array<String> = []
for _ in range(width) {
row.append(".")
}
emptyBoard.append(row)
}
return emptyBoard
}
// 随机生成方块
func generateRandomPiece(): Piece {
var shapes: Array<Array<Array<Int64>>> = [
[[1], [1], [1], [1]], // I型
[[1, 1], [1, 1]], // O型
[[0, 1, 0], [1, 1, 1]] // T型
]
var colors: Array<String> = ["🟩", "🟥", "🟦"]
var randomIndex: Int64 = getRandomNumberInRange(0, len(shapes)-1)
return Piece{
shape: shapes[randomIndex],
color: colors[randomIndex],
x: 3,
y: 0
}
}
// 将方块放置到棋盘上
func placePieceOnBoard(piece: Piece) {
clearLinesIfFull()
for i in range(len(piece.shape)) {
for j in range(len(piece.shape[i])) {
if piece.shape[i][j] == 1 && piece.y+i >= 0 { // 确保不超出边界
board[piece.y+i][piece.x+j] = piece.color
}
}
}
renderBoard(board)
}
// 删除满行并下移其余行
func clearLinesIfFull() {
var newBoard: Array<Array<String>> = []
for _, row in board {
if !isRowFull(row) {
newBoard.append(row)
} else {
println("清除一行!")
}
}
while len(newBoard) < BOARD_HEIGHT {
var newRow: Array<String> = []
for _ in range(BOARD_WIDTH) {
newRow.append(".")
}
newBoard.insertAt(0, newRow)
}
board = newBoard
}
// 判断某行是否已满
func isRowFull(row: Array<String>): Boolean {
for cell in row {
if cell == "." {
return false
}
}
return true
}
// 渲染棋盘
func renderBoard(board: Array<Array<String>>) {
for row in board {
for cell in row {
print(cell + " ")
}
println("")
}
println("-----------------------------")
}
// 开始游戏主循环
func startGameLoop() {
var currentPiece: Piece = generateRandomPiece()
while true {
handleInput(¤tPiece)
if canMoveDown(currentPiece) {
movePieceDown(¤tPiece)
} else {
lockPieceToBoard(currentPiece)
currentPiece = generateRandomPiece()
if hasCollision(currentPiece) {
break // 游戏结束条件
}
}
sleep(500ms)
}
endGame()
}
// 锁定方块到棋盘
func lockPieceToBoard(piece: Piece) {
for i in range(len(piece.shape)) {
for j in range(len(piece.shape[i])) {
if piece.shape[i][j] == 1 {
board[piece.y+i][piece.x+j] = piece.color
}
}
}
clearLinesIfFull()
renderBoard(board)
}
// 处理用户输入
func handleInput(piecePtr: Pointer<Piece>) {
var inputKey: String = getInputFromUser()
switch (inputKey) {
case "left":
if canMoveLeft(*piecePtr) {
(*piecePtr).x -= 1
}
case "right":
if canMoveRight(*piecePtr) {
(*piecePtr).x += 1
}
case "down":
if canMoveDown(*piecePtr) {
(*piecePtr).y += 1
}
case "rotate":
rotatePiece(piecePtr)
}
}
// 获取随机数范围内的值
func getRandomNumberInRange(minValue: Int64, maxValue: Int64): Int64 {
return minValue + rand() % (maxValue - minValue + 1)[^1]
}
// 检查方块能否向左移动
func canMoveLeft(piece: Piece): Boolean {
for i in range(len(piece.shape)) {
for j in range(len(piece.shape[i])) {
if piece.shape[i][j] == 1 && (piece.x+j <= 0 || board[piece.y+i][piece.x+j-1] != ".") {
return false
}
}
}
return true
}
// 检查方块能否向右移动
func canMoveRight(piece: Piece): Boolean {
for i in range(len(piece.shape)) {
for j in range(len(piece.shape[i])) {
if piece.shape[i][j] == 1 && (piece.x+j >= BOARD_WIDTH-1 || board[piece.y+i][piece.x+j+1] != ".") {
return false
}
}
}
return true
}
// 检查方块能否向下移动
func canMoveDown(piece: Piece): Boolean {
for i in range(len(piece.shape)) {
for j in range(len(piece.shape[i])) {
if piece.shape[i][j] == 1 && (piece.y+i >= BOARD_HEIGHT-1 || board[piece.y+i+1][piece.x+j] != ".") {
return false
}
}
}
return true
}
// 检查是否有碰撞发生
func hasCollision(piece: Piece): Boolean {
for i in range(len(piece.shape)) {
for j in range(len(piece.shape[i])) {
if piece.shape[i][j] == 1 && (piece.y+i < 0 || board[piece.y+i][piece.x+j] != ".") {
return true
}
}
}
return false
}
// 方块向下移动
func movePieceDown(piecePtr: Pointer<Piece>) {
(*piecePtr).y += 1
}
// 旋转方块
func rotatePiece(piecePtr: Pointer<Piece>) {
var rotatedShape: Array<Array<Int64>> = transposeMatrix((*piecePtr).shape)
if !hasCollision(Piece{rotatedShape, (*piecePtr).color, (*piecePtr).x, (*piecePtr).y}) {
(*piecePtr).shape = rotatedShape
}
}
// 转置矩阵用于旋转操作
func transposeMatrix(matrix: Array<Array<Int64>>): Array<Array<Int64>> {
var transposed: Array<Array<Int64>> = []
for colIdx in range(len(matrix[0])) {
var newRow: Array<Int64> = []
for rowIdx in range(len(matrix)) {
newRow.append(matrix[rowIdx][colIdx])
}
transposed.append(newRow)
}
return reverseRows(transposed)
}
// 反转数组中的每一行
func reverseRows(matrix: Array<Array<Int64>>): Array<Array<Int64>> {
var reversed: Array<Array<Int64>> = []
for row in matrix {
reversed.append(reverseArray(row))
}
return reversed
}
// 反转单个数组
func reverseArray(array: Array<Int64>): Array<Int64> {
var reversed: Array<Int64> = []
for i in range(len(array)-1, -1, -1) {
reversed.append(array[i])
}
return reversed
}
// 获取用户输入
func getInputFromUser(): String {
println("请输入指令 (left/right/down/rotate)")
return readLine().trim()
}
// 结束游戏
func endGame() {
println("游戏结束!感谢游玩。")
}
```
---
### 功能说明
1. **棋盘初始化**
`createEmptyBoard` 函数负责创建一个初始为空的二维棋盘,大小由常量定义[^1]。
2. **方块生成与控制**
- `generateRandomPiece` 函数会随机生成不同形状的颜色方块。
- 支持方向键控制(左右平移、加速下降)、旋转功能。
3. **碰撞检测**
提供多个辅助函数判断方块是否可以合法移动或旋转,防止越界或重叠。
4. **消除满行**
当某一横行被完全填满时自动删除该行,并让上方所有行依次下移填补空位。
5. **游戏结束判定**
若新生成的方块无法放入顶部区域,则触发失败逻辑退出循环。
---
###