예제 #1
0
        public override void GenerateMaze(int size, ref double animationDelay, ref int behaviorValue)
        {
            MazeData.CreateEmpty(size);

            var tree = new KruskalTree(size);
            
            var mazeWidth = size;
            var mazeHeight = size;

            AppData.AppState = AppData.AppStates.LongTask;

            var walls = new LinkedList<MazePoint>();
            for (var i = 1; i < mazeWidth - 1; i++)
            {
                var extra = i % 2 == 0 ? 1 : 0;
                for (var j = 2 - extra; j < mazeHeight - 2 + extra; j += 2)
                    if (MazeData.MazeMatrix[i, j].State == CellState.Wall)
                        walls.AddLast(new MazePoint(i, j));
            }
            walls.Shuffle();


            while (walls.First != null && AppData.AppState == AppData.AppStates.LongTask)
            {
                /*if (AnimateCheckBox.Checked)
                    BeginInvoke(fetchKruskalInfoDelegate);*/

                var wall = walls.First.Value;
                var x = 0;
                var y = 0;
                if (wall.X % 2 == 0 && wall.Y % 2 == 1)
                    x = 1;
                else if (wall.X % 2 == 1 && wall.Y % 2 == 0)
                    y = 1;

                var connected = tree.AreConnected(wall.X - x, wall.Y - y, wall.X + x, wall.Y + y);
                if (!connected)
                {
                    MazeData.MazeMatrix[wall.X - x, wall.Y - y].State = CellState.Walkway;
                    MazeData.MazeMatrix[wall.X, wall.Y].State = CellState.Walkway;
                    MazeData.MazeMatrix[wall.X + x, wall.Y + y].State = CellState.Walkway;
                    tree.Connect(wall.X - x, wall.Y - y, wall.X + x, wall.Y + y);

                    if (animationDelay > 0)
                        Utils.Sleep(animationDelay);
                }

                walls.RemoveFirst();
            }

            MakeEntranceExit();
            AppData.AppState = AppData.AppStates.Idle;

            /*MakeEntranceExit(AnimateCheckBox.Checked);
            if (!AnimateCheckBox.Checked)
                DrawMatrix(true);
            Invoke(() => EnableButtons());
            _debugStopwatch.Toc(true);
            _debugStopwatch.Reset(true);*/
        }
예제 #2
0
        public override void GenerateMaze(int size, ref double animationDelay, ref int behaviorValue)
        {
            MazeData.CreateEmpty(size, true);

            var mazeWidth  = size;
            var mazeHeight = size;

            AppData.AppState = AppData.AppStates.LongTask;

            RecursivelyGenerate(0, 0, mazeWidth, mazeHeight, 1, animationDelay);

            MakeEntranceExit();
            AppData.AppState = AppData.AppStates.Idle;
        }
