public List <Cell> GetAvailableNeighbors(int timeunit) { var allNeighbors = GetNeighbors(); var availableNeighbors = new List <Cell>(); foreach (var neighbor in allNeighbors) { if (!grid.ReservationTable.ContainsKey(new Grid.CellTimePair(neighbor, timeunit))) { // head to head collision prevention var neighborReservation = new Grid.CellTimePair(neighbor, timeunit - 1); if (grid.ReservationTable.ContainsKey(neighborReservation)) { var neighborStudent = grid.ReservationTable[neighborReservation]; var cellNextReservation = new Grid.CellTimePair(this, timeunit); if (grid.ReservationTable.ContainsKey(cellNextReservation) && grid.ReservationTable[cellNextReservation] == neighborStudent) { // head-to-head collision detected continue; } } availableNeighbors.Add(neighbor); } } return(availableNeighbors); }
private List <Grid.CellTimePair> GetPath(Cell startCell, Cell destinationCell, int startTimeUnit = 0) { // implementation of A star // a timeunit represents one movement var grid = GameManager.Grid; if (startCell == null) { throw new System.NullReferenceException("Student is not in grid"); } var rra = getRRA(startCell, destinationCell); var queue = new PriorityQueue <Grid.CellTimePair>(); var startCellTime = new Grid.CellTimePair(startCell, startTimeUnit); queue.Enqueue(startCellTime, 0); var pathParents = new Dictionary <Grid.CellTimePair, Grid.CellTimePair>(); while (!queue.IsEmpty()) { var currentCellTimePair = queue.Peek(); var currentCell = currentCellTimePair.cell; if (currentCellTimePair.timeUnit - startTimeUnit == searchDepth || currentCell == destinationCell) { break; } queue.Dequeue(); var neighborGCost = currentCellTimePair.timeUnit + 1; foreach (var neighborCell in currentCell.GetAvailableNeighbors(neighborGCost)) { var neighborCellTimePair = new Grid.CellTimePair(neighborCell, neighborGCost); var neighborHCost = rra.GetTrueDistance(neighborCell); pathParents[neighborCellTimePair] = currentCellTimePair; queue.Enqueue(neighborCellTimePair, neighborGCost + neighborHCost); } } var path = new List <Grid.CellTimePair>(); if (queue.IsEmpty()) // path not found { path.Add(new Grid.CellTimePair(startCell, startTimeUnit + 1)); path.Add(new Grid.CellTimePair(startCell, startTimeUnit + 2)); path.Add(new Grid.CellTimePair(startCell, startTimeUnit + 3)); return(path); } var destinationCellTimePair = queue.Peek(); var parent = destinationCellTimePair; while (pathParents.ContainsKey(parent)) { GameManager.Grid.ReservationTable.Add(parent, this); path.Add(parent); parent = pathParents[parent]; } path.Reverse(); return(path); }
private List <Grid.CellTimePair> GetIdlePath(Cell idleCell, int idleTime, int startTimeUnit = 0) { // a star that favors staying at the current cell var grid = GameManager.Grid; if (idleCell == null) { throw new System.NullReferenceException("Student is not in grid"); } var queue = new PriorityQueue <Grid.CellTimePair>(); var startCellTime = new Grid.CellTimePair(idleCell, startTimeUnit); queue.Enqueue(startCellTime, 0); var pathParents = new Dictionary <Grid.CellTimePair, Grid.CellTimePair>(); var currentIdleTime = 0; while (!queue.IsEmpty()) { var currentCellTimePair = queue.Peek(); var currentCell = currentCellTimePair.cell; if (currentCell == idleCell && ++currentIdleTime >= idleTime) { break; } queue.Dequeue(); var time = currentCellTimePair.timeUnit + 1; foreach (var neighborCell in currentCell.GetAvailableNeighbors(time)) { var neighborCellTimePair = new Grid.CellTimePair(neighborCell, time); var neighborHCost = Cell.ManhanttanDistance(neighborCell, idleCell); pathParents[neighborCellTimePair] = currentCellTimePair; queue.Enqueue(neighborCellTimePair, neighborHCost); } } var path = new List <Grid.CellTimePair>(); if (queue.IsEmpty()) // path not found { path.Add(new Grid.CellTimePair(idleCell, startTimeUnit + 1)); path.Add(new Grid.CellTimePair(idleCell, startTimeUnit + 2)); path.Add(new Grid.CellTimePair(idleCell, startTimeUnit + 3)); return(path); } var destinationCellTimePair = queue.Peek(); var parent = destinationCellTimePair; while (pathParents.ContainsKey(parent)) { GameManager.Grid.ReservationTable.Add(parent, this); path.Add(parent); parent = pathParents[parent]; } path.Reverse(); return(path); }