NLDClient-yudde/ProjectNLD/Assets/Code/Scripts/Gameplay/LegionBattle/View/FightLineMap.cs

386 lines
12 KiB
C#
Raw Normal View History

2025-03-07 13:24:45 +08:00
using System.Collections.Generic;
using UnityEngine;
namespace Gameplay.LegionBattle.View
{
public class FightLineMap
{
private FightLineCell[,] _cellMap;
public FightLineMap(int xCount,
int yCount)
{
_cellMap = new FightLineCell[xCount, yCount];
for (int i = 0; i < xCount; i++)
{
for (int j = 0; j < yCount; j++)
{
_cellMap[i, j] = new FightLineCell(i, j);
}
}
// build neighbors
for (int i = 0; i < xCount; i++)
{
for (int j = 0; j < yCount; j++)
{
_cellMap[i, j].BuildNeighbors(_cellMap);
}
}
}
public void FillStartWeights()
{
// x<20 -1 x>20 1
for (int i = 0; i < _cellMap.GetLength(0); i++)
{
for (int j = 0; j < _cellMap.GetLength(1); j++)
{
var cell = _cellMap[i, j];
if (cell.pos.x < 20)
{
cell.standValue = -1;
}
else
{
cell.standValue = 1;
}
}
}
}
public void CreateViewMap(GameObject sampleObj,
Transform parent)
{
// 遍历_cellMap创建view
for (int i = 0; i < _cellMap.GetLength(0); i++)
{
for (int j = 0; j < _cellMap.GetLength(1); j++)
{
var cell = _cellMap[i, j];
var obj = Object.Instantiate(sampleObj, parent);
obj.transform.position = new Vector3(cell.pos.x, cell.pos.y, 0);
obj.name = $"Cell_pos_{cell.pos.x}_{cell.pos.y}";
cell.BindViewObj(obj);
}
}
}
public void UpdateColors()
{
for (int i = 0; i < _cellMap.GetLength(0); i++)
{
for (int j = 0; j < _cellMap.GetLength(1); j++)
{
var cell = _cellMap[i, j];
cell.UpdateColor();
}
}
}
public void ReverseTuDian()
{
ForEachCell(cell =>
{
if (cell.CheckIsTuDian())
{
cell.standValue = -cell.standValue;
}
});
}
public void ReverseAloneArea()
{
FightLineArea mainLeft = null;
FightLineArea mainRight = null;
for (int i = 0; i < _areaList.Count; i++)
{
var area = _areaList[i];
if (area.isMainArea)
{
if (area.cellList[0].standValue == -1)
{
mainLeft = area;
}
else if (area.cellList[0].standValue == 1)
{
mainRight = area;
}
continue;
}
area.ReverseArea();
}
if (mainLeft == null || mainRight == null)
{
Debug.LogError("不存在主区域");
return;
}
for (int i = 0; i < _areaList.Count; i++)
{
var area = _areaList[i];
if (area.isMainArea)
{
continue;
}
if (area.cellList[0].standValue == -1)
{
mainLeft.AddArea(area);
}
else if (area.cellList[0].standValue == 1)
{
mainRight.AddArea(area);
}
}
leftArea.ResetArea(mainLeft);
rightArea.ResetArea(mainRight);
}
private List<FightLineArea> _areaList = new List<FightLineArea>();
public FightLineArea leftArea = new FightLineArea();
public FightLineArea rightArea = new FightLineArea();
public void UpdateAreas()
{
_areaList.Clear();
for (int i = 0; i < _cellMap.GetLength(0); i++)
{
for (int j = 0; j < _cellMap.GetLength(1); j++)
{
var cell = _cellMap[i, j];
cell.isVisited = false;
}
}
var workList = new Queue<FightLineCell>();
var firstCell = _SearchNoFinishCell();
workList.Enqueue(firstCell);
firstCell.isVisited = true;
var workArea = new FightLineArea();
_areaList.Add(workArea);
while (workList.Count > 0)
{
var workCell = workList.Dequeue();
workArea.AddCell(workCell);
var aroundNeighbors = workCell.fullNeighbors;
var fullNeighborCount = aroundNeighbors.Count;
for (int i = 0; i < fullNeighborCount; i++)
{
var neighbor = aroundNeighbors[i];
if (neighbor.isVisited) continue;
if (neighbor.standValue != workCell.standValue)
continue;
workList.Enqueue(neighbor);
neighbor.isVisited = true;
}
if (workList.Count == 0)
{
// 区域完结
var nextCell = _SearchNoFinishCell();
if (nextCell != null)
{
workList.Enqueue(nextCell);
nextCell.isVisited = true;
workArea = new FightLineArea();
_areaList.Add(workArea);
}
}
}
}
private FightLineCell _SearchNoFinishCell()
{
for (int i = 0; i < _cellMap.GetLength(0); i++)
{
for (int j = 0; j < _cellMap.GetLength(1); j++)
{
var cell = _cellMap[i, j];
if (!cell.isVisited)
{
return cell;
}
}
}
return null;
}
public void ForEachCell(System.Action<FightLineCell> action)
{
for (int i = 0; i < _cellMap.GetLength(0); i++)
{
for (int j = 0; j < _cellMap.GetLength(1); j++)
{
var cell = _cellMap[i, j];
action(cell);
}
}
}
public FightLineCell GetCellByGridPos(Vector2Int gridPos)
{
return GetCellByGridPos(gridPos.x, gridPos.y);
}
public FightLineCell GetCellByGridPos(int x,
int y)
{
if (x < 0 || x >= _cellMap.GetLength(0) ||
y < 0 || y >= _cellMap.GetLength(1))
{
return null;
}
else
{
return _cellMap[x, y];
}
}
public List<FightLineCell> leftBoardCells = new List<FightLineCell>();
public List<FightLineCell> rightBoardCells = new List<FightLineCell>();
public void UpdateLineBoard()
{
leftBoardCells.Clear();
rightBoardCells.Clear();
// 遍历整个棋盘
for (int i = 0; i < _cellMap.GetLength(0); i++)
{
for (int j = 0; j < _cellMap.GetLength(1); j++)
{
var cell = _cellMap[i, j];
if (cell.standValue < 0)
{
leftBoardCells.Add(cell);
}
else if (cell.standValue > 0)
{
rightBoardCells.Add(cell);
}
}
}
// 遍历左边的cell
for (int i = 0; i < leftBoardCells.Count; i++)
{
var cell = leftBoardCells[i];
if (cell.CheckIsCenter())
{
leftBoardCells.RemoveAt(i);
i--;
}
}
// 遍历右边的cell
for (int i = 0; i < rightBoardCells.Count; i++)
{
var cell = rightBoardCells[i];
if (cell.CheckIsCenter())
{
rightBoardCells.RemoveAt(i);
i--;
}
}
}
public List<FightLine> CalcLines(List<FightLineCell> boardCells,
List<FightLine> result)
{
while (boardCells.Count > 0)
{
var workCell = boardCells[0];
boardCells.RemoveAt(0);
var line = new FightLine();
line.AddCell(workCell);
result.Add(line);
while (workCell != null)
{
var neighbors = workCell.neighbors;
var isFind = false;
for (int i = 0; i < neighbors.Count; i++)
{
var neighbor = neighbors[i];
if (neighbor.standValue == workCell.standValue
&& boardCells.Contains(neighbor))
{
boardCells.Remove(neighbor);
line.AddCell(neighbor);
workCell = neighbor;
isFind = true;
break;
}
}
if (!isFind)
{
break;
}
}
}
for (int i = 0; i < result.Count; i++)
{
var line = result[i];
var lineHead = line.cells[0];
var lineEnd = line.cells[^1];
for (int j = i + 1; j < result.Count; j++)
{
var line2 = result[j];
var line2Head = line2.cells[0];
var line2End = line2.cells[^1];
var isConnect = true;
if (lineHead.CheckIsConnect(line2Head))
{
// 头头相接
// 先把1反转,再把2加入
line.Reverse();
line.AddLine(line2);
lineHead = line.cells[0];
lineEnd = line.cells[^1];
}
else if (lineHead.CheckIsConnect(line2End))
{
// 头尾相接
// 把2反转, 再把2加入
line2.Reverse();
line.AddLine(line2);
lineEnd = line.cells[^1];
}
else if (lineEnd.CheckIsConnect(lineHead))
{
// 尾头相接
// 把2加入
line.AddLine(line2);
lineEnd = line.cells[^1];
}
else if (lineEnd.CheckIsConnect(line2End))
{
// 尾尾相接
// 先把2反转, 再把2加入
line2.Reverse();
line.AddLine(line2);
lineEnd = line.cells[^1];
}
else
{
isConnect = false;
}
if (isConnect)
{
result.RemoveAt(j);
j--;
}
}
}
return result;
}
}
}