예제 #3
0
파일: HeatMap.cs 프로젝트: m3Lith/ktu-maze
        public static HeatPoint[,] Generate(int fromX, int fromY, bool draw, int breakOnX, int breakOnY)
        {
            var _mazeWidth  = MazeData.MazeSize;
            var _mazeHeight = MazeData.MazeSize;

            //distMatrix = new int[_mazeWidth, _mazeHeight];
            //precMatrix = new MazePoint[_mazeWidth, _mazeHeight];

            var heatMatrix = new HeatPoint[_mazeWidth, _mazeHeight];

            for (int i = 0; i < _mazeWidth; i++)
            {
                for (int j = 0; j < _mazeHeight; j++)
                {
                    heatMatrix[i, j] = new HeatPoint();
                }
            }

            var point = new MazePoint(fromX, fromY);
            var row   = new LinkedList <MazePoint>();

            row.AddFirst(point);

            var endPointFound = false;
            var count         = 1;
            var newCount      = -1;
            var index         = -1;

            for (var curr = row.First; curr != null; curr = curr.Next)
            {
                index++;
                if (AppData.AppState == AppData.AppStates.Idle)
                {
                    break;
                }

                if (index == count)
                {
                    newCount = row.Count;
                }

                if (index == newCount)
                {
                    for (var i = 0; i < count; i++)
                    {
                        row.RemoveFirst();
                    }
                    index   -= count;
                    count    = newCount - count;
                    newCount = row.Count;
                }

                var adjPoints = MazeData.GetAdjPoints(curr.Value);
                foreach (var adjPoint in adjPoints)
                {
                    MazePoint goToPoint;

                    /*if (MazeData.MazeMatrix[adjPoint.X, adjPoint.Y] == CellState.HorWeave ||
                     *  MazeData.MazeMatrix[adjPoint.X, adjPoint.Y] == CellState.VertWeave)
                     * {
                     *  goToPoint = new MazePoint(adjPoint.X + (adjPoint.X - curr.Value.X),
                     *      adjPoint.Y + (adjPoint.Y - curr.Value.Y));
                     * }
                     * else*/
                    goToPoint = adjPoint;

                    if (row.Contains(goToPoint))
                    {
                        continue;
                    }
                    row.AddLast(goToPoint);
                    heatMatrix[goToPoint.X, goToPoint.Y].Preceding = curr.Value;
                    heatMatrix[goToPoint.X, goToPoint.Y].Distance  = heatMatrix[curr.Value.X, curr.Value.Y].Distance + 1;

                    if (breakOnX > 0 && breakOnY > 0 && goToPoint.X == breakOnX && goToPoint.Y == breakOnY)
                    {
                        endPointFound = true;
                        break;
                    }
                }
                //if (AnimateCheckBox.Checked && Convert.ToInt32(DelayTextBox.Text) > 0)
                //    Thread.Sleep(Convert.ToInt32(DelayTextBox.Text));
                if (endPointFound)
                {
                    break;
                }
            }

            /*for (var i = 0; i < _mazeWidth; i++)
             * {
             *  for (var j = 0; j < _mazeHeight; j++)
             *  {
             *      switch (_mazeMatrix[i, j])
             *      {
             *          case CellState.VertWeave:
             *              distMatrix[i, j] = (distMatrix[i + 1, j] + distMatrix[i - 1, j]) / 2;
             *              break;
             *          case CellState.HorWeave:
             *              distMatrix[i, j] = (distMatrix[i, j + 1] + distMatrix[i, j - 1]) / 2;
             *              break;
             *      }
             *  }
             * }*/

            if (!draw)
            {
                return(heatMatrix);
            }

            var maxDist = 1;

            for (var i = 0; i < _mazeWidth; i++)
            {
                for (var j = 0; j < _mazeHeight; j++)
                {
                    if (heatMatrix[i, j].Distance > maxDist)
                    {
                        maxDist = heatMatrix[i, j].Distance;
                    }
                }
            }

            for (var i = 0; i < _mazeWidth; i++)
            {
                for (var j = 0; j < _mazeHeight; j++)
                {
                    if (MazeData.MazeMatrix[i, j] == null || MazeData.MazeMatrix[i, j].State == CellState.Wall)
                    {
                        continue;
                    }

                    var   red = heatMatrix[i, j].Distance * 255 / maxDist;
                    Color c;
                    if (heatMatrix[i, j].Distance < 1)
                    {
                        c = MazeData.MazeColors[CellState.Entrance];
                    }
                    else if (heatMatrix[i, j].Distance > maxDist - 1)
                    {
                        c = MazeData.MazeColors[CellState.Furthest];
                    }
                    else
                    {
                        c = Color.FromRgba(50 * 256 * 256 + 50 * 256 + red);
                    }
                    MazeData.MazeMatrix[i, j].Display = c;
                }
            }

            return(heatMatrix);
        }
