diff --git a/cmd/server/main.go b/cmd/server/main.go index 72a9e39..ecb6ce3 100644 --- a/cmd/server/main.go +++ b/cmd/server/main.go @@ -34,6 +34,7 @@ func main() { // --- DI 配線(ここだけが全層を組み立てる) --- s := server.New(cfg, server.Handlers{ Health: handler.NewHealthHandler(database), + Janken: handler.NewGameHandler(database), }) log.Fatal(s.Serve(cfg.Port)) } diff --git a/internal/handler/janken.go b/internal/handler/janken.go new file mode 100644 index 0000000..6326184 --- /dev/null +++ b/internal/handler/janken.go @@ -0,0 +1,83 @@ +package handler + +import ( + "database/sql" + "fmt" + "math/rand" + "net/http" + + "github.com/labstack/echo/v5" +) + +var winningMap = map[string]string{ + "rock": "scissors", + "scissors": "paper", + "paper": "rock", +} + +type GameHandler struct { + db *sql.DB +} + +func NewGameHandler(db *sql.DB) *GameHandler { + return &GameHandler{db: db} +} + +// リクエストボディの構造体 +type PlayGameRequest struct { + UserHand string `json:"user_hand"` // "rock", "scissors", "paper" +} + +// 200 OK: 成功時のレスポンス +type PlayGameResponse struct { + Result string `json:"result"` // "win", "lose", "draw" + CPUHand string `json:"cpu_hand"` // "rock", "scissors", "paper" +} + +// PlayGame godoc +// @Summary じゃんけんを実行する +// @Description ユーザーの手を受け取って、CPUとのじゃんけん対戦の結果を返してくれるAPI +// @Accept json +// @Produce json +// @Param request body PlayGameRequest true "ユーザーの手" +// @Success 200 {object} PlayGameResponse +// @Failure 400 {object} map[string]string +// @Router /janken [post] +func (g *GameHandler) PlayGame(c *echo.Context) error { + // ユーザーの手を読み込む + var req PlayGameRequest + if err := c.Bind(&req); err != nil { + fmt.Println(err) + return c.JSON(http.StatusBadRequest, map[string]string{"error": "リクエストが不正です", "cause": err.Error()}) + } + + // rock, scissors, paper以外を弾く + if _, exists := winningMap[req.UserHand]; !exists { + return c.JSON(http.StatusBadRequest, map[string]string{"error": "rock, scissors, paperのいずれかを送信してください"}) + } + + // CPUの手をランダムに決める + hands := []string{"rock", "scissors", "paper"} + cpuHand := hands[rand.Intn(3)] + + // 勝敗を判定する + result := getMatchResult(req.UserHand, cpuHand) + + // JSONで結果を返す + res := PlayGameResponse{ + Result: result, + CPUHand: cpuHand, + } + return c.JSON(http.StatusOK, res) +} + +func getMatchResult(userHand, cpuHand string) string { + ans := "lose" + + if userHand == cpuHand { + ans = "draw" + } else if winningMap[userHand] == cpuHand { + ans = "win" + } + return ans +} diff --git a/internal/server/server.go b/internal/server/server.go index 2f5f8cd..515eca1 100644 --- a/internal/server/server.go +++ b/internal/server/server.go @@ -12,6 +12,7 @@ import ( type Handlers struct { Health *handler.HealthHandler + Janken *handler.GameHandler } type Server struct { @@ -32,6 +33,7 @@ func New(cfg config.Config, h Handlers) *Server { func registerRoutes(e *echo.Echo, h Handlers) { e.GET("/health", h.Health.Health) e.GET("/health/db", h.Health.DBHealth) + e.POST("/janken", h.Janken.PlayGame) // OpenAPI 3.x (swag v2) 用の Swagger UI e.GET("/swagger/*", echoSwagger.WrapHandlerV3)