#4 Gives the snake a tail.

This commit is contained in:
Sacha Ligthert 2023-11-23 22:36:44 +01:00
parent 3902d2b0a9
commit aea82ab765
6 changed files with 133 additions and 40 deletions

View File

@ -15,7 +15,8 @@ import (
// return foodsRune[randomIndex] // return foodsRune[randomIndex]
// } // }
func placeApple(snakex *int, snakey *int) Apple { // func placeApple(snakex int, snakey int) Apple {
func placeApple(snake *Snake) Apple {
var x, y int var x, y int
var found bool var found bool
@ -24,12 +25,15 @@ func placeApple(snakex *int, snakey *int) Apple {
x = rand.Intn(80) x = rand.Intn(80)
y = rand.Intn(24) y = rand.Intn(24)
if x != *snakex && y != *snakey { if x != snake.head.x && y != snake.head.y {
found = true found = true
} }
if x == 0 || x == 79 || y == 0 || y == 23 { if x == 0 || x == 79 || y == 0 || y == 23 {
found = false found = false
} }
if hitsTail(snake, x, y) {
found = false
}
} }
@ -42,6 +46,6 @@ func placeApple(snakex *int, snakey *int) Apple {
} }
func drawApple(screen tcell.Screen, style tcell.Style, x int, y int) { func drawApple(screen tcell.Screen, style tcell.Style, apple *Apple) {
screen.SetContent(x, y, '🍎', nil, style) screen.SetContent(apple.x, apple.y, 'o', nil, style)
} }

36
game.go
View File

@ -45,12 +45,6 @@ func gameDirector(screen tcell.Screen, style tcell.Style, keypresses chan int, g
var score int = 0 var score int = 0
var scoreCounter int = 1 var scoreCounter int = 1
//var field [80][24]int
// fill up the field:
// 0: empty
// 1: snake
// 2: apple
// 3: border
// Board size // Board size
var screenx = 80 var screenx = 80
@ -63,30 +57,38 @@ func gameDirector(screen tcell.Screen, style tcell.Style, keypresses chan int, g
// Last direction we went in // Last direction we went in
var lastpress int = 1 var lastpress int = 1
var apple Apple = placeApple(&snakex, &snakey) var snake Snake = initSnake(&snakex, &snakey)
var apple Apple = placeApple(&snake)
for { for {
// Take input or sleep // Take input or sleep
select { select {
case press := <-keypresses: case press := <-keypresses:
snakeDirection(press, &snakex, &snakey) snakeDirection(press, &snake)
lastpress = press lastpress = press
case <-time.After(500 * time.Millisecond): case <-time.After(500 * time.Millisecond):
snakeDirection(lastpress, &snakex, &snakey) snakeDirection(lastpress, &snake)
} }
if snakex == apple.x && snakey == apple.y { if snake.head.x == apple.x && snake.head.y == apple.y {
apple = placeApple(&snakex, &snakey) apple = placeApple(&snake)
score += scoreCounter score += scoreCounter
scoreCounter++ scoreCounter++
snake.length = 3 + score
} }
// Call it quits once the snake hits the border. // Call it quits once the snake hits the border.
if snakex == 0 || snakex == screenx-1 { if snake.head.x == 0 || snake.head.x == screenx-1 {
close(gamestate) close(gamestate)
return return
} else if snakey == 0 || snakey == screeny-1 { } else if snake.head.y == 0 || snake.head.y == screeny-1 {
close(gamestate)
return
}
// Check if head intersects with any parts of the body
if hitsTail(&snake, snake.head.x, snake.head.y) {
close(gamestate) close(gamestate)
return return
} }
@ -95,10 +97,10 @@ func gameDirector(screen tcell.Screen, style tcell.Style, keypresses chan int, g
screen.Clear() screen.Clear()
// Draw the screen // Draw the screen
drawBox(screen, 0, 0, screenx-1, screeny-1, style) drawBox(screen, style, 0, 0, screenx-1, screeny-1)
drawCoords(screen, style, &snakex, &snakey) drawCoords(screen, style, &snake)
drawApple(screen, style, apple.x, apple.y) drawApple(screen, style, &apple)
drawSnake(screen, style, snakex, snakey) drawSnake(screen, style, &snake)
drawScore(screen, style, score) drawScore(screen, style, score)
// Draw the screen // Draw the screen

View File

@ -4,15 +4,6 @@ import (
"log" "log"
) )
type Position struct {
x int
y int
}
type Apple Position
//type Snake Position
func main() { func main() {
// Create channles to manage keypresses and the gamestate // Create channles to manage keypresses and the gamestate

View File

@ -26,15 +26,15 @@ func drawScore(screen tcell.Screen, style tcell.Style, score int) {
} }
} }
func drawCoords(screen tcell.Screen, style tcell.Style, snakex *int, snakey *int) { func drawCoords(screen tcell.Screen, style tcell.Style, snake *Snake) {
var x, y int = 25, 24 var x, y int = 25, 24
for _, r := range []rune("[ x:" + strconv.FormatInt(int64(*snakex), 10) + " y: " + strconv.FormatInt(int64(*snakey), 10) + " ]") { for _, r := range []rune("[ x:" + strconv.FormatInt(int64(*&snake.head.x), 10) + " y: " + strconv.FormatInt(int64(*&snake.head.y), 10) + " ]") {
screen.SetContent(x, y-1, r, nil, style) screen.SetContent(x, y-1, r, nil, style)
x++ x++
} }
} }
func drawBox(s tcell.Screen, x1, y1, x2, y2 int, style tcell.Style) { func drawBox(s tcell.Screen, style tcell.Style, x1, y1, x2, y2 int) {
if y2 < y1 { if y2 < y1 {
y1, y2 = y2, y1 y1, y2 = y2, y1
} }

View File

@ -4,18 +4,99 @@ import (
"github.com/gdamore/tcell/v2" "github.com/gdamore/tcell/v2"
) )
func drawSnake(screen tcell.Screen, style tcell.Style, x int, y int) { func initSnake(snakex *int, snakey *int) Snake {
screen.SetContent(x, y, '🐍', nil, style) var x, y int = *snakex, *snakey
snake := Snake{
head: Position{
x: x,
y: y,
},
tail: []Position{
{
x: x - 1,
y: y,
},
{
x: x - 2,
y: y,
},
{
x: x - 3,
y: y,
},
},
length: 3,
direction: 1,
} }
func snakeDirection(press int, snakex *int, snakey *int) { return snake
}
func drawSnake(screen tcell.Screen, style tcell.Style, snake *Snake) {
// Reverse tail, chop of the excesses,
snake.tail = ReverseSlice(snake.tail)
if len(snake.tail) > snake.length {
snake.tail = snake.tail[:snake.length]
}
// reverse it back to the original order, replace the tail in `snake`
snake.tail = ReverseSlice(snake.tail)
// Draw the body
for _, segment := range snake.tail {
screen.SetContent(segment.x, segment.y, '+', nil, style)
}
// Draw the head, make sure it is on top of everything
screen.SetContent(snake.head.x, snake.head.y, '0', nil, style)
}
func snakeDirection(press int, snake *Snake) {
if press == Left { if press == Left {
*snakex-- if snake.direction != Right {
snake.head.x--
snake.tail = append(snake.tail, Position{x: snake.head.x + 1, y: snake.head.y})
snake.direction = press
}
} else if press == Right { } else if press == Right {
*snakex++ if snake.direction != Left {
snake.head.x++
snake.tail = append(snake.tail, Position{x: snake.head.x - 1, y: snake.head.y})
snake.direction = press
}
} else if press == Up { } else if press == Up {
*snakey-- if snake.direction != Down {
snake.head.y--
snake.tail = append(snake.tail, Position{x: snake.head.x, y: snake.head.y + 1})
snake.direction = press
}
} else if press == Down { } else if press == Down {
*snakey++ if snake.direction != Up {
snake.head.y++
snake.tail = append(snake.tail, Position{x: snake.head.x, y: snake.head.y - 1})
snake.direction = press
} }
} }
}
// Check if a pos hits the tail
func hitsTail(snake *Snake, x int, y int) bool {
var hit bool = false
for _, segment := range snake.tail {
if segment.x == x && segment.y == y {
hit = true
}
}
return hit
}
func ReverseSlice[T comparable](s []T) []T {
var r []T
for i := len(s) - 1; i >= 0; i-- {
r = append(r, s[i])
}
return r
}

15
types.go Normal file
View File

@ -0,0 +1,15 @@
package main
type Position struct {
x int
y int
}
type Apple Position
type Snake struct {
head Position
tail []Position
length int
direction int
}