예제 #4
0
        public override void GenerateMaze(int size, ref double animationDelay, ref int behaviorValue)
        {
            MazeData.CreateEmpty(size);

            var mazeWidth  = size;
            var mazeHeight = size;

            AppData.AppState = AppData.AppStates.LongTask;

            var verticalInfluenceValue = 500;
            var binaryTreeValue        = 0;

            const bool startFromBottom = false;

            for (var j = startFromBottom ? 1 : mazeHeight - 2; startFromBottom?j < mazeHeight - 1 : j > 0; j += startFromBottom ? 2 : -2)
            {
                if (AppData.AppState != AppData.AppStates.LongTask)
                {
                    break;
                }
                var setLength = 1;
                for (var i = 1; i < mazeWidth - 1; i += 2)
                {
                    if (AppData.AppState != AppData.AppStates.LongTask)
                    {
                        break;
                    }

                    bool digHorizontal;
                    var  useBinaryTree = _rng.Next(0, 1000) >= binaryTreeValue;

                    //var dirX = binaryTreeValue == 0 && (NWBiasRadioButton.Checked || SWBiasRadioButton.Checked) ? -1 : 1;
                    //var dirY = binaryTreeValue == 0 && (SWBiasRadioButton.Checked || SEBiasRadioButton.Checked) ? 1 : -1;

                    var dirX = 1;
                    var dirY = 1;

                    var canGoHorizontal = dirX > 0 ? i < MazeData.MazeSize - 2 : i > 2;
                    var canGoVertical   = dirY > 0 ? j < MazeData.MazeSize - 2 : j > 2;

                    //var canGoHorizontal = i > 2 && i < MazeData.MazeSize - 2;
                    //var canGoVertical = j > 2 && j < MazeData.MazeSize - 2;

                    //var canGoHorizontal = _mazeRectangle.Contains(i + dirX * 2, j);
                    //var canGoVertical = _mazeRectangle.Contains(i, j + dirY * 2);

                    if (!canGoHorizontal && !canGoVertical)
                    {
                        continue;
                    }
                    if (canGoHorizontal && canGoVertical)
                    {
                        digHorizontal = _rng.Next(0, 1000) >= verticalInfluenceValue;
                    }
                    else if (canGoHorizontal)
                    {
                        digHorizontal = true;
                    }
                    else
                    {
                        digHorizontal = false;
                    }


                    if (digHorizontal)
                    {
                        setLength++;
                        MazeData.MazeMatrix[i + dirX, j].State     = CellState.Walkway;
                        MazeData.MazeMatrix[i + dirX * 2, j].State = CellState.Walkway;
                    }
                    else
                    {
                        //var rand = useBinaryTree ? 0 : _rng.Next(0, setLength) * 2;
                        var rand = _rng.Next(0, setLength) * 2;
                        setLength = 1;
                        MazeData.MazeMatrix[i - rand, j + dirY].State = CellState.Walkway;
                    }
                    MazeData.MazeMatrix[i, j].State = CellState.Walkway;

                    if (animationDelay > 0)
                    {
                        Utils.Sleep(animationDelay);
                    }
                }
            }
            MakeEntranceExit();
            AppData.AppState = AppData.AppStates.Idle;
        }
