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

samsmithnz / PuzzleSolver / 4338719335

pending completion
4338719335

Pull #46

github

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

920 of 978 branches covered (94.07%)

Branch coverage included in aggregate %.

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

1609 of 1640 relevant lines covered (98.11%)

1112128.48 hits per line

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

93.26
/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; }
146✔
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; }
254✔
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; }
107✔
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
                {
39✔
189
                    //it's a right location drop-off
190
                    adjacentLocation = new Vector2((int)destinationLocation.X + 1, (int)destinationLocation.Y);
39✔
191
                }
39✔
192
                else if (destinationLocation.X == map.GetUpperBound(0))
7✔
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)
5!
198
                {
5✔
199
                    //it's a top location drop-off
200
                    adjacentLocation = new Vector2((int)destinationLocation.X, (int)destinationLocation.Y + 1);
5✔
201
                }
5✔
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)
91✔
224
            {
86✔
225
                //Sort the progress list to find the robot with the least number of turns - this is the robot who should pick up next
226
                List<KeyValuePair<int, int>> orderedRobotProgress = robotProgress.OrderBy(x => x.Value).ToList();
191✔
227
                //For each robot
228
                foreach (Robot robot in Robots)
364✔
229
                {
96✔
230
                    //Find the robot with the least progress, and then break
231
                    if (orderedRobotProgress[0].Key == robot.RobotId)
96✔
232
                    {
86✔
233
                        RobotAction robotAction = new RobotAction();
86✔
234
                        Piece piece = null;
86✔
235
                        //See if the robot needs to move to the pickup zone
236
                        if (robot.Location != robot.PickupLocation)
86✔
237
                        {
40✔
238
                            //Move the robot to the pickup zone - By doing this first we ensure we don't pick up a piece until we are there.
239
                            Vector2 currentRobotLocation = robot.Location;
40✔
240
                            Vector2 pickupLocation = robot.PickupLocation;
40✔
241

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

264
                        //process the robot action
265
                        if (robotAction != null)
86✔
266
                        {
86✔
267
                            int turn = robotProgress[robot.RobotId];
86✔
268
                            int turnsNeeded = 0;
86✔
269

270
                            //move to pickup
271
                            if (robotAction.PathToPickup != null)
86✔
272
                            {
40✔
273
                                turnsNeeded += robotAction.PathToPickup.Path.Count;
40✔
274
                            }
40✔
275
                            //pickup piece
276
                            if (robotAction.PickupAction != null)
86✔
277
                            {
46✔
278
                                turnsNeeded++;
46✔
279
                            }
46✔
280
                            //move to drop off
281
                            if (robotAction.PathToDropoff != null)
86✔
282
                            {
46✔
283
                                turnsNeeded += robotAction.PathToDropoff.Path.Count;
46✔
284
                            }
46✔
285
                            //drop off piece
286
                            if (robotAction.DropoffAction != null)
86✔
287
                            {
46✔
288
                                turnsNeeded++;
46✔
289
                            }
46✔
290
                            //Initialize the turns needed for this robot to complete it's turn
291
                            for (int j = turn; j < turn + turnsNeeded; j++)
762✔
292
                            {
295✔
293
                                if (timeline.Turns.Any(t => t.TurnNumber == j + 1) == false)
9,062✔
294
                                {
263✔
295
                                    timeline.Turns.Add(new Turn(j + 1));
263✔
296
                                }
263✔
297
                            }
295✔
298

299
                            //Now populate the turns with the pickup path
300
                            int pickupCounter = 0;
86✔
301
                            if (robotAction.PathToPickup != null &&
86✔
302
                                robotAction.PathToPickup.Path != null &&
86✔
303
                                robotAction.PathToPickup.Path.Count > 0)
86✔
304
                            {
40✔
305
                                pickupCounter++;
40✔
306
                                timeline.Turns[turn].RobotActions.Add(new RobotTurnAction(robot.RobotId, null)
40✔
307
                                {
40✔
308
                                    Movement = new List<Vector2>() { robotAction.RobotPickupStartingLocation, robotAction.PathToPickup.Path[0] }
40✔
309
                                });
40✔
310
                                for (int j = 1; j <= robotAction.PathToPickup.Path.Count - 1; j++)
190✔
311
                                {
55✔
312
                                    pickupCounter++;
55✔
313
                                    timeline.Turns[turn + j].RobotActions.Add(new RobotTurnAction(robot.RobotId, null)
55✔
314
                                    {
55✔
315
                                        Movement = new List<Vector2>() { robotAction.PathToPickup.Path[j - 1], robotAction.PathToPickup.Path[j] }
55✔
316
                                    });
55✔
317
                                }
55✔
318
                            }
40✔
319

320
                            if (robotAction.PickupAction != null)
86✔
321
                            {
46✔
322
                                timeline.Turns[pickupCounter + turn].RobotActions.Add(new RobotTurnAction(robot.RobotId, piece.Id)
46✔
323
                                {
46✔
324
                                    PickupAction = robotAction.PickupAction
46✔
325
                                });
46✔
326
                                pickupCounter++;
46✔
327
                                robot.Location = robotAction.RobotPickupEndingLocation;
46✔
328
                            }
46✔
329

330
                            //Now populate the turns with the dropoff path
331
                            int dropoffCounter = 0;
86✔
332
                            if (robotAction.PathToDropoff != null &&
86✔
333
                                robotAction.PathToDropoff.Path != null &&
86✔
334
                                robotAction.PathToDropoff.Path.Count > 0)
86✔
335
                            {
45✔
336
                                dropoffCounter++;
45✔
337
                                timeline.Turns[pickupCounter + turn].RobotActions.Add(new RobotTurnAction(robot.RobotId, piece.Id)
45✔
338
                                {
45✔
339
                                    Movement = new List<Vector2>() { robotAction.RobotDropoffStartingLocation, robotAction.PathToDropoff.Path[0] }
45✔
340
                                });
45✔
341
                                for (int j = 1; j <= robotAction.PathToDropoff.Path.Count - 1; j++)
216✔
342
                                {
63✔
343
                                    dropoffCounter++;
63✔
344
                                    timeline.Turns[pickupCounter + turn + j].RobotActions.Add(new RobotTurnAction(robot.RobotId, piece.Id)
63✔
345
                                    {
63✔
346
                                        Movement = new List<Vector2>() { robotAction.PathToDropoff.Path[j - 1], robotAction.PathToDropoff.Path[j] }
63✔
347
                                    });
63✔
348
                                }
63✔
349
                            }
45✔
350

351
                            if (robotAction.DropoffAction != null)
86✔
352
                            {
46✔
353
                                robotAction.DropoffAction.DestinationPieceCount = GetPieceCount(robotAction.DropoffAction.Location);
46✔
354
                                timeline.Turns[pickupCounter + dropoffCounter + turn].RobotActions.Add(new RobotTurnAction(robot.RobotId, piece.Id)
46✔
355
                                {
46✔
356
                                    DropoffAction = robotAction.DropoffAction
46✔
357
                                });
46✔
358
                                dropoffCounter++;
46✔
359
                                robot.Location = robotAction.RobotDropoffEndingLocation;
46✔
360
                            }
46✔
361
                            robotProgress[robot.RobotId] += pickupCounter + dropoffCounter;
86✔
362
                        }
86✔
363

364
                        //RobotAction robotPickupAction = new RobotAction();
365
                        ////Move the robot to the pickup zone - By doing this first we ensure we don't pick up a piece until we are there.
366
                        //Vector2 currentRobotLocation = robot.Location;
367
                        //Vector2 pickupLocation = robot.PickupLocation;
368

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

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

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

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

447
                        //    if (robotAction.PickupAction != null)
448
                        //    {
449
                        //        timeline.Turns[pickupCounter + turn].RobotActions.Add(new RobotTurnAction(robot.RobotId, piece.Id)
450
                        //        {
451
                        //            PickupAction = robotAction.PickupAction
452
                        //        });
453
                        //        pickupCounter++;
454
                        //        robot.Location = robotAction.RobotPickupEndingLocation;
455
                        //    }
456

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

478
                        //    if (robotAction.DropoffAction != null)
479
                        //    {
480
                        //        robotAction.DropoffAction.DestinationPieceCount = GetPieceCount(robotAction.DropoffAction.Location);
481
                        //        timeline.Turns[pickupCounter + dropoffCounter + turn].RobotActions.Add(new RobotTurnAction(robot.RobotId, piece.Id)
482
                        //        {
483
                        //            DropoffAction = robotAction.DropoffAction
484
                        //        });
485
                        //        dropoffCounter++;
486
                        //        robot.Location = robotAction.RobotDropoffEndingLocation;
487
                        //    }
488
                        //    robotProgress[robot.RobotId] += pickupCounter + dropoffCounter;
489
                        //}
490
                        break;
86✔
491
                    }
492
                }
10✔
493
            }
86✔
494

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

506
                    // Move to unsorted pile
507
                    robotAction.RobotPickupStartingLocation = currentRobotLocation;
5✔
508
                    if (currentRobotLocation != pickupLocation)
5✔
509
                    {
5✔
510
                        PathFindingResult pathFindingResultForPickup = PathFinding.FindPath(Map, currentRobotLocation, pickupLocation);
5✔
511
                        if (pathFindingResultForPickup != null && pathFindingResultForPickup.Path.Any())
5!
512
                        {
5✔
513
                            //Move robot
514
                            robotAction.PathToPickup = pathFindingResultForPickup;
5✔
515
                            currentRobotLocation = pathFindingResultForPickup.Path.Last();
5✔
516
                        }
5✔
517
                    }
5✔
518
                    robotAction.RobotPickupEndingLocation = currentRobotLocation;
5✔
519
                    robot.Location = currentRobotLocation;
5✔
520

521
                    //process the robot action
522
                    if (robotAction != null)
5✔
523
                    {
5✔
524
                        int turn = robotProgress[robot.RobotId];
5✔
525
                        int turnsNeeded = 0;
5✔
526

527
                        //move to pickup
528
                        if (robotAction.PathToPickup != null)
5✔
529
                        {
5✔
530
                            turnsNeeded += robotAction.PathToPickup.Path.Count;
5✔
531
                        }
5✔
532
                        //Initialize the turns needed for this robot to complete it's turn
533
                        for (int j = turn; j < turn + turnsNeeded; j++)
36✔
534
                        {
13✔
535
                            if (timeline.Turns.Any(t => t.TurnNumber == j + 1) == false)
720✔
536
                            {
13✔
537
                                timeline.Turns.Add(new Turn(j + 1));
13✔
538
                            }
13✔
539
                        }
13✔
540

541
                        //Now populate the turns with the pickup path
542
                        int pickupCounter = 0;
5✔
543
                        if (robotAction.PathToPickup != null &&
5!
544
                            robotAction.PathToPickup.Path != null &&
5✔
545
                            robotAction.PathToPickup.Path.Count > 0)
5✔
546
                        {
5✔
547
                            pickupCounter++;
5✔
548
                            timeline.Turns[turn].RobotActions.Add(new RobotTurnAction(robot.RobotId, null)
5✔
549
                            {
5✔
550
                                Movement = new List<Vector2>() { robotAction.RobotPickupStartingLocation, robotAction.PathToPickup.Path[0] }
5✔
551
                            });
5✔
552
                            for (int j = 1; j <= robotAction.PathToPickup.Path.Count - 1; j++)
26✔
553
                            {
8✔
554
                                pickupCounter++;
8✔
555
                                timeline.Turns[turn + j].RobotActions.Add(new RobotTurnAction(robot.RobotId, null)
8✔
556
                                {
8✔
557
                                    Movement = new List<Vector2>() { robotAction.PathToPickup.Path[j - 1], robotAction.PathToPickup.Path[j] }
8✔
558
                                });
8✔
559
                            }
8✔
560
                        }
5✔
561
                        robotProgress[robot.RobotId] += pickupCounter;
5✔
562
                    }
5✔
563
                }
