Skip to content

Commit

Permalink
feat: add game details page
Browse files Browse the repository at this point in the history
  • Loading branch information
Tarow committed Dec 23, 2023
1 parent f25a5b1 commit 33e89c5
Show file tree
Hide file tree
Showing 18 changed files with 765 additions and 143 deletions.
8 changes: 6 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,12 @@ module github.com/tarow/skat-counter
go 1.21.5

require (
github.com/a-h/templ v0.2.476 // indirect
github.com/labstack/echo/v4 v4.11.4 // indirect
github.com/a-h/templ v0.2.476
github.com/google/uuid v1.5.0
github.com/labstack/echo/v4 v4.11.4
)

require (
github.com/labstack/gommon v0.4.2 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
Expand Down
12 changes: 12 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
github.com/a-h/templ v0.2.476 h1:+H4hP4CwK4kfJwXsE6kHeFWMGtcVOVoOm/I64uzARBk=
github.com/a-h/templ v0.2.476/go.mod h1:zQ95mSyadNTGHv6k5Fm+wQU8zkBMMbHCHg7eAvUZKNM=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/uuid v1.5.0 h1:1p67kYwdtXjb0gL0BPiP1Av9wiZPo5A8z2cWkTZ+eyU=
github.com/google/uuid v1.5.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/labstack/echo/v4 v4.11.4 h1:vDZmA+qNeh1pd/cCkEicDMrjtrnMGQ1QFI9gWN1zGq8=
github.com/labstack/echo/v4 v4.11.4/go.mod h1:noh7EvLwqDsmh/X/HWKPUl1AjzJrhyptRyEbQJfxen8=
github.com/labstack/gommon v0.4.2 h1:F8qTUNXgG1+6WQmqoUWnz8WiEU60mXVVw0P4ht1WRA0=
Expand All @@ -9,6 +15,10 @@ github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovk
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
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/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
github.com/valyala/fasttemplate v1.2.2 h1:lxLXG0uE3Qnshl9QyaK6XJxMXlQZELvChBOCmQD0Loo=
Expand All @@ -23,3 +33,5 @@ golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc=
golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
77 changes: 75 additions & 2 deletions internal/api/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package skat

import (
"context"
"fmt"
"net/http"
"strconv"

Expand Down Expand Up @@ -35,16 +36,88 @@ func (h Handler) GetGameDetails(c echo.Context) error {
return err
}

game, err := h.service.Find(parsedId)
game := h.service.Find(parsedId)
if err != nil {
return err
}

gameDetails := template.GameDetails(game)
gameDetails := template.GameDetails(*game)

return render(c, http.StatusOK, gameDetails)
}

func (h Handler) CreateGame(c echo.Context) error {
g := skat.Game{}
c.Bind(&g)
fmt.Println("received game", g)
g = h.service.Create(g)
fmt.Println("created game", g)
details := template.GameDetails(g)

c.Response().Header().Set("Access-Control-Expose-Headers", "*")
//c.Response().Header().Set("Access-Control-Allow-Origin", "*")
//c.Response().Header().Set("Access-Control-Allow-Headers", "*")
c.Response().Header().Set("HX-Push-Url", fmt.Sprintf("/games/%v", g.Id))

return render(c, http.StatusCreated, details)
}

func (h Handler) AddRound(c echo.Context) error {
gameId := c.Param("id")
parsedId, err := strconv.Atoi(gameId)
if err != nil {
return err
}

game := h.service.Find(parsedId)
if err != nil {
return err
}
fmt.Printf("rounds before: %+v", len(game.Rounds))
var params map[string]string = make(map[string]string)
c.Bind(&params)

round := skat.Round{}
for _, player := range game.Players {
role, exists := params[player]
if !exists {
continue
}

switch role {
case "declarer":
round.Declarer = player
case "opponent":
round.Opponents = append(round.Opponents, player)
case "dealer":
round.Dealer = player
}
}

wonStr, exists := params["won"]
if exists {
won, err := strconv.ParseBool(wonStr)
if err != nil {
return err
}
round.Won = won
}

gameValueStr, exists := params["gamevalue"]
if exists {
gameValue, err := strconv.Atoi(gameValueStr)
if err != nil {
return err
}
round.Value = gameValue
}

game.Rounds = append(game.Rounds, round)
fmt.Printf("rounds after: %+v", len(game.Rounds))
gameDetails := template.GameDetails(*game)
return render(c, http.StatusCreated, gameDetails)
}

func (h Handler) GetCreateGameForm(c echo.Context) error {
form := components.CreateGameForm()
return render(c, http.StatusOK, form)
Expand Down
59 changes: 24 additions & 35 deletions internal/skat/service.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package skat

import (
"fmt"
"math/rand"
"time"
)

Expand All @@ -12,62 +12,51 @@ func NewService() Service {
return Service{}
}

var db = []Game{
var DB = []Game{
{
Id: 0,
Active: false,
Started: time.Now().AddDate(0, 0, -1),
Stake: 2,
Ended: nil,
Players: []string{"Jannik", "Moritz", "Manuel", "Niklas"},
Online: false,
Rounds: []Round{
{
Dealer: "Niklas",
Dealer: "Jannik",
Declarer: "Moritz",
Opponents: []string{"Jannik", "Manuel"},
Opponents: []string{"Niklas", "Manuel"},
Won: true,
Value: 24,
},
{
Dealer: "Niklas",
Declarer: "Moritz",
Opponents: []string{"Jannik", "Manuel"},
Won: false,
},
},
},
{
Id: 1,
Active: true,
Started: time.Now(),
Ended: nil,
Players: []string{"Jannik", "Moritz", "Manuel", "Niklas"},
Online: true,
Rounds: []Round{
{
Dealer: "Niklas",
Declarer: "Moritz",
Opponents: []string{"Jannik", "Manuel"},
Won: true,
},
{
Dealer: "Niklas",
Declarer: "Moritz",
Opponents: []string{"Jannik", "Manuel"},
Dealer: "Moritz",
Declarer: "Manuel",
Opponents: []string{"Jannik", "Niklas"},
Won: false,
Value: 24,
},
},
},
}

func (s Service) List() []Game {
return db
return DB
}

func (s Service) Find(gameId int) (Game, error) {
for _, e := range db {
func (s Service) Find(gameId int) *Game {
for i, e := range DB {
if gameId == e.Id {
return e, nil
return &DB[i]
}
}
return Game{}, fmt.Errorf("no game found with id %v", gameId)
return nil
}

func (s Service) Create(g Game) Game {
g.Id = rand.Intn(100)
g.Started = time.Now()
g.Ended = nil

DB = append(DB, g)
return g
}
63 changes: 57 additions & 6 deletions internal/skat/skat.go
Original file line number Diff line number Diff line change
@@ -1,25 +1,76 @@
package skat

import "time"
import (
"slices"
"time"
)

type Game struct {
Id int
Active bool
Started time.Time
Ended *time.Time
Players []string
Rounds []Round
Online bool
Stake float32 `form:"stake"`
Players []string `form:"player"`
Rounds []Round `form:"round"`
Online bool `form:"online"`
}

type Round struct {
Dealer string
Declarer string
Opponents []string
Won bool
Points uint
Value int
}

func (g Game) IsActive() bool {
return g.Ended == nil || g.Ended.After(time.Now())
}

func (g Game) GetDate() string {
return g.Started.Format("Monday, 02.01.2006")
}

func (g Game) GetTotalPlayerScore(player string) int {
sum := 0
for _, r := range g.Rounds {
roundScore := r.GetRoundScore(player)
if roundScore != nil {
sum += *roundScore
}
}
return sum
}

func (g Game) GetTotalPayment() float32 {
sum := 0
for _, player := range g.Players {
sum += g.GetTotalPlayerScore(player)
}

return float32(sum) * g.Stake
}

func (r Round) GetRoundScore(player string) *int {
if player == r.Declarer {
if r.Won {
return intPtr(0)
} else {
return intPtr(2 * r.Value)
}
}

if slices.Contains(r.Opponents, player) {
if r.Won {
return &r.Value
} else {
return intPtr(0)
}
}

return nil
}

func intPtr(i int) *int {
return &i
}
14 changes: 2 additions & 12 deletions main.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
package main

import (
"fmt"

"github.com/labstack/echo/v4"
api "github.com/tarow/skat-counter/internal/api"
"github.com/tarow/skat-counter/internal/skat"
Expand All @@ -25,16 +23,8 @@ func registerRoutes(e *echo.Echo, handler api.Handler) {
e.Static("/static", "./static")
e.GET("/", handler.GetIndex)

e.POST("/games", handler.CreateGame)
e.GET("/games/:id", handler.GetGameDetails)
e.GET("/games/create", handler.GetCreateGameForm)

e.Any("/test", func(c echo.Context) error {
//body, _ := io.ReadAll(c.Request().Body)
//fmt.Printf("received request on test endpoint: %v\n", string(body))
e.POST("/games/:id/rounds", handler.AddRound)

f := Form{}
c.Bind(&f)
fmt.Printf("Received form: %+v\n", f)
return nil
})
}
12 changes: 9 additions & 3 deletions templates/GameDetails.templ
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package template

import "github.com/tarow/skat-counter/internal/skat"
import "fmt"
import "github.com/tarow/skat-counter/templates/components"

templ GameDetailsNavbar() {
<div class="navbar bg-base-200">
Expand All @@ -16,8 +16,14 @@ templ GameDetailsNavbar() {
templ GameDetails (game skat.Game) {
@Base() {
@GameDetailsNavbar()
<div>
Details for Game with id { fmt.Sprintf("%v", game.Id) }
<div class="container flex pt-4 mx-auto">
<div class="flex w-full flex-row flex-wrap-reverse gap-8 justify-around items-end">
@components.RoundsList(game)
<div class="flex flex-col items-center gap-4">
@components.Game(game, false)
@components.AddRoundForm(game)
</div>
</div>
</div>
}
}
Loading

0 comments on commit 33e89c5

Please sign in to comment.