/// <summary>
        /// Get adjacent safe cells from a given cell.
        /// </summary>
        /// <param name="p_hHero"> Hero. </param>
        /// <param name="p_fcCell"> Current cell. </param>
        /// <returns> The safe neighboors. </returns>
        private static List <ForestCell> GetAdjacentSafeCells(Hero p_hHero, ForestCell p_fcCell)
        {
            List <ForestCell> fcResult         = new List <ForestCell>();
            List <MemoryCell> fcNeighboorsList = Hero.Memory[p_fcCell.LineIndex, p_fcCell.ColumnIndex].getAdjacentMemoryCells();

            foreach (MemoryCell mcItem in fcNeighboorsList)
            {
                if (MainWindow.Forest[mcItem.LineIndex, mcItem.ColumnIndex].Closed)
                {
                    continue;
                }
                if (mcItem.HasNoHole == 1 && mcItem.HasNoAlien == 1)
                {
                    double fTemp = p_fcCell.Distance;

                    ForestCell fcItem = MainWindow.Forest[mcItem.LineIndex, mcItem.ColumnIndex];

                    // If new distance is less than distance found before.
                    if (fTemp > fcItem.Distance)
                    {
                        fcItem.ParentCell = p_fcCell;
                        fcResult.Add(fcItem);
                    }
                }
                else
                {
                    ForestCell fcItem = MainWindow.Forest[mcItem.LineIndex, mcItem.ColumnIndex];
                    fcItem.ParentCell = p_fcCell;
                    fcItem.Closed     = false;
                    fcResult.Add(fcItem);
                }
            }
            return(fcResult.Distinct().ToList());
        }
        /// <summary>
        /// Initializes the text containing the cell's details (monster, smell, etc...).
        /// </summary>
        public void EditTextDetails()
        {
            VerboseCellContent = string.Empty;
            ForestCell currentCell = steveTheHero.CurrentForestCell;

            if (currentCell.HasNothing)
            {
                VerboseCellContent = string.Concat(VerboseCellContent, "- Nothing\n");
            }
            if (currentCell.HasHole)
            {
                VerboseCellContent = string.Concat(VerboseCellContent, "- A hole ! Damned !\n");
            }
            if (currentCell.HasAlien)
            {
                VerboseCellContent = string.Concat(VerboseCellContent, "- An Alien ! Game Over\n");
            }
            if (currentCell.HasWind)
            {
                VerboseCellContent = string.Concat(VerboseCellContent, "- Some wind\n");
            }
            if (currentCell.HasRadiation)
            {
                VerboseCellContent = string.Concat(VerboseCellContent, "- Some smell\n");
            }
            if (currentCell.HasPortal)
            {
                VerboseCellContent = string.Concat(VerboseCellContent, "- Some light\n");
            }
            currentCellText.Text = VerboseCellContent;
        }
 /// <summary>
 /// Init cell distance to destination cell.
 /// </summary>
 /// <param name="p_hHero"> hero. </param>
 /// <param name="p_fcDestinationCell"> Destination cell. </param>
 public static void InitCost(Hero p_hHero, ForestCell p_fcDestinationCell)
 {
     for (int i = 0; i < MainWindow.ForestSize; i++)
     {
         for (int j = 0; j < MainWindow.ForestSize; j++)
         {
             MainWindow.Forest[i, j].Distance = Math.Sqrt(Math.Pow(p_fcDestinationCell.LineIndex - i, 2) + Math.Pow(p_fcDestinationCell.ColumnIndex - j, 2));
         }
     }
 }
        /// <summary>
        /// Randomly puts either a monster, a hole, or nothing on the input cell
        /// Also updates the neighboring cells with either smell or wind accordingly.
        /// </summary>
        /// <param name="pCell"> The input cell to populate </param>
        public void PopulateCellRandomly(ForestCell pCell, Random r)
        {
            // Generates a random number between 0 (included) and 100 (excluded).
            int die = r.Next(0, 100);

            // There is 8 % of chance for the generated number to be in the following range.
            if ((die >= 0) && (die < 8))
            {
                pCell.AddAlienOnCell();
            }
            // There is 8 % of chance for the generated number to be in the following range.
            if ((die >= 92) && (die <= 100))
            {
                pCell.AddHoleOnCell();
            }
        }
        /// <summary>
        /// Run the A* search for the given parameters.
        /// </summary>
        /// <param name="p_hHero"> Hero. </param>
        /// <param name="p_fcDestinationCell"> Destination cell. </param>
        /// <returns> The fastest safest path if found. </returns>
        public static List <ForestCell> FindPath(Hero p_hHero, ForestCell p_fcDestinationCell)
        {
            List <ForestCell> lfcPath = new List <ForestCell>();
            bool bSuccess             = Search(p_hHero, p_hHero.CurrentForestCell, p_fcDestinationCell);

            if (bSuccess)
            {
                ForestCell node = p_fcDestinationCell;
                while (node.ParentCell != null)
                {
                    lfcPath.Add(node);
                    node = node.ParentCell;
                }
                lfcPath.Reverse();
            }
            return(lfcPath);
        }
        /// <summary>
        /// Creates a forest matrix with the size "m_iForestSize" with a ForestCell in each cell.
        /// </summary>
        public void CreateForest()
        {
            // Nullify the current instances of the objects.
            m_afcForest = null;
            m_afcForest = new ForestCell[m_iForestSize, m_iForestSize];

            // For every cell we want, we create a new ForestCell
            // and we address it to the ForestCell matrix.
            for (int i = 0; i < m_iForestSize; i++)
            {
                for (int j = 0; j < m_iForestSize; j++)
                {
                    // Creates a new ForestCell and gives it the correct attributes for row and column.
                    m_afcForest[i, j]             = new ForestCell();
                    m_afcForest[i, j].LineIndex   = i;
                    m_afcForest[i, j].ColumnIndex = j;
                }
            }
        }
        /// <summary>
        /// Recursive search to find the path.
        /// </summary>
        /// <param name="p_hHero"> Hero. </param>
        /// <param name="p_fcStartingCell"> Starting cell. </param>
        /// <param name="p_fcDestinationCell"> Destination cell. </param>
        /// <returns></returns>
        private static bool Search(Hero p_hHero, ForestCell p_fcStartingCell, ForestCell p_fcDestinationCell)
        {
            p_fcStartingCell.Closed = true;
            List <ForestCell> lfcNextCells = GetAdjacentSafeCells(p_hHero, p_fcStartingCell);

            lfcNextCells.Sort((cell1, cell2) => cell1.Distance.CompareTo(cell2.Distance));
            foreach (ForestCell nextCell in lfcNextCells)
            {
                if (nextCell.Equals(p_fcDestinationCell))
                {
                    return(true);
                }
                else
                {
                    if (Search(p_hHero, nextCell, p_fcDestinationCell))
                    {
                        return(true);
                    }
                }
            }
            return(false);
        }
 /// <summary>
 /// Event thrown when the Hero move, update sprite emplacement.
 /// Start the cycle if the Hero dies.
 /// </summary>
 /// <param name="prevForestCell"> Previous cell.  </param>
 /// <param name="NewForestCell"> Cell to move to. </param>
 public void OnMove(ForestCell prevForestCell, ForestCell NewForestCell)
 {
     for (int i = 0; i < m_iForestSize; i++)
     {
         for (int j = 0; j < m_iForestSize; j++)
         {
             if (m_afcForest[i, j] == prevForestCell)
             {
                 m_afcForest[i, j].HasHero = false;
             }
             if (m_afcForest[i, j] == NewForestCell)
             {
                 m_afcForest[i, j].HasHero = true;
             }
         }
     }
     if (steveTheHero.CurrentForestCell.HasAlien || steveTheHero.CurrentForestCell.HasHole)
     {
         UpdateGUI();
         OnDeath();
     }
 }
