4
4
using System . Text ;
5
5
6
6
7
- Test ( ) ;
7
+ Test1 ( ) ;
8
+ Test2 ( ) ;
9
+ Test3 ( ) ;
8
10
11
+ static void Test1 ( )
12
+ {
13
+ Console . WriteLine ( "==============" ) ;
14
+ Console . WriteLine ( "Test2" ) ;
15
+ Console . WriteLine ( "_____" ) ;
16
+ int reqStepCount = 1 ;
17
+ Game game_2 = new ( "[[1,2,3],[4,0,5]]" ) ;
18
+ GameState resolvedState = game_2 . GetSolution ( ) ;
19
+ Console . WriteLine ( resolvedState . ToString ( ) ) ;
20
+ Console . WriteLine ( resolvedState . Status . ToString ( ) ) ;
21
+ Console . WriteLine ( $ "resolved in { resolvedState . StepCount } steps") ;
22
+ Console . WriteLine ( $ "Test result { ( resolvedState . StepCount == reqStepCount ? "passed" : "failed" ) } .") ;
23
+ }
9
24
10
- static void Test ( )
25
+ static void Test2 ( )
11
26
{
12
27
Console . WriteLine ( "==============" ) ;
13
28
Console . WriteLine ( "Test2" ) ;
@@ -17,10 +32,23 @@ static void Test()
17
32
GameState resolvedState = game_2 . GetSolution ( ) ;
18
33
Console . WriteLine ( resolvedState . ToString ( ) ) ;
19
34
Console . WriteLine ( resolvedState . Status . ToString ( ) ) ;
20
- Console . WriteLine ( $ "resolved in { resolvedState . moveHist . Count } steps") ;
21
- Console . WriteLine ( $ "Test result { ( resolvedState . moveHist . Count == reqStepCount ? "passed" : "failed" ) } .") ;
35
+ Console . WriteLine ( $ "resolved in { resolvedState . StepCount } steps") ;
36
+ Console . WriteLine ( $ "Test result { ( resolvedState . StepCount == reqStepCount ? "passed" : "failed" ) } .") ;
22
37
}
23
38
39
+ static void Test3 ( )
40
+ {
41
+ Console . WriteLine ( "==============" ) ;
42
+ Console . WriteLine ( "Test2" ) ;
43
+ Console . WriteLine ( "_____" ) ;
44
+ int reqStepCount = - 1 ;
45
+ Game game_2 = new ( "[[1,2,3],[5,4,0]]" ) ;
46
+ GameState resolvedState = game_2 . GetSolution ( ) ;
47
+ Console . WriteLine ( resolvedState . ToString ( ) ) ;
48
+ Console . WriteLine ( resolvedState . Status . ToString ( ) ) ;
49
+ Console . WriteLine ( $ "resolved in { resolvedState . StepCount } steps") ;
50
+ Console . WriteLine ( $ "Test result { ( resolvedState . StepCount == reqStepCount ? "passed" : "failed" ) } .") ;
51
+ }
24
52
25
53
[ Flags ]
26
54
public enum Movements
@@ -40,8 +68,25 @@ public enum StateStatus
40
68
}
41
69
public class GameState
42
70
{
43
- public static int RowNumber = 2 ;
44
- public static int ColNumber = 3 ;
71
+ public static int rowNumber = 2 ;
72
+ public static int colNumber = 3 ;
73
+
74
+ int _stepCount ;
75
+ public int StepCount
76
+ {
77
+ get
78
+ {
79
+ if ( Status == StateStatus . FAILED )
80
+ {
81
+ return - 1 ;
82
+ }
83
+ return _stepCount ;
84
+ }
85
+ private set
86
+ {
87
+ _stepCount = value ;
88
+ }
89
+ }
45
90
public int [ ] [ ] Values { get ; set ; }
46
91
public int [ ] AddressOfVoid { get ; set ; } = new int [ 2 ] ;
47
92
public Movements LastMovementFrom { get ; set ; }
@@ -57,9 +102,10 @@ public class GameState
57
102
/// </remarks>
58
103
/// <param name="initialState"></param>
59
104
/// <param name="lastMovementFrom"></param>
60
- public GameState ( int [ ] [ ] initialState , Movements lastMovementFrom , List < Movements > movesHistory )
105
+ public GameState ( int [ ] [ ] initialState , Movements lastMovementFrom , List < Movements > movesHistory , int t )
61
106
{
62
107
Status = StateStatus . IN_PROGRESS ;
108
+ StepCount = t ;
63
109
Values = new int [ initialState . Length ] [ ] ;
64
110
LastMovementFrom = lastMovementFrom ;
65
111
moveHist = new ( ) ;
@@ -113,6 +159,7 @@ public void Move(Movements movement)
113
159
break ;
114
160
}
115
161
moveHist . Add ( movement ) ;
162
+ StepCount ++ ;
116
163
}
117
164
public override string ToString ( )
118
165
{
@@ -142,25 +189,25 @@ public void SetAvailableMovements()
142
189
{
143
190
NextMovements |= Movements . TOP ;
144
191
}
145
- if ( row + 1 < RowNumber )
192
+ if ( row + 1 < rowNumber )
146
193
{
147
194
NextMovements |= Movements . BOTTOM ;
148
195
}
149
196
if ( col - 1 >= 0 )
150
197
{
151
198
NextMovements |= Movements . LEFT ;
152
199
}
153
- if ( col + 1 < ColNumber )
200
+ if ( col + 1 < colNumber )
154
201
{
155
202
NextMovements |= Movements . RIGHT ;
156
203
}
157
204
NextMovements ^= LastMovementFrom ; // do not repeat last movement
158
205
}
159
206
private void _getAddressOfVoid ( )
160
207
{
161
- for ( int i = 0 ; i < RowNumber ; i ++ )
208
+ for ( int i = 0 ; i < rowNumber ; i ++ )
162
209
{
163
- for ( int j = 0 ; j < ColNumber ; j ++ )
210
+ for ( int j = 0 ; j < colNumber ; j ++ )
164
211
{
165
212
if ( Values [ i ] [ j ] == 0 )
166
213
{
@@ -176,7 +223,7 @@ class Game
176
223
int rowNumber ;
177
224
int colNumber ;
178
225
GameState _initState ;
179
- public HashSet < string > stateHist { get ; set ; }
226
+ public Dictionary < string , int > stateHist { get ; set ; }
180
227
181
228
/// <summary>
182
229
/// init state as "n,n,n/n,n,n" or "[[n,n,n],[n,n,n]]"
@@ -221,14 +268,14 @@ public Game(int[][] initialState)
221
268
}
222
269
public void SetState ( int [ ] [ ] initialState )
223
270
{
224
- rowNumber = GameState . RowNumber ;
225
- colNumber = GameState . ColNumber ;
271
+ rowNumber = GameState . rowNumber ;
272
+ colNumber = GameState . colNumber ;
226
273
if ( ! ValidateInput ( initialState ) )
227
274
{
228
275
Console . WriteLine ( "Invalid game state as a starting point!" ) ;
229
276
return ;
230
277
}
231
- _initState = new GameState ( initialState , Movements . NONE , new List < Movements > ( ) ) ;
278
+ _initState = new GameState ( initialState , Movements . NONE , new List < Movements > ( ) , 0 ) ;
232
279
stateHist = new ( ) ;
233
280
}
234
281
public GameState GetSolution ( )
@@ -237,64 +284,71 @@ public GameState GetSolution()
237
284
}
238
285
private GameState GetSolution ( GameState state )
239
286
{
240
- if ( ! stateHist . Add ( state . ToString ( ) ) )
287
+ string stateToken = state . ToString ( ) ;
288
+ if ( ! stateHist . TryAdd ( stateToken , state . StepCount ) )
241
289
{
242
- state . Status = StateStatus . FAILED ;
243
- return state ;
290
+ // This state has been passed before
291
+ // if this rout reaches this state by longer path, then this path is failed.
292
+ // -> The other one is more closer to the solution then this branch, no need to continue on this rout
293
+ if ( state . StepCount >= stateHist [ stateToken ] )
294
+ {
295
+ state . Status = StateStatus . FAILED ;
296
+ return state ;
297
+ }
298
+ stateHist [ stateToken ] = state . StepCount ;
244
299
}
245
300
if ( _isSolved ( state ) )
246
301
{
247
302
state . Status = StateStatus . SUCCESS ;
248
303
return state ;
249
304
}
250
305
state . SetAvailableMovements ( ) ;
251
- List < GameState > newStates = new ( ) ;
252
- CheckMovement ( state , Movements . LEFT , newStates ) ;
253
- CheckMovement ( state , Movements . TOP , newStates ) ;
254
- CheckMovement ( state , Movements . RIGHT , newStates ) ;
255
- CheckMovement ( state , Movements . BOTTOM , newStates ) ;
256
-
306
+ List < GameState > nextStates = new ( ) ;
307
+ CheckMovement ( state , Movements . TOP , nextStates ) ;
308
+ CheckMovement ( state , Movements . BOTTOM , nextStates ) ;
309
+ CheckMovement ( state , Movements . RIGHT , nextStates ) ;
310
+ CheckMovement ( state , Movements . LEFT , nextStates ) ;
257
311
258
312
GameState resolvedState = state ;
259
313
int count = int . MaxValue ;
260
314
bool successFound = false ;
261
- foreach ( GameState newState in newStates )
315
+ foreach ( GameState newState in nextStates )
262
316
{
263
317
GameState newResolvedState = GetSolution ( newState ) ;
264
318
if ( successFound == false && newResolvedState . Status == StateStatus . SUCCESS )
265
319
{
266
320
successFound = true ;
267
321
resolvedState = newResolvedState ;
268
- count = resolvedState . moveHist . Count ;
322
+ count = resolvedState . StepCount ;
269
323
}
270
324
else if ( successFound && newResolvedState . Status == StateStatus . SUCCESS )
271
325
{
272
- if ( newResolvedState . moveHist . Count < count )
326
+ if ( newResolvedState . StepCount < count )
273
327
{
274
328
resolvedState = newResolvedState ;
275
- count = resolvedState . moveHist . Count ;
329
+ count = resolvedState . StepCount ;
276
330
}
277
331
}
278
332
else if ( successFound == false )
279
333
{
280
- if ( newResolvedState . moveHist . Count < count )
334
+ if ( newResolvedState . StepCount < count )
281
335
{
282
336
resolvedState = newResolvedState ;
283
- count = resolvedState . moveHist . Count ;
337
+ count = resolvedState . StepCount ;
284
338
}
285
339
}
286
340
}
287
341
return resolvedState ;
288
342
}
289
- private void CheckMovement ( GameState state , Movements movement , List < GameState > newStates )
343
+ private void CheckMovement ( GameState state , Movements movement , List < GameState > nexStates )
290
344
{
291
345
// check availablity
292
346
bool isMovementAvailable = state . NextMovements . HasFlag ( movement ) ;
293
- if ( isMovementAvailable == false ) return ;
347
+ if ( ! isMovementAvailable ) return ;
294
348
// we return early if this movement is not available
295
349
GameState _state ;
296
- _state = new GameState ( state . Values , state . LastMovementFrom , state . moveHist ) ;
297
- newStates . Add ( _state ) ;
350
+ _state = new GameState ( state . Values , state . LastMovementFrom , state . moveHist , state . StepCount ) ;
351
+ nexStates . Add ( _state ) ;
298
352
299
353
_state . Move ( movement ) ;
300
354
}
0 commit comments