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;
                        }
                    }
                }
            });
        }
Ejemplo n.º 2
0
        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);
        }