Changeset 265 for trunk/UGame.pas


Ignore:
Timestamp:
Jan 15, 2019, 1:03:40 AM (6 years ago)
Author:
chronos
Message:
  • Modified: Cell power is now internally represented as unit power (TUnit class).
  • Modified: Allow to have only one player in the game.
  • Added: New win objective None to just play freely without any win objective.
  • Added: New win objective to capture entire map.
  • Added: TGameSystem class to represent various game play systems of other existing games.
  • Fixed: Clear correctly defender player from unit moves if his cell is captured.
  • Fixed: Do not allow to remove too many players to have at least minimum players.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/UGame.pas

    r263 r265  
    88  Classes, SysUtils, ExtCtrls, Graphics, XMLConf, XMLRead, XMLWrite, Forms,
    99  DOM, Math, LazFileUtils, UXMLUtils, Dialogs, LCLType, LCLIntf, fgl,
    10   UGeometry, UPlayer, UMap, UMapType;
     10  UGeometry, UPlayer, UMap, UMapType, UUnit, UGameSystem;
    1111
    1212const
    1313  DefaultPlayerStartUnits = 5;
     14  MinPlayerCount = 1;
    1415  MaxPlayerCount = 8;
    1516
     
    2829  TGrowCells = (gcNone, gcPlayerCities, gcPlayerAll);
    2930  TMapType = (mtNone, mtHexagon, mtSquare, mtTriangle, mtRandom, mtIsometric);
    30   TWinObjective = (woDefeatAllOponents, woDefeatAllOponentsCities,
    31     woSpecialCaptureCell, woStayAliveForDefinedTurns);
     31  TWinObjective = (woNone, woDefeatAllOponents, woDefeatAllOponentsCities,
     32    woSpecialCaptureCell, woStayAliveForDefinedTurns, woCaptureEntireMap);
    3233
    3334  { TGame }
     
    3536  TGame = class
    3637  private
     38    FGameSystem: TGameSystem;
    3739    FMapType: TMapType;
    3840    FOnChange: TNotifyEvent;
     
    4648    ProbabilityMatrix: array of array of Single;
    4749    procedure RecordTurnStats;
     50    procedure SetGameSystem(AValue: TGameSystem);
    4851    procedure SetMapType(AValue: TMapType);
    4952    procedure SetRunning(AValue: Boolean);
     
    5760    DevelMode: Boolean;
    5861    Players: TPlayers;
     62    Units: TUnits;
    5963    Map: TMap;
    6064    MapImageFileName: string;
     
    7781    BridgeEnabled: Boolean;
    7882    MaxPower: Integer;
    79     EmptyCellsNeutral: Boolean;
    8083    procedure PostConfig;
    8184    procedure Assign(Source: TGame);
     
    9598    property Running: Boolean read FRunning write SetRunning;
    9699    property MapType: TMapType read FMapType write SetMapType;
     100    property GameSystem: TGameSystem read FGameSystem write SetGameSystem;
    97101  published
    98102    property OnMoveUpdated: TMoveUpdatedEvent read FOnMoveUpdated write FOnMoveUpdated;
     
    123127
    124128resourcestring
    125   SMinimumPlayers = 'You need at least two players';
     129  SMinimumPlayers = 'You need at least one player';
    126130  SHuman = 'Human';
    127131  SComputer = 'Computer';
     
    263267  if FRunning = AValue then Exit;
    264268  if AValue then begin
    265     if Players.Count < 2 then raise Exception.Create(SMinimumPlayers);
     269    if Players.Count < 1 then raise Exception.Create(SMinimumPlayers);
    266270    FRunning := AValue;
    267271  end else begin
     
    284288          else Terrain := ttNormal;
    285289      end;
    286     Power := Random(MaxNeutralUnits + 1);
     290    if not Assigned(OneUnit) then
     291      OneUnit := Units.AddNew(GameSystem.UnitKinds[0], Random(MaxNeutralUnits + 1));
    287292    Player := nil;
    288293  end;
     
    428433  BridgeEnabled := Source.BridgeEnabled;
    429434  MaxPower := Source.MaxPower;
    430   EmptyCellsNeutral := Source.EmptyCellsNeutral;
     435  GameSystem := Source.GameSystem;
    431436end;
    432437
     
    452457    SetValue(DOMString(Path + '/StayAliveForDefinedTurns'), StayAliveForDefinedTurns);
    453458    SetValue(DOMString(Path + '/SpecialCaptureCellCount'), SpecialCaptureCellCount);
    454     SetValue(DOMString(Path + '/EmptyCellsNeutral'), EmptyCellsNeutral);
    455459    Players.SaveConfig(Config, Path + '/Players');
    456460  end;
     
    488492    StayAliveForDefinedTurns := GetValue(DOMString(Path + '/StayAliveForDefinedTurns'), 20);
    489493    SpecialCaptureCellCount := GetValue(DOMString(Path + '/SpecialCaptureCellCount'), 1);
    490     EmptyCellsNeutral := GetValue(DOMString(Path + '/EmptyCellsNeutral'), False);
    491494    Players.LoadConfig(Config, Path + '/Players');
    492495  end;
     
    524527      WinObjective := TWinObjective(ReadInteger(RootNode, 'WinObjective', Integer(woDefeatAllOponents)));
    525528      StayAliveForDefinedTurns := ReadInteger(RootNode, 'StayAliveForDefinedTurns', 10);
    526       EmptyCellsNeutral := ReadBoolean(RootNode, 'EmptyCellsNeutral', False);
     529
     530      NewNode := FindNode('GameSystem');
     531      if Assigned(NewNode) then
     532        GameSystem.LoadFromNode(NewNode);
    527533
    528534      NewNode := FindNode('Map');
     
    536542        else CurrentPlayer := nil;
    537543
     544      NewNode := FindNode('Units');
     545      if Assigned(NewNode) then
     546        Units.LoadFromNode(NewNode);
     547
    538548      Map.Cells.FixRefId;
     549      Units.FixRefId;
    539550
    540551      for I := 0 to Players.Count - 1 do begin
     
    578589      WriteInteger(RootNode, 'WinObjective', Integer(WinObjective));
    579590      WriteInteger(RootNode, 'StayAliveForDefinedTurns', StayAliveForDefinedTurns);
    580       WriteBoolean(RootNode, 'EmptyCellsNeutral', EmptyCellsNeutral);
    581591      WriteBoolean(RootNode, 'Running', Running);
     592
     593      NewNode := OwnerDocument.CreateElement('GameSystem');
     594      AppendChild(NewNode);
     595      GameSystem.SaveToNode(NewNode);
    582596
    583597      NewNode := OwnerDocument.CreateElement('Map');
     
    588602      AppendChild(NewNode);
    589603      Players.SaveToNode(NewNode);
     604
     605      NewNode := OwnerDocument.CreateElement('Units');
     606      AppendChild(NewNode);
     607      Units.SaveToNode(NewNode);
    590608    end;
    591609    if ExtractFileDir(FileName) <> '' then
     
    633651    TurnStats.Add(NewStat);
    634652  end;
     653end;
     654
     655procedure TGame.SetGameSystem(AValue: TGameSystem);
     656begin
     657  if FGameSystem = AValue then Exit;
     658  FGameSystem := AValue;
    635659end;
    636660
     
    687711  R: Boolean;
    688712  I: Integer;
     713  PlayersCount: Integer;
    689714begin
    690715  Winner := nil;
     
    724749    if TurnCounter > StayAliveForDefinedTurns then
    725750      EndGame(nil);
     751  end else
     752  if WinObjective = woCaptureEntireMap then begin
     753    Player := nil;
     754    for I := 0 to Map.Cells.Count - 1 do
     755    if TCell(Map.Cells[I]).Terrain <> ttVoid then begin
     756      if (TCell(Map.Cells[I]).Player <> nil) then begin
     757        if Player = nil then begin
     758          // First player found
     759          Player := TPlayer(TCell(Map.Cells[I]).Player);
     760        end else
     761        if Player <> TCell(Map.Cells[I]).Player then begin
     762          // Multiple players still alive
     763          Player := nil;
     764          Break;
     765        end;
     766      end else begin
     767        // Neutral cell
     768        Player := nil;
     769        Break;
     770      end;
     771    end;
     772    if Player <> nil then
     773      EndGame(Player);
    726774  end;
    727775end;
     
    729777constructor TGame.Create;
    730778begin
     779  Units := TUnits.Create;
     780  Units.Game := Self;
    731781  Map := TMap.Create;
     782  Map.Game := Self;
    732783  Players := TPlayers.Create;
    733784  Players.Game := Self;
     
    742793  MaxNeutralUnits := Min(4, MaxPower);
    743794
    744   Map.Game := Self;
    745795  Map.Size := TPoint.Create(3, 3);
    746796end;
     
    750800  FreeAndNil(Players);
    751801  FreeAndNil(Map);
     802  FreeAndNil(Units);
    752803  inherited Destroy;
    753804end;
     
    784835  end;
    785836
    786   for Player in Players do Player.StartCell := nil;
     837  for Player in Players do begin
     838    Player.Reset;
     839    Player.StartCell := nil;
     840  end;
    787841  I := 0;
    788842  for Player in Players do
     
    797851        StartCell.Terrain := ttCity;
    798852        StartCell.Player := Player;
    799         StartCell.Power := Player.StartUnits;
     853        if not Assigned(StartCell.OneUnit) then
     854          StartCell.OneUnit := Units.AddNew(GameSystem.UnitKinds[0], Player.StartUnits);
     855        StartCell.OneUnit.Power := Player.StartUnits;
     856        StartCell.OneUnit.Kind := GameSystem.UnitKinds[0];
    800857      end;
    801858    end;
Note: See TracChangeset for help on using the changeset viewer.