5✔
564
            }
6✔
565

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

585
            return timeline;
5✔
586
        }
5✔
587

588
        private List<Turn> ProcessRobotActions(RobotAction robotAction)
589
        {
×
590
            List<Turn> turns = new List<Turn>();
×
591

592
            return turns;
×
593
        }
×
594

595
        private RobotAction GetRobotAction(Robot robot, Piece piece)
596
        {
46✔
597
            RobotAction robotAction = new RobotAction();
46✔
598

599
            Vector2 currentRobotLocation = robot.Location;
46✔
600
            Vector2 pickupLocation = robot.PickupLocation;
46✔
601

602
            // Move to unsorted pile
603
            robotAction.RobotPickupStartingLocation = currentRobotLocation;
46✔
604
            if (currentRobotLocation != pickupLocation)
46!
605
            {
×
606
                PathFindingResult pathFindingResultForPickup = PathFinding.FindPath(Map, currentRobotLocation, pickupLocation);
×
607
                if (pathFindingResultForPickup != null && pathFindingResultForPickup.Path.Any())
×
608
                {
×
609
                    //Move robot
610
                    robotAction.PathToPickup = pathFindingResultForPickup;
×
611
                    currentRobotLocation = pathFindingResultForPickup.Path.Last();
×
612
                }
×
613
            }
×
614
            robotAction.RobotPickupEndingLocation = currentRobotLocation;
46✔
615

616
            // Pickup an unsorted piece from the unsorted pile
617
            robot.Piece = piece;
46✔
618
            robotAction.PieceId = piece.Id;
46✔
619
            robotAction.PickupAction = new ObjectInteraction()
46✔
620
            {
46✔
621
                Location = piece.Location
46✔
622
            };
46✔
623

624
            // Process the unsorted piece to work out where it goes
625
            Vector2? destinationLocation = null;
46✔
626
            foreach (SortedDropZone sortedDropZone in SortedDropZones)
346✔
627
            {
127✔
628
                if (sortedDropZone.Color == robot.Piece.ImageStats.TopColorGroupColor)
127✔
629
                {
46✔
630
                    destinationLocation = sortedDropZone.Location;
46✔
631
                    break;
46✔
632
                }
633
            }
81✔
634

635
            //Get the best adjacent location to the destination
636
            Vector2? pathDestinationLocation = destinationLocation;
46✔
637
            if (destinationLocation != null)
46✔
638
            {
46✔
639
                Vector2? adjacentLocation = GetAdjacentLocation((Vector2)destinationLocation, Map, SortedDropZones);
46✔
640
                if (adjacentLocation != null)
46✔
641
                {
46✔
642
                    pathDestinationLocation = (Vector2)adjacentLocation;
46✔
643
                }
46✔
644
            }
46✔
645

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

681
            return robotAction;
46✔
682
        }
46✔
683
    }
684
}
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