This repository has been archived by the owner on Dec 18, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Board.cs
252 lines (243 loc) · 10.7 KB
/
Board.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
using System;
using static System.Console;
namespace Labyrinth
{
/// <summary>The board class</summary>
class Board
{
#region Attributes
/// <summary>The starting position.</summary>
public Position Start {get; private set;}
/// <summary>The ending position.</summary>
public Position End {get; private set;}
/// <summary>The bonus position.</summary>
public Position Bonus {get; private set;}
/// <summary>The board as a matrix.</summary>
public int[,] Matrix {get; set; }
/// <summary>The difficulty of the labyrinth.</summary>
public static int s_Difficulty {get; set; }
#endregion
#region Constructors
/// <summary>This method is used to initialize a new instance of the <see cref="T:Labyrinth.Board"/> class.</summary>
public Board()
{
Start = new Position(0,0);
End = new Position(0,0);
Bonus = new Position(0,0);
switch (s_Difficulty)
{
case 0 : Matrix = new int[5,5]; break;
case 1 : Matrix = new int[15,15]; break;
case 2 : Matrix = new int[35,35]; break;
case 3 : Matrix = new int[55,55]; break;
default : Matrix = new int[5,5]; break;
}
Matrix = MatrixGeneration();
}
/// <summary>This method is used to initialize a new instance of the <see cref="T:Labyrinth.Board"/> class especially for the demonstration.</summary>
public Board(int s_Difficulty)
{
Start = new Position(0,0);
End = new Position(0,0);
Bonus = new Position(0,0);
switch (s_Difficulty)
{
case 0 : Matrix = new int[5,5]; break;
case 1 : Matrix = new int[15,15]; break;
case 2 : Matrix = new int[35,35]; break;
case 3 : Matrix = new int[55,55]; break;
default : Matrix = new int[5,5]; break;
}
}
#endregion
#region Methods
public void LabyrinthCreationDemonstration()
{
RawPrintBoard();
int size = Matrix.GetLength(0);
for(int i = 0; i < size; i+=2)for(int j = 0; j < size; j++)Matrix[i, j] = 1;
for(int i = 0; i < size; i++)for(int j = 0; j < size; j+=2)Matrix[i, j] = 1;
RawPrintBoard();
FillWithIncrements();
RawPrintBoard();
Bridge(true);
SwitchValues(Matrix[1, 1], 0);
RawPrintBoard();
Matrix[1, 0] = 2;
Start = new Position(1,0);
Matrix[size - 2, size - 1]=3;
End = new Position(size - 2, size - 1);
Bonus = new Position(size / 2, size / 2);
Matrix[size / 2, size / 2] = 6;
RawPrintBoard();
PrintBoard();
}
/// <summary>This method is used to generate the matrix representing the board.</summary>
/// <returns>The generated matrix.</returns>
private int[,] MatrixGeneration()
{
int size = Matrix.GetLength(0);
for(int i = 0; i < size; i+=2)for(int j = 0; j < size; j++)Matrix[i, j] = 1;
for(int i = 0; i < size; i++)for(int j = 0; j < size; j+=2)Matrix[i, j] = 1;
FillWithIncrements();
Bridge();
SwitchValues(Matrix[1, 1], 0);
Matrix[1, 0] = 2;
Start = new Position(1,0);
Matrix[size - 2, size - 1]=3;
End = new Position(size - 2, size - 1);
Bonus = new Position(size / 2, size / 2);
Matrix[size / 2, size / 2] = 6;
return Matrix;
}
/// <summary>This method is used to fill the matrix with increments so that every empty space is filled with a different value.</summary>
private void FillWithIncrements()
{
int increment = 2;
for (int i = 0; i < Matrix.GetLength(0); i++)
{
for (int j = 1; j < Matrix.GetLength(0)-1; j++)
{
if (Matrix[i,j]==0)
{
Matrix[i,j]=increment;
increment++;
}
}
}
}
/// <summary>This method is used to create a bridge randomly between two lines or two columns.If the values between thses two is different, it breaks the wall and enable to generate the labyrinth step by step.</summary>
private void Bridge(bool demonstration = false)
{
List<Position> positions = new List<Position>();
Random rnd = new Random();
bool cond = true;
int size = Matrix.GetLength(0);
while(!IsMatrixDone())
{
Position p = new Position(rnd.Next(1, size - 1), rnd.Next(1, size - 1));
if (cond&&!positions.Contains(p))
{
positions.Add(p);
if (Matrix[p.X,p.Y]==1&&Matrix[p.X,p.Y+1]!=1&&Matrix[p.X,p.Y-1]!=1)
{
if (Matrix[p.X,p.Y-1]>Matrix[p.X,p.Y+1])
{
SwitchValues(Matrix[p.X,p.Y+1],Matrix[p.X,p.Y-1]);
Matrix[p.X,p.Y]=Matrix[p.X,p.Y-1];
}
else if (Matrix[p.X,p.Y-1]<Matrix[p.X,p.Y+1])
{
SwitchValues(Matrix[p.X,p.Y-1],Matrix[p.X,p.Y+1]);
Matrix[p.X,p.Y]=Matrix[p.X,p.Y+1];
}
}
cond = false;
}
else if (!positions.Contains(p))
{
positions.Add(p);
if (Matrix[p.X,p.Y]==1&&Matrix[p.X+1,p.Y]!=1&&Matrix[p.X-1,p.Y]!=1)
{
if (Matrix[p.X-1,p.Y]>Matrix[p.X+1,p.Y])
{
SwitchValues(Matrix[p.X+1,p.Y],Matrix[p.X-1,p.Y]);
Matrix[p.X,p.Y]=Matrix[p.X-1,p.Y];
}
else if (Matrix[p.X-1,p.Y]<Matrix[p.X+1,p.Y])
{
SwitchValues(Matrix[p.X-1,p.Y],Matrix[p.X+1,p.Y]);
Matrix[p.X,p.Y]=Matrix[p.X+1,p.Y];
}
}
cond = true;
}
if (demonstration)RawPrintBoard();
}
}
/// <summary>This method is used to replace the values int the matrix after breaking a wall. This allows the matrix to finally contain exclusively 1(walls) or a value(the paths). This algorithm provides a simple labyrinth where every position in a path is accessible from another.</summary>
/// <param name="previous">The value to replace.</param>
/// <param name="next">The value to set.</param>
private void SwitchValues(int previous, int next)
{
for (int i = 0; i < Matrix.GetLength(0); i++)for (int j = 0; j < Matrix.GetLength(1); j++)if (Matrix[i,j]==previous)Matrix[i,j]=next;
}
/// <summary>This method is used to check if the matrix is completed.</summary>
/// <returns>True if the matrix is completed, false otherwise.</returns>
private bool IsMatrixDone()
{
int referenceValue = Matrix[1,1];
for (int i = 1; i < Matrix.GetLength(0)-1; i++)for (int j = 1; j < Matrix.GetLength(1)-1; j++)if (Matrix[i, j] != referenceValue && Matrix[i, j] != 1) return false;
return true;
}
/// <summary>This method is used to display the matrix in the console.</summary>
public void PrintBoard()
{
Clear();
for(int i = 0; i < Matrix.GetLength(0) ; i++)
{
BackgroundColor = ConsoleColor.Black;
ForegroundColor = ConsoleColor.Black;
string line = "";
for (int j = 0; j < Matrix.GetLength(0); j++)
{
switch(Matrix[i,j])
{
case 0 : line += " ";break;
case 1 : line += "# ";break;
case 2 : line += " ";continue;
case 3 : line += " ";continue;
case 4 : line += ". ";continue;
case 5 : line += GamePawn.s_PawnSymbol+" ";continue;
case 6 : line += GamePawn.s_BonusSymbol+" ";continue;
}
}
if (i == 1)
{
BackgroundColor = ConsoleColor.Red;
ForegroundColor = ConsoleColor.Black;
Write("Start → ");
BackgroundColor = ConsoleColor.Green;
ForegroundColor = ConsoleColor.Black;
WriteLine(line);
}
else if (i == Matrix.GetLength(0)-2)
{
Write("\t");
BackgroundColor = ConsoleColor.Green;
Write(line);
BackgroundColor = ConsoleColor.Blue;
ForegroundColor = ConsoleColor.Black;
WriteLine(" → Exit");
}
else
{
Write("\t");
BackgroundColor = ConsoleColor.Green;
WriteLine(line);
}
}
Methods.ConsoleConfig();
}
/// <summary>This method is used to check if a position is available in the matrix.</summary>
/// <param name="position">The position to check.</param>
/// <returns>True if the position is available, false otherwise.</returns>
public bool IsAvailable(Position position) => (Matrix[position.X,position.Y] == 1 || Matrix[position.X,position.Y] == 5)? false : true;
public void RawPrintBoard()
{
Clear();
for(int i = 0; i < Matrix.GetLength(0) ; i++)
{
BackgroundColor = ConsoleColor.Green;
for (int j = 0; j < Matrix.GetLength(0); j++)
{
Write(Matrix[i,j]+" ");
}
BackgroundColor = ConsoleColor.Black;
WriteLine();
}
ReadKey(false);
}
#endregion
}
}