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;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
}
|
|||
|
|
}
|