Skip to content

Commit

Permalink
feat(pacman): implement moving, eating
Browse files Browse the repository at this point in the history
  • Loading branch information
ary82 committed Jul 10, 2024
1 parent c39e020 commit c0b2823
Show file tree
Hide file tree
Showing 3 changed files with 141 additions and 13 deletions.
9 changes: 8 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,25 @@ module github.com/ary82/pacman

go 1.22.4

require github.com/charmbracelet/bubbletea v0.26.6
require (
github.com/charmbracelet/bubbletea v0.26.6
github.com/charmbracelet/lipgloss v0.11.0
)

require (
github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect
github.com/charmbracelet/x/ansi v0.1.2 // indirect
github.com/charmbracelet/x/input v0.1.0 // indirect
github.com/charmbracelet/x/term v0.1.1 // indirect
github.com/charmbracelet/x/windows v0.1.0 // indirect
github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f // indirect
github.com/lucasb-eyer/go-colorful v1.2.0 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/mattn/go-localereader v0.0.1 // indirect
github.com/mattn/go-runewidth v0.0.15 // indirect
github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6 // indirect
github.com/muesli/cancelreader v0.2.2 // indirect
github.com/muesli/termenv v0.15.2 // indirect
github.com/rivo/uniseg v0.4.7 // indirect
github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect
golang.org/x/sync v0.7.0 // indirect
Expand Down
11 changes: 11 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
github.com/aymanbagabas/go-osc52/v2 v2.0.1 h1:HwpRHbFMcZLEVr42D4p7XBqjyuxQH5SMiErDT4WkJ2k=
github.com/aymanbagabas/go-osc52/v2 v2.0.1/go.mod h1:uYgXzlJ7ZpABp8OJ+exZzJJhRNQ2ASbcXHWsFqH8hp8=
github.com/charmbracelet/bubbletea v0.26.6 h1:zTCWSuST+3yZYZnVSvbXwKOPRSNZceVeqpzOLN2zq1s=
github.com/charmbracelet/bubbletea v0.26.6/go.mod h1:dz8CWPlfCCGLFbBlTY4N7bjLiyOGDJEnd2Muu7pOWhk=
github.com/charmbracelet/lipgloss v0.11.0 h1:UoAcbQ6Qml8hDwSWs0Y1cB5TEQuZkDPH/ZqwWWYTG4g=
github.com/charmbracelet/lipgloss v0.11.0/go.mod h1:1UdRTH9gYgpcdNN5oBtjbu/IzNKtzVtb7sqN1t9LNn8=
github.com/charmbracelet/x/ansi v0.1.2 h1:6+LR39uG8DE6zAmbu023YlqjJHkYXDF1z36ZwzO4xZY=
github.com/charmbracelet/x/ansi v0.1.2/go.mod h1:dk73KoMTT5AX5BsX0KrqhsTqAnhZZoCBjs7dGWp4Ktw=
github.com/charmbracelet/x/input v0.1.0 h1:TEsGSfZYQyOtp+STIjyBq6tpRaorH0qpwZUj8DavAhQ=
Expand All @@ -10,6 +14,10 @@ github.com/charmbracelet/x/windows v0.1.0 h1:gTaxdvzDM5oMa/I2ZNF7wN78X/atWemG9Wp
github.com/charmbracelet/x/windows v0.1.0/go.mod h1:GLEO/l+lizvFDBPLIOk+49gdX49L9YWMB5t+DZd0jkQ=
github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f h1:Y/CXytFA4m6baUTXGLOoWe4PQhGxaX0KpnayAqC48p4=
github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f/go.mod h1:vw97MGsxSvLiUE2X8qFplwetxpGLQrlU1Q9AUEIzCaM=
github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY=
github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0=
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/mattn/go-localereader v0.0.1 h1:ygSAOl7ZXTx4RdPYinUpg6W99U8jWvWi9Ye2JC/oIi4=
github.com/mattn/go-localereader v0.0.1/go.mod h1:8fBrzywKY7BI3czFoHkuzRoWE9C+EiG4R1k4Cjx5p88=
github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U=
Expand All @@ -18,6 +26,8 @@ github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6 h1:ZK8zHtRHOkbHy6Mmr5D
github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6/go.mod h1:CJlz5H+gyd6CUWT45Oy4q24RdLyn7Md9Vj2/ldJBSIo=
github.com/muesli/cancelreader v0.2.2 h1:3I4Kt4BQjOR54NavqnDogx/MIoWBFa0StPA8ELUXHmA=
github.com/muesli/cancelreader v0.2.2/go.mod h1:3XuTXfFS2VjM+HTLZY9Ak0l6eUKfijIfMUZ4EgX0QYo=
github.com/muesli/termenv v0.15.2 h1:GohcuySI0QmI3wN8Ok9PtKGkgkFIk7y6Vpb5PvrY+Wo=
github.com/muesli/termenv v0.15.2/go.mod h1:Epx+iuz8sNs7mNKhxzH4fWXGNpZwUaJKRS1noLXviQ8=
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ=
github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
Expand All @@ -28,6 +38,7 @@ golang.org/x/exp v0.0.0-20220909182711-5c715a9e8561/go.mod h1:cyybsKvd6eL0RnXn6p
golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M=
golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws=
golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/text v0.3.8 h1:nAL+RVCQ9uMn3vJZbV+MRnydTJFPf8qqY42YiA6MrqY=
Expand Down
134 changes: 122 additions & 12 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,50 @@ package main
import (
"fmt"
"os"
"time"

tea "github.com/charmbracelet/bubbletea"
"github.com/charmbracelet/lipgloss"
)

type model struct {
board [31][28]int
board [31][28]int
lives int
score int
pacman pacman
ghosts [4]ghost
}

type pacman struct {
xPosition int
yPosition int
direction int // 0: static, 1: up, 2: down, 3: left 4: right
}

type ghost struct {
xPosition int
yPosition int
}

type updatePacmanPosition int

const (
blockStr string = "███"
pacmanStr string = " 󰮯 "
ghostStr string = " 󰊠 "
emptyStr string = " "
pelletStr string = " 🞄 "
)

var (
pacmanStyle = lipgloss.NewStyle().Foreground(lipgloss.Color("11"))
blockStyle = lipgloss.NewStyle().Foreground(lipgloss.Color("4"))
blinkyStyle = lipgloss.NewStyle().Foreground(lipgloss.Color("9"))
pinkyStyle = lipgloss.NewStyle().Foreground(lipgloss.Color("13"))
inkyStyle = lipgloss.NewStyle().Foreground(lipgloss.Color("14"))
clydeStyle = lipgloss.NewStyle().Foreground(lipgloss.Color("202"))
)

func initialModel() model {
return model{
board: [31][28]int{
Expand All @@ -26,10 +62,10 @@ func initialModel() model {
{0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0},
{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
{0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 3, 3, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 3, 3, 3, 3, 3, 3, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0},
{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 3, 3, 3, 3, 3, 3, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
{0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 3, 3, 3, 3, 3, 3, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0},
Expand All @@ -46,28 +82,93 @@ func initialModel() model {
{0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0},
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
},
pacman: pacman{
xPosition: 1,
yPosition: 1,
direction: 0,
},
score: 0,
lives: 3,
ghosts: [4]ghost{
{xPosition: 15, yPosition: 12},
{xPosition: 15, yPosition: 13},
{xPosition: 15, yPosition: 14},
{xPosition: 15, yPosition: 15},
},
}
}

func movePacman() tea.Cmd {
return tea.Every(50*time.Millisecond, func(t time.Time) tea.Msg {
return updatePacmanPosition(0)
})
}

func (m model) Init() tea.Cmd {
return nil
return movePacman()
}

func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
switch msg := msg.(type) {
// Is it a key press?
case tea.KeyMsg:

// Cool, what was the actual key pressed?
switch msg.String() {
case "j", "down", "s":
m.pacman.direction = 2
case "k", "up", "w":
m.pacman.direction = 1
case "h", "left", "a":
m.pacman.direction = 3
case "l", "right", "d":
m.pacman.direction = 4

// These keys should exit the program.
case "ctrl+c", "q":
return m, tea.Quit
}

case updatePacmanPosition:
prevX := m.pacman.xPosition
prevY := m.pacman.yPosition
newX := prevX
newY := prevY

switch m.pacman.direction {
case 0:
case 1:
newX -= 1
case 2:
newX += 1
case 3:
newY -= 1
case 4:
newY += 1
}

if newX == 14 && newY == -1 {
newY = 27
}
if newX == 14 && newY == 28 {
newY = 0
}

switch newPosition := m.board[newX][newY]; newPosition {
case 1:
m.score += 1
m.pacman.xPosition = newX
m.pacman.yPosition = newY
m.board[prevX][prevY] = 3
m.board[newX][newY] = 2
case 3:
m.pacman.xPosition = newX
m.pacman.yPosition = newY
m.board[prevX][prevY] = 3
m.board[newX][newY] = 2
}
return m, movePacman()
}

// Return the updated model to the Bubble Tea runtime for processing.
// Note that we're not returning a command.
return m, nil
}

Expand All @@ -78,20 +179,29 @@ func (m model) View() string {
for _, num := range v {
switch num {
case 0:
s += "███"
s += blockStyle.Render(blockStr)
case 1:
s += " 🞄 "
s += pelletStr
case 2:
s += pacmanStyle.Render(pacmanStr)
case 3:
s += emptyStr
}
}
s += "\n"
}
s += fmt.Sprintf("direction: %v\n", m.pacman.direction)
s += fmt.Sprintf("score: %v\n", m.score)
s += fmt.Sprintf("xPosition: %v\n", m.pacman.xPosition)
s += fmt.Sprintf("yPosition: %v\n", m.pacman.yPosition)

// Send the UI for rendering
return s
}

func main() {
p := tea.NewProgram(initialModel())
model := initialModel()
p := tea.NewProgram(model)
if _, err := p.Run(); err != nil {
fmt.Printf("error: %v", err)
os.Exit(1)
Expand Down

0 comments on commit c0b2823

Please sign in to comment.