- Timestamp:
- Mar 26, 2015, 4:31:05 PM (10 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/UEngine.pas
r6 r7 20 20 21 21 TMetroStation = class 22 private 23 public 22 24 Engine: TEngine; 23 25 Shape: TStationShape; … … 25 27 Passengers: TMetroPassengers; 26 28 Lines: TMetroLines; 29 ShapeDistance: array[TStationShape] of Integer; 30 function GetBestStationForShape(Shape: TStationShape; Check: TMetroStation): Boolean; 27 31 constructor Create; 28 32 destructor Destroy; override; … … 127 131 procedure DrawShape(Canvas: TCanvas; Position: TPoint; Shape: TStationShape; 128 132 Size: Integer); 133 procedure ComputeShapeDistance; 134 procedure ComputeShapeDistanceStation(Station: TMetroStation; 135 UpdatedShape: TStationShape; Distance: Integer); 129 136 public 130 137 Passengers: TMetroPassengers; … … 226 233 Result.Shape := TStationShape(Random(Integer(Engine.ShapeCount))); 227 234 Add(Result); 235 Engine.ComputeShapeDistance; 228 236 end; 229 237 … … 272 280 end; 273 281 end; 282 Engine.ComputeShapeDistance; 274 283 end; 275 284 … … 292 301 end; 293 302 end; 303 Engine.ComputeShapeDistance; 294 304 end; 295 305 … … 388 398 389 399 { TMetroStation } 400 401 function TMetroStation.GetBestStationForShape(Shape: TStationShape; 402 Check: TMetroStation): Boolean; 403 var 404 I: Integer; 405 Distance: Integer; 406 StationIndex: Integer; 407 begin 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; 426 end; 390 427 391 428 constructor TMetroStation.Create; … … 488 525 end; 489 526 527 procedure TEngine.ComputeShapeDistance; 528 var 529 I: Integer; 530 L: Integer; 531 S: TStationShape; 532 begin 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; 546 end; 547 548 procedure TEngine.ComputeShapeDistanceStation(Station: TMetroStation; 549 UpdatedShape: TStationShape; Distance: Integer); 550 var 551 I: Integer; 552 StationIndex: Integer; 553 begin 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; 569 end; 570 490 571 procedure TEngine.Tick; 491 572 const … … 499 580 PosDelta: Integer; 500 581 TargetStationIndex: Integer; 582 CurrentStation: TMetroStation; 583 BestStation: TMetroStation; 501 584 begin 502 585 if State = gsRunning then begin … … 531 614 if InStation then begin 532 615 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; 559 617 560 618 // Choose next target station … … 568 626 end; 569 627 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 570 661 LastPosDelta := Abs(TrackPos - Line.GetStationTrackPos(TargetStation)); 571 662 InStation := False; … … 594 685 for I := 0 to Stations.Count - 1 do 595 686 with TMetroStation(Stations[I]) do begin 596 if Passengers.Count > MaxWaitingPassengers then State := gsGameOver;687 //if Passengers.Count > MaxWaitingPassengers then State := gsGameOver; 597 688 end; 598 689 … … 837 928 Canvas.Pen.Color := clBlack; 838 929 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); 839 934 840 935 // Draw passengers
Note:
See TracChangeset
for help on using the changeset viewer.