Esempio n. 9
0
 /// <summary>
 /// Check if cell has radiation.
 /// </summary>
 /// <param name="p_fcCell"> Current cell. </param>
 /// <returns> True if cell has radiation, false otherwise. </returns>
 public static bool HasRadiation(ForestCell p_fcCell)
 {
     return(p_fcCell.HasRadiation);
 }
Esempio n. 10
0
 /// <summary>
 /// Check if cell has wind.
 /// </summary>
 /// <param name="p_fcCell"> Current cell. </param>
 /// <returns> True if cell has wind, false otherwise. </returns>
 public static bool HasWind(ForestCell p_fcCell)
 {
     return(p_fcCell.HasWind);
 }
Esempio n. 11
0
 /// <summary>
 /// Check if cell has light.
 /// </summary>
 /// <param name="p_fcCell"> Current cell. </param>
 /// <returns> True if cell has portal, false otherwise. </returns>
 public static bool HasLight(ForestCell p_fcCell)
 {
     return(p_fcCell.HasPortal);
 }
Esempio n. 12
0
 /// <summary>
 /// Test if cell is empty.
 /// </summary>
 /// <param name="p_fcCell"> Current cell. </param>
 /// <returns> Tru if cell is empty, false otherwise. </returns>
 public static bool HasNothing(ForestCell p_fcCell)
 {
     return(p_fcCell.HasNothing);
 }
