• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

samsmithnz / PuzzleSolver / 4337368677

pending completion
4337368677

Pull #46

github

GitHub
Merge 9e00abc26 into 3080f4de1
Pull Request #46: Adding multiple robots

918 of 976 branches covered (94.06%)

Branch coverage included in aggregate %.

278 of 278 new or added lines in 6 files covered. (100.0%)

1605 of 1636 relevant lines covered (98.11%)

1114822.85 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

93.17
/src/PuzzleSolver/Board.cs
1
using PuzzleSolver.Images;
2
using PuzzleSolver.Map;
3
using PuzzleSolver.MultipleRobots;
4
using PuzzleSolver.Processing;
5
using SixLabors.ImageSharp.PixelFormats;
6
using System.Collections.Generic;
7
using System.Linq;
8
using System.Numerics;
9

10
namespace PuzzleSolver
11
{
12
    public class Board
13
    {
14
        public string[,] Map { get; set; }
144✔
15

16
        //Color Palette
17
        public List<Rgb24> ColorPalette { get; set; }
14✔
18

19
        //Pieces
20
        public Vector2 UnsortedPiecesLocation { get; set; }
9✔
21
        public Queue<Piece> UnsortedPieces { get; set; }
243✔
22
        public List<Piece> SortedPieces { get; set; }
63✔
23
        public List<SortedDropZone> SortedDropZones { get; set; }
254✔
24

25
        //Characters
26
        public List<Robot> Robots { get; set; }
96✔
27

28
        //Constructor
29
        public Board(string[,] map,
7✔
30
            Vector2 unsortedPiecesLocation,
7✔
31
            List<Rgb24> colorPalette,
7✔
32
            List<Piece> unsortedPieceList,
7✔
33
            List<SortedDropZone> sortedDropZones,
7✔
34
            List<Robot> robots)
7✔
35
        {
7✔
36
            Map = map;
7✔
37
            UnsortedPiecesLocation = unsortedPiecesLocation;
7✔
38
            ColorPalette = colorPalette;
7✔
39
            UnsortedPieces = new Queue<Piece>();
7✔
40
            ImageColorGroups imageProcessing = new ImageColorGroups(ColorPalette);
7✔
41
            for (int i = 0; i < unsortedPieceList.Count; i++)
122✔
42
            {
54✔
43
                Piece piece = unsortedPieceList[i];
54✔
44
                piece.ImageStats = imageProcessing.ProcessStatsForImage(null, piece.Image);
54✔
45
                UnsortedPieces.Enqueue(piece);
54✔
46
            }
54✔
47
            SortedDropZones = sortedDropZones;
7✔
48
            SortedPieces = new List<Piece>();
7✔
49
            Robots = robots;
7✔
50
        }
7✔
51

52
        ////Function to calculate the robot moves
53
        //public Queue<RobotAction> RunRobot()
54
        //{
55
        //    Queue<RobotAction> results = new Queue<RobotAction>();
56

57
        //    //Get the pickup location
58
        //    Vector2 PickUpLocation = Robots[0].PickupLocation;
59
        //    Vector2 currentRobotLocation = Robots[0].Location;
60

61
        //    //Loop through the queue of unsorted pieces
62
        //    while (UnsortedPieces.Count > 0)
63
        //    {
64
        //        RobotAction robotAction = new RobotAction();
65

66
        //        // Move to unsorted pile
67
        //        robotAction.RobotPickupStartingLocation = currentRobotLocation;
68
        //        if (currentRobotLocation != PickUpLocation)
69
        //        {
70
        //            PathFindingResult pathFindingResultForPickup = PathFinding.FindPath(Map, currentRobotLocation, PickUpLocation);
71
        //            if (pathFindingResultForPickup != null && pathFindingResultForPickup.Path.Any())
72
        //            {
73
        //                //Move robot
74
        //                robotAction.PathToPickup = pathFindingResultForPickup;
75
        //                currentRobotLocation = pathFindingResultForPickup.Path.Last();
76
        //            }
77
        //        }
78
        //        robotAction.RobotPickupEndingLocation = currentRobotLocation;
79

80
        //        // Pickup an unsorted piece from the unsorted pile
81
        //        Robots[0].Piece = UnsortedPieces.Dequeue();
82
        //        robotAction.PieceId = Robots[0].Piece.Id;
83
        //        robotAction.PickupAction = new ObjectInteraction()
84
        //        {
85
        //            Location = PickUpLocation
86
        //        };
87

88
        //        // Process the unsorted piece to work out where it goes
89
        //        Vector2? destinationLocation = null;
90
        //        foreach (SortedDropZone sortedDropZone in SortedDropZones)
91
        //        {
92
        //            if (sortedDropZone.Color == Robots[0].Piece.ImageStats.TopColorGroupColor)
93
        //            {
94
        //                destinationLocation = sortedDropZone.Location;
95
        //                break;
96
        //            }
97
        //        }
98

99
        //        //Get the best adjacent location to the destination
100
        //        Vector2? pathDestinationLocation = destinationLocation;
101
        //        if (destinationLocation != null)
102
        //        {
103
        //            Vector2? adjacentLocation = GetAdjacentLocation((Vector2)destinationLocation, Map, SortedDropZones);
104
        //            if (adjacentLocation != null)
105
        //            {
106
        //                pathDestinationLocation = (Vector2)adjacentLocation;
107
        //            }
108
        //        }
109

110
        //        // Move the sorted piece to the correct pile
111
        //        robotAction.RobotDropoffStartingLocation = currentRobotLocation;
112
        //        if (destinationLocation != null && pathDestinationLocation != null)
113
        //        {
114
        //            //now find the path
115
        //            PathFindingResult pathFindingResultForDropoff = PathFinding.FindPath(Map, currentRobotLocation, (Vector2)pathDestinationLocation);
116
        //            if (pathFindingResultForDropoff != null && pathFindingResultForDropoff.Path.Count >= 0)
117
        //            {
118
        //                //Move robot
119
        //                robotAction.PathToDropoff = pathFindingResultForDropoff;
120
        //                robotAction.DropoffAction = new ObjectInteraction()
121
        //                {
122
        //                    Location = (Vector2)destinationLocation
123
        //                };
124
        //                //Move the piece from the robot to the sorted pile
125
        //                Robots[0].Piece.Location = robotAction.DropoffAction.Location;
126
        //                SortedPieces.Add(Robots[0].Piece);
127
        //                foreach (SortedDropZone sortedDropZone in SortedDropZones)
128
        //                {
129
        //                    if (sortedDropZone.Location == destinationLocation)
130
        //                    {
131
        //                        sortedDropZone.Count++;
132
        //                        break;
133
        //                    }
134
        //                }
135
        //                Robots[0].Piece = null;
136
        //                robotAction.DropoffPieceCount = GetPieceCount(robotAction.DropoffAction.Location);
137
        //                if (pathFindingResultForDropoff.Path.Count > 0)
138
        //                {
139
        //                    currentRobotLocation = pathFindingResultForDropoff.Path.Last();
140
        //                }
141
        //            }
142
        //        }
143
        //        robotAction.RobotDropoffEndingLocation = currentRobotLocation;
144

145
        //        // Add to queue
146
        //        results.Enqueue(robotAction);
147
        //    }
148

149
        //    //Add last action to return to the starting point
150
        //    RobotAction robotActionReset = new RobotAction();
151
        //    robotActionReset.RobotPickupStartingLocation = currentRobotLocation;
152
        //    if (currentRobotLocation != PickUpLocation)
153
        //    {
154
        //        PathFindingResult pathFindingResultForPickup = PathFinding.FindPath(Map, currentRobotLocation, PickUpLocation);
155
        //        if (pathFindingResultForPickup != null && pathFindingResultForPickup.Path.Any())
156
        //        {
157
        //            //Move robot
158
        //            robotActionReset.PathToPickup = pathFindingResultForPickup;
159
        //            currentRobotLocation = pathFindingResultForPickup.Path.Last();
160
        //        }
161
        //    }
162
        //    robotActionReset.RobotPickupEndingLocation = currentRobotLocation;
163
        //    results.Enqueue(robotActionReset);
164

165
        //    return results;
166
        //}
167

168
        public int GetPieceCount(Vector2 dropOfflocation)
169
        {
94✔
170
            int pieceCount = 0;
94✔
171
            foreach (SortedDropZone sortedDropZone in SortedDropZones)
700✔
172
            {
256✔
173
                if (sortedDropZone.Location == dropOfflocation)
256✔
174
                {
94✔
175
                    pieceCount = sortedDropZone.Count;
94✔
176
                    break;
94✔
177
                }
178
            }
162✔
179
            return pieceCount;
94✔
180
        }
94✔
181

182
        private Vector2? GetAdjacentLocation(Vector2 destinationLocation, string[,] map, List<SortedDropZone> sortedDropZones)
183
        {
46✔
184
            Vector2? adjacentLocation = null;
46✔
185
            if (destinationLocation != null)
46✔
186
            {
46✔
187
                if (destinationLocation.X == 0)
46✔
188
                {
35✔
189
                    //it's a right location drop-off
190
                    adjacentLocation = new Vector2((int)destinationLocation.X + 1, (int)destinationLocation.Y);
35✔
191
                }
35✔
192
                else if (destinationLocation.X == map.GetUpperBound(0))
11✔
193
                {
2✔
194
                    //it's a left location drop-off
195
                    adjacentLocation = new Vector2((int)destinationLocation.X - 1, (int)destinationLocation.Y);
2✔
196
                }
2✔
197
                else if (destinationLocation.Y == 0)
9!
198
                {
9✔
199
                    //it's a top location drop-off
200
                    adjacentLocation = new Vector2((int)destinationLocation.X, (int)destinationLocation.Y + 1);
9✔
201
                }
9✔
202
                else if (destinationLocation.Y == map.GetUpperBound(1))
×
203
                {
×
204
                    //it's a bottom location drop-off
205
                    adjacentLocation = new Vector2((int)destinationLocation.X, (int)destinationLocation.Y - 11);
×
206
                }
×
207
            }
46✔
208
            return adjacentLocation;
46✔
209
        }
46✔
210

211
        public TimeLine RunRobots()
212
        {
5✔
213
            TimeLine timeline = new TimeLine();
5✔
214

215
            //Create a dictonary to track robot turn progress over time
216
            Dictionary<int, int> robotProgress = new Dictionary<int, int>();
5✔
217
            foreach (Robot robot in Robots)
27✔
218
            {
6✔
219
                robotProgress.Add(robot.RobotId, 0);
6✔
220
            }
6✔
221

222
            //Need to loop through all unsorted pieces until they are sorted
223
            while (UnsortedPieces.Count > 0)
80✔
224
            {
75✔
225
                //For each robot
226
                foreach (Robot robot in Robots)
393✔
227
                {
84✔
228
                    RobotAction robotAction = new RobotAction();
84✔
229
                    Piece piece = null;
84✔
230
                    //See if the robot needs to move to the pickup zone
231
                    if (robot.Location != robot.PickupLocation)
84✔
232
                    {
38✔
233
                        //Move the robot to the pickup zone - By doing this first we ensure we don't pick up a piece until we are there.
234
                        Vector2 currentRobotLocation = robot.Location;
38✔
235
                        Vector2 pickupLocation = robot.PickupLocation;
38✔
236

237
                        // Move to unsorted pile
238
                        robotAction.RobotPickupStartingLocation = currentRobotLocation;
38✔
239
                        if (currentRobotLocation != pickupLocation)
38✔
240
                        {
38✔
241
                            PathFindingResult pathFindingResultForPickup = PathFinding.FindPath(Map, currentRobotLocation, pickupLocation);
38✔
242
                            if (pathFindingResultForPickup != null && pathFindingResultForPickup.Path.Any())
38!
243
                            {
38✔
244
                                //Move robot
245
                                robotAction.PathToPickup = pathFindingResultForPickup;
38✔
246
                                currentRobotLocation = pathFindingResultForPickup.Path.Last();
38✔
247
                            }
38✔
248
                        }
38✔
249
                        robotAction.RobotPickupEndingLocation = currentRobotLocation;
38✔
250
                        robot.Location = currentRobotLocation;
38✔
251
                    }
38✔
252
                    //Else do the pickup, dropoff and delivery
253
                    else if (UnsortedPieces.Count > 0)
46✔
254
                    {
46✔
255
                        piece = UnsortedPieces.Dequeue();
46✔
256
                        robotAction = GetRobotAction(robot, piece);
46✔
257
                    }
46✔
258

259
                    //process the robot action
260
                    if (robotAction != null)
84✔
261
                    {
84✔
262
                        int turn = robotProgress[robot.RobotId];
84✔
263
                        int turnsNeeded = 0;
84✔
264

265
                        //move to pickup
266
                        if (robotAction.PathToPickup != null)
84✔
267
                        {
38✔
268
                            turnsNeeded += robotAction.PathToPickup.Path.Count;
38✔
269
                        }
38✔
270
                        //pickup piece
271
                        if (robotAction.PickupAction != null)
84✔
272
                        {
46✔
273
                            turnsNeeded++;
46✔
274
                        }
46✔
275
                        //move to drop off
276
                        if (robotAction.PathToDropoff != null)
84✔
277
                        {
46✔
278
                            turnsNeeded += robotAction.PathToDropoff.Path.Count;
46✔
279
                        }
46✔
280
                        //drop off piece
281
                        if (robotAction.DropoffAction != null)
84✔
282
                        {
46✔
283
                            turnsNeeded++;
46✔
284
                        }
46✔
285
                        //Initialize the turns needed for this robot to complete it's turn
286
                        for (int j = turn; j < turn + turnsNeeded; j++)
630✔
287
                        {
231✔
288
                            if (timeline.Turns.Any(t => t.TurnNumber == j + 1) == false)
6,025✔
289
                            {
212✔
290
                                timeline.Turns.Add(new Turn(j + 1));
212✔
291
                            }
212✔
292
                        }
231✔
293

294
                        //Now populate the turns with the pickup path
295
                        int pickupCounter = 0;
84✔
296
                        if (robotAction.PathToPickup != null &&
84✔
297
                            robotAction.PathToPickup.Path != null &&
84✔
298
                            robotAction.PathToPickup.Path.Count > 0)
84✔
299
                        {
38✔
300
                            pickupCounter++;
38✔
301
                            timeline.Turns[turn].RobotActions.Add(new RobotTurnAction(robot.RobotId, null)
38✔
302
                            {
38✔
303
                                Movement = new List<Vector2>() { robotAction.RobotPickupStartingLocation, robotAction.PathToPickup.Path[0] }
38✔
304
                            });
38✔
305
                            for (int j = 1; j <= robotAction.PathToPickup.Path.Count - 1; j++)
130✔
306
                            {
27✔
307
                                pickupCounter++;
27✔
308
                                timeline.Turns[turn + j].RobotActions.Add(new RobotTurnAction(robot.RobotId, null)
27✔
309
                                {
27✔
310
                                    Movement = new List<Vector2>() { robotAction.PathToPickup.Path[j - 1], robotAction.PathToPickup.Path[j] }
27✔
311
                                });
27✔
312
                            }
27✔
313
                        }
38✔
314

315
                        if (robotAction.PickupAction != null)
84✔
316
                        {
46✔
317
                            timeline.Turns[pickupCounter + turn].RobotActions.Add(new RobotTurnAction(robot.RobotId, piece.Id)
46✔
318
                            {
46✔
319
                                PickupAction = robotAction.PickupAction
46✔
320
                            });
46✔
321
                            pickupCounter++;
46✔
322
                            robot.Location = robotAction.RobotPickupEndingLocation;
46✔
323
                        }
46✔
324

325
                        //Now populate the turns with the dropoff path
326
                        int dropoffCounter = 0;
84✔
327
                        if (robotAction.PathToDropoff != null &&
84✔
328
                            robotAction.PathToDropoff.Path != null &&
84✔
329
                            robotAction.PathToDropoff.Path.Count > 0)
84✔
330
                        {
43✔
331
                            dropoffCounter++;
43✔
332
                            timeline.Turns[pickupCounter + turn].RobotActions.Add(new RobotTurnAction(robot.RobotId, piece.Id)
43✔
333
                            {
43✔
334
                                Movement = new List<Vector2>() { robotAction.RobotDropoffStartingLocation, robotAction.PathToDropoff.Path[0] }
43✔
335
                            });
43✔
336
                            for (int j = 1; j <= robotAction.PathToDropoff.Path.Count - 1; j++)
148✔
337
                            {
31✔
338
                                dropoffCounter++;
31✔
339
                                timeline.Turns[pickupCounter + turn + j].RobotActions.Add(new RobotTurnAction(robot.RobotId, piece.Id)
31✔
340
                                {
31✔
341
                                    Movement = new List<Vector2>() { robotAction.PathToDropoff.Path[j - 1], robotAction.PathToDropoff.Path[j] }
31✔
342
                                });
31✔
343
                            }
31✔
344
                        }
43✔
345

346
                        if (robotAction.DropoffAction != null)
84✔
347
                        {
46✔
348
                            robotAction.DropoffAction.DestinationPieceCount = GetPieceCount(robotAction.DropoffAction.Location);
46✔
349
                            timeline.Turns[pickupCounter + dropoffCounter + turn].RobotActions.Add(new RobotTurnAction(robot.RobotId, piece.Id)
46✔
350
                            {
46✔
351
                                DropoffAction = robotAction.DropoffAction
46✔
352
                            });
46✔
353
                            dropoffCounter++;
46✔
354
                            robot.Location = robotAction.RobotDropoffEndingLocation;
46✔
355
                        }
46✔
356
                        robotProgress[robot.RobotId] += pickupCounter + dropoffCounter;
84✔
357
                    }
84✔
358

359
                    //RobotAction robotPickupAction = new RobotAction();
360
                    ////Move the robot to the pickup zone - By doing this first we ensure we don't pick up a piece until we are there.
361
                    //Vector2 currentRobotLocation = robot.Location;
362
                    //Vector2 pickupLocation = robot.PickupLocation;
363

364
                    //// Move to unsorted pile
365
                    //robotPickupAction.RobotPickupStartingLocation = currentRobotLocation;
366
                    //if (currentRobotLocation != pickupLocation)
367
                    //{
368
                    //    PathFindingResult pathFindingResultForPickup = PathFinding.FindPath(Map, currentRobotLocation, pickupLocation);
369
                    //    if (pathFindingResultForPickup != null && pathFindingResultForPickup.Path.Any())
370
                    //    {
371
                    //        //Move robot
372
                    //        robotPickupAction.PathToPickup = pathFindingResultForPickup;
373
                    //        currentRobotLocation = pathFindingResultForPickup.Path.Last();
374
                    //    }
375
                    //}
376
                    //robotPickupAction.RobotPickupEndingLocation = currentRobotLocation;
377
                    //robot.Location = currentRobotLocation;
378

379
                    //Pick up and deliver the piece
380
                    //if (UnsortedPieces.Count > 0)
381
                    //{
382
                    //    //retrieve piece from queue/pile and setup robot to take action on the piece
383
                    //    Piece piece = UnsortedPieces.Dequeue();
384
                    //    RobotAction robotAction = GetRobotAction(robot, piece);
385
                    //    //merge the pickup and piece delivery
386
                    //    //robotAction.PathToPickup = robotPickupAction.PathToPickup;
387
                    //    //robotAction.RobotPickupStartingLocation = robotPickupAction.RobotPickupStartingLocation;
388
                    //    //robotAction.RobotPickupEndingLocation = robotPickupAction.RobotPickupEndingLocation;
389
                    //    int turn = robotProgress[robot.RobotId];
390
                    //    int turnsNeeded = 0;
391

392
                    //    //move to pickup
393
                    //    if (robotAction.PathToPickup != null)
394
                    //    {
395
                    //        turnsNeeded += robotAction.PathToPickup.Path.Count;
396
                    //    }
397
                    //    //pickup piece
398
                    //    if (robotAction.PickupAction != null)
399
                    //    {
400
                    //        turnsNeeded++;
401
                    //    }
402
                    //    //move to drop off
403
                    //    if (robotAction.PathToDropoff != null)
404
                    //    {
405
                    //        turnsNeeded += robotAction.PathToDropoff.Path.Count;
406
                    //    }
407
                    //    //drop off piece
408
                    //    if (robotAction.DropoffAction != null)
409
                    //    {
410
                    //        turnsNeeded++;
411
                    //    }
412
                    //    //Initialize the turns needed for this robot to complete it's turn
413
                    //    for (int j = turn; j < turn + turnsNeeded; j++)
414
                    //    {
415
                    //        if (timeline.Turns.Any(t => t.TurnNumber == j + 1) == false)
416
                    //        {
417
                    //            timeline.Turns.Add(new Turn(j + 1));
418
                    //        }
419
                    //    }
420

421
                    //    //Now populate the turns with the pickup path
422
                    //    int pickupCounter = 0;
423
                    //    if (robotAction.PathToPickup != null &&
424
                    //        robotAction.PathToPickup.Path != null &&
425
                    //        robotAction.PathToPickup.Path.Count > 0)
426
                    //    {
427
                    //        pickupCounter++;
428
                    //        timeline.Turns[turn].RobotActions.Add(new RobotTurnAction(robot.RobotId, piece.Id)
429
                    //        {
430
                    //            Movement = new List<Vector2>() { robotAction.RobotPickupStartingLocation, robotAction.PathToPickup.Path[0] }
431
                    //        });
432
                    //        for (int j = 1; j <= robotAction.PathToPickup.Path.Count - 1; j++)
433
                    //        {
434
                    //            pickupCounter++;
435
                    //            timeline.Turns[turn + j].RobotActions.Add(new RobotTurnAction(robot.RobotId, piece.Id)
436
                    //            {
437
                    //                Movement = new List<Vector2>() { robotAction.PathToPickup.Path[j - 1], robotAction.PathToPickup.Path[j] }
438
                    //            });
439
                    //        }
440
                    //    }
441

442
                    //    if (robotAction.PickupAction != null)
443
                    //    {
444
                    //        timeline.Turns[pickupCounter + turn].RobotActions.Add(new RobotTurnAction(robot.RobotId, piece.Id)
445
                    //        {
446
                    //            PickupAction = robotAction.PickupAction
447
                    //        });
448
                    //        pickupCounter++;
449
                    //        robot.Location = robotAction.RobotPickupEndingLocation;
450
                    //    }
451

452
                    //    //Now populate the turns with the dropoff path
453
                    //    int dropoffCounter = 0;
454
                    //    if (robotAction.PathToDropoff != null &&
455
                    //        robotAction.PathToDropoff.Path != null &&
456
                    //        robotAction.PathToDropoff.Path.Count > 0)
457
                    //    {
458
                    //        dropoffCounter++;
459
                    //        timeline.Turns[pickupCounter + turn].RobotActions.Add(new RobotTurnAction(robot.RobotId, piece.Id)
460
                    //        {
461
                    //            Movement = new List<Vector2>() { robotAction.RobotDropoffStartingLocation, robotAction.PathToDropoff.Path[0] }
462
                    //        });
463
                    //        for (int j = 1; j <= robotAction.PathToDropoff.Path.Count - 1; j++)
464
                    //        {
465
                    //            dropoffCounter++;
466
                    //            timeline.Turns[pickupCounter + turn + j].RobotActions.Add(new RobotTurnAction(robot.RobotId, piece.Id)
467
                    //            {
468
                    //                Movement = new List<Vector2>() { robotAction.PathToDropoff.Path[j - 1], robotAction.PathToDropoff.Path[j] }
469
                    //            });
470
                    //        }
471
                    //    }
472

473
                    //    if (robotAction.DropoffAction != null)
474
                    //    {
475
                    //        robotAction.DropoffAction.DestinationPieceCount = GetPieceCount(robotAction.DropoffAction.Location);
476
                    //        timeline.Turns[pickupCounter + dropoffCounter + turn].RobotActions.Add(new RobotTurnAction(robot.RobotId, piece.Id)
477
                    //        {
478
                    //            DropoffAction = robotAction.DropoffAction
479
                    //        });
480
                    //        dropoffCounter++;
481
                    //        robot.Location = robotAction.RobotDropoffEndingLocation;
482
                    //    }
483
                    //    robotProgress[robot.RobotId] += pickupCounter + dropoffCounter;
484
                    //}
485
                }
84✔
486
            }
75✔
487

488
            //Move the robots back to the start location
489
            foreach (Robot robot in Robots)
27✔
490
            {
6✔
491
                if (robot.Location != robot.PickupLocation)
6✔
492
                {
5✔
493
                    RobotAction robotAction = new RobotAction();
5✔
494
                    Piece piece = null;
5✔
495
                    //Move the robot to the pickup zone - By doing this first we ensure we don't pick up a piece until we are there.
496
                    Vector2 currentRobotLocation = robot.Location;
5✔
497
                    Vector2 pickupLocation = robot.PickupLocation;
5✔
498

499
                    // Move to unsorted pile
500
                    robotAction.RobotPickupStartingLocation = currentRobotLocation;
5✔
501
                    if (currentRobotLocation != pickupLocation)
5✔
502
                    {
5✔
503
                        PathFindingResult pathFindingResultForPickup = PathFinding.FindPath(Map, currentRobotLocation, pickupLocation);
5✔
504
                        if (pathFindingResultForPickup != null && pathFindingResultForPickup.Path.Any())
5!
505
                        {
5✔
506
                            //Move robot
507
                            robotAction.PathToPickup = pathFindingResultForPickup;
5✔
508
                            currentRobotLocation = pathFindingResultForPickup.Path.Last();
5✔
509
                        }
5✔
510
                    }
5✔
511
                    robotAction.RobotPickupEndingLocation = currentRobotLocation;
5✔
512
                    robot.Location = currentRobotLocation;
5✔
513

514
                    //process the robot action
515
                    if (robotAction != null)
5✔
516
                    {
5✔
517
                        int turn = robotProgress[robot.RobotId];
5✔
518
                        int turnsNeeded = 0;
5✔
519

520
                        //move to pickup
521
                        if (robotAction.PathToPickup != null)
5✔
522
                        {
5✔
523
                            turnsNeeded += robotAction.PathToPickup.Path.Count;
5✔
524
                        }
5✔
525
                        //Initialize the turns needed for this robot to complete it's turn
526
                        for (int j = turn; j < turn + turnsNeeded; j++)
28✔
527
                        {
9✔
528
                            if (timeline.Turns.Any(t => t.TurnNumber == j + 1) == false)
423✔
529
                            {
8✔
530
                                timeline.Turns.Add(new Turn(j + 1));
8✔
531
                            }
8✔
532
                        }
9✔
533

534
                        //Now populate the turns with the pickup path
535
                        int pickupCounter = 0;
5✔
536
                        if (robotAction.PathToPickup != null &&
5!
537
                            robotAction.PathToPickup.Path != null &&
5✔
538
                            robotAction.PathToPickup.Path.Count > 0)
5✔
539
                        {
5✔
540
                            pickupCounter++;
5✔
541
                            timeline.Turns[turn].RobotActions.Add(new RobotTurnAction(robot.RobotId, null)
5✔
542
                            {
5✔
543
                                Movement = new List<Vector2>() { robotAction.RobotPickupStartingLocation, robotAction.PathToPickup.Path[0] }
5✔
544
                            });
5✔
545
                            for (int j = 1; j <= robotAction.PathToPickup.Path.Count - 1; j++)
18✔
546
                            {
4✔
547
                                pickupCounter++;
4✔
548
                                timeline.Turns[turn + j].RobotActions.Add(new RobotTurnAction(robot.RobotId, null)
4✔
549
                                {
4✔
550
                                    Movement = new List<Vector2>() { robotAction.PathToPickup.Path[j - 1], robotAction.PathToPickup.Path[j] }
4✔
551
                                });
4✔
552
                            }
4✔
553
                        }
5✔
554
                        robotProgress[robot.RobotId] += pickupCounter;
5✔
555
                    }
5✔
556
                }
5✔
557
            }
6✔
558

559
            //if (UnsortedPieces.Count == 0)
560
            //{
561
            //    //Add last action to return to the starting point
562
            //    RobotAction robotActionReset = new RobotAction();
563
            //    robotActionReset.RobotPickupStartingLocation = currentRobotLocation;
564
            //    if (currentRobotLocation != PickUpLocation)
565
            //    {
566
            //        PathFindingResult pathFindingResultForPickup = PathFinding.FindPath(Map, currentRobotLocation, PickUpLocation);
567
            //        if (pathFindingResultForPickup != null && pathFindingResultForPickup.Path.Any())
568
            //        {
569
            //            //Move robot
570
            //            robotActionReset.PathToPickup = pathFindingResultForPickup;
571
            //            currentRobotLocation = pathFindingResultForPickup.Path.Last();
572
            //        }
573
            //    }
574
            //    robotActionReset.RobotPickupEndingLocation = currentRobotLocation;
575
            //    results.Enqueue(robotActionReset);
576
            //}
577

578
            return timeline;
5✔
579
        }
5✔
580

581
        private List<Turn> ProcessRobotActions(RobotAction robotAction)
582
        {
×
583
            List<Turn> turns = new List<Turn>();
×
584

585
            return turns;
×
586
        }
×
587

588
        private RobotAction GetRobotAction(Robot robot, Piece piece)
589
        {
46✔
590
            RobotAction robotAction = new RobotAction();
46✔
591

592
            Vector2 currentRobotLocation = robot.Location;
46✔
593
            Vector2 pickupLocation = robot.PickupLocation;
46✔
594

595
            // Move to unsorted pile
596
            robotAction.RobotPickupStartingLocation = currentRobotLocation;
46✔
597
            if (currentRobotLocation != pickupLocation)
46!
598
            {
×
599
                PathFindingResult pathFindingResultForPickup = PathFinding.FindPath(Map, currentRobotLocation, pickupLocation);
×
600
                if (pathFindingResultForPickup != null && pathFindingResultForPickup.Path.Any())
×
601
                {
×
602
                    //Move robot
603
                    robotAction.PathToPickup = pathFindingResultForPickup;
×
604
                    currentRobotLocation = pathFindingResultForPickup.Path.Last();
×
605
                }
×
606
            }
×
607
            robotAction.RobotPickupEndingLocation = currentRobotLocation;
46✔
608

609
            // Pickup an unsorted piece from the unsorted pile
610
            robot.Piece = piece;
46✔
611
            robotAction.PieceId = piece.Id;
46✔
612
            robotAction.PickupAction = new ObjectInteraction()
46✔
613
            {
46✔
614
                Location = piece.Location
46✔
615
            };
46✔
616

617
            // Process the unsorted piece to work out where it goes
618
            Vector2? destinationLocation = null;
46✔
619
            foreach (SortedDropZone sortedDropZone in SortedDropZones)
346✔
620
            {
127✔
621
                if (sortedDropZone.Color == robot.Piece.ImageStats.TopColorGroupColor)
127✔
622
                {
46✔
623
                    destinationLocation = sortedDropZone.Location;
46✔
624
                    break;
46✔
625
                }
626
            }
81✔
627

628
            //Get the best adjacent location to the destination
629
            Vector2? pathDestinationLocation = destinationLocation;
46✔
630
            if (destinationLocation != null)
46✔
631
            {
46✔
632
                Vector2? adjacentLocation = GetAdjacentLocation((Vector2)destinationLocation, Map, SortedDropZones);
46✔
633
                if (adjacentLocation != null)
46✔
634
                {
46✔
635
                    pathDestinationLocation = (Vector2)adjacentLocation;
46✔
636
                }
46✔
637
            }
46✔
638

639
            // Move the sorted piece to the correct pile
640
            robotAction.RobotDropoffStartingLocation = currentRobotLocation;
46✔
641
            if (destinationLocation != null && pathDestinationLocation != null)
46!
642
            {
46✔
643
                //now find the path
644
                PathFindingResult pathFindingResultForDropoff = PathFinding.FindPath(Map, currentRobotLocation, (Vector2)pathDestinationLocation);
46✔
645
                if (pathFindingResultForDropoff != null && pathFindingResultForDropoff.Path.Count >= 0)
46!
646
                {
46✔
647
                    //Move robot
648
                    robotAction.PathToDropoff = pathFindingResultForDropoff;
46✔
649
                    robotAction.DropoffAction = new ObjectInteraction()
46✔
650
                    {
46✔
651
                        Location = (Vector2)destinationLocation
46✔
652
                    };
46✔
653
                    //Move the piece from the robot to the sorted pile
654
                    robot.Piece.Location = robotAction.DropoffAction.Location;
46✔
655
                    SortedPieces.Add(robot.Piece);
46✔
656
                    foreach (SortedDropZone sortedDropZone in SortedDropZones)
346✔
657
                    {
127✔
658
                        if (sortedDropZone.Location == destinationLocation)
127!
659
                        {
46✔
660
                            sortedDropZone.Count++;
46✔
661
                            break;
46✔
662
                        }
663
                    }
81✔
664
                    robot.Piece = null;
46✔
665
                    robotAction.DropoffPieceCount = GetPieceCount(robotAction.DropoffAction.Location);
46✔
666
                    if (pathFindingResultForDropoff.Path.Count > 0)
46✔
667
                    {
43✔
668
                        currentRobotLocation = pathFindingResultForDropoff.Path.Last();
43✔
669
                    }
43✔
670
                }
46✔
671
            }
46✔
672
            robotAction.RobotDropoffEndingLocation = currentRobotLocation;
46✔
673

674
            return robotAction;
46✔
675
        }
46✔
676
    }
677
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc