#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]
|
// 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
36
game.go
@ -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
|
||||||
|
9
main.go
9
main.go
@ -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
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
|
95
snake.go
95
snake.go
@ -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
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user