Esempio n. 13
0
        /// <summary>
        /// Infere the possible action from the memory and the current cell state.
        /// </summary>
        /// <param name="p_iStateEnv"> Current cell state. </param>
        /// <returns> A list of PossibleAction. </returns>
        private List <PossibleAction> ActionDeclenchable(int p_iStateEnv)
        {
            ThrowRockLeft   paActToThrowRockLeft   = new ThrowRockLeft(this);
            ThrowRockRight  paActToThrowRockRight  = new ThrowRockRight(this);
            ThrowRockTop    paActToThrowRockTop    = new ThrowRockTop(this);
            ThrowRockBottom paActToThrowRockBottom = new ThrowRockBottom(this);
            Exit            paActToExit            = new Exit(this);

            List <PossibleAction> aListPossibleAction = new List <PossibleAction>();

            // if the current cell is empty cell or with wind
            if (p_iStateEnv == 0 || p_iStateEnv == 2)
            {
                bool bFlagOK = false;
                // If there are some remaining safe cells, move there.
                if (m_lfcCellsOK.Any())
                {
                    int        iCost         = int.MaxValue;
                    ForestCell fcDestination = m_lfcCellsOK[new Random().Next(0, m_lfcCellsOK.Count)];
                    foreach (ForestCell fcOK in m_lfcCellsOK)
                    {
                        if (!fcOK.AlreadyVisited)
                        {
                            Pathfinding.InitCost(this, fcOK);
                            // Find the fastest safe path to the destination cell.
                            List <ForestCell> PathFound = Pathfinding.FindPath(this, fcOK);
                            Pathfinding.ResetGridCost();

                            if (PathFound.Count < iCost)
                            {
                                fcDestination = fcOK;
                                iCost         = PathFound.Count;
                                bFlagOK       = true;
                            }
                        }
                    }
                    if (bFlagOK)
                    {
                        Move paActToMove = new Move(this, fcDestination, iCost);
                        aListPossibleAction.Add(paActToMove);
                    }
                }

                bool bFlagSuspicious = false;
                // Else go to a cell with smell to kill monster.
                if (m_lfcCellsWithRadiation.Any() && !bFlagOK)
                {
                    int        iCost = int.MaxValue;
                    ForestCell dest  = null;
                    foreach (ForestCell fcRadiation in m_lfcCellsWithRadiation)
                    {
                        Pathfinding.InitCost(this, fcRadiation);
                        // Find the fastest safe path to the destination cell.
                        List <ForestCell> lfcPathFound = Pathfinding.FindPath(this, fcRadiation);
                        Pathfinding.ResetGridCost();

                        // If the new path is better than the old one.
                        if (lfcPathFound.Count < iCost)
                        {
                            dest            = fcRadiation;
                            iCost           = lfcPathFound.Count;
                            bFlagSuspicious = true;
                        }
                    }
                    if (bFlagSuspicious)
                    {
                        Move paActToMove = new Move(this, dest, iCost);
                        aListPossibleAction.Add(paActToMove);
                    }
                }
                if (!bFlagSuspicious && !bFlagOK)
                {
                    // Else try the closest suspicious cell.
                    if (m_lfcCellsSuspicous.Any())
                    {
                        bool       bPathFound    = false;
                        int        iCost         = int.MaxValue;
                        ForestCell fcDestination = null;
                        foreach (ForestCell fcSuspicious in m_lfcCellsSuspicous)
                        {
                            if (!fcSuspicious.AlreadyVisited)
                            {
                                Pathfinding.InitCost(this, fcSuspicious);
                                // Find the fastest safe path to the destination cell.
                                List <ForestCell> lfcPathFound = Pathfinding.FindPath(this, fcSuspicious);
                                Pathfinding.ResetGridCost();

                                // If the new path is better than the old one.
                                if (lfcPathFound.Count < iCost)
                                {
                                    fcDestination = fcSuspicious;
                                    iCost         = lfcPathFound.Count;
                                    bPathFound    = true;
                                }
                            }
                        }
                        if (bPathFound)
                        {
                            Move paActToMove = new Move(this, fcDestination, iCost);
                            aListPossibleAction.Add(paActToMove);
                        }
                    }
                }
            }

            // If the current cell contains radiation.
            if (p_iStateEnv == 1)
            {
                bool bCellOKFlag = false;
                // If there are some remaining safe cells, move there.
                if (m_lfcCellsOK.Any())
                {
                    int        iCost         = int.MaxValue;
                    ForestCell fcDestination = null;
                    foreach (ForestCell fcOK in m_lfcCellsOK)
                    {
                        if (!fcOK.AlreadyVisited)
                        {
                            Pathfinding.InitCost(this, fcOK);
                            // Find the fastest safe path to the destination cell.
                            List <ForestCell> lfcPathFound = Pathfinding.FindPath(this, fcOK);
                            Pathfinding.ResetGridCost();

                            // If the new path is better than the old one.
                            if (lfcPathFound.Count < iCost)
                            {
                                fcDestination = fcOK;
                                iCost         = lfcPathFound.Count;
                                bCellOKFlag   = true;
                            }
                        }
                    }
                    // If we found a path.
                    if (bCellOKFlag)
                    {
                        Move paActToMove = new Move(this, fcDestination, iCost);
                        aListPossibleAction.Add(paActToMove);
                    }
                }
                // Else try to kill the alien.
                if (!bCellOKFlag)
                {
                    // Try to find a valid target i.e. cell in m_lfcCellsSuspicous and not the cell we come from.
                    List <ForestCell> lfcTargets = CurrentForestCell.getAdjacentCells();
                    // Remove cell visited just before from targets.
                    for (int i = lfcTargets.Count - 1; i >= 0; i--)
                    {
                        if (Memory[lfcTargets[i].LineIndex, lfcTargets[i].ColumnIndex].HasNoAlien == 1 ||
                            Memory[lfcTargets[i].LineIndex, lfcTargets[i].ColumnIndex].IsSafe == 1)
                        {
                            lfcTargets.Remove(lfcTargets[i]);
                        }
                    }

                    // Randomly choose target from remaining cells.
                    Random r            = new Random();
                    int    iTargetIndex = r.Next(0, lfcTargets.Count);

                    if (lfcTargets[iTargetIndex].ColumnIndex < m_fcCurrentForestCell.ColumnIndex)
                    {
                        aListPossibleAction.Add(paActToThrowRockLeft);
                    }
                    else
                    {
                        if (lfcTargets[iTargetIndex].ColumnIndex > m_fcCurrentForestCell.ColumnIndex)
                        {
                            aListPossibleAction.Add(paActToThrowRockRight);
                        }
                        else
                        {
                            if (lfcTargets[iTargetIndex].LineIndex < m_fcCurrentForestCell.LineIndex)
                            {
                                aListPossibleAction.Add(paActToThrowRockTop);
                            }
                            else
                            {
                                if (lfcTargets[iTargetIndex].LineIndex > m_fcCurrentForestCell.LineIndex)
                                {
                                    aListPossibleAction.Add(paActToThrowRockBottom);
                                }
                            }
                        }
                    }
                }
            }

            // Smell + Wind
            if (p_iStateEnv == 3)
            {
                bool bCellOKFlag = false;
                // If there are some remaining safe cells, move there
                if (m_lfcCellsOK.Any())
                {
                    int        iCost         = int.MaxValue;
                    ForestCell fcDestination = null;
                    foreach (ForestCell fcOK in m_lfcCellsOK)
                    {
                        if (!fcOK.AlreadyVisited)
                        {
                            Pathfinding.InitCost(this, fcOK);
                            // Find the fastest safe path to the destination cell.
                            List <ForestCell> lfcPathFound = Pathfinding.FindPath(this, fcOK);
                            Pathfinding.ResetGridCost();

                            // If the new path is better than the old one.
                            if (lfcPathFound.Count < iCost)
                            {
                                fcDestination = fcOK;
                                iCost         = lfcPathFound.Count;
                                bCellOKFlag   = true;
                            }
                        }
                    }
                    if (bCellOKFlag)
                    {
                        Move paActToMove = new Move(this, fcDestination, iCost);
                        aListPossibleAction.Add(paActToMove);
                    }
                }
                // Else try to kill monster and wait for result.
                if (!bCellOKFlag)
                {
                    List <ForestCell> lfcTargets = CurrentForestCell.getAdjacentCells();
                    // Remove cell visited just before from targets.
                    for (int i = lfcTargets.Count - 1; i >= 0; i--)
                    {
                        if (Memory[lfcTargets[i].LineIndex, lfcTargets[i].ColumnIndex].HasNoAlien == 1)
                        {
                            lfcTargets.Remove(lfcTargets[i]);
                        }
                    }
                    // if no more target, try random cell.
                    if (!lfcTargets.Any())
                    {
                        if (m_lfcCellsSuspicous.Any())
                        {
                            bool       bPathFound    = false;
                            int        iCost         = int.MaxValue;
                            ForestCell fcDestination = null;
                            foreach (ForestCell fcSuspicious in m_lfcCellsSuspicous)
                            {
                                if (!fcSuspicious.AlreadyVisited)
                                {
                                    Pathfinding.InitCost(this, fcSuspicious);
                                    List <ForestCell> PathFound = Pathfinding.FindPath(this, fcSuspicious);
                                    Pathfinding.ResetGridCost();

                                    if (PathFound.Count < iCost)
                                    {
                                        fcDestination = fcSuspicious;
                                        iCost         = PathFound.Count;
                                        bPathFound    = true;
                                    }
                                }
                            }
                            if (bPathFound)
                            {
                                Move paActToMove = new Move(this, fcDestination, iCost);
                                aListPossibleAction.Add(paActToMove);
                            }
                        }
                    }
                    else
                    {
                        // Randomly choose target from remaining cells.
                        Random r            = new Random();
                        int    iTargetIndex = r.Next(0, lfcTargets.Count);

                        if (lfcTargets[iTargetIndex].ColumnIndex < m_fcCurrentForestCell.ColumnIndex)
                        {
                            aListPossibleAction.Add(paActToThrowRockLeft);
                        }
                        else
                        {
                            if (lfcTargets[iTargetIndex].ColumnIndex > m_fcCurrentForestCell.ColumnIndex)
                            {
                                aListPossibleAction.Add(paActToThrowRockRight);
                            }
                            else
                            {
                                if (lfcTargets[iTargetIndex].LineIndex < m_fcCurrentForestCell.LineIndex)
                                {
                                    aListPossibleAction.Add(paActToThrowRockTop);
                                }
                                else
                                {
                                    if (lfcTargets[iTargetIndex].LineIndex > m_fcCurrentForestCell.LineIndex)
                                    {
                                        aListPossibleAction.Add(paActToThrowRockBottom);
                                    }
                                }
                            }
                        }
                    }
                }
            }
            // Light
            if (p_iStateEnv == 4)
            {
                // GET OUT !
                aListPossibleAction.Add(paActToExit);
            }

            return(aListPossibleAction);
        }