aboutsummaryrefslogtreecommitdiff
path: root/cmd/gosnake.go
diff options
context:
space:
mode:
authorGuillermo Ramos2021-04-05 10:55:35 +0200
committerGuillermo Ramos2021-04-05 10:55:35 +0200
commit27abcd076bd4af77ab51fcc7701d59cac260f9e9 (patch)
treede33ef17645a3749ebd54dcec8f791160f0f266c /cmd/gosnake.go
parentaaffd2ad23293a99ea85c4a67b62058c71d9746a (diff)
downloadgosnake-27abcd076bd4af77ab51fcc7701d59cac260f9e9.tar.gz
Improve directory structure
Diffstat (limited to 'cmd/gosnake.go')
-rw-r--r--cmd/gosnake.go188
1 files changed, 0 insertions, 188 deletions
diff --git a/cmd/gosnake.go b/cmd/gosnake.go
deleted file mode 100644
index 3d77877..0000000
--- a/cmd/gosnake.go
+++ /dev/null
@@ -1,188 +0,0 @@
-package main
-
-import (
- "bytes"
- "fmt"
- tea "github.com/charmbracelet/bubbletea"
- "math/rand"
- "os"
- "time"
-)
-
-type point struct {
- x, y int
-}
-
-type direction int
-
-const (
- up = iota
- right
- down
- left
-)
-
-func (d direction) toByte() byte {
- return []byte{'^', '>', 'v', '<'}[d]
-}
-
-type tickMsg time.Time
-
-type model struct {
- dx, dy int
- head point
- tail []point
- maxLen int
- dir, newDir direction
- food point
- points int
-}
-
-func (m model) toOffset(p point) int {
- return p.y*(m.dx+1) + p.x
-}
-
-func (m model) isEmpty(p point) bool {
- // Check collision with head
- if p == m.head {
- return false
- }
-
- // Check collision with borders
- if p.x < 0 || p.x >= m.dx || p.y < 0 || p.y >= m.dy {
- return false
- }
-
- // Check collision with tail
- for _, t := range m.tail {
- if p == t {
- return false
- }
- }
-
- return true
-}
-
-func (m model) randFood() point {
- candidate := point{x: rand.Intn(m.dx), y: rand.Intn(m.dy)}
- for !m.isEmpty(candidate) {
- candidate = point{x: rand.Intn(m.dx), y: rand.Intn(m.dy)}
- }
- return candidate
-}
-
-func initialModel() model {
- m := model{
- dx: 20,
- dy: 10,
- head: point{1, 1},
- tail: make([]point, 0, 10),
- maxLen: 5,
- dir: right,
- newDir: right,
- points: 0,
- }
- m.food = m.randFood()
- return m
-}
-
-func tickCmd(points int) func() tea.Msg {
- base := 300
- scaled := base - (10 * points)
- return tea.Tick(time.Millisecond*time.Duration(scaled), func(t time.Time) tea.Msg {
- return tickMsg(t)
- })
-}
-
-func (m model) Init() tea.Cmd {
- return tickCmd(m.points)
-}
-
-func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
- switch msg := msg.(type) {
- case tea.KeyMsg:
- var newDir direction
- switch msg.String() {
- case "ctrl+c":
- return m, tea.Quit
- case "up", "k":
- newDir = up
- case "right", "l":
- newDir = right
- case "down", "j":
- newDir = down
- case "left", "h":
- newDir = left
- }
-
- // Prevent from going in the reverse direction
- if (newDir+2)%4 != m.dir {
- m.newDir = newDir
- }
-
- case tickMsg:
- // Calculate new head position
- var newHead point
- switch m.newDir {
- case up:
- newHead = point{m.head.x, m.head.y - 1}
- case right:
- newHead = point{m.head.x + 1, m.head.y}
- case down:
- newHead = point{m.head.x, m.head.y + 1}
- case left:
- newHead = point{m.head.x - 1, m.head.y}
- }
- m.dir = m.newDir
-
- if !m.isEmpty(newHead) {
- fmt.Println("DEP, siempre saludaba.")
- return m, tea.Quit
- }
-
- // Good to go; update head and tail
- m.tail = append(m.tail, m.head)
- if len(m.tail) >= m.maxLen {
- m.tail = m.tail[1:]
- }
- m.head = newHead
-
- // Finally, when the snake eats the food:
- if m.head == m.food {
- m.food = m.randFood()
- m.maxLen += 1
- m.points += 1
- }
-
- return m, tickCmd(m.points)
- }
- return m, nil
-}
-
-func (m model) View() string {
- // Generate board
- row := append(bytes.Repeat([]byte{'-'}, m.dx), '\n')
- board := bytes.Repeat(row, m.dy)
-
- // Draw head
- board[m.toOffset(m.head)] = m.dir.toByte()
-
- // Draw tail
- for _, p := range m.tail {
- board[m.toOffset(p)] = '#'
- }
-
- // Draw food
- board[m.toOffset(m.food)] = 'o'
-
- return fmt.Sprintf("%s\nPoints: %d\n", string(board), m.points)
-}
-
-func main() {
- rand.Seed(time.Now().UnixNano())
- p := tea.NewProgram(initialModel())
- if err := p.Start(); err != nil {
- fmt.Println(err)
- os.Exit(1)
- }
-}