180 lines
3.7 KiB
Go
180 lines
3.7 KiB
Go
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)
|
|
fmt.Println(lang)
|
|
c.Redirect(http.StatusMovedPermanently, fmt.Sprintf("/%s/0/%s", lang, initGame(false)))
|
|
})
|
|
|
|
r.GET("/:lang", func(c *gin.Context) {
|
|
lang := getLang(c)
|
|
c.Redirect(http.StatusMovedPermanently, fmt.Sprintf("/%s/0/%s", lang, initGame(false)))
|
|
})
|
|
|
|
r.GET("/:lang/:ai_second", func(c *gin.Context) {
|
|
lang := getLang(c)
|
|
aiSecond, err := strconv.ParseBool(c.Param("ai_second"))
|
|
if err != nil {
|
|
aiSecond = false
|
|
}
|
|
|
|
aiSecondVar := "0"
|
|
if aiSecond {
|
|
aiSecondVar = "1"
|
|
}
|
|
|
|
c.Redirect(
|
|
http.StatusMovedPermanently,
|
|
fmt.Sprintf("/%s/%s/%s", lang, aiSecondVar, initGame(aiSecond)),
|
|
)
|
|
})
|
|
|
|
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)
|
|
|
|
fmt.Println(gameState)
|
|
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 initGame(aiSecond bool) string {
|
|
if aiSecond {
|
|
return "0"
|
|
}
|
|
|
|
// get from DB
|
|
return "1"
|
|
}
|
|
|
|
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 "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
|
|
}
|