package main import ( "embed" "fmt" "net/http" "f1-game/internal/algorithm/astar" "f1-game/internal/algorithm/astar6" "f1-game/internal/types" cherryTime "github.com/cherry-game/cherry/extend/time" "github.com/gin-gonic/gin" ) //go:embed index.html var staticFiles embed.FS var ( aStar *astar.AStar aStarV6 *astar6.AStar // mapSize represents the width and height of the grid mapSize int32 = 1000 ) // PathRequest represents the request body for finding a path // Contains start point, end point, and optional obstacle points type PathRequest struct { StartX int32 `json:"startX"` StartY int32 `json:"startY"` EndX int32 `json:"endX"` EndY int32 `json:"endY"` Obstacles []Point `json:"obstacles"` // 障碍点列表 } type Point struct { X int32 `json:"x"` Y int32 `json:"y"` } func main() { // Initialize A* // Initializing with all 1 (walkable) mapData := make([][]int32, mapSize) for i := range mapData { mapData[i] = make([]int32, mapSize) for j := range mapData[i] { mapData[i][j] = 1 //可走 } } config := astar.Config{ Width: mapSize, Height: mapSize, MapData: mapData, IsWalkableFunc: nil, IsDebug: false, } aStar = astar.New(config) // 初始化 astar6 算法 config6 := astar6.Config{ Min: types.NewPoint(1, 1), Max: types.NewPoint(mapSize, mapSize), MapData: mapData, IsWalkableFunc: nil, IsDebug: false, } aStarV6 = astar6.New(config6) r := gin.Default() r.GET("/", func(c *gin.Context) { // Serve the embedded index.html content, err := staticFiles.ReadFile("index.html") if err != nil { c.String(http.StatusInternalServerError, "Could not read index.html") return } c.Data(http.StatusOK, "text/html; charset=utf-8", content) }) // POST /find-path - 寻找路径接口 // 功能:根据起点、终点和障碍点列表,使用A*算法计算最优路径 r.POST("/find-path", func(c *gin.Context) { var req PathRequest if err := c.ShouldBindJSON(&req); err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) return } // 重置缓存 aStar.ResetCache() // 设置障碍点(0表示不可行走) for _, obs := range req.Obstacles { aStar.SetObstacles(obs.X, obs.Y, false) } ct := cherryTime.Now() pathNodes, err := aStar.FindPath(req.StartX, req.StartY, req.EndX, req.EndY) costTime := ct.NowDiffMillisecond() if !err { c.JSON(http.StatusOK, gin.H{"path": []Point{}, "error": err}) // Return empty path on error (no path found) return } // Convert to simple Point struct for JSON path := make([]Point, len(pathNodes)) for i, node := range pathNodes { path[i] = Point{ X: node.X(), Y: node.Y(), } } c.JSON(http.StatusOK, gin.H{ "path": path, "costTime": costTime, }) }) // POST /find-path-astar6 - 使用 astar6 寻找路径接口 // 功能:根据起点、终点和障碍点列表,使用 astar6 算法计算最优路径 r.POST("/find-path-astar6", func(c *gin.Context) { var req PathRequest if err := c.ShouldBindJSON(&req); err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) return } aStarV6.ResetCache() // 设置障碍点(0表示不可行走) for _, obs := range req.Obstacles { aStarV6.SetNode(obs.X, obs.Y, false) } ct := cherryTime.Now() pathNodes, found := aStarV6.FindPath(astar6.DefaultFindContext(req.StartX, req.StartY, req.EndX, req.EndY)) costTime := ct.NowDiffMillisecond() if !found { c.JSON(http.StatusOK, gin.H{"path": []Point{}, "error": "No path found"}) return } // Convert to simple Point struct for JSON path := make([]Point, len(pathNodes)) for i, node := range pathNodes { path[i] = Point{ X: node.X(), Y: node.Y(), } } c.JSON(http.StatusOK, gin.H{ "path": path, "costTime": costTime, }) }) fmt.Println("Server running on http://localhost:8080") r.Run(":8080") }