package logic import ( "math/rand" "wuziqi-server/core" ) // GenerateGrid 创建一个新的随机网格 func GenerateGrid(gridSize int, bombCount int, itemMin int, itemMax int, enabledItems map[string]bool, itemWeights map[string]int, allItemTypes []string) []*core.GridCell { totalCells := gridSize * gridSize grid := make([]*core.GridCell, totalCells) for i := 0; i < totalCells; i++ { grid[i] = &core.GridCell{Type: "empty", Revealed: false} } // 放置炸弹 bombsPlaced := 0 for bombsPlaced < bombCount && bombsPlaced < totalCells { idx := rand.Intn(totalCells) if grid[idx].Type == "empty" { grid[idx].Type = "bomb" bombsPlaced++ } } // 过滤启用的道具 var pool []string if len(enabledItems) > 0 { for _, it := range allItemTypes { if enabled, ok := enabledItems[it]; ok && enabled { weight := 10 if w, ok := itemWeights[it]; ok && w > 0 { weight = w } for i := 0; i < weight; i++ { pool = append(pool, it) } } } } if len(pool) == 0 { pool = allItemTypes } // 放置道具 itemCount := rand.Intn(itemMax-itemMin+1) + itemMin itemsPlaced := 0 for itemsPlaced < itemCount && (bombsPlaced+itemsPlaced) < totalCells { idx := rand.Intn(totalCells) if grid[idx].Type == "empty" { grid[idx].Type = "item" grid[idx].ItemID = pool[rand.Intn(len(pool))] itemsPlaced++ } } // 计算邻居 for i := 0; i < totalCells; i++ { if grid[i].Type == "bomb" { continue } count := 0 neighbors := GetNeighborIndices(i, gridSize) for _, neighborIdx := range neighbors { if grid[neighborIdx].Type == "bomb" { count++ } } grid[i].NeighborBombs = count } return grid } func GetNeighborIndices(index int, gridSize int) []int { neighbors := []int{} row := index / gridSize col := index % gridSize for r := row - 1; r <= row+1; r++ { for c := col - 1; c <= col+1; c++ { if (r == row && c == col) || r < 0 || r >= gridSize || c < 0 || c >= gridSize { continue } neighbors = append(neighbors, r*gridSize+c) } } return neighbors } // RevealSafeArea 使用泛洪填充算法揭示连续的空位 // 标准扫雷规则:揭示边界的数字格子,但不从它们继续扩展 // 道具和炸弹都不会被揭示,它们阻断泛洪填充 func RevealSafeArea(state *core.GameState, startIndex int) []int { revealed := []int{} visited := make(map[int]bool) // 起始格子可能已经被揭示(在调用前被设置), // 我们需要从它的邻居开始扩展 startCell := state.Grid[startIndex] visited[startIndex] = true // 初始化队列 var queue []int if startCell.NeighborBombs == 0 { // 起始格子是空白格(无数字),从邻居开始扩展 queue = GetNeighborIndices(startIndex, state.GridSize) } // 如果起始格子有数字,不扩展邻居 for len(queue) > 0 { idx := queue[0] queue = queue[1:] if visited[idx] { continue } visited[idx] = true cell := state.Grid[idx] // 如果已揭示、是炸弹或道具则跳过(道具和炸弹阻断泛洪填充) if cell.Revealed || cell.Type == "bomb" || cell.Type == "item" { continue } // 揭示空格子(包括有数字的边界格子) cell.Revealed = true revealed = append(revealed, idx) // 只有无炸弹邻居的空位才继续扩展 if cell.NeighborBombs == 0 { neighbors := GetNeighborIndices(idx, state.GridSize) queue = append(queue, neighbors...) } } return revealed }