package main import ( "fmt" "net/http" "strconv" "github.com/foolin/goview/supports/ginview" "github.com/gin-contrib/sessions" "github.com/gin-contrib/sessions/cookie" "github.com/gin-gonic/gin" ) func main() { r := gin.Default() r.HTMLRender = ginview.Default() store := cookie.NewStore([]byte("secret")) r.Use(sessions.Sessions("mysession", store)) r.StaticFile("/favicon.ico", "./assets/favicon.ico") r.StaticFile("/sgs.png", "./assets/sgs.png") r.StaticFile("/en.png", "./assets/en.png") r.StaticFile("/cross.png", "./assets/cross.png") r.StaticFile("/nought.png", "./assets/nought.png") r.GET("/", func(c *gin.Context) { lang := getLang(c) c.Redirect(http.StatusMovedPermanently, fmt.Sprintf("/%s/0/x", lang)) }) r.GET("/:lang", func(c *gin.Context) { lang := getLang(c) c.Redirect(http.StatusMovedPermanently, fmt.Sprintf("/%s/0/x", lang)) }) r.GET("/:lang/:ai_second/:game", func(c *gin.Context) { lang := getLang(c) gameFlow, gameState := getGameFlow(c) aiSecond, err := strconv.ParseBool(c.Param("ai_second")) if err != nil { aiSecond = false } game := newGame(gameFlow, aiSecond) if gameState == GameStateInProgress && !game.isFinished() { gameFlow = gameFlow + getNewClick(gameFlow) game = newGame(gameFlow, aiSecond) } // if game ended - save results c.HTML(http.StatusOK, "index", gin.H{ "title": "Index title!", "lang": lang, "gameFlow": gameFlow, "game": game, "fields": [9]int{1, 2, 3, 4, 5, 6, 7, 8, 9}, "fieldClass": func(game *Game, fieldNum int) string { fieldClass := FieldClass[fieldNum] if field, ok := game.fields[fieldNum]; ok { if len(field.image) > 0 { fieldClass = fieldClass + " " + field.image } if field.line { fieldClass = fieldClass + " line" } } return fieldClass }, "disabled": func(game *Game, fieldNum int) bool { if field, ok := game.fields[fieldNum]; ok { return field.disabled } return false }, }) }) r.Run() } func getLang(c *gin.Context) string { session := sessions.Default(c) lang := session.Get("lang").(string) pLang, hasParam := c.Params.Get("lang") if hasParam && pLang != lang { lang = pLang session.Set("lang", lang) session.Save() } if lang != "sgs" && lang != "en" { lang = "sgs" session.Set("lang", lang) session.Save() } return lang } func getGameFlow(c *gin.Context) (string, int) { gameFlow := c.Param("game") if "0" == gameFlow { return gameFlow, GameStateWaitingUser } if "x" == gameFlow { return "", GameStateInProgress } if "0" == string(gameFlow[0]) { gameFlow = string(gameFlow[1:]) } if len(gameFlow) >= 9 { return gameFlow, GameStateEnded } return gameFlow, GameStateInProgress } func getNewClick(gameFlow string) string { return difference("123456789", gameFlow)[0] } func difference(a, b string) []string { mb := make(map[string]struct{}, len(b)) for _, x := range str2array(b) { mb[x] = struct{}{} } var diff []string for _, x := range str2array(a) { if _, found := mb[x]; !found { diff = append(diff, x) } } return diff } func str2array(str string) []string { chars := []rune(str) var splited []string for i := 0; i < len(chars); i++ { splited = append(splited, string(chars[i])) } return splited }