Skip to content

Commit

Permalink
Merge pull request #5 from iamananya/ananya
Browse files Browse the repository at this point in the history
character api added
  • Loading branch information
GuiltyMorishita authored May 29, 2023
2 parents b34b394 + 3e98fde commit fe2ed5f
Show file tree
Hide file tree
Showing 4 changed files with 221 additions and 77 deletions.
Binary file modified cmd/main/main
Binary file not shown.
153 changes: 102 additions & 51 deletions pkg/controllers/gacha-controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,63 +5,33 @@ import (
"fmt"
"io/ioutil"
"net/http"
"strconv"

"github.com/gorilla/mux"
"github.com/iamananya/ginco-task/pkg/models"
"github.com/iamananya/ginco-task/pkg/utils"
)

var NewUser models.User

/*
TODO----(Task completed)
[*] Handle case for empty name- return error (Error code 400), non exisiting user ID return error
[*] Autogenerate Token Don't take it from user
[*] For UpdateUser don't show response
[*] Check swagger yaml for responses.
*/
var NewCharacter models.Character

func GetUser(w http.ResponseWriter, r *http.Request) {
newUsers := models.GetAllUsers()
res, _ := json.Marshal(newUsers)
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusOK)
w.Write(res)
}
// Authenticate user using x-token in headers to get user details-----
token := r.Header.Get("X-Token")
user := models.GetAllUsers(token)

func GetUserById(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
userId := vars["userId"]
ID, err := strconv.ParseInt(userId, 0, 0)
if err != nil {
fmt.Println("error while parsing")
w.WriteHeader(http.StatusBadRequest)
return
}
// Invalid ID error handling done here

userDetails, db := models.GetUserById(ID)
if db.Error != nil {
if db.RecordNotFound() {
w.WriteHeader(http.StatusNotFound)
} else {
w.WriteHeader(http.StatusInternalServerError)
}
if user == nil {
w.WriteHeader(http.StatusNotFound)
return
}

res, err := json.Marshal(userDetails)
res, err := json.Marshal(user)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
return
}

w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusOK)
w.Write(res)

}

func CreateUser(w http.ResponseWriter, r *http.Request) {
Expand Down Expand Up @@ -97,26 +67,107 @@ func CreateUser(w http.ResponseWriter, r *http.Request) {

}

// UpdateUser does not show any reponse.

func UpdateUser(w http.ResponseWriter, r *http.Request) {
var updateUser = &models.User{}
utils.ParseBody(r, updateUser)
vars := mux.Vars(r)
userId := vars["userId"]
ID, err := strconv.ParseInt(userId, 0, 0)
if err != nil {
fmt.Println("error while parsing")
// Authenticate user using x-token in headers to get user details--------

var updateUser models.User
utils.ParseBody(r, &updateUser)
token := r.Header.Get("X-Token")
user := models.GetUserByToken(token)
fmt.Print(user)

if user == nil {
w.WriteHeader(http.StatusNotFound)
return
}
userDetails, db := models.GetUserById(ID)

if updateUser.Name != "" {
userDetails.Name = updateUser.Name
user[0].Name = updateUser.Name
}
if updateUser.Token != "" {
userDetails.Token = updateUser.Token
user[0].Token = updateUser.Token
}

err := models.UpdateUser(&user[0])
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
return
}

w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusOK)
}

func ListCharacters(w http.ResponseWriter, r *http.Request) {

characters := models.GetAllCharacters()

res, _ := json.Marshal(characters)

w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusOK)
w.Write(res)
}

func HandleGachaDraw(w http.ResponseWriter, r *http.Request) {

var reqBody models.GachaDrawRequest
err := json.NewDecoder(r.Body).Decode(&reqBody)
if err != nil {
http.Error(w, "Invalid request body", http.StatusBadRequest)
return
}
db.Save(&userDetails)
fmt.Printf("Received request: %+v\n", reqBody)
characters := models.GetAllCharacters()
characterPool := generateCharacterPool(characters)
response := models.GachaDrawResponse{
Results: []models.CharacterResponse{},
}
// fmt.Println(reqBody.NumTrials)
for i := 0; i < reqBody.Times; i++ {
character := models.DrawCharacter(characters, characterPool) // Simulate drawing a character
fmt.Println(character)
response.Results = append(response.Results, models.CharacterResponse{
CharacterID: fmt.Sprintf("Character-%d", character.ID),
Name: character.Name,
})

}

respBody, err := json.Marshal(response)
if err != nil {
http.Error(w, "Error creating response", http.StatusInternalServerError)
return
}

w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusOK)
w.Write(respBody)

}
func generateCharacterPool(characters []models.Character) []models.Character {
var characterPool []models.Character

for _, character := range characters {
rarity := character.Rarity

// Assign the probability based on rarity
var probability int
switch rarity {
case "SSR":
probability = 5
case "SR":
probability = 15
case "R":
probability = 80
}

// Add the character to the pool multiple times based on its probability
poolSize := probability
for i := 0; i < poolSize; i++ {
characterPool = append(characterPool, character)
}
}

return characterPool
}
138 changes: 115 additions & 23 deletions pkg/models/gacha.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
package models

