Changeset 7


Ignore:
Timestamp:
Mar 26, 2015, 4:31:05 PM (9 years ago)
Author:
chronos
Message:
  • Added: Now passengers use path finding to change line and wait for nearest station with same symbol.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/UEngine.pas

    r6 r7  
    2020
    2121  TMetroStation = class
     22  private
     23  public
    2224    Engine: TEngine;
    2325    Shape: TStationShape;
     
    2527    Passengers: TMetroPassengers;
    2628    Lines: TMetroLines;
     29    ShapeDistance: array[TStationShape] of Integer;
     30    function GetBestStationForShape(Shape: TStationShape; Check: TMetroStation): Boolean;
    2731    constructor Create;
    2832    destructor Destroy; override;
     
    127131    procedure DrawShape(Canvas: TCanvas; Position: TPoint; Shape: TStationShape;
    128132      Size: Integer);
     133    procedure ComputeShapeDistance;
     134    procedure ComputeShapeDistanceStation(Station: TMetroStation;
     135      UpdatedShape: TStationShape; Distance: Integer);
    129136  public
    130137    Passengers: TMetroPassengers;
     
    226233  Result.Shape := TStationShape(Random(Integer(Engine.ShapeCount)));
    227234  Add(Result);
     235  Engine.ComputeShapeDistance;
    228236end;
    229237
     
    272280       end;
    273281  end;
     282  Engine.ComputeShapeDistance;
    274283end;
    275284
     
    292301      end;
    293302  end;
     303  Engine.ComputeShapeDistance;
    294304end;
    295305
     
    388398
    389399{ TMetroStation }
     400
     401function TMetroStation.GetBestStationForShape(Shape: TStationShape;
     402  Check: TMetroStation): Boolean;
     403var
     404  I: Integer;
     405  Distance: Integer;
     406  StationIndex: Integer;
     407begin
     408  Distance := High(Integer);
     409  for I := 0 to Lines.Count - 1 do
     410  with TMetroLine(Lines[I]) do begin
     411    StationIndex := Stations.IndexOf(Self);
     412    if StationIndex > 0 then begin
     413      if (TMetroStation(Stations[StationIndex - 1]).ShapeDistance[Shape] <> -1) and
     414        (TMetroStation(Stations[StationIndex - 1]).ShapeDistance[Shape] < Distance) then begin
     415        Distance := TMetroStation(Stations[StationIndex - 1]).ShapeDistance[Shape];
     416      end;
     417    end;
     418    if (StationIndex >= 0) and (StationIndex < Stations.Count - 1) then begin
     419      if (TMetroStation(Stations[StationIndex + 1]).ShapeDistance[Shape] <> -1) and
     420        (TMetroStation(Stations[StationIndex + 1]).ShapeDistance[Shape] < Distance) then begin
     421        Distance := TMetroStation(Stations[StationIndex + 1]).ShapeDistance[Shape];
     422      end;
     423    end
     424  end;
     425  Result := Check.ShapeDistance[Shape] = Distance;
     426end;
    390427
    391428constructor TMetroStation.Create;
     
    488525end;
    489526
     527procedure TEngine.ComputeShapeDistance;
     528var
     529  I: Integer;
     530  L: Integer;
     531  S: TStationShape;
     532begin
     533  // Reset all distances
     534  for I := 0 to Stations.Count - 1 do
     535  with TMetroStation(Stations[I]) do begin
     536    for S := Low(ShapeDistance) to High(ShapeDistance) do
     537      ShapeDistance[S] := -1;
     538  end;
     539
     540  // Propagate shape distance for all stations
     541  // Distace 0 means that station is final target
     542  for I := 0 to Stations.Count - 1 do
     543  with TMetroStation(Stations[I]) do begin
     544    ComputeShapeDistanceStation(TMetroStation(Stations[I]), Shape, 0);
     545  end;
     546end;
     547
     548procedure TEngine.ComputeShapeDistanceStation(Station: TMetroStation;
     549  UpdatedShape: TStationShape; Distance: Integer);
     550var
     551  I: Integer;
     552  StationIndex: Integer;
     553begin
     554  with Station do begin
     555    if (Distance < ShapeDistance[UpdatedShape]) or (ShapeDistance[UpdatedShape] = -1) then begin
     556      ShapeDistance[UpdatedShape] := Distance;
     557      // Do for all lines connected to station
     558      for I := 0 to Lines.Count - 1 do
     559      with TMetroLine(Lines[I]) do begin
     560        StationIndex := Stations.IndexOf(Station);
     561        // Update for all adjecent stations
     562        if StationIndex > 0 then
     563          ComputeShapeDistanceStation(TMetroStation(Stations[StationIndex - 1]), UpdatedShape, Station.ShapeDistance[UpdatedShape] + 1);
     564        if (StationIndex >= 0) and (StationIndex < Stations.Count - 1) then
     565          ComputeShapeDistanceStation(TMetroStation(Stations[StationIndex + 1]), UpdatedShape, Station.ShapeDistance[UpdatedShape] + 1);
     566      end;
     567    end;
     568  end;
     569end;
     570
    490571procedure TEngine.Tick;
    491572const
     
    499580  PosDelta: Integer;
    500581  TargetStationIndex: Integer;
     582  CurrentStation: TMetroStation;
     583  BestStation: TMetroStation;
    501584begin
    502585  if State = gsRunning then begin
     
    531614      if InStation then begin
    532615        if (Now - StationStopTime) > OneSecond then begin
    533           // Unload passengers
    534           for P := Passengers.Count - 1 downto 0 do begin
    535             if TMetroPassenger(Passengers[P]).Shape = TargetStation.Shape then begin
    536               Passenger := TMetroPassenger(Passengers[P]);
    537               Passengers.Delete(P);
    538               Self.Passengers.Remove(Passenger);
    539               Inc(ServedPassengerCount);
    540             end;
    541           end;
    542           while (TargetStation.Passengers.Count > 0) and (Passengers.Count < TrainPassengerCount) do begin
    543             Passenger := TMetroPassenger(TargetStation.Passengers[0]);
    544             Passenger.Station := nil;
    545             TargetStation.Passengers.Delete(0);
    546             Passengers.Add(Passenger);
    547             Passenger.Train := TMetroTrain(Trains[I]);
    548           end;
    549 
    550 
    551           // Load new passengers
    552           while (TargetStation.Passengers.Count > 0) and (Passengers.Count < TrainPassengerCount) do begin
    553             Passenger := TMetroPassenger(TargetStation.Passengers[0]);
    554             Passenger.Station := nil;
    555             TargetStation.Passengers.Delete(0);
    556             Passengers.Add(Passenger);
    557             Passenger.Train := TMetroTrain(Trains[I]);
    558           end;
     616          CurrentStation := TargetStation;
    559617
    560618          // Choose next target station
     
    568626          end;
    569627          TargetStation := TMetroStation(Line.Stations[TargetStationIndex]);
     628
     629          // Unload passengers in target station
     630          for P := Passengers.Count - 1 downto 0 do begin
     631            if TMetroPassenger(Passengers[P]).Shape = CurrentStation.Shape then begin
     632              Passenger := TMetroPassenger(Passengers[P]);
     633              Passengers.Delete(P);
     634              Self.Passengers.Remove(Passenger);
     635              Inc(ServedPassengerCount);
     636            end;
     637          end;
     638          // Unload passengers to change line
     639          for P := Passengers.Count - 1 downto 0 do begin
     640            if not CurrentStation.GetBestStationForShape(TMetroPassenger(Passengers[P]).Shape, TargetStation) then begin
     641              Passenger := TMetroPassenger(Passengers[P]);
     642              Passengers.Delete(P);
     643              CurrentStation.Passengers.Add(Passenger);
     644              Passenger.Station := CurrentStation;
     645            end;
     646          end;
     647
     648          // Load new passengers
     649          for P := CurrentStation.Passengers.Count - 1 downto 0 do begin
     650            if (Passengers.Count < TrainPassengerCount) then begin
     651              Passenger := TMetroPassenger(CurrentStation.Passengers[P]);
     652              if CurrentStation.GetBestStationForShape(Passenger.Shape, TargetStation) then begin
     653                Passenger.Station := nil;
     654                CurrentStation.Passengers.Delete(P);
     655                Passengers.Add(Passenger);
     656                Passenger.Train := TMetroTrain(Trains[I]);
     657              end;
     658            end else Break; // No more space
     659          end;
     660
    570661          LastPosDelta := Abs(TrackPos - Line.GetStationTrackPos(TargetStation));
    571662          InStation := False;
     
    594685  for I := 0 to Stations.Count - 1 do
    595686  with TMetroStation(Stations[I]) do begin
    596     if Passengers.Count > MaxWaitingPassengers then State := gsGameOver;
     687    //if Passengers.Count > MaxWaitingPassengers then State := gsGameOver;
    597688  end;
    598689
     
    837928    Canvas.Pen.Color := clBlack;
    838929    DrawShape(Canvas, Position, Shape, StationSize);
     930    Text := '';
     931    for P := 0 to 2 do
     932      Text := Text + IntToStr(ShapeDistance[TStationShape(P)]) + ',';
     933    Canvas.TextOut(Position.X + 20, Position.Y + 20, Text);
    839934
    840935    // Draw passengers
Note: See TracChangeset for help on using the changeset viewer.