initialize repo
This commit is contained in:
26
Lib/Civilization.Core/Actions/ActionQueue.cs
Normal file
26
Lib/Civilization.Core/Actions/ActionQueue.cs
Normal file
@@ -0,0 +1,26 @@
|
||||
using Civilization.Core.Interfaces;
|
||||
|
||||
namespace Civilization.Core.Actions;
|
||||
|
||||
public class ActionQueue
|
||||
{
|
||||
private readonly Queue<IGameAction> _pending = new();
|
||||
private readonly Stack<ExecutedAction> _history = new();
|
||||
|
||||
public void Enqueue(IGameAction action)
|
||||
{
|
||||
_pending.Enqueue(action);
|
||||
}
|
||||
|
||||
public void ExecuteAll(GameActionContext context)
|
||||
{
|
||||
while (_pending.Count > 0)
|
||||
{
|
||||
var action = _pending.Dequeue();
|
||||
if (!action.CanExecute(context)) continue;
|
||||
|
||||
action.Execute(context);
|
||||
_history.Push(new ExecutedAction(action, context));
|
||||
}
|
||||
}
|
||||
}
|
15
Lib/Civilization.Core/Actions/ExecutedAction.cs
Normal file
15
Lib/Civilization.Core/Actions/ExecutedAction.cs
Normal file
@@ -0,0 +1,15 @@
|
||||
using Civilization.Core.Interfaces;
|
||||
|
||||
namespace Civilization.Core.Actions;
|
||||
|
||||
public class ExecutedAction
|
||||
{
|
||||
public IGameAction Action { get; }
|
||||
public GameActionContext ContextSnapshot { get; }
|
||||
|
||||
public ExecutedAction(IGameAction action, GameActionContext snapshot)
|
||||
{
|
||||
Action = action;
|
||||
ContextSnapshot = snapshot;
|
||||
}
|
||||
}
|
39
Lib/Civilization.Core/Actions/ExpandTerritoryAction.cs
Normal file
39
Lib/Civilization.Core/Actions/ExpandTerritoryAction.cs
Normal file
@@ -0,0 +1,39 @@
|
||||
using Civilization.Core.Interfaces;
|
||||
|
||||
|
||||
namespace Civilization.Core.Actions;
|
||||
|
||||
public class ExpandTerritoryAction(Guid cityId, Vec2I targetTile) : IGameAction
|
||||
{
|
||||
public Guid CityId { get; } = cityId;
|
||||
public Vec2I TargetTile { get; } = targetTile;
|
||||
|
||||
public bool CanExecute(GameActionContext context)
|
||||
{
|
||||
var city = context.State.FindCity(CityId);
|
||||
if (city == null || city.ActionPoints < 1) return false;
|
||||
|
||||
if (!context.Map.Grid.IsValidPosition(TargetTile)) return false;
|
||||
|
||||
var tile = context.Map.GetTile(TargetTile);
|
||||
if (tile is not { OwnerId: null }) return false;
|
||||
|
||||
return city.Territory.Any(t =>
|
||||
{
|
||||
var neighbors = context.Map.GetNeighbors(t);
|
||||
return neighbors.Contains(tile);
|
||||
});
|
||||
}
|
||||
|
||||
public void Execute(GameActionContext context)
|
||||
{
|
||||
var city = context.State.FindCity(CityId)!;
|
||||
city.ClaimTile(context.Map, TargetTile);
|
||||
city.SpendActionPoint();
|
||||
}
|
||||
|
||||
public void Undo(GameActionContext context)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
19
Lib/Civilization.Core/Actions/GameActionContext.cs
Normal file
19
Lib/Civilization.Core/Actions/GameActionContext.cs
Normal file
@@ -0,0 +1,19 @@
|
||||
using Civilization.Core.Game;
|
||||
|
||||
namespace Civilization.Core.Actions;
|
||||
|
||||
public class GameActionContext
|
||||
{
|
||||
public GameMap Map { get; }
|
||||
public List<Player> Players { get; }
|
||||
public GameState State { get; }
|
||||
|
||||
public GameActionContext(GameState gameState)
|
||||
{
|
||||
State = gameState;
|
||||
Map = gameState.Map;
|
||||
Players = gameState.Players;
|
||||
}
|
||||
|
||||
public Player CurrentPlayer => State.CurrentPlayer;
|
||||
}
|
31
Lib/Civilization.Core/Actions/MoveUnitAction.cs
Normal file
31
Lib/Civilization.Core/Actions/MoveUnitAction.cs
Normal file
@@ -0,0 +1,31 @@
|
||||
using Civilization.Core.Interfaces;
|
||||
|
||||
|
||||
namespace Civilization.Core.Actions;
|
||||
|
||||
public class MoveUnitAction(Guid unitId, Vec2I targetPosition) : IGameAction
|
||||
{
|
||||
public Guid UnitId { get; } = unitId;
|
||||
public Vec2I TargetPosition { get; } = targetPosition;
|
||||
|
||||
public bool CanExecute(GameActionContext context)
|
||||
{
|
||||
var unit = context.State.FindUnit(UnitId);
|
||||
if (unit == null || unit.OwnerId != context.CurrentPlayer.Id) return false;
|
||||
|
||||
return context.Map.Grid.IsValidPosition(TargetPosition) && unit.CanMoveTo(TargetPosition, context.Map);
|
||||
}
|
||||
|
||||
public void Execute(GameActionContext context)
|
||||
{
|
||||
var unit = context.State.FindUnit(UnitId);
|
||||
if (unit == null) return;
|
||||
unit.Position = TargetPosition;
|
||||
unit.ActionPoints -= 1;
|
||||
}
|
||||
|
||||
public void Undo(GameActionContext context)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
45
Lib/Civilization.Core/Actions/SettleCityAction.cs
Normal file
45
Lib/Civilization.Core/Actions/SettleCityAction.cs
Normal file
@@ -0,0 +1,45 @@
|
||||
using Civilization.Core.Game;
|
||||
using Civilization.Core.Interfaces;
|
||||
using Civilization.Core.Units;
|
||||
|
||||
namespace Civilization.Core.Actions;
|
||||
|
||||
public class SettleCityAction(Guid unitId) : IGameAction
|
||||
{
|
||||
private const int CityNearbyRange = 4;
|
||||
public Guid UnitId { get; } = unitId;
|
||||
|
||||
public bool CanExecute(GameActionContext context)
|
||||
{
|
||||
var unit = context.State.FindUnit(UnitId);
|
||||
|
||||
if (unit == null || !unit.HasTag(UnitTag.Settle)) return false;
|
||||
if (unit.OwnerId != context.CurrentPlayer.Id) return false;
|
||||
if (unit.ActionPoints < 1) return false;
|
||||
|
||||
var tile = context.Map.GetTile(unit.Position);
|
||||
if (tile is not { OwnerId: null }) return false;
|
||||
|
||||
// Later we could also check if there is city nearby
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public void Execute(GameActionContext context)
|
||||
{
|
||||
var unit = context.State.FindUnit(UnitId)!;
|
||||
var position = unit.Position;
|
||||
|
||||
context.State.RemoveUnit(UnitId);
|
||||
|
||||
var city = new City(unit.OwnerId, position);
|
||||
city.ClaimTile(context.Map, position);
|
||||
|
||||
context.State.AddCity(city);
|
||||
}
|
||||
|
||||
public void Undo(GameActionContext context)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user