public void PlayIntelligently() { Task.Run(() => { // create initial node Node root = new Node(); root.Position.Row = player.Position.Row; root.Position.Column = player.Position.Column; root.CellItemType = player.CellItemType; // add the root node to the search space game.SearchSpace = root; // add the node object to the dictionary to prevent duplicate objects per cell. game.NodeMemo.Add((root.Position.Row, root.Position.Column), root); game.CurrentNode = root; // player to discover the rest of the nodes bool end = false; bool changeTarget = true; List <(int, int, Direction)> genTargets = new List <(int, int, Direction)>(); while (!end) { while (!dashboard.pauseStatus()) { //No Beacon Stepped Yet if (!player.steppedOnBeacon) { ActionType action; BaseCellItem cell; List <(Node, double)> priorityChildren = new List <(Node, double)>(); int prio = 0; Node node = new Node(); // if not existing in the map, if (!player.PositionHistory.Any(item => item.Item1 == player.Position.Row && item.Item2 == player.Position.Column)) { // discover the map //Rotate and Scan to East player.Facing = Direction.East; action = ActionType.Rotate; dashboard.UpdateDashboard(player, action); // update rotate count this.Dispatcher.Invoke(() => RefreshGrid(false)); Thread.Sleep(player.Metrics.gameSpeed); (cell, node, prio) = player.Discover(game); if (prio > 0) { priorityChildren.Add((node, prio)); } prio = 0; action = ActionType.Scan; dashboard.UpdateDashboard(player, action, cell.CellItemType); // update scan count Thread.Sleep(player.Metrics.gameSpeed); //Rotate and Scan to South player.Facing = Direction.South; action = ActionType.Rotate; dashboard.UpdateDashboard(player, action); // update rotate count this.Dispatcher.Invoke(() => RefreshGrid(false)); Thread.Sleep(player.Metrics.gameSpeed); (cell, node, prio) = player.Discover(game); if (prio > 0) { priorityChildren.Add((node, prio)); } prio = 0; action = ActionType.Scan; dashboard.UpdateDashboard(player, action, cell.CellItemType); // update scan count //Rotate and Scan to West player.Facing = Direction.West; action = ActionType.Rotate; dashboard.UpdateDashboard(player, action); // update rotate count this.Dispatcher.Invoke(() => RefreshGrid(false)); Thread.Sleep(player.Metrics.gameSpeed); (cell, node, prio) = player.Discover(game); if (prio > 0) { priorityChildren.Add((node, prio)); } prio = 0; action = ActionType.Scan; dashboard.UpdateDashboard(player, action, cell.CellItemType); // update scan count //Rotate and Scan to North player.Facing = Direction.North; action = ActionType.Rotate; dashboard.UpdateDashboard(player, action); // update rotate count this.Dispatcher.Invoke(() => RefreshGrid(false)); Thread.Sleep(player.Metrics.gameSpeed); (cell, node, prio) = player.Discover(game); if (prio > 0) { priorityChildren.Add((node, prio)); } prio = 0; action = ActionType.Scan; dashboard.UpdateDashboard(player, action, cell.CellItemType); // update scan count //Sort list based on ascending (greater value is more priority) priorityChildren.Sort((pair1, pair2) => pair1.Item2.CompareTo(pair2.Item2)); foreach (var item in priorityChildren) { game.CurrentNode.Children.Push(item.Item1); } if (game.CurrentNode.Children.Count > 0) { // rotate here var priorityCell = game.CurrentNode.Children.Peek(); var cellinFront = player.ScanForward(game); while (priorityCell.CellItemType != CellItemType.Wall && priorityCell.CellItemType != CellItemType.Empty && cellinFront.Position.Row != priorityCell.Position.Row && cellinFront.Position.Column != priorityCell.Position.Column) { player.Rotate(); dashboard.UpdateDashboard(player, ActionType.Rotate); // update rotate Thread.Sleep(player.Metrics.gameSpeed); cellinFront = player.ScanForward(game); dashboard.UpdateDashboard(player, ActionType.Rotate); // update csan this.Dispatcher.Invoke(() => RefreshGrid(true)); Thread.Sleep(player.Metrics.gameSpeed); } } } else { // dont discover if current node is already discovered, do no thing in this case } // move the player to the popped element at the top of the fringe CellItemType t = new CellItemType(); try { game.ClearCell(player.Position.Row, player.Position.Column); this.Dispatcher.Invoke(() => RefreshGrid(true)); (t, player.beaconValue) = player.MoveWithStrategy(game); this.Dispatcher.Invoke(() => RefreshGrid(false)); action = ActionType.Move; if (t == CellItemType.Beacon) { player.steppedOnBeacon = true; Node beaconRoot = new Node(); beaconRoot.Position.Row = player.Position.Row; beaconRoot.Position.Column = player.Position.Column; beaconRoot.CellItemType = player.CellItemType; game.BeaconMemo.Add((player.Position.Row, player.Position.Column), beaconRoot); genTargets = player.GenerateTargetGrids(game); } //this.Dispatcher.Invoke(() => RefreshGrid(true)); } catch (Exception) { end = true; action = ActionType.NoPossible; t = CellItemType.Empty; //throw; } if (t == CellItemType.GoldenSquare) { end = true; action = ActionType.Win; } dashboard.UpdateDashboard(player, action); // update move //this.Dispatcher.Invoke(() => RefreshGrid(true)); Thread.Sleep(player.Metrics.gameSpeed); } //Beacon Stepped else { //Head towards that direction if (!changeTarget) { ActionType action; Direction priorityDirection = player.currentBeaconTarget.Item3; List <(Node, double)> priorityChildren = new List <(Node, double)>(); BaseCellItem cell = new BaseCellItem(); //Scan and rotate 4 times surroudings but prioritize direction for (int i = 0; i < 4; i++) { action = ActionType.Rotate; player.Rotate(); dashboard.UpdateDashboard(player, action); this.Dispatcher.Invoke(() => RefreshGrid(false)); if (changeTarget) { player.DiscoverUsingBeacon(game, cell, priorityChildren, genTargets); } else { changeTarget = player.DiscoverUsingBeacon(game, cell, priorityChildren, genTargets); } action = ActionType.Scan; dashboard.UpdateDashboard(player, action, cell.CellItemType); Thread.Sleep(player.Metrics.gameSpeed); } //this.Dispatcher.Invoke(() => RefreshGrid(true)); Thread.Sleep(player.Metrics.gameSpeed); //Sort list based on ascending (greater value is more priority) priorityChildren.Sort((pair1, pair2) => pair1.Item2.CompareTo(pair2.Item2)); //Commented parts are for checking //========================================= //string priorities = String.Format("Current target: {0},{1}:{2}{3}", // player.currentBeaconTarget.Item1, player.currentBeaconTarget.Item2, // player.currentBeaconTarget.Item3.ToString(), Environment.NewLine); foreach (var item in priorityChildren) { game.CurrentNode.Children.Push(item.Item1); } if (game.CurrentNode.Children.Count > 0) { // rotate here var priorityCell = game.CurrentNode.Children.Peek(); var cellinFront = player.ScanForward(game); while (priorityCell.CellItemType != CellItemType.Wall && priorityCell.CellItemType != CellItemType.Empty && cellinFront.Position.Row != priorityCell.Position.Row && cellinFront.Position.Column != priorityCell.Position.Column) { player.Rotate(); dashboard.UpdateDashboard(player, ActionType.Rotate); // update move Thread.Sleep(player.Metrics.gameSpeed); cellinFront = player.ScanForward(game); dashboard.UpdateDashboard(player, ActionType.Rotate); // update move this.Dispatcher.Invoke(() => RefreshGrid(true)); Thread.Sleep(player.Metrics.gameSpeed); } } // move the player to the popped element at the top of the fringe CellItemType t = new CellItemType(); try { Beacon beacon = new Beacon(); game.ClearCell(player.Position.Row, player.Position.Column); this.Dispatcher.Invoke(() => RefreshGrid(true)); (t, beacon) = player.MoveWithStrategy(game); this.Dispatcher.Invoke(() => RefreshGrid(false)); action = ActionType.Move; try { if (t == CellItemType.Beacon) { List <(int, int, Direction)> anotherBeaconTargets = player.RegenTargetGrids(game, beacon); if (!player.steppedOnSecond) { for (int i = 0; i < genTargets.Count; i++) { foreach (var anotherBeacon in anotherBeaconTargets) { if (genTargets[i].Item1 == anotherBeacon.Item1 && genTargets[i].Item2 == anotherBeacon.Item2) { player.currentBeaconTarget = new Tuple <int, int, Direction>(genTargets[i].Item1, genTargets[i].Item2, genTargets[i].Item3); genTargets.RemoveAt(i); #if DEBUG MessageBox.Show(String.Format("Changed target to: {0},{1}", player.currentBeaconTarget.Item1, player.currentBeaconTarget.Item2), "Recalculating...", MessageBoxButton.OK, MessageBoxImage.Information, MessageBoxResult.OK, MessageBoxOptions.DefaultDesktopOnly); #endif changeTarget = false; break; } } } game.BeaconMemo = new Dictionary <(int, int), Node>(); Node beaconRoot = new Node(); beaconRoot.Position.Row = player.Position.Row; beaconRoot.Position.Column = player.Position.Column; beaconRoot.CellItemType = player.CellItemType; game.BeaconMemo.Add((player.Position.Row, player.Position.Column), beaconRoot); player.steppedOnSecond = true; } } } catch (Exception ex) { continue; } } catch (Exception ex) { end = true; action = ActionType.NoPossible; t = CellItemType.Empty; } if (t == CellItemType.GoldenSquare) { end = true; action = ActionType.Win; } dashboard.UpdateDashboard(player, action); // update move Thread.Sleep(player.Metrics.gameSpeed); } //Set a beacon target for the robot to lean towards a certain direction else // changetarget is true { int row = 0, col = 0, index = 0; if (genTargets.Count > 1) { // randomize target to choose index = Randomizer.RandomizeNumber(0, genTargets.Count); row = genTargets[index].Item1; col = genTargets[index].Item2; player.currentBeaconTarget = new Tuple <int, int, Direction>(row, col, genTargets[index].Item3); genTargets.RemoveAt(index); #if DEBUG MessageBox.Show(String.Format("Changed target to: {0},{1}", player.currentBeaconTarget.Item1, player.currentBeaconTarget.Item2), "Recalculating...", MessageBoxButton.OK, MessageBoxImage.Information, MessageBoxResult.OK, MessageBoxOptions.DefaultDesktopOnly); #endif } else if (genTargets.Count == 1) { row = genTargets[0].Item1; col = genTargets[0].Item2; player.currentBeaconTarget = new Tuple <int, int, Direction>(row, col, genTargets[0].Item3); genTargets.RemoveAt(index); #if DEBUG MessageBox.Show(String.Format("Changed target to: {0},{1}", player.currentBeaconTarget.Item1, player.currentBeaconTarget.Item2), "Recalculating...", MessageBoxButton.OK, MessageBoxImage.Information, MessageBoxResult.OK, MessageBoxOptions.DefaultDesktopOnly); #endif } //else //{ // dashboard.UpdateDashboard(player, ActionType.NoPossible); // update move // this.Dispatcher.Invoke(() => RefreshGrid()); // end = true; //} changeTarget = false; } } if (end) { this.Dispatcher.Invoke(() => RefreshGrid()); break; } } } }); }
public BaseCellItem MoveForward(Game game, bool random, int gameSpeed) { int times = 1; if (random) { times = Randomizer.RandomizeNumber(1, game.Size); } Console.WriteLine(string.Format("The player will move to the {0} for {1} time(s)!", Facing.ToString(), times)); BaseCellItem cell = null; for (int i = 0; i < times; i++) { Thread.Sleep(gameSpeed); cell = ScanForward(game); //scanCount += 1; if (cell.CellItemType == CellItemType.Wall) { Console.WriteLine("The player ran into a thick wall and cannot move forward. Aborting the remaining moves, if any."); break; } // remove the player from its current cell game.ClearCell(Position.Row, Position.Column); // assign new coordinates to the player Position.Row = cell.Position.Row; Position.Column = cell.Position.Column; game.AssignPlayerToCell(this); var newCoordinates = new Tuple <int, int>(Position.Row, Position.Column); Console.WriteLine(string.Format("Player moved to coordinates [{0},{1}]", Position.Row, Position.Column)); if (PositionHistory.Contains(newCoordinates)) { Metrics.backtrackCount++; } PositionHistory.Add(newCoordinates); //moveCount += 1; Metrics.moveCount++; if (cell.CellItemType == CellItemType.Pit) { // die Console.WriteLine("The player died a horrible death."); break; } else if (cell.CellItemType == CellItemType.GoldenSquare) { // win Console.WriteLine("The player has struck gold."); break; } else if (cell.CellItemType == CellItemType.Beacon) { // clue Console.WriteLine("The player has found a beacon."); break; } } return(cell); }