以下是一个简单的 2048 小游戏,使用 Go 编写:
”`go package main
import (
"fmt"
"math/rand"
"time"
)
const (
boardSize = 4
winValue = 2048
)
type direction int
const (
up direction = iota
down
left
right
)
type gameBoard [boardSize][boardSize]int
func (gb *gameBoard) String() string {
var s string
for _, row := range gb {
for _, val := range row {
s += fmt.Sprintf("%4d", val)
}
s += "\n"
}
return s
}
func (gb *gameBoard) addRandomTile() bool {
if gb.isFull() {
return false
}
rand.Seed(time.Now().UnixNano())
for i := 0; i < boardSize*boardSize; i++ {
row, col := rand.Intn(boardSize), rand.Intn(boardSize)
if gb[row][col] == 0 {
gb[row][col] = (rand.Int()%2 + 1) * 2 // either 2 or 4 with equal probability
return true
}
}
panic("unreachable")
}
func (gb *gameBoard) isFull() bool {
for _, row := range gb {
for _, val := range row {
if val == 0 {
return false
}
}
}
return true
}
func (gb *gameBoard) canMove(d direction) bool {
switch d {
case up:
for col := range gb[0] {
for row := boardSize - 1; row > 0; row-- { // start from bottom to avoid redundant checks when shifting tiles up and left.
if gb[row][col] != 0 && (gb[row-1][col] == 0 || gb[row-1][col] == gb[row][col]) {
return true
}
}
}
case down:
for col := range gb[0] {
for row := 0; row < boardSize-1; row++ { // start from top to avoid redundant checks when shifting tiles down and right.
if gb[row][col] != 0 && (gb[row+1][col] == 0 || gb[row+1][col] == gb[row][col]) {
return true
}
}
}
case left:
for row := range gb {
for col := boardSize - 1; col > 0; col-- { // start from right to avoid redundant checks when shifting tiles up and left.
if gb[row][col] != 0 && (gb[row][col-1] == 0 || gb[row][col-1] == gb[row][col]) {
return true
}
}
}
case right:
for row := range gb {
for col := 0; col < boardSize-1; col++ { // start from left to avoid redundant checks when shifting tiles down and right.
if gb[row][col] != 0 && (gb[row][col+1] == 0 || gb[row][col+1] == gb[row][col]) {
return true
}
}
}
default:
panic("invalid direction")
}
return false
}
func (gb *gameBoard) shift(d direction) bool {
var moved bool
switch d {
case up:
for col := range gb[0