move puzzle implementations out of engine
This commit is contained in:
38
Assets/Engine/Runtime/Utilities/Orientation.cs
Normal file
38
Assets/Engine/Runtime/Utilities/Orientation.cs
Normal file
@@ -0,0 +1,38 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace EscapeRoomEngine.Engine.Runtime.Utilities
|
||||
{
|
||||
public enum Orientation
|
||||
{
|
||||
North = 0, East = 90, South = 180, West = 270
|
||||
}
|
||||
|
||||
public static class OrientationExtensions
|
||||
{
|
||||
public static HashSet<Orientation> EveryOrientation() => new(new[]
|
||||
{
|
||||
Orientation.North, Orientation.East, Orientation.South, Orientation.West
|
||||
});
|
||||
|
||||
/// <summary>
|
||||
/// Return the orientation corresponding to an angle, starting at 0 degrees North and going clockwise around the compass.
|
||||
/// </summary>
|
||||
public static Orientation FromAngle(int angle) => (Orientation)angle;
|
||||
|
||||
/// <summary>
|
||||
/// Turn an orientation into its corresponding angle.
|
||||
/// </summary>
|
||||
public static float Angle(this Orientation orientation) => (float)orientation;
|
||||
|
||||
/// <summary>
|
||||
/// Turn an orientation into its corresponding angle.
|
||||
/// </summary>
|
||||
public static int AngleInt(this Orientation orientation) => (int)orientation;
|
||||
|
||||
/// <summary>
|
||||
/// Rotate an orientation by a specific amount of quarter rotations. Rotating <c>East</c> thrice would return <c>North</c>.
|
||||
/// </summary>
|
||||
public static Orientation Rotated(this Orientation orientation, int quarterRotations) =>
|
||||
orientation + quarterRotations * 90;
|
||||
}
|
||||
}
|
||||
3
Assets/Engine/Runtime/Utilities/Orientation.cs.meta
Normal file
3
Assets/Engine/Runtime/Utilities/Orientation.cs.meta
Normal file
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 892800b15ed4409582647cfc5659b820
|
||||
timeCreated: 1669115056
|
||||
173
Assets/Engine/Runtime/Utilities/Placement.cs
Normal file
173
Assets/Engine/Runtime/Utilities/Placement.cs
Normal file
@@ -0,0 +1,173 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace EscapeRoomEngine.Engine.Runtime.Utilities
|
||||
{
|
||||
/// <summary>
|
||||
/// A placement defines the position, size and orientation of a module or space.
|
||||
/// </summary>
|
||||
public struct Placement
|
||||
{
|
||||
/// <summary>
|
||||
/// The placement position is always considered to be at <c>(0.5, 0.5)</c> relative to the placement.
|
||||
///
|
||||
/// <example>In a placement of size <c>(1, 1)</c>, the position is at the center of the placement. In a larger placement, the position is in the center of the bottom left square.</example>
|
||||
/// </summary>
|
||||
public Vector3Int position;
|
||||
public Vector2Int size;
|
||||
public Orientation orientation;
|
||||
|
||||
/// <summary>
|
||||
/// Return the bottom left corner position of the module.
|
||||
/// </summary>
|
||||
public Vector3Int BottomLeft {
|
||||
get
|
||||
{
|
||||
var sizeMinusOne = size - Vector2Int.one;
|
||||
return orientation switch
|
||||
{
|
||||
Orientation.North => position,
|
||||
Orientation.East => position - new Vector3Int(0, 0, sizeMinusOne.x),
|
||||
Orientation.South => position - new Vector3Int(sizeMinusOne.x, 0, sizeMinusOne.y),
|
||||
Orientation.West => position - new Vector3Int(sizeMinusOne.y, 0, 0),
|
||||
_ => throw new ArgumentOutOfRangeException()
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the geometric center of this placement taking into account its orientation.
|
||||
/// </summary>
|
||||
public Vector3 GeometricCenter
|
||||
{
|
||||
get
|
||||
{
|
||||
var sizeMinusOne = size - Vector2Int.one;
|
||||
var half = new Vector2(sizeMinusOne.x/2f, sizeMinusOne.y/2f);
|
||||
var horizontal = new Vector3(half.x, 0, half.y);
|
||||
var vertical = new Vector3(half.y, 0, -half.x);
|
||||
var geometricPosition = position + new Vector3(0.5f, 0, 0.5f);
|
||||
#pragma warning disable CS8524
|
||||
return orientation switch
|
||||
#pragma warning restore CS8524
|
||||
{
|
||||
Orientation.North => geometricPosition + horizontal,
|
||||
Orientation.East => geometricPosition + vertical,
|
||||
Orientation.South => geometricPosition - horizontal,
|
||||
Orientation.West => geometricPosition - vertical
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the integer positions of the two back corners. The first one is just the position of the placement.
|
||||
/// </summary>
|
||||
public (Vector3Int, Vector3Int) BackCorners {
|
||||
get
|
||||
{
|
||||
var width = size.x - 1;
|
||||
var horizontal = new Vector3Int(width, 0, 0);
|
||||
var vertical = new Vector3Int(0, 0, width);
|
||||
#pragma warning disable CS8524
|
||||
var otherCorner = orientation switch
|
||||
#pragma warning restore CS8524
|
||||
{
|
||||
Orientation.North => position + horizontal,
|
||||
Orientation.East => position - vertical,
|
||||
Orientation.South => position - horizontal,
|
||||
Orientation.West => position + vertical
|
||||
};
|
||||
return (position, otherCorner);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create a set with every possible combination of position and orientation of placements that fit in a given space.
|
||||
/// The size of the placements are given by this placement.
|
||||
/// </summary>
|
||||
/// <param name="space">The generated placements will fit inside the placement of the given space.</param>
|
||||
public List<Placement> EveryPlacementInSpace(Space space)
|
||||
{
|
||||
var placements = new List<Placement>();
|
||||
var sizeMinusOne = size - Vector2Int.one;
|
||||
var spaceSize = space.rrPlacement.size;
|
||||
|
||||
foreach (var o in OrientationExtensions.EveryOrientation())
|
||||
{
|
||||
Range x;
|
||||
Range z;
|
||||
|
||||
switch (o)
|
||||
{
|
||||
case Orientation.North:
|
||||
x = new Range(0, spaceSize.x - sizeMinusOne.x);
|
||||
z = new Range(0, spaceSize.y - sizeMinusOne.y);
|
||||
break;
|
||||
case Orientation.East:
|
||||
x = new Range(0, spaceSize.x - sizeMinusOne.y);
|
||||
z = new Range(sizeMinusOne.x, spaceSize.y);
|
||||
break;
|
||||
case Orientation.South:
|
||||
x = new Range(sizeMinusOne.x, spaceSize.x);
|
||||
z = new Range(sizeMinusOne.y, spaceSize.y);
|
||||
break;
|
||||
case Orientation.West:
|
||||
x = new Range(sizeMinusOne.y, spaceSize.x);
|
||||
z = new Range(0, spaceSize.y - sizeMinusOne.x);
|
||||
break;
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException();
|
||||
}
|
||||
|
||||
placements.AddRange(ConstrainedPlacements(o, size, x, z));
|
||||
}
|
||||
|
||||
return placements;
|
||||
}
|
||||
|
||||
private static IEnumerable<Placement> ConstrainedPlacements(
|
||||
Orientation orientation,
|
||||
Vector2Int size,
|
||||
Range xRange, Range zRange)
|
||||
{
|
||||
var placements = new List<Placement>(xRange.Length * zRange.Length);
|
||||
|
||||
for (var z = zRange.min; z < zRange.max; z++)
|
||||
{
|
||||
for (var x = xRange.min; x < xRange.max; x++)
|
||||
{
|
||||
placements.Add(new Placement
|
||||
{
|
||||
position = new Vector3Int(x, 0, z),
|
||||
size = size,
|
||||
orientation = orientation
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return placements;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Performs the specified action for each position inside the size of this placement.
|
||||
///
|
||||
/// <example>For the placement {(2, 0, 3), (1, 2), East} the action would be called twice with the parameters (2, 0, 3) and (3, 0, 3).</example>
|
||||
/// </summary>
|
||||
public void ForEachPosition(Action<Vector3Int> action)
|
||||
{
|
||||
var bottomLeft = BottomLeft;
|
||||
|
||||
for (var z = 0; z < (orientation is Orientation.North or Orientation.South ? size.y : size.x); z++)
|
||||
{
|
||||
for (var x = 0; x < (orientation is Orientation.North or Orientation.South ? size.x : size.y); x++)
|
||||
{
|
||||
action(bottomLeft + new Vector3Int(x, 0, z));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public string ToStringShort() => $"{{{position}, {orientation}}}";
|
||||
public override string ToString() => $"{{{position}, {size}, {orientation}}}";
|
||||
}
|
||||
}
|
||||
3
Assets/Engine/Runtime/Utilities/Placement.cs.meta
Normal file
3
Assets/Engine/Runtime/Utilities/Placement.cs.meta
Normal file
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: fd604a23d14e49aeb740a8108bd35111
|
||||
timeCreated: 1669114833
|
||||
Reference in New Issue
Block a user