Skip to content

Commit 4d0aed5

Browse files
committed
Add README files to examples
1 parent 343ddfa commit 4d0aed5

13 files changed

Lines changed: 460 additions & 3 deletions

File tree

Examples/15 puzzle/15 puzzle.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@
5050
</ItemGroup>
5151
<ItemGroup>
5252
<None Include="App.config" />
53+
<None Include="README.md" />
5354
</ItemGroup>
5455
<ItemGroup>
5556
<ProjectReference Include="..\..\SharpPDDL\SharpPDDL.csproj">

Examples/15 puzzle/README.md

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
Treatment the game: [wiki](https://en.wikipedia.org/wiki/15_puzzle)
2+
3+
Due to many steps essential to solve the puzzle and complexity of problem final goal was divided for several smaller.
4+
5+
The part of the code responsible for adding next sub-goals:
6+
```cs
7+
static void AddTileXGoal(object a, object b)
8+
{
9+
GoalPDDL goalPDDL = (GoalPDDL)a;
10+
int c = int.Parse(goalPDDL.Name);
11+
AddTileXGoal(c);
12+
}
13+
14+
static void AddTileXGoal(int i)
15+
{
16+
if (i < 15)
17+
{
18+
GoalPDDL Tile1Goal = new GoalPDDL((i + 1).ToString());
19+
20+
for (int j = 0; j < i + 1; j++)
21+
Tile1Goal.AddExpectedObjectState(ExpressionsOfXTile(j));
22+
23+
Tile1Goal.GoalRealized += AddTileXGoal;
24+
GemPuzzleDomein.AddGoal(Tile1Goal);
25+
}
26+
}
27+
```
28+
29+
In the beginning algorithm realize solution for tile no. 1 and add goal to put correct tiles no 1 and 2. In the end of sub-goal realize is add goal of one tile goal more.
30+
31+
Solution of 1st sub-goal:
32+
```
33+
╔══╤══╤═┉
34+
║ 1│ ?│
35+
╟──┼──┼─┉
36+
⁞ ?⁞ ?⁞
37+
```
38+
39+
Solution of 2nd sub-goal:
40+
```
41+
╔══╤══╤══╤══╗
42+
║ 1│ 2│ ?│ ?║
43+
╟──┼──┼──┼──╢
44+
⁞ ?⁞ ?⁞ ?⁞ ?⁞
45+
```
46+
47+
Solution of 5th sub-goal:
48+
```
49+
╔══╤══╤══╤══╗
50+
║ 1│ 2│ 3│ 4║
51+
╟──┼──┼──┼──╢
52+
║ 5│ ?│ ?│ ?║
53+
╟──┼──┼──┼──╢
54+
⁞ ?⁞ ?⁞ ?⁞ ?⁞
55+
```
56+
57+
Final goal of all tile is reach in time of less then 3 mins:
58+
```
59+
╔══╤══╤══╤══╗
60+
║ 1│ 2│ 3│ 4║
61+
╟──┼──┼──┼──╢
62+
║ 5│ 6│ 7│ 8║
63+
╟──┼──┼──┼──╢
64+
║ 9│10│11│12║
65+
╟──┼──┼──┼──╢
66+
║13│14│15│ ║
67+
╚══╧══╧══╧══╝
68+
```

Examples/Hanoi Tower/Hanoi Tower.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@
4848
</ItemGroup>
4949
<ItemGroup>
5050
<None Include="App.config" />
51+
<None Include="README.md" />
5152
</ItemGroup>
5253
<ItemGroup>
5354
<ProjectReference Include="..\..\SharpPDDL\SharpPDDL.csproj">

Examples/Hanoi Tower/README.md

Lines changed: 181 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,181 @@
1+
Treatment the puzzle: [wiki](https://en.wikipedia.org/wiki/Tower_of_Hanoi)
2+
```cs
3+
public class HanoiObj //It cannot be abstract
4+
{
5+
public int HanoiObjSizeUpSide = 0;
6+
public bool IsEmptyUpSide;
7+
}
8+
9+
public class HanoiBrick : HanoiObj
10+
{
11+
readonly public int Size;
12+
}
13+
14+
public class HanoiTable : HanoiObj
15+
{
16+
public readonly int no;
17+
}
18+
```
19+
```mermaid
20+
21+
classDiagram
22+
23+
namespace Legend {
24+
25+
class Class{
26+
Its a block representant some class
27+
}
28+
29+
class Object {
30+
Its a block representant some object / class instance
31+
}
32+
33+
}
34+
35+
style Object fill:#391, stroke-style:..
36+
style Class fill:#139, stroke-style:..
37+
38+
namespace HanoiTower {
39+
40+
class HanoiObj{
41+
+int HanoiObjSizeUpSide
42+
+bool IsEmptyUpSide
43+
}
44+
45+
class HanoiBrick{
46+
+int Size
47+
}
48+
49+
class HanoiTable {
50+
+int no
51+
}
52+
}
53+
HanoiObj <|-- HanoiBrick
54+
HanoiObj <|-- HanoiTable
55+
56+
style HanoiObj fill:#139, stroke-style:..
57+
style HanoiBrick fill:#139, stroke-style:..
58+
style HanoiTable fill:#139, stroke-style:..
59+
60+
namespace SharpPDDL {
61+
62+
class Root_TreeNode{
63+
~SingleTypeOfDomain Content
64+
~List~TreeNode~ Children
65+
}
66+
67+
class HanoiObj_SingleTypeOfDomain {
68+
~Type Type : BaseShapes.HanoiObj
69+
~List~ValueOfThumbnail~ CumulativeValues
70+
}
71+
72+
class 0_TreeNode{
73+
~SingleTypeOfDomain Content
74+
~List~TreeNode~ Children
75+
}
76+
77+
class HanoiBrick_SingleTypeOfDomain {
78+
~Type Type : BaseShapes.HanoiObj
79+
~List~ValueOfThumbnail~ CumulativeValues
80+
}
81+
82+
class 1_TreeNode{
83+
~SingleTypeOfDomain Content
84+
~List~TreeNode~ Children
85+
}
86+
87+
class HanoiTable_SingleTypeOfDomain {
88+
~Type Type : BaseShapes.HanoiObj
89+
~List~ValueOfThumbnail~ CumulativeValues
90+
}
91+
}
92+
style Root_TreeNode fill:#391, stroke-style:..
93+
style 0_TreeNode fill:#391, stroke-style:..
94+
style 1_TreeNode fill:#391, stroke-style:..
95+
style HanoiObj_SingleTypeOfDomain fill:#391, stroke-style:..
96+
style HanoiBrick_SingleTypeOfDomain fill:#391, stroke-style:..
97+
style HanoiTable_SingleTypeOfDomain fill:#391, stroke-style:..
98+
99+
Root_TreeNode --> "Children[0]" 0_TreeNode
100+
Root_TreeNode --> "Children[1]" 1_TreeNode
101+
0_TreeNode --> "Content" HanoiBrick_SingleTypeOfDomain
102+
1_TreeNode --> "Content" HanoiTable_SingleTypeOfDomain
103+
Root_TreeNode --> "Content" HanoiObj_SingleTypeOfDomain
104+
HanoiObj_SingleTypeOfDomain ..> "≙" HanoiObj
105+
HanoiBrick_SingleTypeOfDomain ..> "≙" HanoiBrick
106+
HanoiTable_SingleTypeOfDomain ..> "≙" HanoiTable
107+
108+
note for HanoiObj_SingleTypeOfDomain "CumulativeValues:<br> 1: HanoiObSizeUpSide<br> 2: IsEmptyUpSide"
109+
note for HanoiTable_SingleTypeOfDomain "CumulativeValues:<br> 1: HanoiObSizeUpSide<br> 2: IsEmptyUpSide<br> // int:no is not use in any action"
110+
note for HanoiBrick_SingleTypeOfDomain "CumulativeValues:<br> 1: HanoiObSizeUpSide<br> 2: IsEmptyUpSide<br> 3: Size"
111+
112+
```
113+
Instances of class used to define action shouldn't be use in other part of program. In time of create actions library create class instance excluding use the class constructor.
114+
115+
For these classes one can define rules in library like "Move brick onto another brick" or "Move brick on table". Preconditions, effect etc. are phrased by library's user as Expressions (System.Linq.Expressions):
116+
117+
```cs
118+
HanoiBrick MovedBrick = null; //you can take brick...
119+
HanoiObj ObjBelowMoved = null; //...from table or another brick...
120+
HanoiBrick NewStandB = null; //...and put it into bigger brick...
121+
HanoiTable NewStandT = null; //...or empty table spot.
122+
123+
Expression<Predicate<HanoiObj>> ObjectIsNoUp = (HO => HO.IsEmptyUpSide); //Moved brick have to be empty up side
124+
Expression<Predicate<HanoiBrick, HanoiBrick>> PutSmallBrickAtBigger = ((MB, NSB) => (MB.Size < NSB.Size)); //you can put smaller brick onto bigger one
125+
Expression<Predicate<HanoiBrick, HanoiObj>> FindObjBelongMovd = ((MB, OBM) => (MB.Size == OBM.HanoiObjSizeUpSide));
126+
127+
ActionPDDL moveBrickOnBrick = new ActionPDDL("Move brick onto another brick"); //1st action with 3 parameters: MovedBrick, ObjBelowMoved, NewStandB
128+
129+
moveBrickOnBrick.AddPartOfActionSententia(ref MovedBrick, "Place the {0}-size brick ", MB => MB.Size);
130+
moveBrickOnBrick.AddPartOfActionSententia(ref NewStandB, "onto {0}-size brick.", MB => MB.Size);
131+
132+
moveBrickOnBrick.AddPrecondition("Moved brick is no up", ref MovedBrick, ObjectIsNoUp); //MovedBrick.IsEmptyUpSide == true
133+
moveBrickOnBrick.AddPrecondition("New stand is empty", ref NewStandB, ObjectIsNoUp); //NewStandB.IsEmptyUpSide == true
134+
moveBrickOnBrick.AddPrecondition("Small brick on bigger one", ref MovedBrick, ref NewStandB, PutSmallBrickAtBigger); //MovedBrick.Size < NewStandB.Size
135+
moveBrickOnBrick.AddPrecondition("Find brick bottom moved one", ref MovedBrick, ref ObjBelowMoved, FindObjBelongMovd); //MovedBrick.Size == ObjBelowMoved.HanoiObjSizeUpSide
136+
137+
moveBrickOnBrick.AddEffect("New stand is full", ref NewStandB, NS => NS.IsEmptyUpSide, false); //NewStandB.IsEmptyUpSide = false
138+
moveBrickOnBrick.AddEffect("Old stand is empty", ref ObjBelowMoved, NS => NS.IsEmptyUpSide, true); //ObjBelowMoved.IsEmptyUpSide = true
139+
moveBrickOnBrick.AddEffect("UnConsociate Objs", ref ObjBelowMoved, OS => OS.HanoiObjSizeUpSide, 0); //ObjBelowMoved.HanoiObjSizeUpSide = 0
140+
moveBrickOnBrick.AddEffect("Consociate Bricks", ref NewStandB, NSB => NSB.HanoiObjSizeUpSide, ref MovedBrick, MB => MB.Size); //NewStandB.HanoiObjSizeUpSide = MovedBrick.Size
141+
142+
newDomain.AddAction(moveBrickOnBrick); //Putting empty brick onto bigger one
143+
144+
ActionPDDL moveBrickOnTable = new ActionPDDL("Move brick on table"); //2st action with 3 parameters: MovedBrick, ObjBelowMoved, NewStandT
145+
146+
moveBrickOnTable.AddPartOfActionSententia(ref MovedBrick, "Place the {0}-size brick ", MB => MB.Size);
147+
moveBrickOnTable.AddPartOfActionSententia(ref NewStandT, "onto table no {0}.", NS => NS.no);
148+
149+
moveBrickOnTable.AddPrecondition("Moved brick is no up", ref MovedBrick, ObjectIsNoUp); //MovedBrick.IsEmptyUpSide == true
150+
moveBrickOnTable.AddPrecondition("New table is empty", ref NewStandT, ObjectIsNoUp); //NewStandT.IsEmptyUpSide == true
151+
moveBrickOnTable.AddPrecondition("Find brick bottom moved one", ref MovedBrick, ref ObjBelowMoved, FindObjBelongMovd); //MovedBrick.Size == ObjBelowMoved.HanoiObjSizeUpSide
152+
153+
moveBrickOnTable.AddEffect("New stand is full", ref NewStandT, NS => NS.IsEmptyUpSide, false); //NewStandT.IsEmptyUpSide = false
154+
moveBrickOnTable.AddEffect("Old stand is empty", ref ObjBelowMoved, NS => NS.IsEmptyUpSide, true); //ObjBelowMoved.IsEmptyUpSide = true
155+
moveBrickOnTable.AddEffect("UnConsociate Objs", ref ObjBelowMoved, OS => OS.HanoiObjSizeUpSide, 0); //ObjBelowMoved.HanoiObjSizeUpSide = 0
156+
moveBrickOnTable.AddEffect("Consociate Bricks", ref NewStandT, NST => NST.HanoiObjSizeUpSide, ref MovedBrick, MB => MB.Size); //NewStandT.HanoiObjSizeUpSide = MovedBrick.Size
157+
158+
newDomain.AddAction(moveBrickOnTable); //Putting empty brick onto empty table spot
159+
```
160+
161+
Solution output for 3-bricks-hanoi-tower problem:
162+
```
163+
Transfer bricks onto table no. 3 determined!!! Total Cost: 7
164+
Move brick on table: Place the 1-size brick onto table no 2.
165+
Move brick on table: Place the 2-size brick onto table no 1.
166+
Move brick onto another brick: Place the 1-size brick onto 2-size brick.
167+
Move brick on table: Place the 3-size brick onto table no 2.
168+
Move brick on table: Place the 1-size brick onto table no 0.
169+
Move brick onto another brick: Place the 2-size brick onto 3-size brick.
170+
Move brick onto another brick: Place the 1-size brick onto 2-size brick.
171+
```
172+
173+
```mermaid
174+
175+
xychart-beta
176+
title "Time of making the solution"
177+
x-axis "Number of blocks" [1,2,3,4,5,6,7,8,9,10]
178+
y-axis "Time (in sec)" 0 --> 30
179+
bar [0.29, 0.29, 0.30, 0.30, 0.39, 0.54, 1.13, 2.75, 8.14, 28.1]
180+
181+
```

Examples/Peg solitaire/Peg solitaire.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@
5050
</ItemGroup>
5151
<ItemGroup>
5252
<None Include="App.config" />
53+
<None Include="README.md" />
5354
</ItemGroup>
5455
<ItemGroup>
5556
<ProjectReference Include="..\..\SharpPDDL\SharpPDDL.csproj">

Examples/Peg solitaire/README.md

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
Treatment the game: [wiki](https://en.wikipedia.org/wiki/Peg_solitaire)
2+
3+
In this example used triangular, 15-holes variant as easiest to solve.
4+
5+
Due to shape of game board it needs to use 3 possible action of jump. One of it, the horizontal move is shown below:
6+
```cs
7+
Expression<Predicate<Spot>> FullSpot = S => S.Full;
8+
Expression<Predicate<Spot>> EmptySpot = S => !S.Full;
9+
10+
ActionPDDL HorizontalJump = new ActionPDDL("Horizontal jump");
11+
12+
HorizontalJump.AddPrecondition<Spot, Spot>("Jumping peg exists", ref JumpingPeg, FullSpot);
13+
HorizontalJump.AddPrecondition<Spot, Spot>("Remove peg exists", ref RemovePeg, FullSpot);
14+
HorizontalJump.AddPrecondition<Spot, Spot>("Final position of peg is empty", ref FinalPegPos, EmptySpot);
15+
16+
Expression<Predicate<Spot, Spot, Spot>> Horizontalcollinear = ((JP, RP, FPP) => (JP.Row == RP.Row && RP.Row == FPP.Row));
17+
HorizontalJump.AddPrecondition("The same vertical line", ref JumpingPeg, ref RemovePeg, ref FinalPegPos, Horizontalcollinear);
18+
19+
Expression<Predicate<Spot, Spot>> VerticalClose = ((S1, S2) => ((S1.Column - S2.Column) == 1 || (S1.Column - S2.Column) == -1));
20+
HorizontalJump.AddPrecondition("Jumper is close", ref JumpingPeg, ref RemovePeg, VerticalClose);
21+
HorizontalJump.AddPrecondition("Hole is close", ref FinalPegPos, ref RemovePeg, VerticalClose);
22+
23+
HorizontalJump.AddEffect("Jumping Peg Spot is empty", ref JumpingPeg, JP => JP.Full, false);
24+
HorizontalJump.AddEffect("Remove Peg Spot is empty", ref RemovePeg, RP => RP.Full, false);
25+
HorizontalJump.AddEffect("Final Peg Spot is full", ref FinalPegPos, RP => RP.Full, true);
26+
```
27+
The execution of it uses effects from above and static voids of Spot class.
28+
```cs
29+
HorizontalJump.AddExecution("Reset colours", () => Reset(), false);
30+
HorizontalJump.AddExecution("Jumping Peg Spot is empty");
31+
HorizontalJump.AddExecution("Remove Peg Spot is empty");
32+
HorizontalJump.AddExecution("Final Peg Spot is full");
33+
HorizontalJump.AddExecution("Draw it", () => Board.Draw(spots), true);
34+
HorizontalJump.AddExecution("Wait", () => Thread.Sleep(1500), true);
35+
```
36+
At this case it's possible to reach 3016 possible states, which is generated in time of about 13s.
37+
38+
![Peg_solitaire_solution](https://github.com/user-attachments/assets/4c7a440f-be36-4bcc-a737-d9266bb88809)
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
Treatment the puzzle: [wiki](https://en.wikipedia.org/wiki/Wolf,_goat_and_cabbage_problem)
2+
3+
Putting a thing to the boat:
4+
```cs
5+
ActionPDDL TakingCabbage = new ActionPDDL("TakingCabbage");
6+
TakingCabbage.AddPartOfActionSententia("Take the cabbage.");
7+
TakingCabbage.AddPrecondition("Boat is near the bank", ref nextToBank, b => b.IsBoat);
8+
TakingCabbage.AddPrecondition("Cabbage is at the bank", ref nextToBank, b => b.IsCabbage);
9+
TakingCabbage.AddPrecondition("Boat is empty", ref boat, b => !b.IsCabbage && !b.IsGoat && !b.IsWolf);
10+
TakingCabbage.AddEffect("Remove the cabbage from the bank", ref nextToBank, b => b.IsCabbage, false);
11+
TakingCabbage.AddEffect("Put the cabbage on the boat", ref boat, b => b.IsCabbage, true);
12+
RiverCrossing.AddAction(TakingCabbage);
13+
```
14+
15+
Putting a thing away:
16+
```cs
17+
ActionPDDL PutCabbageAway = new ActionPDDL("PuttingCabbageAway");
18+
PutCabbageAway.AddPartOfActionSententia("Put the cabbage away.");
19+
PutCabbageAway.AddPrecondition("Boat is near the bank", ref nextToBank, b => b.IsBoat);
20+
PutCabbageAway.AddPrecondition("Goat is on the bank", ref boat, b => b.IsCabbage);
21+
PutCabbageAway.AddEffect("Remove the goat from the bank", ref nextToBank, b => b.IsCabbage, true);
22+
PutCabbageAway.AddEffect("Add the goat to the boat", ref boat, b => b.IsCabbage, false);
23+
RiverCrossing.AddAction(PutCabbageAway);
24+
```
25+
26+
One need to use the above 3 times. For the cabbage, goat and wolf.
27+
28+
Going to the other river bank:
29+
```cs
30+
ActionPDDL CrossTheRiver = new ActionPDDL("CrossingTheRiver");
31+
CrossTheRiver.AddPartOfActionSententia("Cross the river.");
32+
CrossTheRiver.AddPrecondition("Boat is near the bank", ref nextToBank, b => b.IsBoat);
33+
CrossTheRiver.AddPrecondition("Nothing won't be eaten", ref nextToBank, b => b.IsGoat ? (!b.IsCabbage && !b.IsWolf) : true );
34+
RiverBank SecendBank = null;
35+
CrossTheRiver.AddEffect("Leave the river bank", ref nextToBank, b => b.IsBoat, false);
36+
CrossTheRiver.AddEffect("Go to the other bank", ref SecendBank, b => b.IsBoat, true);
37+
RiverCrossing.AddAction(CrossTheRiver);
38+
```
39+
40+
Generated plan:
41+
```
42+
1: Take the goat.
43+
2: Cross the river.
44+
3: Put the goat away.
45+
4: Cross the river.
46+
5: Take the wolf.
47+
6: Cross the river.
48+
7: Put the wolf away.
49+
8: Take the goat.
50+
9: Cross the river.
51+
10: Put the goat away.
52+
11: Take the cabbage.
53+
12: Cross the river.
54+
13: Put the cabbage away.
55+
14: Cross the river.
56+
15: Take the goat.
57+
16: Cross the river.
58+
17: Put the goat away.
59+
```

Examples/River crossing puzzle/River crossing puzzle.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@
4848
</ItemGroup>
4949
<ItemGroup>
5050
<None Include="App.config" />
51+
<None Include="README.md" />
5152
</ItemGroup>
5253
<ItemGroup>
5354
<ProjectReference Include="..\..\SharpPDDL\SharpPDDL.csproj">

0 commit comments

Comments
 (0)