package v1 import ( "math/rand/v2" "net/http" "time" "github.com/gin-gonic/gin" "jp.wtf/go-fishing/internal/api" ) var sayings = []string{ // Near Misses "Close but no cigar", "Almost only counts in horseshoes and hand grenades", "A day late and a dollar short", "A miss is as good as a mile", "Always a bridesmaid, never a bride", "Snatched defeat from the jaws of victory", "Fell at the last hurdle", "Missed the boat", "Missed it by a whisker", "So near, and yet so far", "A swing and a miss", // Futile Efforts "Beating a dead horse", "Tilting at windmills", "Squeezing blood from a stone", "Nailing jelly to a wall", "Herding cats", "Rearranging deck chairs on the Titanic", "Pushing a rope", "Spitting in the wind", "Putting toothpaste back in the tube", "Shoveling snow in a blizzard", "Spinning your wheels", "Emptying the ocean with a teaspoon", "Barking up the wrong tree", "A wild goose chase", "Catching the wind in a net", } func (h *V1Router) Cast(c *gin.Context) { angler, err := api.GetAnglerFromSession(c) if err != nil { api.Fail(c, http.StatusInternalServerError, api.APIErrorCodeUnknown, err.Error()) return } is_casting, check_err := h.DB.IsCasting(angler.ID) if check_err != nil { api.Fail(c, http.StatusInternalServerError, api.APIErrorCodeUnknown, "Unable to check for existing cast") return } if is_casting { api.Fail(c, http.StatusBadRequest, api.APIErrorCodeInvalidRequest, "You are already casting! >:|") return } cast, cast_create_err := h.DB.CreateNewCast(angler.ID) if cast_create_err != nil { api.Fail(c, http.StatusInternalServerError, api.APIErrorCodeUnknown, "Unable to start your cast") return } // Fishing can take anywhere from 2-5 seconds minTime, maxTime := 2, 5 timeToWait := rand.IntN(maxTime-minTime+1) + minTime select { case <-time.After(time.Duration(timeToWait) * time.Second): // One we complete fishing we must decide if we caught anything chance := 75 gen := rand.IntN(100) caught := gen < chance _, end_cast_err := h.DB.EndCastByID(cast.ID) if end_cast_err != nil { api.Fail(c, http.StatusInternalServerError, api.APIErrorCodeUnknown, "Unable to update your cast — may have left you in a bad state :(") return } if caught { // If so then we must select a fish. // Then we must determine a size between the min and max of said fish // Finally record the catch and return it api.OK(c, "Got one! Nice!") } else { // Otherwise return. You are left empty handed api.Fail(c, http.StatusNotFound, api.APIErrorCodeNotFound, sayings[rand.IntN(len(sayings))]) } case <-c.Done(): _, end_cast_err := h.DB.EndCastByID(cast.ID) if end_cast_err != nil { api.Fail(c, http.StatusInternalServerError, api.APIErrorCodeUnknown, "Unable to update your cast — may have left you in a bad state :(") return } api.Fail(c, http.StatusRequestTimeout, api.APIErrorCodeUnknown, "Cast terminiated for unknown reason") } }