Skip to content
GitLab
Explore
Sign in
Register
Primary navigation
Search or go to…
Project
P
puzzleplayer
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Package registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Floris
puzzleplayer
Commits
4ad417af
Commit
4ad417af
authored
3 months ago
by
bionic85
Browse files
Options
Downloads
Patches
Plain Diff
het doet ten minste iets
parent
796d00dd
No related branches found
Branches containing commit
No related tags found
No related merge requests found
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
PuzzlePlayer/Binary.cs
+2
-15
2 additions, 15 deletions
PuzzlePlayer/Binary.cs
PuzzlePlayer/Board.cs
+24
-1
24 additions, 1 deletion
PuzzlePlayer/Board.cs
PuzzlePlayer/Maze.cs
+140
-17
140 additions, 17 deletions
PuzzlePlayer/Maze.cs
with
166 additions
and
33 deletions
PuzzlePlayer/Binary.cs
+
2
−
15
View file @
4ad417af
...
...
@@ -215,21 +215,8 @@ namespace PuzzlePlayer_Namespace
return
null
;
}
///*
// shuffle the choices in the list around to get different results every time
// First answer from: https://stackoverflow.com/questions/273313/randomize-a-listt
Random
random
=
new
Random
();
int
n
=
choices
.
Count
;
while
(
n
>
1
)
{
n
--;
int
rand
=
random
.
Next
(
n
+
1
);
Move
copy
=
choices
[
rand
];
choices
[
rand
]
=
choices
[
n
];
choices
[
n
]
=
copy
;
}
//*/
choices
.
Shuffle
();
//shuffle the choices around for random results everytime
//(Shuffle methode from the extentions class in the Board.cs file
// do the algorithm for every move
foreach
(
Move
m
in
choices
)
...
...
This diff is collapsed.
Click to expand it.
PuzzlePlayer/Board.cs
+
24
−
1
View file @
4ad417af
...
...
@@ -72,10 +72,11 @@ namespace PuzzlePlayer_Namespace
return
false
;
}
}
public
abstract
void
Draw
(
Graphics
gr
,
Rectangle
r
);
// a methode for solving the whole board. It uses the private SolveStep methode untill the whole board is solved
// it has one parameter. setting this to true will only give a return value without changing the current boardState
public
SOLUTIONS
Solve
(
bool
CheckOnly
)
public
virtual
SOLUTIONS
Solve
(
bool
CheckOnly
)
{
// two variables for storing the result and the next solveStep
int
[,]
result
=
(
int
[,])
boardState
.
Clone
();
...
...
@@ -136,4 +137,26 @@ namespace PuzzlePlayer_Namespace
// performs a left/right (X) click on tile P, changing its value
public
virtual
void
TileClick
(
Point
p
,
int
x
)
{
}
}
// static class for extentions
public
static
class
Extensions
{
private
static
readonly
Random
rng
=
new
Random
();
// shuffle the elements in a list around to get different results every time from the generator algoritms
// First answer from: https://stackoverflow.com/questions/273313/randomize-a-listt
public
static
void
Shuffle
<
T
>(
this
IList
<
T
>
list
)
{
int
n
=
list
.
Count
;
while
(
n
>
1
)
{
n
--;
int
k
=
rng
.
Next
(
n
+
1
);
T
value
=
list
[
k
];
list
[
k
]
=
list
[
n
];
list
[
n
]
=
value
;
}
}
}
}
This diff is collapsed.
Click to expand it.
PuzzlePlayer/Maze.cs
+
140
−
17
View file @
4ad417af
...
...
@@ -4,18 +4,21 @@ using System.Collections.Generic;
using
System.Diagnostics
;
using
System.Drawing
;
using
System.Linq
;
using
System.Security.Policy
;
using
System.Text
;
using
System.Threading.Tasks
;
using
System.Xml.XPath
;
using
static
System
.
Runtime
.
InteropServices
.
JavaScript
.
JSType
;
namespace
PuzzlePlayer_Namespace
{
/*
* all the info about the maze is stored in the mazeState int[,]
* this way the boardState can be used to keep track off the spaces that the player has visited
* all the info about where the walls in the maze are is stored in the mazeState int[,]
* the info of wich cells are already visited by the generator methode are stored in the visitedCells
* the boardState is used to keep track of the spaces that the player has visited while solving the maze
*
* if the player has not yet visited a space then it is equal to the emptyspace constant
* if the player did visit the space then it is equal to 1
* if the player
/generator
has not yet visited a space then it is equal to the emptyspace constant
* if the player
/generator
did visit the space then it is equal to 1
*
* The maze board consists of cells with a number between 1 and 15
* the number represents where the walls are
...
...
@@ -36,13 +39,17 @@ namespace PuzzlePlayer_Namespace
class
Maze
:
Board
{
int
[,]
mazeState
;
int
[,]
visitedCells
;
public
Maze
(
int
size
=
3
)
public
Maze
(
int
size
=
6
)
{
// init all 2D array's
boardState
=
GetClearBoard
(
size
);
mazeState
=
GetClearBoard
(
size
);
visitedCells
=
GetClearBoard
(
size
);
// example thingy
/*
// example thingy (DELETE LATER)
mazeState[0, 0] = 5;
mazeState[1, 0] = 3;
mazeState[2, 0] = 11;
...
...
@@ -54,20 +61,21 @@ namespace PuzzlePlayer_Namespace
mazeState[2, 2] = 5;
boardState[0, 2] = 1;
*/
}
// two funcions to go from number to walls and back
private
int
getNumberFromWalls
(
bool
top
,
bool
right
,
bool
bottom
,
bool
left
)
private
int
getNumberFromWalls
(
(
bool
top
,
bool
right
,
bool
bottom
,
bool
left
)
cell
)
{
int
result
=
0
;
if
(
top
)
if
(
cell
.
top
)
result
++;
if
(
right
)
if
(
cell
.
right
)
result
+=
2
;
if
(
bottom
)
if
(
cell
.
bottom
)
result
+=
4
;
if
(
left
)
if
(
cell
.
left
)
result
+=
8
;
if
(
result
==
0
)
...
...
@@ -79,7 +87,8 @@ namespace PuzzlePlayer_Namespace
private
(
bool
,
bool
,
bool
,
bool
)
getWallsFromNumber
(
int
number
)
{
if
(
number
==
emptySpace
)
return
(
false
,
false
,
false
,
false
);
//if the place is empty then there are no walls
return
(
true
,
true
,
true
,
true
);
//if the place is empty then it is completly walled in,
//so that the walls can be removed when generating the maze
// bitwise and opperations to check each bit
bool
top
=
(
number
&
1
)
!=
0
;
...
...
@@ -92,6 +101,9 @@ namespace PuzzlePlayer_Namespace
public
override
void
Draw
(
Graphics
gr
,
Rectangle
r
)
{
// clear screen
gr
.
FillRectangle
(
Brushes
.
DarkGreen
,
r
);
Size
tilesize
=
new
Size
(
r
.
Width
/
boardState
.
GetLength
(
0
),
r
.
Height
/
boardState
.
GetLength
(
1
));
Pen
wall
=
new
Pen
(
Color
.
Black
,
tilesize
.
Width
/
5
);
...
...
@@ -127,15 +139,126 @@ namespace PuzzlePlayer_Namespace
gr
.
DrawString
(
"END"
,
SettingForm
.
mainFont
,
Brushes
.
Red
,
r
.
Right
-
tilesize
.
Width
/
4
,
r
.
Bottom
-
tilesize
.
Height
/
2
);
}
protected
override
List
<
Move
>
GetSolveList
(
int
[,]
boardToSolve
)
// this methode generates a Maze starting with an empty board
// it uses the randomized depth first search algoritm as described on this wiki page:
// https://en.wikipedia.org/wiki/Maze_generation_algorithm#Randomized_depth-first_search
public
override
void
Generate
()
{
throw
new
NotImplementedException
();
// clear visitedCells
visitedCells
=
GetClearBoard
(
mazeState
.
GetLength
(
0
));
Random
rnd
=
new
Random
();
int
x
=
rnd
.
Next
(
mazeState
.
GetLength
(
0
));
int
y
=
rnd
.
Next
(
mazeState
.
GetLength
(
0
));
RND_Recursive_DepthFirstSearchMaze
(
x
,
y
);
}
// https://en.wikipedia.org/wiki/Maze_generation_algorithm#Randomized_depth-first_search
public
override
void
Generate
()
private
bool
RND_Recursive_DepthFirstSearchMaze
(
int
x
,
int
y
)
{
throw
new
NotImplementedException
();
visitedCells
[
x
,
y
]
=
1
;
// mark current cell as visited (this is needed for the first cell)
// get a list of all the unvisited neigbour cells
List
<(
int
,
int
)>
validNeigbours
=
getNeigbours
(
x
,
y
,
emptySpace
);
if
(
validNeigbours
.
Count
==
0
)
return
false
;
// backtrack
validNeigbours
.
Shuffle
();
//shuffle the neigbours around for random results everytime
//(Shuffle methode from the extentions class in the Board.cs file
foreach
((
int
nx
,
int
ny
)
neighbour
in
validNeigbours
)
{
visitedCells
[
neighbour
.
nx
,
neighbour
.
ny
]
=
1
;
// mark as visited and update all the walls that are effected
UpdateWalls
(
x
,
y
,
neighbour
.
nx
,
neighbour
.
ny
);
if
(
RND_Recursive_DepthFirstSearchMaze
(
neighbour
.
nx
,
neighbour
.
ny
))
//recursion
return
true
;
// if true then the maze is finished and this cell should return true too
}
return
false
;
// backtrack if all the neighbours are already visited
}
// update the walls between two cells
private
void
UpdateWalls
(
int
x
,
int
y
,
int
x2
,
int
y2
)
{
// get the walls from the two cells
(
bool
top
,
bool
right
,
bool
bottom
,
bool
left
)
first
=
getWallsFromNumber
(
mazeState
[
x
,
y
]);
(
bool
top
,
bool
right
,
bool
bottom
,
bool
left
)
second
=
getWallsFromNumber
(
mazeState
[
x2
,
y2
]);
int
dx
=
x
-
x2
;
int
dy
=
y
-
y2
;
if
(
dx
==
-
1
)
{
first
.
right
=
false
;
second
.
left
=
false
;
}
else
if
(
dx
==
1
)
{
first
.
left
=
false
;
second
.
right
=
false
;
}
else
if
(
dy
==
-
1
)
{
first
.
bottom
=
false
;
second
.
top
=
false
;
}
else
if
(
dy
==
1
)
{
first
.
top
=
false
;
second
.
bottom
=
false
;
}
// update the walls
mazeState
[
x
,
y
]
=
getNumberFromWalls
(
first
);
mazeState
[
x2
,
y2
]
=
getNumberFromWalls
(
second
);
}
// checks all the neighbours for the checkFor param (this is used to get either the visited or the unvisited neighbours)
private
List
<(
int
,
int
)>
getNeigbours
(
int
x
,
int
y
,
int
checkFor
)
{
List
<(
int
,
int
)>
result
=
new
List
<(
int
,
int
)>
();
if
(
x
-
1
>=
0
)
if
(
visitedCells
[
x
-
1
,
y
]
==
checkFor
)
result
.
Add
((
x
-
1
,
y
));
if
(
y
-
1
>=
0
)
if
(
visitedCells
[
x
,
y
-
1
]
==
checkFor
)
result
.
Add
((
x
,
y
-
1
));
if
(
x
+
1
<
visitedCells
.
GetLength
(
0
))
if
(
visitedCells
[
x
+
1
,
y
]
==
checkFor
)
result
.
Add
((
x
+
1
,
y
));
if
(
y
+
1
<
visitedCells
.
GetLength
(
1
))
if
(
visitedCells
[
x
,
y
+
1
]
==
checkFor
)
result
.
Add
((
x
,
y
+
1
));
/*
for (int checkX = x-1;checkX <= x+1; checkX++)
for(int checkY = y-1;checkY <= y+1;checkY++)
{
// check if checkX/Y are within bounds
if(checkX >= 0 && checkY >=0 && checkX < visitedCells.GetLength(0) && checkY < visitedCells.GetLength(1))
if(visitedCells[checkX,checkY] == checkFor)
result.Add((checkX,checkY));
}
*/
return
result
;
}
// overrite the Solve methode because a maze and an ordinary board puzzle like a sudoku or binary puzzle
// don't have much in common in regards to solving. So most of the code in the abstract Board class is to no use for us here
public
override
SOLUTIONS
Solve
(
bool
CheckOnly
)
{
List
<
Move
>
shortestPath
=
new
List
<
Move
>();
return
SOLUTIONS
.
NONE
;
}
// this methode is not needed because we write our own Solve methode
protected
override
List
<
Move
>
GetSolveList
(
int
[,]
boardToSolve
)
{
return
null
;
}
public
override
void
TileInput
(
Point
p
,
int
x
)
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment