Esempio n. 1
0
 /// <summary>
 /// Generates a new maze.
 /// </summary>
 /// <param name="goal">The intended goal of the maze.</param>
 /// <returns>The intended start of the maze.</returns>
 public CoordI generate(CoordI goal)
 {
     walls = new bool[size.x * size.y * 2];
     flood = new int[size.x, size.y];
     r_generate(goal);
     return(furthest_from_goal());
 }
Esempio n. 2
0
        /// <summary>
        /// Recursive maze generation based on the "Growing tree" algorithm.
        /// Should be invoked with the goal coordinates of the maze, and no value for f.
        /// </summary>
        /// <param name="c">Coordinates generate from.</param>
        /// <param name="f">Flood fill value for this cell.</param>
        private void r_generate(CoordI c, int f = 1)
        {
            if (flood[c.x, c.y] == 0)
            {
                flood[c.x, c.y] = f;

                walls[get_wall(c, 0)] = true;
                walls[get_wall(c, 1)] = true;
                if (c.x < size.x - 1)
                {
                    walls[get_wall(c, 2)] = true;
                }
                if (c.y < size.y - 1)
                {
                    walls[get_wall(c, 3)] = true;
                }

                Stack <int> items = new Stack <int>(new int[] { 0, 1, 2, 3 }.OrderBy(n => rand.Next()).ToArray());

                while (items.Count > 0)
                {
                    int    active = items.Pop();
                    CoordI new_c  = c + order[active];

                    if (in_bounds(new_c) && flood[new_c.x, new_c.y] == 0)
                    {
                        r_generate(new_c, f + 1);
                        walls[get_wall(c, active)] = false;
                    }
                }
            }
        }
Esempio n. 3
0
 /// <summary>
 /// Obtains the one dimensional index from a CoordI for a cell and direction for a wall.
 /// </summary>
 /// <param name="c">The coordinates of the cell.</param>
 /// <param name="dir">The direction of the wall.</param>
 /// <returns>The corresponding index of the walls array.</returns>
 public int get_wall(CoordI c, int dir)
 {
     if (dir < 3)
     {
         return(2 * (c.x + c.y * size.x) + dir); // west, north, east
     }
     return(2 * (c.x + (c.y + 1) * size.x) + 1); // south
 }
Esempio n. 4
0
        public void move(CoordI pos)
        {
            velocity.O.x = pos.x;
            velocity.O.y = pos.y;
            grid_pos     = new CoordI(velocity.O / m.cell_size);

            for (int i = 0; i < num_eyes; ++i)
            {
                eyes[i].move(velocity.O);
            }
        }
Esempio n. 5
0
        /// <summary>
        /// Initialise in a given position.
        /// </summary>
        /// <param name="pos">The position to move to.</param>
        public void init(CoordD pos)
        {
            max_energy = Program.settings.maze_time;
            num_eyes   = Program.settings.bot_eyes;
            radius     = Program.settings.bot_radius;

            alive    = true;
            goal     = false;
            energy   = max_energy;
            grid_pos = new CoordI(pos / m.cell_size);

            move(pos);
            turn_to(0.0);
        }
Esempio n. 6
0
        /// <summary>
        /// Finds a point in the maze that is as far or further than any other point from the goal.
        /// </summary>
        /// <returns>The furthest point in the maze from the goal.</returns>
        public CoordI furthest_from_goal()
        {
            int    largest = 0;
            CoordI coord   = new CoordI(0, 0);

            for (int x = 0; x < size.x; ++x)
            {
                for (int y = 0; y < size.y; ++y)
                {
                    if (largest < flood[x, y])
                    {
                        largest = flood[x, y];
                        coord.x = x;
                        coord.y = y;
                    }
                }
            }

            return(coord);
        }
