Files
blockout/BlockOutReplica/Assets/Scripts/Domain/LevelDefinition.cs
T
2026-10-20 13:21:04 +08:00

93 lines
3.7 KiB
C#

using System;
using System.Collections.Generic;
using UnityEngine;
namespace BlockOutReplica.Domain
{
public enum DoorSide { Top, Bottom, Left, Right }
[Serializable]
public struct GridPosition : IEquatable<GridPosition>
{
public int X;
public int Y;
public GridPosition(int x, int y) { X = x; Y = y; }
public bool Equals(GridPosition other) => X == other.X && Y == other.Y;
public override bool Equals(object obj) => obj is GridPosition other && Equals(other);
public override int GetHashCode() => (X * 397) ^ Y;
}
public sealed class PieceDefinition
{
public int ColorId { get; }
public IReadOnlyList<GridPosition> Cells { get; }
public int InitialIceCount { get; }
public bool HasLayer { get; }
public int LayerColorId { get; }
public PieceDefinition(int colorId, IReadOnlyList<GridPosition> cells,
int initialIceCount = 0, bool hasLayer = false, int layerColorId = 0)
{
ColorId = colorId; Cells = cells; InitialIceCount = Math.Max(0, initialIceCount);
HasLayer = hasLayer; LayerColorId = layerColorId;
}
}
public sealed class DoorDefinition
{
public int ColorId { get; }
public IReadOnlyList<GridPosition> Cells { get; }
public DoorSide Side { get; }
public int InitialIceCount { get; }
public DoorDefinition(int colorId, IReadOnlyList<GridPosition> cells, DoorSide side, int initialIceCount = 0)
{ ColorId = colorId; Cells = cells; Side = side; InitialIceCount = Math.Max(0, initialIceCount); }
}
public sealed class CurtainLockDefinition
{
public IReadOnlyList<GridPosition> Cells { get; }
public int InitialLockCount { get; }
public CurtainLockDefinition(IReadOnlyList<GridPosition> cells, int initialLockCount)
{ Cells = cells; InitialLockCount = Math.Max(0, initialLockCount); }
}
public sealed class LevelDefinition
{
public IReadOnlyList<PieceDefinition> Pieces { get; }
public IReadOnlyList<DoorDefinition> Doors { get; }
public IReadOnlyList<GridPosition> Walls { get; }
public IReadOnlyList<GridPosition> Cells { get; }
public IReadOnlyList<CurtainLockDefinition> CurtainLocks { get; }
public GridPosition BoardStart { get; }
public int MinX { get; }
public int MaxX { get; }
public int MinY { get; }
public int MaxY { get; }
public Vector2 GridCenter => new Vector2((MinX + MaxX) * 0.5f, (MinY + MaxY) * 0.5f);
public LevelDefinition(IReadOnlyList<PieceDefinition> pieces,
IReadOnlyList<DoorDefinition> doors, IReadOnlyList<GridPosition> walls,
IReadOnlyList<GridPosition> cells, GridPosition boardStart,
int minX, int maxX, int minY, int maxY, IReadOnlyList<CurtainLockDefinition> curtainLocks = null)
{
Pieces = pieces; Doors = doors; Walls = walls; Cells = cells;
BoardStart = boardStart; MinX = minX; MaxX = maxX; MinY = minY; MaxY = maxY;
CurtainLocks = curtainLocks ?? Array.Empty<CurtainLockDefinition>();
}
public Vector3 GridToWorld(GridPosition position, float height = 0f)
{
Vector2 center = GridCenter;
return new Vector3(position.X - center.x, height, position.Y - center.y);
}
public Vector3 AverageWorld(IReadOnlyList<GridPosition> positions, float height = 0f)
{
Vector3 result = Vector3.zero;
for (int i = 0; i < positions.Count; i++)
result += GridToWorld(positions[i], height);
return positions.Count == 0 ? new Vector3(0f, height, 0f) : result / positions.Count;
}
}
}