93 lines
3.7 KiB
C#
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;
|
|
}
|
|
}
|
|
}
|