Esempio n. 7
0
        /// <summary>
        /// Raycasts a given <c>Ray</c> in this maze.
        /// </summary>
        /// <param name="ray">The <c>Ray</c> to cast.</param>
        /// <param name="radius">The radius of the thing casting the ray.</param>
        public void raycast(ref Ray ray, double radius)
        {
            if (ray.r == 0)
            {
                ray.v = 0;
                return;
            }

            CoordI grid_coords = new CoordI(ray.O / cell_size);
            int    dir         = -1;
            double len         = 0;
            double Ax;
            double Ay;

            bool walled = false;
            bool south  = ray.going_south();
            bool east   = ray.going_east();

            if ((south && !east) || (!south && east))
            {
                Ax = 1.0 / Math.Cos(Consts.η - ray.θ % Consts.η);
                Ay = 1.0 / Math.Cos(ray.θ % Consts.η);
            }
            else
            {
                Ax = 1.0 / Math.Cos(ray.θ % Consts.η);
                Ay = 1.0 / Math.Cos(Consts.η - ray.θ % Consts.η);
            }

            CoordD test_coord = ray.O - grid_coords * cell_size;
            CoordD test_space = cell_size - test_coord;

            if (walls.test_wall(grid_coords, 2) && test_space.x < radius)
            {
                ray.O.x -= radius - test_space.x;
            }
            else if (walls.test_wall(grid_coords, 3) && test_space.y < radius)
            {
                ray.O.y -= radius - test_space.y;
            }
            else if (walls.test_wall(grid_coords, 0) && test_coord.x < radius)
            {
                ray.O.x += radius - test_coord.x;
            }
            else if (walls.test_wall(grid_coords, 1) && test_coord.y < radius)
            {
                ray.O.y += radius - test_coord.y;
            }

            while (len < ray.r && !walled)
            {
                CoordD grid_space = ray.O.by_angle(ray.θ, len) - grid_coords * cell_size;
                CoordD cell_space = cell_size - grid_space;
                grid_space.abs();
                cell_space.abs();

                double hx = (east ? cell_space.x : grid_space.x) * Ax;
                double hy = (south ? cell_space.y : grid_space.y) * Ay;

                if (hx < hy)
                {
                    len += (east ? Math.Max(0, cell_space.x - radius) : Math.Max(0, grid_space.x - radius)) * Ax;
                }
                else
                {
                    len += (south ? Math.Max(0, cell_space.y - radius) : Math.Max(0, grid_space.y - radius)) * Ay;
                }

                dir = hx < hy ? 0 : 1;
                if ((hx < hy && east) || (hx >= hy && south))
                {
                    dir += 2;
                }

                walled = !walls.in_bounds(grid_coords, dir) || walls.test_wall(grid_coords, dir);

                if (!walled)
                {
                    if (dir == 0)
                    {
                        grid_coords.x -= 1;
                    }
                    else if (dir == 1)
                    {
                        grid_coords.y -= 1;
                    }
                    else if (dir == 2)
                    {
                        grid_coords.x += 1;
                    }
                    else if (dir == 3)
                    {
                        grid_coords.y += 1;
                    }
                }
            }

            ray.v = Math.Min(len, ray.r) / ray.r;
        }
Esempio n. 8
0
 public void generate()
 {
     goal  = new CoordI(rand.Next(0, 2) * (walls.size.x - 1), rand.Next(0, 2) * (walls.size.y - 1));
     start = walls.generate(goal);
 }
Esempio n. 9
0
 public void copy(CoordI other)
 {
     this.x = other.x;
     this.y = other.y;
 }
Esempio n. 10
0
 /// <summary>
 /// Tests if a cell and wall are out of bounds, or if it is set.
 /// </summary>
 /// <param name="c">The coordinates of the cell.</param>
 /// <param name="dir">The direction of the wall to test.</param>
 /// <returns>True if the wall is out of bounds, or if the wall is set.</returns>
 public bool test_wall(CoordI c, int dir)
 {
     return(!in_bounds(c, dir) || walls[get_wall(c, dir)]);
 }
Esempio n. 11
0
 public bool in_bounds(CoordI c, int dir)
 {
     return(in_bounds(c) && in_bounds(dir) &&
            !(dir == 2 && c.x == size.x - 1) &&
            !(dir == 3 && c.y == size.y - 1));
 }
Esempio n. 12
0
 public bool in_bounds(CoordI c)
 {
     return(c.x >= 0 && c.x < size.x && c.y >= 0 && c.y < size.y);
 }
Esempio n. 13
0
 public CoordI(CoordI other)
 {
     this.x = other.x;
     this.y = other.y;
 }
Esempio n. 14
0
 public int get_path_value(CoordI c)
 {
     return(flood[c.x, c.y]);
 }
Esempio n. 15
0
 public Wall_grid(int x, int y)
 {
     size  = new CoordI(x, y);
     walls = null;
     flood = null;
 }