diff options
author | Guillermo Ramos | 2021-04-05 10:55:35 +0200 |
---|---|---|
committer | Guillermo Ramos | 2021-04-05 10:55:35 +0200 |
commit | 27abcd076bd4af77ab51fcc7701d59cac260f9e9 (patch) | |
tree | de33ef17645a3749ebd54dcec8f791160f0f266c /cmd/gosnake.go | |
parent | aaffd2ad23293a99ea85c4a67b62058c71d9746a (diff) | |
download | gosnake-27abcd076bd4af77ab51fcc7701d59cac260f9e9.tar.gz |
Improve directory structure
Diffstat (limited to 'cmd/gosnake.go')
-rw-r--r-- | cmd/gosnake.go | 188 |
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) - } -} |