import (
"math/rand"
"time"
"crypto/rand"
"math/big"

"github.com/iamananya/ginco-task/pkg/config"
"github.com/jinzhu/gorm"
Expand All @@ -12,8 +12,55 @@ var db *gorm.DB

type User struct {
gorm.Model
Name string `gorm:"type:varchar(30);size:30" json:"name"`
Token string `gorm:"type:char(30)" json:"token"`
Name string `gorm:"type:varchar(30);size:30" json:"name"`
Token string `gorm:"type:char(30)" json:"token"`
Characters []UserCharacter `gorm:"foreignKey:UserID" json:"characters"`
}
type Character struct {
gorm.Model
Name string `gorm:"type:varchar(30);size:30" json:"name"`
AttackPower int `gorm:"column:attack_power" json:"attack_power"`
Defense int `gorm:"column:defense" json:"defense"`
Speed int `json:"speed"`
HitPoints int `gorm:"column:hit_points" json:"hit_points"`
CriticalHitRate float64 `gorm:"column:critical_hit_rate" json:"critical_hit_rate"`
ElementalAffinity string `json:"elemental_affinity"`
Rarity string `json:"rarity"`
Synergy bool `json:"synergy"`
Evolution bool `json:"evolution"`
Users []UserCharacter `gorm:"foreignKey:CharacterID" json:"users"`
}

type UserCharacter struct {
gorm.Model
UserID uint `gorm:"index" json:"user_id"`
CharacterID uint `gorm:"index" json:"character_id"`
AttackPower int `gorm:"column:attack_power" json:"attack_power"`
Defense int `gorm:"column:defense" json:"defense"`
Speed int `json:"speed"`
HitPoints int `gorm:"column:hit_points" json:"hit_points"`
CriticalHitRate float64 `gorm:"column:critical_hit_rate" json:"critical_hit_rate"`
ElementalAffinity string `json:"elemental_affinity"`
Rarity string `json:"rarity"`
Synergy bool `json:"synergy"`
Evolution bool `json:"evolution"`
}
type GachaResult struct {
gorm.Model
CharacterID uint `gorm:"index" json:"character_id"`
CharacterName string `json:"character_name"`
}

type GachaDrawRequest struct {
Times int `json:"times"`
}

type GachaDrawResponse struct {
Results []CharacterResponse `json:"results"`
}
type CharacterResponse struct {
CharacterID string `json:"characterID"`
Name string `json:"name"`
}

func init() {
Expand All @@ -22,42 +69,87 @@ func init() {
db.AutoMigrate(&User{})
db.Model(&User{}).ModifyColumn("name", "varchar(30)")
db.Model(&User{}).ModifyColumn("token", "char(30)")
db.AutoMigrate(&Character{})
db.Model(&Character{}).ModifyColumn("name", "varchar(30)")
db.AutoMigrate(&UserCharacter{})
db.AutoMigrate(&GachaResult{})
}

func (u *User) CreateUser() *User {
rand.Seed(time.Now().UnixNano())

u.Token = generateRandomString(30)
db.NewRecord(u)
db.Create(&u)
return u
}

// Function defined to generate random string for token

// Function defined to generate random string for token---
func generateRandomString(length int) string {
const charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
charsetLength := big.NewInt(int64(len(charset)))
b := make([]byte, length)
for i := range b {
b[i] = charset[rand.Intn(len(charset))]
for i := 0; i < length; i++ {
randomIndex, _ := rand.Int(rand.Reader, charsetLength)
b[i] = charset[randomIndex.Int64()]
}
return string(b)
}

func GetAllUsers() []User {
var Users []User
db.Find(&Users)
return Users
// Function used to verify user token-----
func GetUserByToken(token string) []User {
var users []User
db.Where("token = ?", token).Find(&users)
return users
}

func GetUserById(Id int64) (*User, *gorm.DB) {
var getUser User
db := db.Where("ID=?", Id).Find(&getUser)
return &getUser, db
func GetAllUsers(token string) []User {

if token != "" {
return GetUserByToken(token)
}
return nil

// If no token is provided, retrieve all users
// var users []User
// db.Find(&users)
// return users
}

func UpdateUser(user *User) error {

if err := db.Save(user).Error; err != nil {
return err
}

return nil
}

// func DeleteUser(Id int64) User {
// var user User
// db.Where("ID=?", Id).Delete(user)
// return user
// }
func GetAllCharacters() []Character {
var Characters []Character
db.Find(&Characters)
return Characters
}
func (uc *UserCharacter) CreateUserCharacter() *UserCharacter {
db.Create(&uc)
return uc
}

func DrawCharacter(characters []Character, characterPool []Character) Character {
randIndex, _ := rand.Int(rand.Reader, big.NewInt(int64(len(characterPool))))

index := int(randIndex.Int64())
selectedCharacter := characterPool[index]

// Save the gacha result in the database
gachaResult := GachaResult{
CharacterID: selectedCharacter.ID,
CharacterName: selectedCharacter.Name,
}
_ = gachaResult.SaveGachaResult()

return selectedCharacter
}
func (gr *GachaResult) SaveGachaResult() error {
db := config.GetDB()
err := db.Create(gr).Error
return err
}
7 changes: 4 additions & 3 deletions pkg/routes/gacha-routes.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,9 @@ import (
var RegisterUserRoute = func(router *mux.Router) {
router.HandleFunc("/user/", controllers.CreateUser).Methods("POST")
router.HandleFunc("/user/", controllers.GetUser).Methods("GET")
router.HandleFunc("/user/{userId}", controllers.GetUserById).Methods("GET")
router.HandleFunc("/user/{userId}", controllers.UpdateUser).Methods("PUT")
// router.HandleFunc("/user/{userId}", controllers.DeleteUser).Methods("DELETE")
router.HandleFunc("/user/", controllers.UpdateUser).Methods("PUT")

router.HandleFunc("/characters/list/", controllers.ListCharacters).Methods("GET")
router.HandleFunc("/gacha/draw/", controllers.HandleGachaDraw).Methods("POST")
// router.HandleFunc("/user/characters/", controllers.CreateUserCharacter).Methods("POST")
}

0 comments on commit fe2ed5f

Please sign in to comment.