@@ -19,8 +19,9 @@ const (
19
19
lineVertical = '|'
20
20
lineHorizontal = '-'
21
21
empty = ' '
22
- player = 'o '
22
+ player = '0 '
23
23
item = '$'
24
+ enemy = 'X'
24
25
)
25
26
26
27
// model encapsulates our data for displaying and updating.
@@ -30,49 +31,68 @@ type model struct {
30
31
playerRow int
31
32
playerCol int
32
33
33
- itemRow int
34
- itemCol int
34
+ gameOver bool
35
35
}
36
36
37
37
func (m * model ) spawnItem () {
38
+ row , col := m .randomFreeCoordinates ()
39
+ m.table [row ][col ] = item
40
+ }
41
+
42
+ func (m * model ) spawnEnemy () {
43
+ row , col := m .randomFreeCoordinates ()
44
+ m.table [row ][col ] = enemy
45
+ }
46
+
47
+ func (m * model ) randomFreeCoordinates () (row , col int ) {
38
48
// Generate some random coordinates.
39
- row , col : = randomCoordinates ()
49
+ row , col = randomCoordinates ()
40
50
41
51
// Check that the random cell is empty.
42
52
// If not repeat randomizing until we find an empty cell.
43
53
for m.table [row ][col ] != 0 {
44
54
row , col = randomCoordinates ()
45
55
}
46
56
47
- m.table [row ][col ] = item
48
- m .itemRow = row
49
- m .itemCol = col
57
+ return
50
58
}
51
59
52
60
// randomCoordinates returns a new set of random coordinates within the
53
61
// playing field excluding borders. However, it is not guaranteed that the
54
62
// cell under the returned coordinates is actually empty.
55
- func randomCoordinates () (row int , col int ) {
63
+ func randomCoordinates () (row , col int ) {
56
64
row = rand .Intn (tableHeight - 2 ) + 1
57
65
col = rand .Intn (tableWidth - 2 ) + 1
58
66
59
67
return
60
68
}
61
69
62
70
func (m * model ) movePlayer (row , col int ) {
71
+ if m .gameOver {
72
+ return
73
+ }
74
+
63
75
// Clear old player location.
64
76
m.table [m.playerRow ][m.playerCol ] = 0
65
77
78
+ if m.table [row ][col ] == enemy {
79
+ // We ran into an enemy. Signal game over and skip further
80
+ // processing.
81
+ m .gameOver = true
82
+ return
83
+ }
84
+
85
+ if m.table [row ][col ] == item {
86
+ // We collected an item. A new item and enemy needs to be
87
+ // spawned.
88
+ m .spawnItem ()
89
+ m .spawnEnemy ()
90
+ }
91
+
66
92
// Set new player location.
67
93
m.table [row ][col ] = player
68
94
m .playerRow = row
69
95
m .playerCol = col
70
-
71
- // Check if we are at the position of an item. Then we need to
72
- // spawn a new item.
73
- if m .itemRow == row && m .itemCol == col {
74
- m .spawnItem ()
75
- }
76
96
}
77
97
78
98
func (m * model ) playerUp () {
@@ -160,6 +180,11 @@ func (m *model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
160
180
161
181
case tea.KeyMsg :
162
182
183
+ // If our game is lost, any key shall terminate the program.
184
+ if m .gameOver {
185
+ return m , tea .Quit
186
+ }
187
+
163
188
switch msg .String () {
164
189
165
190
// Exit program on ctrl+c or q typing.
@@ -182,6 +207,11 @@ func (m *model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
182
207
// View is required for building what we want to show on the screen.
183
208
// That means we need to translate our model data into a string for displaying.
184
209
func (m * model ) View () string {
210
+ if m .gameOver {
211
+ // Just inform about game over and don't continue.
212
+ return "Player died, Game Over!"
213
+ }
214
+
185
215
builder := strings.Builder {}
186
216
187
217
// Iterate our table (2d array) and print non-empty fields as set in
0 commit comments