175 lines
3.9 KiB
Go
175 lines
3.9 KiB
Go
package main
|
|
|
|
import (
|
|
"github.com/gdamore/tcell/v2"
|
|
)
|
|
|
|
// initSnake Initialize the snake
|
|
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 - 3,
|
|
y: y,
|
|
},
|
|
{
|
|
x: x - 2,
|
|
y: y,
|
|
},
|
|
{
|
|
x: x - 1,
|
|
y: y,
|
|
},
|
|
},
|
|
length: 3,
|
|
direction: 1,
|
|
}
|
|
|
|
return snake
|
|
}
|
|
|
|
func drawSnake(screen tcell.Screen, style tcell.Style, snake *Snake) {
|
|
|
|
var tail []rune
|
|
|
|
// 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)
|
|
|
|
for i, j := range snake.tail {
|
|
// The Tail end
|
|
if i == 0 {
|
|
left := getDirection(j, snake.tail[i+1])
|
|
right := getDirection(j, snake.tail[i+1])
|
|
tail = append(tail, getLineType(left, right))
|
|
|
|
// The Bit behind the head
|
|
} else if i == len(snake.tail)-1 {
|
|
left := getDirection(j, snake.tail[i-1])
|
|
right := getDirection(j, snake.head)
|
|
tail = append(tail, getLineType(left, right))
|
|
|
|
// The body of the snake
|
|
} else {
|
|
left := getDirection(j, snake.tail[i-1])
|
|
right := getDirection(j, snake.tail[i+1])
|
|
tail = append(tail, getLineType(left, right))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// Draw the body
|
|
for i, segment := range snake.tail {
|
|
screen.SetContent(segment.x, segment.y, tail[i], 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 {
|
|
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 {
|
|
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 {
|
|
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 {
|
|
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
|
|
}
|
|
|
|
func validateDirection(snake *Snake, direction int) bool {
|
|
if snake.direction == direction {
|
|
return true
|
|
} else if snake.direction == Left && direction == Right {
|
|
return false
|
|
} else if snake.direction == Right && direction == Left {
|
|
return false
|
|
} else if snake.direction == Up && direction == Down {
|
|
return false
|
|
} else if snake.direction == Down && direction == Up {
|
|
return false
|
|
} else {
|
|
return true
|
|
}
|
|
}
|
|
|
|
func getDirection(from Position, to Position) int {
|
|
|
|
var direction int
|
|
|
|
if from.x-to.x == 1 {
|
|
direction = Left
|
|
} else if from.x-to.x == -1 {
|
|
direction = Right
|
|
} else if from.y-to.y == 1 {
|
|
direction = Up
|
|
} else if from.y-to.y == -1 {
|
|
direction = Down
|
|
}
|
|
|
|
return direction
|
|
}
|
|
|
|
func getLineType(from int, to int) rune {
|
|
|
|
var lineType rune
|
|
|
|
if (from == Left && to == Down) || (from == Down && to == Left) {
|
|
lineType = '┐'
|
|
} else if (from == Up && to == Right) || (from == Right && to == Up) {
|
|
lineType = '└'
|
|
} else if (from == Left && to == Right) || (from == Right && to == Left) {
|
|
lineType = '─'
|
|
} else if (from == Left && to == Up) || (from == Up && to == Left) {
|
|
lineType = '┘'
|
|
} else if (from == Right && to == Down) || (from == Down && to == Right) {
|
|
lineType = '┌'
|
|
} else if (from == Up && to == Down) || (from == Down && to == Up) {
|
|
lineType = '│'
|
|
}
|
|
|
|
return lineType
|
|
}
|