#4 Gives the snake a tail.
This commit is contained in:
parent
3902d2b0a9
commit
aea82ab765
12
apple.go
12
apple.go
@ -15,7 +15,8 @@ import (
|
||||
// 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 found bool
|
||||
|
||||
@ -24,12 +25,15 @@ func placeApple(snakex *int, snakey *int) Apple {
|
||||
x = rand.Intn(80)
|
||||
y = rand.Intn(24)
|
||||
|
||||
if x != *snakex && y != *snakey {
|
||||
if x != snake.head.x && y != snake.head.y {
|
||||
found = true
|
||||
}
|
||||
if x == 0 || x == 79 || y == 0 || y == 23 {
|
||||
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) {
|
||||
screen.SetContent(x, y, '🍎', nil, style)
|
||||
func drawApple(screen tcell.Screen, style tcell.Style, apple *Apple) {
|
||||
screen.SetContent(apple.x, apple.y, 'o', nil, style)
|
||||
}
|
||||
|
36
game.go
36
game.go
@ -45,12 +45,6 @@ func gameDirector(screen tcell.Screen, style tcell.Style, keypresses chan int, g
|
||||
|
||||
var score int = 0
|
||||
var scoreCounter int = 1
|
||||
//var field [80][24]int
|
||||
// fill up the field:
|
||||
// 0: empty
|
||||
// 1: snake
|
||||
// 2: apple
|
||||
// 3: border
|
||||
|
||||
// Board size
|
||||
var screenx = 80
|
||||
@ -63,30 +57,38 @@ func gameDirector(screen tcell.Screen, style tcell.Style, keypresses chan int, g
|
||||
// Last direction we went in
|
||||
var lastpress int = 1
|
||||
|
||||
var apple Apple = placeApple(&snakex, &snakey)
|
||||
var snake Snake = initSnake(&snakex, &snakey)
|
||||
var apple Apple = placeApple(&snake)
|
||||
|
||||
for {
|
||||
|
||||
// Take input or sleep
|
||||
select {
|
||||
case press := <-keypresses:
|
||||
snakeDirection(press, &snakex, &snakey)
|
||||
snakeDirection(press, &snake)
|
||||
lastpress = press
|
||||
case <-time.After(500 * time.Millisecond):
|
||||
snakeDirection(lastpress, &snakex, &snakey)
|
||||
snakeDirection(lastpress, &snake)
|
||||
}
|
||||
|
||||
if snakex == apple.x && snakey == apple.y {
|
||||
apple = placeApple(&snakex, &snakey)
|
||||
if snake.head.x == apple.x && snake.head.y == apple.y {
|
||||
apple = placeApple(&snake)
|
||||
score += scoreCounter
|
||||
scoreCounter++
|
||||
snake.length = 3 + score
|
||||
}
|
||||
|
||||
// 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)
|
||||
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)
|
||||
return
|
||||
}
|
||||
@ -95,10 +97,10 @@ func gameDirector(screen tcell.Screen, style tcell.Style, keypresses chan int, g
|
||||
screen.Clear()
|
||||
|
||||
// Draw the screen
|
||||
drawBox(screen, 0, 0, screenx-1, screeny-1, style)
|
||||
drawCoords(screen, style, &snakex, &snakey)
|
||||
drawApple(screen, style, apple.x, apple.y)
|
||||
drawSnake(screen, style, snakex, snakey)
|
||||
drawBox(screen, style, 0, 0, screenx-1, screeny-1)
|
||||
drawCoords(screen, style, &snake)
|
||||
drawApple(screen, style, &apple)
|
||||
drawSnake(screen, style, &snake)
|
||||
drawScore(screen, style, score)
|
||||
|
||||
// Draw the screen
|
||||
|
9
main.go
9
main.go
@ -4,15 +4,6 @@ import (
|
||||
"log"
|
||||
)
|
||||
|
||||
type Position struct {
|
||||
x int
|
||||
y int
|
||||
}
|
||||
|
||||
type Apple Position
|
||||
|
||||
//type Snake Position
|
||||
|
||||
func main() {
|
||||
|
||||
// Create channles to manage keypresses and the gamestate
|
||||
|
@ -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
|
||||
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)
|
||||
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 {
|
||||
y1, y2 = y2, y1
|
||||
}
|
||||
|
95
snake.go
95
snake.go
@ -4,18 +4,99 @@ import (
|
||||
"github.com/gdamore/tcell/v2"
|
||||
)
|
||||
|
||||
func drawSnake(screen tcell.Screen, style tcell.Style, x int, y int) {
|
||||
screen.SetContent(x, y, '🐍', nil, style)
|
||||
func initSnake(snakex *int, snakey *int) Snake {
|
||||
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 {
|
||||
*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 {
|
||||
*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 {
|
||||
*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 {
|
||||
*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
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user