Moved common TPoint direction code into new unit
This commit is contained in:
parent
19509c6173
commit
8eb76329c1
|
@ -153,6 +153,10 @@
|
||||||
<Filename Value="solvers\USnowverload.pas"/>
|
<Filename Value="solvers\USnowverload.pas"/>
|
||||||
<IsPartOfProject Value="True"/>
|
<IsPartOfProject Value="True"/>
|
||||||
</Unit>
|
</Unit>
|
||||||
|
<Unit>
|
||||||
|
<Filename Value="UCommon.pas"/>
|
||||||
|
<IsPartOfProject Value="True"/>
|
||||||
|
</Unit>
|
||||||
</Units>
|
</Units>
|
||||||
</ProjectOptions>
|
</ProjectOptions>
|
||||||
<CompilerOptions>
|
<CompilerOptions>
|
||||||
|
|
|
@ -0,0 +1,45 @@
|
||||||
|
{
|
||||||
|
Solutions to the Advent Of Code.
|
||||||
|
Copyright (C) 2023-2024 Stefan Müller
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License as published by the Free Software
|
||||||
|
Foundation, either version 3 of the License, or (at your option) any later
|
||||||
|
version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||||
|
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License along with
|
||||||
|
this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
}
|
||||||
|
|
||||||
|
unit UCommon;
|
||||||
|
|
||||||
|
{$mode ObjFPC}{$H+}
|
||||||
|
|
||||||
|
interface
|
||||||
|
|
||||||
|
uses
|
||||||
|
Classes, SysUtils;
|
||||||
|
|
||||||
|
type
|
||||||
|
PPoint = ^TPoint;
|
||||||
|
|
||||||
|
const
|
||||||
|
CNoDirection: TPoint = (X: 0; Y: 0);
|
||||||
|
CDirectionRight: TPoint = (X: 1; Y: 0);
|
||||||
|
CDirectionDown: TPoint = (X: 0; Y: 1);
|
||||||
|
CDirectionLeft: TPoint = (X: -1; Y: 0);
|
||||||
|
CDirectionUp: TPoint = (X: 0; Y: -1);
|
||||||
|
CDirectionRightDown: TPoint = (X: 1; Y: 1);
|
||||||
|
CDirectionRightUp: TPoint = (X: 1; Y: -1);
|
||||||
|
CDirectionLeftDown: TPoint = (X: -1; Y: 1);
|
||||||
|
CDirectionLeftUp: TPoint = (X: -1; Y: -1);
|
||||||
|
CPCardinalDirections: array[0..3] of PPoint = (@CDirectionRight, @CDirectionDown, @CDirectionLeft, @CDirectionUp);
|
||||||
|
|
||||||
|
implementation
|
||||||
|
|
||||||
|
end.
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
Solutions to the Advent Of Code.
|
Solutions to the Advent Of Code.
|
||||||
Copyright (C) 2023 Stefan Müller
|
Copyright (C) 2023-2024 Stefan Müller
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify it under
|
This program is free software: you can redistribute it and/or modify it under
|
||||||
the terms of the GNU General Public License as published by the Free Software
|
the terms of the GNU General Public License as published by the Free Software
|
||||||
|
@ -22,7 +22,7 @@ unit UFloorWillBeLava;
|
||||||
interface
|
interface
|
||||||
|
|
||||||
uses
|
uses
|
||||||
Classes, SysUtils, Generics.Collections, USolver;
|
Classes, SysUtils, Generics.Collections, USolver, UCommon;
|
||||||
|
|
||||||
type
|
type
|
||||||
|
|
||||||
|
@ -37,7 +37,7 @@ type
|
||||||
{ TTransition }
|
{ TTransition }
|
||||||
|
|
||||||
TTransition = record
|
TTransition = record
|
||||||
IncomingDirection, OutgoingDirection, SplitDirection: TPoint;
|
IncomingDirection, OutgoingDirection, SplitDirection: PPoint;
|
||||||
Tile: Char;
|
Tile: Char;
|
||||||
EnergyChange: TEnergyState;
|
EnergyChange: TEnergyState;
|
||||||
end;
|
end;
|
||||||
|
@ -73,32 +73,31 @@ type
|
||||||
end;
|
end;
|
||||||
|
|
||||||
const
|
const
|
||||||
CNoDirection: TPoint = (X: 0; Y: 0);
|
|
||||||
CEmptyChar = '.';
|
CEmptyChar = '.';
|
||||||
CTransitions: array of TTransition = (
|
CTransitions: array of TTransition = (
|
||||||
(IncomingDirection: (X: 1; Y: 0); OutgoingDirection: (X: 0; Y: -1); SplitDirection: (X: 0; Y: 0); Tile: '/';
|
(IncomingDirection: @CDirectionRight; OutgoingDirection: @CDirectionUp; SplitDirection: @CNoDirection; Tile: '/';
|
||||||
EnergyChange: esWestOrHorizontal),
|
EnergyChange: esWestOrHorizontal),
|
||||||
(IncomingDirection: (X: 0; Y: 1); OutgoingDirection: (X: -1; Y: 0); SplitDirection: (X: 0; Y: 0); Tile: '/';
|
(IncomingDirection: @CDirectionDown; OutgoingDirection: @CDirectionLeft; SplitDirection: @CNoDirection; Tile: '/';
|
||||||
EnergyChange: esWestOrHorizontal),
|
EnergyChange: esWestOrHorizontal),
|
||||||
(IncomingDirection: (X: -1; Y: 0); OutgoingDirection: (X: 0; Y: 1); SplitDirection: (X: 0; Y: 0); Tile: '/';
|
(IncomingDirection: @CDirectionLeft; OutgoingDirection: @CDirectionDown; SplitDirection: @CNoDirection; Tile: '/';
|
||||||
EnergyChange: esEastOrVertical),
|
EnergyChange: esEastOrVertical),
|
||||||
(IncomingDirection: (X: 0; Y: -1); OutgoingDirection: (X: 1; Y: 0); SplitDirection: (X: 0; Y: 0); Tile: '/';
|
(IncomingDirection: @CDirectionUp; OutgoingDirection: @CDirectionRight; SplitDirection: @CNoDirection; Tile: '/';
|
||||||
EnergyChange: esEastOrVertical),
|
EnergyChange: esEastOrVertical),
|
||||||
(IncomingDirection: (X: 1; Y: 0); OutgoingDirection: (X: 0; Y: 1); SplitDirection: (X: 0; Y: 0); Tile: '\';
|
(IncomingDirection: @CDirectionRight; OutgoingDirection: @CDirectionDown; SplitDirection: @CNoDirection; Tile: '\';
|
||||||
EnergyChange: esWestOrHorizontal),
|
EnergyChange: esWestOrHorizontal),
|
||||||
(IncomingDirection: (X: 0; Y: 1); OutgoingDirection: (X: 1; Y: 0); SplitDirection: (X: 0; Y: 0); Tile: '\';
|
(IncomingDirection: @CDirectionDown; OutgoingDirection: @CDirectionRight; SplitDirection: @CNoDirection; Tile: '\';
|
||||||
EnergyChange: esEastOrVertical),
|
EnergyChange: esEastOrVertical),
|
||||||
(IncomingDirection: (X: -1; Y: 0); OutgoingDirection: (X: 0; Y: -1); SplitDirection: (X: 0; Y: 0); Tile: '\';
|
(IncomingDirection: @CDirectionLeft; OutgoingDirection: @CDirectionUp; SplitDirection: @CNoDirection; Tile: '\';
|
||||||
EnergyChange: esEastOrVertical),
|
EnergyChange: esEastOrVertical),
|
||||||
(IncomingDirection: (X: 0; Y: -1); OutgoingDirection: (X: -1; Y: 0); SplitDirection: (X: 0; Y: 0); Tile: '\';
|
(IncomingDirection: @CDirectionUp; OutgoingDirection: @CDirectionLeft; SplitDirection: @CNoDirection; Tile: '\';
|
||||||
EnergyChange: esWestOrHorizontal),
|
EnergyChange: esWestOrHorizontal),
|
||||||
(IncomingDirection: (X: 1; Y: 0); OutgoingDirection: (X: 0; Y: -1); SplitDirection: (X: 0; Y: 1); Tile: '|';
|
(IncomingDirection: @CDirectionRight; OutgoingDirection: @CDirectionUp; SplitDirection: @CDirectionDown; Tile: '|';
|
||||||
EnergyChange: esBoth),
|
EnergyChange: esBoth),
|
||||||
(IncomingDirection: (X: -1; Y: 0); OutgoingDirection: (X: 0; Y: -1); SplitDirection: (X: 0; Y: 1); Tile: '|';
|
(IncomingDirection: @CDirectionLeft; OutgoingDirection: @CDirectionUp; SplitDirection: @CDirectionDown; Tile: '|';
|
||||||
EnergyChange: esBoth),
|
EnergyChange: esBoth),
|
||||||
(IncomingDirection: (X: 0; Y: 1); OutgoingDirection: (X: -1; Y: 0); SplitDirection: (X: 1; Y: 0); Tile: '-';
|
(IncomingDirection: @CDirectionDown; OutgoingDirection: @CDirectionLeft; SplitDirection: @CDirectionRight; Tile: '-';
|
||||||
EnergyChange: esBoth),
|
EnergyChange: esBoth),
|
||||||
(IncomingDirection: (X: 0; Y: -1); OutgoingDirection: (X: -1; Y: 0); SplitDirection: (X: 1; Y: 0); Tile: '-';
|
(IncomingDirection: @CDirectionUp; OutgoingDirection: @CDirectionLeft; SplitDirection: @CDirectionRight; Tile: '-';
|
||||||
EnergyChange: esBoth)
|
EnergyChange: esBoth)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -193,11 +192,11 @@ begin
|
||||||
begin
|
begin
|
||||||
// Checks the current position for direction changes and splits.
|
// Checks the current position for direction changes and splits.
|
||||||
for transition in CTransitions do
|
for transition in CTransitions do
|
||||||
if (transition.IncomingDirection = ABeam.Direction) and (transition.Tile = GetTile(ABeam.Position)) then
|
if (transition.IncomingDirection^ = ABeam.Direction) and (transition.Tile = GetTile(ABeam.Position)) then
|
||||||
begin
|
begin
|
||||||
if transition.SplitDirection <> CNoDirection then
|
if transition.SplitDirection^ <> CNoDirection then
|
||||||
stack.Push(GetNewBeam(ABeam.Position + transition.SplitDirection, transition.SplitDirection));
|
stack.Push(GetNewBeam(ABeam.Position + transition.SplitDirection^, transition.SplitDirection^));
|
||||||
ABeam.Direction := transition.OutgoingDirection;
|
ABeam.Direction := transition.OutgoingDirection^;
|
||||||
energyChange := transition.EnergyChange;
|
energyChange := transition.EnergyChange;
|
||||||
Break;
|
Break;
|
||||||
end;
|
end;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
Solutions to the Advent Of Code.
|
Solutions to the Advent Of Code.
|
||||||
Copyright (C) 2023 Stefan Müller
|
Copyright (C) 2023-2024 Stefan Müller
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify it under
|
This program is free software: you can redistribute it and/or modify it under
|
||||||
the terms of the GNU General Public License as published by the Free Software
|
the terms of the GNU General Public License as published by the Free Software
|
||||||
|
@ -22,7 +22,7 @@ unit ULongWalk;
|
||||||
interface
|
interface
|
||||||
|
|
||||||
uses
|
uses
|
||||||
Classes, SysUtils, Generics.Collections, USolver;
|
Classes, SysUtils, Generics.Collections, USolver, UCommon;
|
||||||
|
|
||||||
type
|
type
|
||||||
TPoints = specialize TList<TPoint>;
|
TPoints = specialize TList<TPoint>;
|
||||||
|
@ -93,15 +93,11 @@ type
|
||||||
function GetPuzzleName: string; override;
|
function GetPuzzleName: string; override;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
TDirection = (dirRight, dirDown, dirLeft, dirUp);
|
|
||||||
|
|
||||||
const
|
const
|
||||||
CPathChar = '.';
|
CPathChar = '.';
|
||||||
CForestChar = '#';
|
CForestChar = '#';
|
||||||
CRightSlopeChar = '>';
|
CRightSlopeChar = '>';
|
||||||
CDownSlopeChar = 'v';
|
CDownSlopeChar = 'v';
|
||||||
CDirections: array[TDirection] of TPoint = ((X: 1; Y: 0), (X: 0; Y: 1), (X: -1; Y: 0), (X: 0; Y: -1));
|
|
||||||
CStartReverseDirection: TPoint = (X: 0; Y: -1);
|
|
||||||
|
|
||||||
implementation
|
implementation
|
||||||
|
|
||||||
|
@ -148,7 +144,7 @@ begin
|
||||||
stack := TPathStartQueue.Create;
|
stack := TPathStartQueue.Create;
|
||||||
pathStart.Position := FStart.Position;
|
pathStart.Position := FStart.Position;
|
||||||
pathStart.Crossing := FStart;
|
pathStart.Crossing := FStart;
|
||||||
pathStart.ReverseDirection := CStartReverseDirection;
|
pathStart.ReverseDirection := CDirectionUp;
|
||||||
stack.Enqueue(pathStart);
|
stack.Enqueue(pathStart);
|
||||||
while stack.Count > 0 do
|
while stack.Count > 0 do
|
||||||
StepPath(stack);
|
StepPath(stack);
|
||||||
|
@ -158,7 +154,8 @@ end;
|
||||||
procedure TLongWalk.StepPath(const AStartPositionQueue: TPathStartQueue);
|
procedure TLongWalk.StepPath(const AStartPositionQueue: TPathStartQueue);
|
||||||
var
|
var
|
||||||
start: TPathStart;
|
start: TPathStart;
|
||||||
new, direction: TPoint;
|
new: TPoint;
|
||||||
|
pdirection: PPoint;
|
||||||
c: Char;
|
c: Char;
|
||||||
len: Integer;
|
len: Integer;
|
||||||
oneMore, stop: Boolean;
|
oneMore, stop: Boolean;
|
||||||
|
@ -172,14 +169,14 @@ begin
|
||||||
oneMore := False;
|
oneMore := False;
|
||||||
stop := False;
|
stop := False;
|
||||||
repeat
|
repeat
|
||||||
for direction in CDirections do
|
for pdirection in CPCardinalDirections do
|
||||||
if direction <> start.ReverseDirection then
|
if pdirection^ <> start.ReverseDirection then
|
||||||
begin
|
begin
|
||||||
new := start.Position + direction;
|
new := start.Position + pdirection^;
|
||||||
c := GetPosition(new);
|
c := GetPosition(new);
|
||||||
if c <> CForestChar then
|
if c <> CForestChar then
|
||||||
begin
|
begin
|
||||||
start.ReverseDirection := Point(-direction.X, -direction.Y);
|
start.ReverseDirection := Point(-pdirection^.X, -pdirection^.Y);
|
||||||
start.Position := new;
|
start.Position := new;
|
||||||
|
|
||||||
if oneMore or (new.Y = FLines.Count - 1) then
|
if oneMore or (new.Y = FLines.Count - 1) then
|
||||||
|
@ -233,8 +230,8 @@ begin
|
||||||
Result := TCrossing.Create(APosition);
|
Result := TCrossing.Create(APosition);
|
||||||
|
|
||||||
// Checks if the new crossing has multiple entries.
|
// Checks if the new crossing has multiple entries.
|
||||||
if (GetPosition(APosition + CDirections[dirLeft]) = CRightSlopeChar)
|
if (GetPosition(APosition + CDirectionLeft) = CRightSlopeChar)
|
||||||
and (GetPosition(APosition + CDirections[dirUp]) = CDownSlopeChar) then
|
and (GetPosition(APosition + CDirectionUp) = CDownSlopeChar) then
|
||||||
FWaitingForOtherInPath.Add(Result)
|
FWaitingForOtherInPath.Add(Result)
|
||||||
else
|
else
|
||||||
FCrossings.Add(Result);
|
FCrossings.Add(Result);
|
||||||
|
@ -244,17 +241,17 @@ begin
|
||||||
// Adds the exits of this crossing to the stack as starts for new paths.
|
// Adds the exits of this crossing to the stack as starts for new paths.
|
||||||
pathStart.Crossing := Result;
|
pathStart.Crossing := Result;
|
||||||
|
|
||||||
pathStart.Position := APosition + CDirections[dirRight];
|
pathStart.Position := APosition + CDirectionRight;
|
||||||
if GetPosition(pathStart.Position) = CRightSlopeChar then
|
if GetPosition(pathStart.Position) = CRightSlopeChar then
|
||||||
begin
|
begin
|
||||||
pathStart.ReverseDirection := CDirections[dirLeft];
|
pathStart.ReverseDirection := CDirectionLeft;
|
||||||
AStartPositionQueue.Enqueue(pathStart);
|
AStartPositionQueue.Enqueue(pathStart);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
pathStart.Position := APosition + CDirections[dirDown];
|
pathStart.Position := APosition + CDirectionDown;
|
||||||
if GetPosition(pathStart.Position) = CDownSlopeChar then
|
if GetPosition(pathStart.Position) = CDownSlopeChar then
|
||||||
begin
|
begin
|
||||||
pathStart.ReverseDirection := CDirections[dirUp];
|
pathStart.ReverseDirection := CDirectionUp;
|
||||||
AStartPositionQueue.Enqueue(pathStart);
|
AStartPositionQueue.Enqueue(pathStart);
|
||||||
end;
|
end;
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
Solutions to the Advent Of Code.
|
Solutions to the Advent Of Code.
|
||||||
Copyright (C) 2023 Stefan Müller
|
Copyright (C) 2023-2024 Stefan Müller
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify it under
|
This program is free software: you can redistribute it and/or modify it under
|
||||||
the terms of the GNU General Public License as published by the Free Software
|
the terms of the GNU General Public License as published by the Free Software
|
||||||
|
@ -22,7 +22,7 @@ unit UPipeMaze;
|
||||||
interface
|
interface
|
||||||
|
|
||||||
uses
|
uses
|
||||||
Classes, SysUtils, Generics.Collections, USolver;
|
Classes, SysUtils, Generics.Collections, USolver, UCommon;
|
||||||
|
|
||||||
const
|
const
|
||||||
CStartChar = 'S';
|
CStartChar = 'S';
|
||||||
|
@ -115,24 +115,18 @@ procedure TPipeMaze.InitStepMappings;
|
||||||
var
|
var
|
||||||
i: Integer;
|
i: Integer;
|
||||||
begin
|
begin
|
||||||
FStepMappings.Add(TStepMapping.Create(Point(0, 1), Point(0, 1), '|',
|
FStepMappings.Add(TStepMapping.Create(CDirectionDown, CDirectionDown, '|',
|
||||||
TPointArray.Create(Point(1, 0)),
|
TPointArray.Create(CDirectionRight), TPointArray.Create(CDirectionLeft)));
|
||||||
TPointArray.Create(Point(-1, 0))));
|
FStepMappings.Add(TStepMapping.Create(CDirectionRight, CDirectionRight, '-',
|
||||||
FStepMappings.Add(TStepMapping.Create(Point(1, 0), Point(1, 0), '-',
|
TPointArray.Create(CDirectionUp), TPointArray.Create(CDirectionDown)));
|
||||||
TPointArray.Create(Point(0, -1)),
|
FStepMappings.Add(TStepMapping.Create(CDirectionLeft, CDirectionUp, 'L',
|
||||||
TPointArray.Create(Point(0, 1))));
|
TPointArray.Create(CDirectionDown, CDirectionLeftDown, CDirectionLeft), []));
|
||||||
FStepMappings.Add(TStepMapping.Create(Point(-1, 0), Point(0, -1), 'L',
|
FStepMappings.Add(TStepMapping.Create(CDirectionDown, CDirectionLeft, 'J',
|
||||||
TPointArray.Create(Point(0, 1), Point(-1, 1), Point(-1, 0)),
|
TPointArray.Create(CDirectionRight, CDirectionRightDown, CDirectionDown), []));
|
||||||
[]));
|
FStepMappings.Add(TStepMapping.Create(CDirectionRight, CDirectionDown, '7',
|
||||||
FStepMappings.Add(TStepMapping.Create(Point(0, 1), Point(-1, 0), 'J',
|
TPointArray.Create(CDirectionUp, CDirectionRightUp, CDirectionRight), []));
|
||||||
TPointArray.Create(Point(1, 0), Point(1, 1), Point(0, 1)),
|
FStepMappings.Add(TStepMapping.Create(CDirectionUp, CDirectionRight, 'F',
|
||||||
[]));
|
TPointArray.Create(CDirectionLeft, CDirectionLeftUp, CDirectionUp), []));
|
||||||
FStepMappings.Add(TStepMapping.Create(Point(1, 0), Point(0, 1), '7',
|
|
||||||
TPointArray.Create(Point(0, -1), Point(1, -1), Point(1, 0)),
|
|
||||||
[]));
|
|
||||||
FStepMappings.Add(TStepMapping.Create(Point(0, -1), Point(1, 0), 'F',
|
|
||||||
TPointArray.Create(Point(-1, 0), Point(-1, -1), Point(0, -1)),
|
|
||||||
[]));
|
|
||||||
|
|
||||||
// Adds reverse step mappings.
|
// Adds reverse step mappings.
|
||||||
for i := 0 to FStepMappings.Count - 1 do
|
for i := 0 to FStepMappings.Count - 1 do
|
||||||
|
@ -231,13 +225,12 @@ end;
|
||||||
|
|
||||||
function TPipeMaze.TryCountEnclosureSide(const AChar: Char; out OCount: Int64): Boolean;
|
function TPipeMaze.TryCountEnclosureSide(const AChar: Char; out OCount: Int64): Boolean;
|
||||||
var
|
var
|
||||||
directions: TPointArray;
|
|
||||||
stack: specialize TStack<TPoint>;
|
stack: specialize TStack<TPoint>;
|
||||||
i, j: Integer;
|
i, j: Integer;
|
||||||
position, direction, neighbor: TPoint;
|
position, neighbor: TPoint;
|
||||||
|
pdirection: PPoint;
|
||||||
c: Char;
|
c: Char;
|
||||||
begin
|
begin
|
||||||
directions := TPointArray.Create(Point(0, -1), Point(-1, 0), Point(0, 1), Point(1, 0));
|
|
||||||
stack := specialize TStack<TPoint>.Create;
|
stack := specialize TStack<TPoint>.Create;
|
||||||
|
|
||||||
OCount := 0;
|
OCount := 0;
|
||||||
|
@ -259,12 +252,12 @@ begin
|
||||||
begin
|
begin
|
||||||
position := stack.Pop;
|
position := stack.Pop;
|
||||||
|
|
||||||
for direction in directions do
|
for pdirection in CPCardinalDirections do
|
||||||
begin
|
begin
|
||||||
if CheckMapBounds(position + direction) then
|
if CheckMapBounds(position + pdirection^) then
|
||||||
begin
|
begin
|
||||||
// Checks the neighboring position.
|
// Checks the neighboring position.
|
||||||
neighbor := position + direction;
|
neighbor := position + pdirection^;
|
||||||
c := GetEnclosureMapChar(neighbor);
|
c := GetEnclosureMapChar(neighbor);
|
||||||
if (c <> CFloodFillChar) and (c <> CPathChar) then
|
if (c <> CFloodFillChar) and (c <> CPathChar) then
|
||||||
begin
|
begin
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
Solutions to the Advent Of Code.
|
Solutions to the Advent Of Code.
|
||||||
Copyright (C) 2023 Stefan Müller
|
Copyright (C) 2023-2024 Stefan Müller
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify it under
|
This program is free software: you can redistribute it and/or modify it under
|
||||||
the terms of the GNU General Public License as published by the Free Software
|
the terms of the GNU General Public License as published by the Free Software
|
||||||
|
@ -22,7 +22,7 @@ unit UStepCounter;
|
||||||
interface
|
interface
|
||||||
|
|
||||||
uses
|
uses
|
||||||
Classes, SysUtils, Generics.Collections, USolver;
|
Classes, SysUtils, Generics.Collections, USolver, UCommon;
|
||||||
|
|
||||||
type
|
type
|
||||||
TPoints = specialize TList<TPoint>;
|
TPoints = specialize TList<TPoint>;
|
||||||
|
@ -50,7 +50,6 @@ const
|
||||||
CStartChar = 'S';
|
CStartChar = 'S';
|
||||||
CPlotChar = '.';
|
CPlotChar = '.';
|
||||||
CTraversedChar = '+';
|
CTraversedChar = '+';
|
||||||
CDirections: array of TPoint = ((X: 1; Y: 0), (X: -1; Y: 0), (X: 0; Y: 1), (X: 0; Y: -1));
|
|
||||||
|
|
||||||
implementation
|
implementation
|
||||||
|
|
||||||
|
@ -110,7 +109,8 @@ procedure TStepCounter.Finish;
|
||||||
var
|
var
|
||||||
currentStep: Integer;
|
currentStep: Integer;
|
||||||
currentPlots, nextPlots, temp: TPoints;
|
currentPlots, nextPlots, temp: TPoints;
|
||||||
plot, direction, next: TPoint;
|
plot, next: TPoint;
|
||||||
|
pdirection: PPoint;
|
||||||
begin
|
begin
|
||||||
FWidth := Length(FLines[0]);
|
FWidth := Length(FLines[0]);
|
||||||
FHeight := FLines.Count;
|
FHeight := FLines.Count;
|
||||||
|
@ -124,9 +124,9 @@ begin
|
||||||
while currentStep < FMaxSteps do
|
while currentStep < FMaxSteps do
|
||||||
begin
|
begin
|
||||||
for plot in currentPlots do
|
for plot in currentPlots do
|
||||||
for direction in CDirections do
|
for pdirection in CPCardinalDirections do
|
||||||
begin
|
begin
|
||||||
next := plot + direction;
|
next := plot + pdirection^;
|
||||||
if IsInBounds(next) and (GetPosition(next) = CPlotChar) then
|
if IsInBounds(next) and (GetPosition(next) = CPlotChar) then
|
||||||
begin
|
begin
|
||||||
SetPosition(next, CTraversedChar);
|
SetPosition(next, CTraversedChar);
|
||||||
|
|
Loading…
Reference in New Issue