386 lines
12 KiB
C#
386 lines
12 KiB
C#
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;
|
||
}
|
||
|
||
}
|
||
}
|