Parking/Assets/Scripts/ParkingManager.cs

174 lines
6.6 KiB
C#
Raw Normal View History

2022-08-25 17:58:26 +02:00
using System;
using System.Collections.Generic;
2022-08-28 22:42:21 +02:00
using System.Linq;
2022-08-25 17:58:26 +02:00
using TMPro;
using UnityEngine;
namespace Parking
2022-08-25 17:58:26 +02:00
{
public class ParkingManager : MonoBehaviour
2022-08-28 22:42:21 +02:00
{
public const float Width = 68;
public const float Height = 29;
2022-08-28 22:42:21 +02:00
public static ParkingManager Instance;
2022-08-31 21:19:20 +02:00
public readonly List<List<Spot>> SpotMap = new() {new(), new(), new(), new()};
2022-08-28 22:42:21 +02:00
[SerializeField] private int stepTime = 15;
[SerializeField] private TextMeshProUGUI timeText;
[SerializeField] public TextMeshProUGUI countsText;
[SerializeField] public GameObject spotPrefabA;
[SerializeField] public GameObject spotPrefabB;
[SerializeField] public GameObject spotPrefabC;
2022-08-31 21:19:20 +02:00
[SerializeField] public GameObject spotPrefabD;
2022-09-01 22:31:57 +02:00
[SerializeField] public GameObject carPrefab;
2022-08-28 22:42:21 +02:00
private readonly float[] _spotHeights = {3.5f, 4f, 5f, 7.5f};
2022-08-28 22:42:21 +02:00
2022-09-01 22:31:57 +02:00
private TimeSpan _currentTime = TimeSpan.FromHours(5);
2022-08-28 22:42:21 +02:00
private void Awake()
2022-08-28 22:42:21 +02:00
{
Instance = this;
2022-08-28 22:42:21 +02:00
}
private void Start()
{
timeText.text = _currentTime.ToString();
DataImporter.ReadFile("Assets/Data/v1.csv");
Debug.Log(DataImporter.Drivers);
InitialConfigurationGenerator generator = new();
ArrangeSpots(generator.FindSolution());
2022-08-28 22:42:21 +02:00
}
2022-08-29 23:01:18 +02:00
public void AdvanceTime()
{
_currentTime += TimeSpan.FromMinutes(15);
timeText.text = _currentTime.ToString();
2022-09-01 22:31:57 +02:00
foreach (Driver driver in DataImporter.Drivers)
{
if (_currentTime <= driver.Times[1].TimeOfDay && _currentTime > driver.Times[0].TimeOfDay && !driver.Parked)
{
PlaceCarOnParking(driver);
}else if (_currentTime > driver.Times[1].TimeOfDay && driver.Parked)
{
driver.Spot.Free = true;
driver.Parked = false;
driver.Spot = null;
Destroy(driver.GameObject);
}
}
}
private void PlaceCarOnParking(Driver driver)
{
for (int i = 0; i < SpotMap.Count; i++)
{
foreach (Spot spot in SpotMap[i])
{
if (spot.Size == driver.Size && spot.Free)
{
spot.Free = false;
driver.Spot = spot;
driver.Parked = true;
driver.GameObject = Instantiate(carPrefab, spot.GameObject.transform, true);
driver.GameObject.transform.position = spot.GameObject.transform.position;
return;
}
}
}
Debug.Log($"Placing failed for car {driver.Priority}");
}
2022-08-29 23:01:18 +02:00
public void UpdateText(string text)
2022-08-29 23:01:18 +02:00
{
countsText.text = text;
2022-08-29 23:01:18 +02:00
}
private void ArrangeSpots(int[,] spotsCreated)
2022-08-29 23:01:18 +02:00
{
var spotMap = GenerateSpotMap(spotsCreated);
var maxP3 = _spotHeights[(int) spotMap[2].Max().Size];
var maxP2 = _spotHeights[(int) spotMap[1].Max().Size];
for (var i = 0; i < 4; i++)
2022-08-29 23:01:18 +02:00
{
float currentY;
switch (i)
2022-08-29 23:01:18 +02:00
{
case 0:
currentY = -Height / 2.0f + 2f;
break;
case 1:
currentY = Height / 2 - 5.5f - 5f - maxP3 / 2.0f - maxP2;
2022-08-29 23:01:18 +02:00
break;
case 2:
currentY = Height / 2 - 5.5f - 5f - maxP3 / 2.0f;
2022-08-29 23:01:18 +02:00
break;
case 3:
currentY = Height / 2.0f - 2f;
2022-08-29 23:01:18 +02:00
break;
default:
currentY = -10;
2022-08-29 23:01:18 +02:00
break;
}
float currentX;
if (i != 0) currentX = -Width / 2f - 2.25f / 2f + 2.25f;
else currentX = -Width / 2f + 5.5f - 2.25f / 2f + 2.25f + 1.75f;
2022-08-28 22:42:21 +02:00
var flipped = false;
2022-08-28 22:42:21 +02:00
for (var j = 0; j < spotMap[i].Count; j++)
{
spotMap[i][j].Flipped = flipped;
var alignTop = i % 2 != 0;
switch (spotMap[i][j].Size)
{
case Size.A:
spotMap[i][j].GameObject = Instantiate(Instance.spotPrefabA);
spotMap[i][j].GameObject.transform.position = new Vector3(currentX, currentY, 0);
break;
case Size.B:
spotMap[i][j].GameObject = Instantiate(Instance.spotPrefabB);
spotMap[i][j].GameObject.transform.position =
new Vector3(currentX, currentY + (alignTop ? -1 : 1) * 0.25f, 0);
break;
case Size.C:
spotMap[i][j].GameObject = Instantiate(Instance.spotPrefabC);
spotMap[i][j].GameObject.transform.position =
new Vector3(currentX, currentY + (alignTop ? -1 : 1) * 0.5f, 0);
break;
2022-08-31 21:19:20 +02:00
case Size.D:
spotMap[i][j].GameObject = Instantiate(Instance.spotPrefabD);
spotMap[i][j].GameObject.transform.position =
new Vector3(currentX, currentY -2.0f, 0);
break;
}
2022-09-01 22:31:57 +02:00
spotMap[i][j].GameObject.transform.rotation =
Quaternion.Euler(new Vector3(0, 0, spotMap[i][j].Flipped ? 180 : 0));
currentX += 2.25f;
flipped = !flipped;
2022-08-28 22:42:21 +02:00
}
}
}
private List<List<Spot>> GenerateSpotMap(int[,] spotsCreated)
2022-08-28 22:42:21 +02:00
{
for (var i = 0; i < 4; i++)
for (var j = 0; j < spotsCreated.GetLength(1); j++)
for (var k = 0; k < spotsCreated[i, j]; k++)
SpotMap[i].Add(new Spot((Size) j, false));
SpotMap[0].Sort((a, b) => a.Size.CompareTo(b.Size)); // ascending sort
SpotMap[1].Sort((a, b) => b.Size.CompareTo(a.Size)); // descending sort
SpotMap[2].Sort((a, b) => b.Size.CompareTo(a.Size)); // descending sort
SpotMap[3].Sort((a, b) => a.Size.CompareTo(b.Size)); // ascending sort
2022-08-31 21:19:20 +02:00
SpotMap[2].Add(new Spot(Size.D, false));
return SpotMap;
2022-08-28 22:42:21 +02:00
}
}
}