Skip to content

Commit 7832f3c

Browse files
committed
✨ (2048): add you win and continue logic
1 parent b0b12c7 commit 7832f3c

File tree

3 files changed

+106
-2
lines changed

3 files changed

+106
-2
lines changed

internal/game/end_condition.go

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,3 +44,21 @@ func (g *Game) InitGame() {
4444
g.AddRandomTile(Default)
4545
g.AddRandomTile(Default)
4646
}
47+
48+
// is2048tileShow - 檢查是否已經達成 2048 tile 的完成條件
49+
func (g *Game) is2048tileShow() bool {
50+
for row := 0; row < sideSize; row++ {
51+
for col := 0; col < sideSize; col++ {
52+
if g.board[row][col] == 2048 {
53+
return true
54+
}
55+
}
56+
}
57+
58+
return false
59+
}
60+
61+
// IsPlayerWin - 檢查玩家是否達成勝利條件
62+
func (g *Game) IsPlayerWin() bool {
63+
return g.is2048tileShow()
64+
}

internal/layout/action_handler.go

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,21 @@ func (g *GameLayout) Update() error {
1414
g.handleRestartGame()
1515
return nil
1616
}
17+
18+
// 判斷是否 Player Win
19+
if g.isPlayerWin && !g.isContinue {
20+
g.handleContinueGame()
21+
return nil
22+
}
1723
// 根據輸入產生對應的更新
1824
g.handleInput()
1925

26+
// 根據目前的盤面決定是否要顯示 You Win
27+
if !g.isContinue && g.gameInstance.IsPlayerWin() {
28+
g.isPlayerWin = true
29+
return nil
30+
}
31+
2032
// 根據目前的盤面跟更新是否能夠繼續執行
2133
if g.gameInstance.IsGameOver() {
2234
g.isGameOver = true
@@ -55,8 +67,26 @@ func (g *GameLayout) handleRestartGame() {
5567
}
5668
}
5769

70+
// handleContinueGame - 偵測目前 restart button
71+
func (g *GameLayout) handleContinueGame() {
72+
if ebiten.IsMouseButtonPressed(ebiten.MouseButtonLeft) {
73+
x, y := ebiten.CursorPosition()
74+
if restartButtonRect.Min.X <= x && x <= restartButtonRect.Max.X &&
75+
restartButtonRect.Min.Y <= y && y <= restartButtonRect.Max.Y {
76+
g.continueGame()
77+
}
78+
}
79+
}
80+
5881
// restartGame - 重設目前遊戲狀態
5982
func (g *GameLayout) restartGame() {
6083
g.gameInstance.InitGame()
6184
g.isGameOver = false
85+
g.isContinue = false
86+
}
87+
88+
// continueGame -
89+
func (g *GameLayout) continueGame() {
90+
g.isPlayerWin = false
91+
g.isContinue = true
6292
}

internal/layout/layout.go

Lines changed: 58 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@ import (
1111
"github.com/leetcode-golang-classroom/2048-game/internal/game"
1212
)
1313

14-
var restartButtonRect = image.Rect(165, 250, 285, 300) // X1,Y1,X2,Y2
15-
14+
var restartButtonRect = image.Rect(165, 250, 285, 300) // X1,Y1,X2,Y2
15+
var continueButtonRect = image.Rect(145, 250, 305, 300) // X1,Y1,X2,Y2
1616
const (
1717
tileSize = 100
1818
gridSize = 4
@@ -24,6 +24,8 @@ const (
2424
type GameLayout struct {
2525
gameInstance *game.Game
2626
isGameOver bool
27+
isPlayerWin bool
28+
isContinue bool
2729
}
2830

2931
// drawCell - 透過目前值來畫出目前 cell 的格子顏色
@@ -63,6 +65,10 @@ func (g *GameLayout) Draw(screen *ebiten.Image) {
6365
screen.Fill(color.RGBA{250, 248, 239, 255})
6466
// 畫出目前局面
6567
g.drawBoard(screen)
68+
// 當完成了 2048 條件 顯示 You Win 與 Continue button
69+
if g.isPlayerWin && !g.isContinue {
70+
g.drawYouWin(screen)
71+
}
6672
// 當 gameOver 顯示 GameOver
6773
if g.isGameOver {
6874
g.drawGameOver(screen)
@@ -113,6 +119,56 @@ func (g *GameLayout) drawGameOver(screen *ebiten.Image) {
113119
g.drawRestartButton(screen)
114120
}
115121

122+
func (g *GameLayout) drawConverOnYouWin(screen *ebiten.Image) {
123+
w, h := screen.Bounds().Dx(), screen.Bounds().Dy()
124+
vector.DrawFilledRect(
125+
screen,
126+
0, 0, // x, y
127+
float32(w), float32(h), // width, height
128+
color.RGBA{100, 100, 0, 60}, // 半透明黃色 (128 = 約 50% 透明)
129+
false,
130+
)
131+
}
132+
133+
// drawYouWin 畫出 You Win
134+
func (g *GameLayout) drawYouWin(screen *ebiten.Image) {
135+
g.drawConverOnYouWin(screen)
136+
// 設定顯示 Game Over 文字
137+
textXPos := WinHeight / 2
138+
textYPos := WinWidth / 2
139+
textOpts := &text.DrawOptions{}
140+
textOpts.ColorScale.ScaleWithColor(color.RGBA{220, 220, 0, 255})
141+
textOpts.PrimaryAlign = text.AlignCenter
142+
textOpts.SecondaryAlign = text.AlignCenter
143+
textOpts.GeoM.Translate(float64(textXPos), float64(textYPos))
144+
text.Draw(screen, "You Win", &text.GoTextFace{
145+
Source: mplusFaceSource,
146+
Size: 48.0,
147+
}, textOpts)
148+
g.drawContinueButton(screen)
149+
}
150+
151+
func (g *GameLayout) drawContinueButton(screen *ebiten.Image) {
152+
// 畫 Restart 按鈕
153+
vector.DrawFilledRect(screen,
154+
float32(continueButtonRect.Min.X),
155+
float32(continueButtonRect.Min.Y),
156+
float32(continueButtonRect.Dx()),
157+
float32(continueButtonRect.Dy()),
158+
color.RGBA{100, 100, 100, 200},
159+
true,
160+
)
161+
textOpts := &text.DrawOptions{}
162+
textOpts.ColorScale.ScaleWithColor(color.Black)
163+
textOpts.PrimaryAlign = text.AlignCenter
164+
textOpts.SecondaryAlign = text.AlignCenter
165+
textOpts.GeoM.Translate(float64(continueButtonRect.Min.X+continueButtonRect.Dx()/2), float64(continueButtonRect.Min.Y+continueButtonRect.Dy()/2))
166+
text.Draw(screen, "Continue", &text.GoTextFace{
167+
Source: mplusFaceSource,
168+
Size: 30,
169+
}, textOpts)
170+
}
171+
116172
// drawRestartButton - 畫出 restart button
117173
func (g *GameLayout) drawRestartButton(screen *ebiten.Image) {
118174
// 畫 Restart 按鈕

0 commit comments

Comments
 (0)