Compare commits
4 Commits
c5827793ef
...
v20231124
Author | SHA1 | Date | |
---|---|---|---|
0732e7f809 | |||
763ed9b38a | |||
53e6bfdf4d | |||
44f2c5a41d |
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
builds
|
5
build.sh
Executable file
5
build.sh
Executable file
@ -0,0 +1,5 @@
|
||||
#!/bin/sh
|
||||
|
||||
mkdir -p builds
|
||||
|
||||
go tool dist list | grep -v android | grep -v darwin | grep -v ios | grep -v wasip1 | awk -F '/' '{printf "echo Compiling %s/%s; env CGO_ENABLED=1 GOOS=%s GOARCH=%s go build -o builds/snake.%s-%s\n",$1,$2,$1,$2,$1,$2 }' | sh
|
26
game.go
26
game.go
@ -31,26 +31,19 @@ func quit(screen tcell.Screen) {
|
||||
}
|
||||
}
|
||||
|
||||
func gameDirector(screen tcell.Screen, style tcell.Style, keypresses chan int, gamestate chan int) {
|
||||
func gameDirector(screen tcell.Screen, style tcell.Style, keypresses chan int, gamestate chan int, score *Score) {
|
||||
|
||||
// Destined to die, even before I was born.
|
||||
defer quit(screen)
|
||||
|
||||
var score int = 0
|
||||
var scoreCounter int = 1
|
||||
|
||||
// Board size
|
||||
var screenx = 80
|
||||
var screeny = 24
|
||||
|
||||
// Have snake start at the center of the board
|
||||
var snakex int = (screenx / 2) - 1
|
||||
var snakey int = (screeny / 2) - 1
|
||||
|
||||
// Last direction we went in
|
||||
var lastpress int = 1
|
||||
|
||||
var snake Snake = initSnake(&snakex, &snakey)
|
||||
var snake Snake = initSnake((screenx/2)-1, (screeny/2)-1)
|
||||
var apple Apple = placeApple(&snake)
|
||||
|
||||
for {
|
||||
@ -68,22 +61,25 @@ func gameDirector(screen tcell.Screen, style tcell.Style, keypresses chan int, g
|
||||
|
||||
if snake.head.x == apple.x && snake.head.y == apple.y {
|
||||
apple = placeApple(&snake)
|
||||
score += scoreCounter
|
||||
scoreCounter++
|
||||
snake.length = 3 + score
|
||||
score.score += score.scoreCounter
|
||||
score.scoreCounter++
|
||||
snake.length = 3 + score.score
|
||||
}
|
||||
|
||||
// Call it quits once the snake hits the border.
|
||||
if snake.head.x == 0 || snake.head.x == screenx-1 {
|
||||
score.reason = 2
|
||||
close(gamestate)
|
||||
return
|
||||
} else if snake.head.y == 0 || snake.head.y == screeny-1 {
|
||||
score.reason = 2
|
||||
close(gamestate)
|
||||
return
|
||||
}
|
||||
|
||||
// Check if head intersects with any parts of the body
|
||||
if hitsTail(&snake, snake.head.x, snake.head.y) {
|
||||
score.reason = 3
|
||||
close(gamestate)
|
||||
return
|
||||
}
|
||||
@ -93,7 +89,7 @@ func gameDirector(screen tcell.Screen, style tcell.Style, keypresses chan int, g
|
||||
|
||||
// Draw the screen
|
||||
drawBox(screen, style, 0, 0, screenx-1, screeny-1)
|
||||
drawCoords(screen, style, &snake)
|
||||
//drawCoords(screen, style, &snake)
|
||||
drawApple(screen, style, &apple)
|
||||
drawSnake(screen, style, &snake)
|
||||
drawScore(screen, style, score)
|
||||
@ -105,7 +101,7 @@ func gameDirector(screen tcell.Screen, style tcell.Style, keypresses chan int, g
|
||||
|
||||
}
|
||||
|
||||
func keyboardProcessor(screen tcell.Screen, keypresses chan int, gamestate chan int) {
|
||||
func keyboardProcessor(screen tcell.Screen, keypresses chan int, gamestate chan int, score *Score) {
|
||||
defer close(keypresses)
|
||||
|
||||
for {
|
||||
@ -117,8 +113,10 @@ func keyboardProcessor(screen tcell.Screen, keypresses chan int, gamestate chan
|
||||
switch ev := ev.(type) {
|
||||
case *tcell.EventKey:
|
||||
if ev.Key() == tcell.KeyEscape || ev.Key() == tcell.KeyCtrlC {
|
||||
score.reason = 1
|
||||
return
|
||||
} else if ev.Rune() == 'q' || ev.Rune() == 'Q' {
|
||||
score.reason = 1
|
||||
return
|
||||
} else if ev.Key() == tcell.KeyCtrlL {
|
||||
screen.Sync()
|
||||
|
28
main.go
28
main.go
@ -2,6 +2,7 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
)
|
||||
|
||||
@ -12,19 +13,40 @@ func main() {
|
||||
keypresses := make(chan int)
|
||||
gamestate := make(chan int)
|
||||
|
||||
// Score tracker
|
||||
score := Score{
|
||||
score: 0,
|
||||
scoreCounter: 1,
|
||||
reason: 0,
|
||||
}
|
||||
|
||||
// Initialize tcell and clean up when needed.
|
||||
screen, style, err := initilize()
|
||||
if err != nil {
|
||||
log.Fatalln("Initlization error: ", err)
|
||||
}
|
||||
defer quit(screen)
|
||||
//defer quit(screen)
|
||||
|
||||
// Spawn the Game Director in its own go routine
|
||||
// We give it channels to control...
|
||||
go gameDirector(screen, style, keypresses, gamestate)
|
||||
go gameDirector(screen, style, keypresses, gamestate, &score)
|
||||
|
||||
// A simple function that captures keyboard presses...
|
||||
// ...and sends it to the GameDirector.
|
||||
keyboardProcessor(screen, keypresses, gamestate)
|
||||
keyboardProcessor(screen, keypresses, gamestate, &score)
|
||||
|
||||
// Quit the screen
|
||||
quit(screen)
|
||||
|
||||
// Print the score
|
||||
fmt.Println("Score: ", score.score)
|
||||
switch score.reason {
|
||||
case 1:
|
||||
fmt.Println("Reason: You quit")
|
||||
case 2:
|
||||
fmt.Println("Reason: You hit a wall")
|
||||
case 3:
|
||||
fmt.Println("Reason: You ate your tail")
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -7,9 +7,9 @@ import (
|
||||
)
|
||||
|
||||
// drawScore Print the score
|
||||
func drawScore(screen tcell.Screen, style tcell.Style, score int) {
|
||||
func drawScore(screen tcell.Screen, style tcell.Style, score *Score) {
|
||||
var x, y int = 5, 24
|
||||
for _, r := range []rune("[ Score: " + strconv.FormatInt(int64(score), 10) + " ]") {
|
||||
for _, r := range []rune("[ Score: " + strconv.FormatInt(int64(score.score), 10) + " ]") {
|
||||
screen.SetContent(x, y-1, r, nil, style)
|
||||
x++
|
||||
}
|
||||
|
71
snake.go
71
snake.go
@ -5,8 +5,8 @@ import (
|
||||
)
|
||||
|
||||
// initSnake Initialize the snake
|
||||
func initSnake(snakex *int, snakey *int) Snake {
|
||||
var x, y int = *snakex, *snakey
|
||||
func initSnake(snakex int, snakey int) Snake {
|
||||
var x, y int = snakex, snakey
|
||||
snake := Snake{
|
||||
head: Position{
|
||||
x: x,
|
||||
@ -35,6 +35,8 @@ func initSnake(snakex *int, snakey *int) 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 {
|
||||
@ -43,9 +45,32 @@ func drawSnake(screen tcell.Screen, style tcell.Style, snake *Snake) {
|
||||
// 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 _, segment := range snake.tail {
|
||||
screen.SetContent(segment.x, segment.y, '+', nil, style)
|
||||
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
|
||||
@ -109,3 +134,41 @@ func validateDirection(snake *Snake, direction int) bool {
|
||||
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
|
||||
}
|
||||
|
Reference in New Issue
Block a user