Compare commits

...

6 Commits

8 changed files with 107 additions and 30 deletions

1
.gitignore vendored Normal file
View File

@ -0,0 +1 @@
builds

18
.pre-commit-config.yaml Normal file
View File

@ -0,0 +1,18 @@
# See https://pre-commit.com for more information
# See https://pre-commit.com/hooks.html for more hooks
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v5.0.0
hooks:
- id: trailing-whitespace
- id: end-of-file-fixer
- id: check-yaml
- id: check-added-large-files
- repo: https://github.com/dnephin/pre-commit-golang
rev: v0.5.1
hooks:
- id: go-fmt
- id: go-imports
- id: no-go-testing
- id: golangci-lint
- id: go-unit-tests

28
Taskfile.dist.yaml Normal file
View File

@ -0,0 +1,28 @@
version: '3'
vars:
APP: snake
BUILD_DIR: builds
tasks:
default:
cmds:
- go run .
build:
cmds:
- mkdir -p {{.BUILD_DIR}}
- rm {{.BUILD_DIR}}/* || true
- go tool dist list | grep -v android | grep -v ios | grep -v wasip1 | awk -F '/' '{printf "echo Compiling %s/%s; env CGO_ENABLED=1 GOOS=%s GOARCH=%s go build -o {{.BUILD_DIR}}/{{.APP}}.%s-%s\n",$1,$2,$1,$2,$1,$2 }' | sh
- for i in `ls {{.BUILD_DIR}}/*windows*`; do mv -v $i $i.exe; done
lint:
cmds:
- golangci-lint run
precommit:
cmds:
- pre-commit autoupdate
- pre-commit run --all
silent: true
gource:
cmds:
- gource --auto-skip-seconds 1 --key -r 60
silent: true

24
game.go
View File

@ -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
}
@ -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
View File

@ -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")
}
}

View File

@ -7,22 +7,26 @@ 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) + " ]") {
screen.SetContent(x, y-1, r, nil, style)
content := "[ Score: " + strconv.FormatInt(int64(score.score), 10) + " ]"
for i := 0; i < len(content); i++ {
screen.SetContent(x, y-1, rune(content[i]), nil, style)
x++
}
}
// drawCoords Print the coordinates of the head of the snake
func drawCoords(screen tcell.Screen, style tcell.Style, snake *Snake) {
var x, y int = 25, 24
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 drawCoords(screen tcell.Screen, style tcell.Style, snake *Snake) {
// var x, y int = 25, 24
// var snakex int = *&snake.head.x
// var snakey int = *&snake.head.y
// content := "[ x:" + strconv.Itoa(snakex) + " y: " + strconv.Itoa(snakey) + " ]"
// for i := 0; i < len(content); i++ {
// screen.SetContent(x, y-1, rune(content[i]), nil, style)
// x++
// }
// }
// drawBox Draw the outline of the box the snake can move in
func drawBox(s tcell.Screen, style tcell.Style, x1, y1, x2, y2 int) {

View File

@ -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,
@ -14,7 +14,7 @@ func initSnake(snakex *int, snakey *int) Snake {
},
tail: []Position{
{
x: x - 1,
x: x - 3,
y: y,
},
{
@ -22,7 +22,7 @@ func initSnake(snakex *int, snakey *int) Snake {
y: y,
},
{
x: x - 3,
x: x - 1,
y: y,
},
},

View File

@ -20,3 +20,9 @@ type Snake struct {
length int
direction int
}
type Score struct {
score int
scoreCounter int
reason int
}