예제 #5
0
        public override void GenerateMaze(int size, ref double animationDelay, ref int behaviorValue)
        {
            MazeData.CreateEmpty(size);

            //var loopValue = 0;
            //var weaveValue = 0;

            var useInfluences  = false;
            var leftInfluence  = 0;
            var rightInfluence = 0;
            var upInfluence    = 0;
            var downInfluence  = 0;

            var _mazeWidth  = size;
            var _mazeHeight = size;

            var row = _rng.Next(0, _mazeWidth / 2 - 1) * 2 + 1;
            var col = _rng.Next(0, _mazeHeight / 2 - 1) * 2 + 1;

            var path = new List <MazePoint> {
                new MazePoint(row, col)
            };

            MazeData.MazeMatrix[row, col].State = CellState.Walkway;
            AppData.AppState = AppData.AppStates.LongTask;

            //var permitloop = false;
            var success  = true;
            var moveVect = MazeData.Directions[-1];

            while (path.Count > 0 && AppData.AppState == AppData.AppStates.LongTask)
            {
                int currIndex;
                if (_rng.Next(1, 1001) < behaviorValue)
                {
                    currIndex = _rng.Next(0, path.Count);
                }
                else
                {
                    currIndex = path.Count - 1;
                }

                row = path[currIndex].X;
                col = path[currIndex].Y;

                //var origRow = row;
                //var origCol = col;

                //success = TryDig(ref row, ref col, out moveVect, _rng.Next(0, 1001) < weaveValue, false, useInfluences ? new List<int> { leftInfluence, rightInfluence, upInfluence, downInfluence } : null);
                var rand = 0;
                //var val = 0;
                var probabilities = useInfluences
                    ? new List <int> {
                    leftInfluence, rightInfluence, upInfluence, downInfluence
                }
                    : null;
                if (probabilities == null)
                {
                    probabilities = new List <int> {
                        1, 1, 1, 1
                    }
                }
                ;
                var dirCopy = new List <MazePoint>(MazeData.Directions.Values);

                for (var i = 0; i < 4; i++)
                {
                    if (probabilities.All(x => x == 0))
                    {
                        rand = _rng.Next(0, probabilities.Count);
                    }
                    else
                    {
                        for (var j = 0; j < probabilities.Count; j++)
                        {
                            var leftProb = 0;
                            for (var k = j; k < probabilities.Count; k++)
                            {
                                leftProb += probabilities[k];
                            }
                            var currProb = (1000000 * probabilities[j]) / leftProb;
                            if (_rng.Next(1, 1000001) < currProb)
                            {
                                rand = j;
                                break;
                            }
                        }
                    }

                    var direction = dirCopy[rand];

                    if (MazeData.IsPointInMaze(row + direction.X * 2, col + direction.Y * 2))
                    {
                        // Looping
                        //if (allowLoop)
                        //{
                        //    if (MazeData.MazeMatrix[row + direction.X, col + direction.Y] != CellState.Wall) continue;
                        //    MazeData.MazeMatrix[row + direction.X, col + direction.Y] = CellState.Walkway;
                        //    moveVector = new MyPoint(direction.X * 2, direction.Y * 2);
                        //    row += moveVector.X;
                        //    col += moveVector.Y;
                        //    return true;
                        //}

                        // Simple generation
                        if (MazeData.MazeMatrix[row + direction.X * 2, col + direction.Y * 2].State == CellState.Wall)
                        {
                            MazeData.MazeMatrix[row + direction.X, col + direction.Y].State           = CellState.Walkway;
                            MazeData.MazeMatrix[row + direction.X, col + direction.Y].Display         = MazeData.MazeColors[CellState.Generating];
                            MazeData.MazeMatrix[row + direction.X * 2, col + direction.Y * 2].State   = CellState.Walkway;
                            MazeData.MazeMatrix[row + direction.X * 2, col + direction.Y * 2].Display = MazeData.MazeColors[CellState.Generating];

                            moveVect = new MazePoint(direction.X * 2, direction.Y * 2);
                            row     += moveVect.X;
                            col     += moveVect.Y;
                            success  = true;
                            break;
                        }

                        // Weaving
                        //if (allowWeave && _mazeRectangle.Contains(row + direction.X * 4, col + direction.Y * 4)
                        //    && _mazeMatrix[row + direction.X * 2, col + direction.Y * 2] == CellState.Walkway
                        //    && _mazeMatrix[row + direction.X * 4, col + direction.Y * 4] == CellState.Wall
                        //    && _mazeMatrix[row + direction.X, col + direction.Y] == CellState.Wall)
                        //{
                        //    _mazeMatrix[row + direction.X * 2, col + direction.Y * 2] =
                        //        direction.Y == 0 ? CellState.HorWeave : CellState.VertWeave;
                        //    _mazeMatrix[row + direction.X, col + direction.Y] = CellState.Walkway;
                        //    _mazeMatrix[row + direction.X * 3, col + direction.Y * 3] = CellState.Walkway;
                        //    _mazeMatrix[row + direction.X * 4, col + direction.Y * 4] = CellState.Walkway;
                        //    moveVector = new MyPoint(direction.X * 4, direction.Y * 4);
                        //    row += moveVector.X;
                        //    col += moveVector.Y;
                        //    return true;
                        //}
                    }
                    dirCopy.RemoveAt(rand);
                    try
                    {
                        probabilities.RemoveAt(rand);
                    }
                    catch
                    {
                    }
                    if (i == 3)
                    {
                        //moveVect = MazeData.Directions[-1];
                        success = false;
                    }
                }
                // Failed to generate
                if (success)
                {
                    //permitloop = true;
                    path.Add(new MazePoint(row, col));
                }
                else
                {
                    //if (permitloop && _rng.Next(0, 101) < loopValue)
                    //{
                    //    TryDig(ref row, ref col, out moveVect, false, true, null);
                    //    if (AnimateCheckBox.Checked)
                    //    {
                    //        var rowDiff = row - origRow;
                    //        var colDiff = col - origCol;

                    //        if (rowDiff != 0)
                    //            DrawCell(origRow + (rowDiff > 0 ? 1 : -1), origCol, MazeColors.Walkway.Brush);
                    //        else if (colDiff != 0)
                    //            DrawCell(origRow, origCol + (colDiff > 0 ? 1 : -1), MazeColors.Walkway.Brush);

                    //        RefreshPictureBox(row, col, 1);
                    //    }
                    //}

                    //permitloop = false;
                    for (var i = -1; i < 4; i++)
                    {
                        for (var j = 1; j < 2; j++)
                        {
                            var x = row + MazeData.Directions[i].X * j;
                            var y = col + MazeData.Directions[i].Y * j;
                            if (MazeData.MazeMatrix[x, y] != null && MazeData.MazeMatrix[x, y].State != CellState.Wall)
                            {
                                MazeData.MazeMatrix[x, y].Display = MazeData.MazeColors[CellState.Walkway];
                            }
                        }
                    }
                    path.RemoveAt(currIndex);
                }

                if (animationDelay > 0)
                {
                    Utils.Sleep(animationDelay);
                }
            }


            //GC.Collect();

            MakeEntranceExit();
            AppData.AppState = AppData.AppStates.Idle;
        }

        /*private bool TryDig(ref int row, ref int col, out MazePoint moveVector, bool allowWeave, bool allowLoop, List<int> probabilities)
         * {
         *  var rand = 0;
         *  //var val = 0;
         *  if (probabilities == null)
         *      probabilities = new List<int> { 1, 1, 1, 1 };
         *  var dirCopy = new List<MazePoint>(MazeData.Directions.Values);
         *
         *  for (var i = 0; i < 4; i++)
         *  {
         *      if (probabilities.All(x => x == 0))
         *          rand = _rng.Next(0, probabilities.Count);
         *      else
         *          for (var j = 0; j < probabilities.Count; j++)
         *          {
         *              var leftProb = 0;
         *              for (var k = j; k < probabilities.Count; k++)
         *                  leftProb += probabilities[k];
         *              var currProb = (1000000 * probabilities[j]) / leftProb;
         *              if (_rng.Next(1, 1000001) < currProb)
         *              {
         *                  rand = j;
         *                  break;
         *              }
         *          }
         *
         *      var direction = dirCopy[rand];
         *
         *      if (MazeData.IsPointInMaze(row + direction.X*2, col + direction.Y*2))
         *      {
         *          // Looping
         *          //if (allowLoop)
         *          //{
         *          //    if (MazeData.MazeMatrix[row + direction.X, col + direction.Y] != CellState.Wall) continue;
         *          //    MazeData.MazeMatrix[row + direction.X, col + direction.Y] = CellState.Walkway;
         *          //    moveVector = new MyPoint(direction.X * 2, direction.Y * 2);
         *          //    row += moveVector.X;
         *          //    col += moveVector.Y;
         *          //    return true;
         *          //}
         *
         *          // Simple generation
         *          if (MazeData.MazeMatrix[row + direction.X * 2, col + direction.Y * 2].State == CellState.Wall)
         *          {
         *              MazeData.MazeMatrix[row + direction.X, col + direction.Y].State = CellState.Walkway;
         *              MazeData.MazeMatrix[row + direction.X * 2, col + direction.Y * 2].State = CellState.Walkway;
         *              moveVector = new MazePoint(direction.X * 2, direction.Y * 2);
         *              row += moveVector.X;
         *              col += moveVector.Y;
         *              return true;
         *          }
         *
         *          // Weaving
         *          //if (allowWeave && _mazeRectangle.Contains(row + direction.X * 4, col + direction.Y * 4)
         *          //    && _mazeMatrix[row + direction.X * 2, col + direction.Y * 2] == CellState.Walkway
         *          //    && _mazeMatrix[row + direction.X * 4, col + direction.Y * 4] == CellState.Wall
         *          //    && _mazeMatrix[row + direction.X, col + direction.Y] == CellState.Wall)
         *          //{
         *          //    _mazeMatrix[row + direction.X * 2, col + direction.Y * 2] =
         *          //        direction.Y == 0 ? CellState.HorWeave : CellState.VertWeave;
         *          //    _mazeMatrix[row + direction.X, col + direction.Y] = CellState.Walkway;
         *          //    _mazeMatrix[row + direction.X * 3, col + direction.Y * 3] = CellState.Walkway;
         *          //    _mazeMatrix[row + direction.X * 4, col + direction.Y * 4] = CellState.Walkway;
         *          //    moveVector = new MyPoint(direction.X * 4, direction.Y * 4);
         *          //    row += moveVector.X;
         *          //    col += moveVector.Y;
         *          //    return true;
         *          //}
         *      }
         *      dirCopy.RemoveAt(rand);
         *      try { probabilities.RemoveAt(rand); }
         *      catch { }
         *      // TODO: fix random error
         *  }
         *  // Failed to generate
         *  moveVector = MazeData.Directions[-1];
         *  return false;
         * }*/
    }