diff --git a/button.go b/button.go new file mode 100644 index 0000000..048b0fc --- /dev/null +++ b/button.go @@ -0,0 +1,25 @@ +package main + +import "github.com/maxence-charriere/go-app/v9/pkg/app" + +type button struct { + app.Compo + + id int64 +} + +func NewButton(id int64) *button { + return &button{ + id: id, + } +} + +func (b *button) Render() app.UI { + return app.Button(). + Class("simon-button"). + Body(app.Span().Text("")). + ID("button%d", b.id). + OnClick(func(ctx app.Context, _ app.Event) { + ctx.NewActionWithValue(click, b.id) + }) +} diff --git a/logic.go b/logic.go deleted file mode 100644 index 914914c..0000000 --- a/logic.go +++ /dev/null @@ -1,57 +0,0 @@ -package main - -import ( - "crypto/rand" - "fmt" - "math/big" - "slices" - - "github.com/maxence-charriere/go-app/v9/pkg/app" -) - -func NewSimonSaysLogic() *simonSaysLogic { - return &simonSaysLogic{ - sequence: GenerateSequence(4), - clicks: []int64{}, - } -} - -type simonSaysLogic struct { - sequence []int64 - clicks []int64 -} - -func (s *simonSaysLogic) handleClick(_ app.Context, a app.Action) { - click, ok := a.Value.(int64) - if !ok { - fmt.Println("wrong type") - return - } - - fmt.Println("clicked button:", click) - s.clicks = append(s.clicks, click) - if len(s.clicks) == 4 { - if slices.Equal(s.sequence, s.clicks) { - fmt.Println("YOU WIN!") - } else { - fmt.Println("YOU LOSE!") - } - fmt.Println("RESTART") - s.clicks = []int64{} - s.sequence = GenerateSequence(4) - } -} - -func GenerateSequence(l int) []int64 { - seq := []int64{} - for i := 0; i < l; i++ { - n, err := rand.Int(rand.Reader, big.NewInt(4)) - if err != nil { - panic(err) - } - seq = append(seq, n.Int64()) - - } - fmt.Println("sequence:", seq) - return seq -} diff --git a/main.go b/main.go index 0436ff6..85e8c39 100644 --- a/main.go +++ b/main.go @@ -12,11 +12,10 @@ func main() { serve := flag.Bool("serve", false, "set serve to serve instead of generating resources") flag.Parse() - logic := NewSimonSaysLogic() - app.Handle(click, logic.handleClick) + g := NewGame() + app.Route("/", g) - ui := NewSimonSaysUI() - app.Route("/", ui) + app.Handle(click, g.handleClick) // When executed on the client-side, the RunWhenOnBrowser() function // launches the app, starting a loop that listens for app events and diff --git a/styles.css b/styles.css index 1483c23..cae18f9 100644 --- a/styles.css +++ b/styles.css @@ -25,6 +25,7 @@ html, body { height: 400px; } +/* button */ .simon-button:nth-of-type(1) { background-image: linear-gradient(144deg, rgba(163,163,0,1) 0%, rgba(254,255,0,1) 50%, rgba(251,251,160,1) 100%); } @@ -32,6 +33,7 @@ html, body { .simon-button:nth-of-type(2) { background-image: linear-gradient(144deg, rgba(200,1,1,1) 0%, rgba(255,0,86,1) 50%, rgba(116,0,43,1) 100%); } + .simon-button:nth-of-type(3) { background-image: linear-gradient(144deg, rgba(0,69,255,1) 0%, rgba(73,82,140,1) 50%, rgba(4,0,116,1) 100%); } @@ -40,7 +42,6 @@ html, body { background-image: linear-gradient(144deg, rgba(60,232,54,1) 0%, rgba(73,140,83,1) 50%, rgba(0,116,23,1) 100%); } -/* button */ .simon-button { align-items: center; border: 0; @@ -64,8 +65,8 @@ html, body { cursor: pointer; } -.simon-button:active { - outline: 0; +.simon-button:active span { + background: none; } .simon-button span { @@ -77,8 +78,8 @@ html, body { transition: 300ms; } -.simon-button:hover span { - background: none; +.simon-button.current span { + background-color: #D0D0D0; } @media (min-width: 768px) { diff --git a/ui.go b/ui.go index ee8fafa..f8c7452 100644 --- a/ui.go +++ b/ui.go @@ -1,58 +1,117 @@ package main import ( + "crypto/rand" + "fmt" + "math/big" + "time" + "github.com/maxence-charriere/go-app/v9/pkg/app" ) type events = string const ( - click events = "click" + click events = "click" + playSequence events = "playSequence" ) -func NewSimonSaysUI() *simonSaysUI { - return &simonSaysUI{} +func NewGame() *game { + return &game{ + buttonIds: []string{ + "firstButton", + "secondButton", + "thirdButton", + "fourthButton", + }, + sequence: GenerateSequence(4), + } } -type simonSaysUI struct { +type game struct { app.Compo + + buttonIds []string + sequence []int64 + clicks int +} + +func (h *game) OnMount(ctx app.Context) { + ctx.Handle(playSequence, h.playSequence) } -func (h *simonSaysUI) Render() app.UI { - t := app.Div().Class("game-field") - - t.Body( - app.Button(). - Class("simon-button"). - Body(app.Span().Text("")).OnClick(h.onClickFirst), - app.Button(). - Class("simon-button"). - Body(app.Span().Text("")).OnClick(h.onClickSecond), - app.Button(). - Class("simon-button"). - Body(app.Span().Text("")).OnClick(h.onClickThird), - app.Button(). - Class("simon-button"). - Body(app.Span().Text("")).OnClick(h.onClickFourth), +func (h *game) Render() app.UI { + gameField := app.Div().Class("game-field") + + firstButton := NewButton(0) + secondButton := NewButton(1) + thirdButton := NewButton(2) + fourthButton := NewButton(3) + + gameField.Body( + firstButton, + secondButton, + thirdButton, + fourthButton, ) return app.Div().Class("fill", "background").Body( - t, + gameField, + app.Button().Text("New Game").OnClick(h.handleNewGame), ) } -func (h *simonSaysUI) onClickFirst(ctx app.Context, e app.Event) { - ctx.NewActionWithValue(click, int64(0)) +func (h *game) playSequence(ctx app.Context, a app.Action) { + sequence, ok := a.Value.([]int64) + if !ok { + fmt.Println("wrong type") + return + } + fmt.Println("sequence:", sequence) + for _, btnIndex := range sequence { + btn := app.Window().GetElementByID(h.buttonIds[btnIndex]) + fmt.Println(btn) + ctx.After(time.Second, func(ctx app.Context) { + }) + } } -func (h *simonSaysUI) onClickSecond(ctx app.Context, e app.Event) { - ctx.NewActionWithValue(click, int64(1)) +func (s *game) handleNewGame(ctx app.Context, a app.Event) { + fmt.Println("New Game") } -func (h *simonSaysUI) onClickThird(ctx app.Context, e app.Event) { - ctx.NewActionWithValue(click, int64(2)) +func (s *game) handleClick(_ app.Context, a app.Action) { + click, ok := a.Value.(int64) + if !ok { + fmt.Println("wrong type") + return + } + + fmt.Println("received click:", click) + if s.sequence[s.clicks] != click { + fmt.Println("YOU LOSE!") + s.clicks = 0 + s.sequence = GenerateSequence(4) + return + } + s.clicks++ + if len(s.sequence) == s.clicks { + fmt.Println("YOU WIN!") + s.clicks = 0 + s.sequence = GenerateSequence(4) + } } -func (h *simonSaysUI) onClickFourth(ctx app.Context, e app.Event) { - ctx.NewActionWithValue(click, int64(3)) +func GenerateSequence(l int) []int64 { + seq := []int64{} + for i := 0; i < l; i++ { + n, err := rand.Int(rand.Reader, big.NewInt(4)) + if err != nil { + panic(err) + } + seq = append(seq, n.Int64()) + + } + fmt.Println(seq) + return seq }