C#二維陣列在SLG中的實現和使用

_剋剋克發表於2020-12-26

最近在做一個slg的專案,
需求是要在N xM的矩形範圍內放置2 x 2,3 x 2,3 x 3…等不規則的小矩形
發現二維陣列最合適.
本想用0,1開對二維陣列賦值.在大佬的指點下,改用2的n(不同單位的id)次冪來代替,這樣後期可以通過不同的值就知道該位置是什麼單位,而且還有個好處就是後期考慮單位重疊也是合適的,因為2的不同次冪相加的結果是唯一的.
下面會貼出二維陣列的程式碼(菜雞一個,大佬手下留情)

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

[Serializable]
/// <summary> 配置矩陣</summary>
public class ConfigMatrix
{
	/// <summary> 矩陣維數 </summary>
	public int matrix_X;
	/// <summary> 矩陣每維數量 </summary>
	public int matrix_Y;
	/// <summary> 矩陣元素數量 </summary>
	public int MatrixItemNum;
	/// <summary> 矩陣 </summary>
	public int[,] data;
	/// <summary> 矩陣索引 </summary>
	public List<Vector2Int> matrixIndexes = new List<Vector2Int>();

	/// <summary>
	/// 構造方法
	/// </summary>
	/// <param name="_matrix_X">維數</param>
	/// <param name="_matrix_Y">每維數量</param>
	public ConfigMatrix(int _matrix_X, int _matrix_Y)
	{
		matrix_X = _matrix_X;
		matrix_Y = _matrix_Y;
		data = new int[matrix_X, matrix_Y];
		for (int i = 0; i < _matrix_X; i++)
		{
			for (int j = 0; j < _matrix_Y; j++)
			{
				data[i, j] = (int)Mathf.Pow(2, 0);
				matrixIndexes.Add(new Vector2Int(i, j));
			}
		}
		MatrixItemNum = _matrix_X * _matrix_Y;
	}

	/// <summary>
	/// 構造方法:複製別的配置矩陣的資料
	/// </summary>
	/// <param name="_configMatrix"></param>
	public ConfigMatrix(ConfigMatrix _configMatrix)
	{
		matrix_X = _configMatrix.matrix_X;
		matrix_Y = _configMatrix.matrix_Y;
		data = new int[matrix_X, matrix_Y];
		matrixIndexes = _configMatrix.matrixIndexes;
		foreach (var item in matrixIndexes)
		{
			data[item.x, item.y] = _configMatrix.data[item.x, item.y];
		}
		MatrixItemNum = _configMatrix.MatrixItemNum;
	}

	/// <summary>
	/// 資料儲存
	/// </summary>
	/// <param name="_indexs">索引集合</param>
	/// <param name="_value">資料</param>
	public void SetValueByIndexs(List<Vector2Int> _indexs, int _value)
	{
		if (_indexs == null || _indexs.Count <= 0)
		{
			Debug.LogError("傳入的索引不正確");
			return;
		}
		foreach (Vector2Int vector2 in _indexs)
		{
			data[vector2.x, vector2.y] = _value;
		}
	}

	/// <summary>
	/// 獲取資料
	/// </summary>
	/// <param name="index">資料索引</param>
	/// <returns></returns>
	public int GetData(Vector2Int index)
	{
		int _data = -1;
		if (index.x > matrix_X || index.y > matrix_Y || data == null) return -1;

		_data = data[index.x, index.y];
		return _data;
	}

	/// <summary>
	/// 替換資料
	/// </summary>
	/// <param name="_oldValue">舊資料</param>
	/// <param name="_newValue">新資料</param>
	public void ReplaceDataByOldData(int _oldValue, int _newValue)
	{
		foreach (var item in matrixIndexes)
		{
			if (data[item.x, item.y] == _oldValue)
			{
				data[item.x, item.y] = _newValue;
			}
		}
	}

	/// <summary>
	/// 獲取_Occupied_X*_Occupied_Y範圍空格的下標
	/// </summary>
	/// <param name="_Occupied_X">佔用長</param>
	/// <param name="_Occupied_Y">佔用寬</param>
	/// <param name="_excludeIndexs">剔除的索引 </param>
	/// <returns></returns>
	public List<Vector2Int> GetEmptyItem(int _Occupied_X, int _Occupied_Y, List<Vector2Int> _excludeIndexs = null)
	{
		int num = _Occupied_X * _Occupied_Y;
		foreach (Vector2Int vector2 in matrixIndexes)
		{
			bool isNeedContinue = false;
			List<Vector2Int> positions = new List<Vector2Int>();
			for (int i = vector2.x; i < vector2.x + _Occupied_Y; i++)
			{
				///判斷行數是否超出界限
				if (vector2.x + _Occupied_Y > matrix_X)
				{
					isNeedContinue = true;
					break;
				}
				for (int j = vector2.y; j < vector2.y + _Occupied_X; j++)
				{
					///判斷列數是否超出界限
					if (vector2.y + _Occupied_X > matrix_Y)
					{
						isNeedContinue = true;
						break;
					}
					positions.Add(new Vector2Int(i, j));
				}
			}
			foreach (var item in positions)
			{
				//如果有一個格子不為空就繼續執行
				if (data[item.x, item.y] != (int)Mathf.Pow(2, 0))
				{
					isNeedContinue = true;
					break;
				}
			}
			if (isNeedContinue)
			{
				continue;
			}
			else
			{
				if (_excludeIndexs == null)
				{
					return positions;
				}
				else
				{
					bool isContinue = false;
					foreach (var item in _excludeIndexs)
					{
						if (positions.Contains(item))
						{
							isContinue = true;
							break;
						}
					}
					if (isContinue)
					{
						continue;
					}
					else
					{
						return positions;
					}
				}
			}
		}
		return null;
	}

	/// <summary>
	/// 下標對應的位置是否為空
	/// </summary>
	/// <param name="_indexs"></param>
	/// <returns></returns>
	public bool IsItemEmptyByIndexs(List<Vector2Int> _indexs)
	{
		foreach (var item in _indexs)
		{
			if (data[item.x, item.y] != Mathf.Pow(2, 0))
			{
				return false;
			}
		}
		return true;
	}

	/// <summary>
	/// 資料遷移
	/// </summary>
	/// <param name="newPos">新資料索引</param>
	/// <param name="oldPos">舊資料索引</param>
	public void MoveData(List<Vector2Int> newPos, List<Vector2Int> oldPos)
	{
		if (newPos == null || oldPos == null) return;
		if (newPos.Count == 0 || oldPos.Count == 0 || oldPos.Count != newPos.Count) return;

		int data = GetData(oldPos[0]);
		int defaultData = (int)Mathf.Pow(2, 0);
		SetValueByIndexs(oldPos, defaultData);
		SetValueByIndexs(newPos, data);
	}
}

相關文章