public void Draw(PaintEventArgs e) { var cellScaling = new CoordD(_settings.WinWidth / (double)_engineSettings.MazeWidth, _settings.WinHeight / (double)_engineSettings.MazeHeight); for (var x = 0; x < _walls.Size.X; ++x) { for (var y = 0; y < _walls.Size.Y; ++y) { for (var d = 0; d < 2; ++d) { if (!_walls.test_wall(x, y, d)) continue; var x1 = x * (float) cellScaling.X; var y1 = y * (float) cellScaling.Y; e.Graphics.DrawLine(Pens.White, x1, y1, x1 + (d == 0 ? 0 : (float) cellScaling.X), y1 + (d == 1 ? 0 : (float) cellScaling.Y) ); } } } e.Graphics.DrawLine(Pens.White, (float) cellScaling.X *_walls.Size.X, 0, (float) cellScaling.X *_walls.Size.X, (float) cellScaling.Y *_walls.Size.Y); e.Graphics.DrawLine(Pens.White, 0, (float) cellScaling.Y *_walls.Size.Y, (float) cellScaling.X *_walls.Size.X, (float) cellScaling.Y *_walls.Size.Y); var r1 = new Rectangle((int)(_maze.Start.X *cellScaling.X), (int)(_maze.Start.Y *cellScaling.Y), (int) cellScaling.X, (int) cellScaling.Y); e.Graphics.DrawString("S", Font, Brushes.Red, r1, _fontFormat); var r2 = new Rectangle((int)(_maze.Goal.X *cellScaling.X), (int)(_maze.Goal.Y *cellScaling.Y), (int) cellScaling.X, (int) cellScaling.Y); e.Graphics.DrawString("G", Font, Brushes.Green, r2, _fontFormat); }
public void Move(int x, int y) { var cellScaling = new CoordD(_settings.WinWidth / (double)_engineSettings.MazeWidth, _settings.WinHeight / (double)_engineSettings.MazeHeight); Position.X = x / cellScaling.X; Position.Y = y / cellScaling.Y; foreach (var eye in Eyes) eye.Ray.Origin.Copy(Position); }
/// <summary> /// Draws with a given pen and differed length. /// </summary> /// <param name="e">Event data.</param> /// <param name="ray"></param> /// <param name="p">The <c>Pen</c> to use.</param> /// <param name="val">Length.</param> public void Draw(PaintEventArgs e, Ray ray, Pen p, double val) { var cellScaling = new CoordD(_settings.WinWidth / (double)_engineSettings.MazeWidth, _settings.WinHeight / (double)_engineSettings.MazeHeight); var end = ray.Origin.ByAngle(ray.Angle, val); if (ray.Origin.X * cellScaling.X >= e.ClipRectangle.X && ray.Origin.X * cellScaling.X < e.ClipRectangle.Width && ray.Origin.Y * cellScaling.Y >= e.ClipRectangle.Y && ray.Origin.Y * cellScaling.Y < e.ClipRectangle.Height) e.Graphics.DrawLine(p, new PointF((float)ray.Origin.X * (float)cellScaling.X, (float)ray.Origin.Y * (float)cellScaling.Y), new PointF((float)end.X * (float)cellScaling.X, (float)end.Y * (float)cellScaling.Y)); }
/// <summary> /// Draws with the alpha channel of a given pen modified by <c>v</c>. /// </summary> /// <param name="e">Event data.</param> /// <param name="ray"></param> /// <param name="p">The <c>Pen</c> to use.</param> public void Draw(PaintEventArgs e, Ray ray, Pen p) { var cellScaling = new CoordD(_settings.WinWidth / (double)_engineSettings.MazeWidth, _settings.WinHeight / (double)_engineSettings.MazeHeight); var p1 = new Pen(Color.FromArgb((int)((1.0 - Math.Max(0.0, ray.Velocity)) * 240) + 15, p.Color.R, p.Color.G, p.Color.B)); var end = ray.CastPoint(); if (ray.Origin.X * cellScaling.X >= e.ClipRectangle.X && ray.Origin.X * cellScaling.X < e.ClipRectangle.Width && ray.Origin.Y * cellScaling.Y >= e.ClipRectangle.Y && ray.Origin.Y * cellScaling.Y < e.ClipRectangle.Height) e.Graphics.DrawLine(p1, new PointF((float)ray.Origin.X * (float)cellScaling.X, (float)ray.Origin.Y * (float)cellScaling.Y), new PointF((float)end.X * (float)cellScaling.X, (float)end.Y * (float)cellScaling.Y)); }
public void Draw(PaintEventArgs e, Bot bot) { var cellScaling = new CoordD(_settings.WinWidth / (double)_engineSettings.MazeWidth, _settings.WinHeight / (double)_engineSettings.MazeHeight); if (bot.Goal) foreach (var eye in bot._eyes) _eyeDrawer.Draw(e, eye, Pens.PowderBlue); else if (bot.Alive) foreach (var eye in bot._eyes) _eyeDrawer.Draw(e, eye, Pens.GreenYellow); else foreach (var eye in bot._eyes) _eyeDrawer.Draw(e, eye, Pens.Red); _rayDrawer.Draw(e, bot.Velocity, Pens.Purple, 10*bot._speed); e.Graphics.DrawEllipse(Pens.CornflowerBlue, (float) ((bot.Velocity.Origin.X - _engineSettings.BotRadius)*cellScaling.X), (float) ((bot.Velocity.Origin.Y - _engineSettings.BotRadius)*cellScaling.Y), (float) (2*_engineSettings.BotRadius*cellScaling.X), (float) (2*_engineSettings.BotRadius*cellScaling.Y)); }
/// <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 (Math.Abs(ray.Magnitude) < Double.Epsilon) { ray.Velocity = 0; return; } var gridCoords = new CoordI(ray.Origin); double len = 0; double ax; double ay; var walled = false; var south = ray.GoingSouth(); var east = ray.GoingEast(); if ((south && !east) || (!south && east)) { ax = 1.0 / Math.Cos(Consts.QuarterTurn - ray.Angle % Consts.QuarterTurn); ay = 1.0 / Math.Cos(ray.Angle % Consts.QuarterTurn); } else { ax = 1.0 / Math.Cos(ray.Angle % Consts.QuarterTurn); ay = 1.0 / Math.Cos(Consts.QuarterTurn - ray.Angle % Consts.QuarterTurn); } var testCoord = ray.Origin - gridCoords; var testSpace = new CoordD(1,1) - testCoord; if (_walls.test_wall(gridCoords, 2) && testSpace.X < radius) ray.Origin.X -= radius - testSpace.X; else if (_walls.test_wall(gridCoords, 3) && testSpace.Y < radius) ray.Origin.Y -= radius - testSpace.Y; else if (_walls.test_wall(gridCoords, 0) && testCoord.X < radius) ray.Origin.X += radius - testCoord.X; else if (_walls.test_wall(gridCoords, 1) && testCoord.Y < radius) ray.Origin.Y += radius - testCoord.Y; while (len < ray.Magnitude && !walled) { var gridSpace = ray.Origin.ByAngle(ray.Angle, len) - gridCoords; var cellSpace = new CoordD(1,1) - gridSpace; gridSpace.Abs(); cellSpace.Abs(); var hx = (east ? cellSpace.X : gridSpace.X) * ax; var hy = (south ? cellSpace.Y : gridSpace.Y) * ay; if (hx < hy) len += (east ? Math.Max(0, cellSpace.X - radius) : Math.Max(0, gridSpace.X - radius)) * ax; else len += (south ? Math.Max(0, cellSpace.Y - radius) : Math.Max(0, gridSpace.Y - radius)) * ay; var dir = hx < hy ? 0 : 1; if ((hx < hy && east) || (hx >= hy && south)) dir += 2; walled = !_walls.InBounds(gridCoords, dir) || _walls.test_wall(gridCoords, dir); if (walled) continue; switch (dir) { case 0: gridCoords.X -= 1; break; case 1: gridCoords.Y -= 1; break; case 2: gridCoords.X += 1; break; case 3: gridCoords.Y += 1; break; } } ray.Velocity = Math.Min(len, ray.Magnitude) / ray.Magnitude; }
public CoordD(CoordD other) { X = other.X; Y = other.Y; }
public bool Equals(CoordD other) { return X.Equals(other.X) && Y.Equals(other.Y); }
public void Copy(CoordD other) { X = other.X; Y = other.Y; }
/// <summary> /// Use the <c>Brain</c> with variable inputs based on <c>_engineSettings</c>. /// </summary> public void Think() { if (!Alive) return; for (int i = 0; i < _numEyes; ++i) Brain.SetInput(i, (float)_eyes[i].Ray.Velocity); var extra = 0; if (_engineSettings.ThinkDistance) { Brain.SetInput(_numEyes + extra++, (float)(((_maze.Goal - Velocity.Origin) / (_walls.Size + 1)).Length())); } if (_engineSettings.ThinkPath) { var thisPos = _walls.GetPathValue(_maze.Start) + 1; if (_walls.InBounds(GridPos)) thisPos = _walls.GetPathValue(GridPos); Brain.SetInput(_numEyes + extra++, thisPos / (float)_walls.GetPathValue(_maze.Start)); var dir = 0; if (Velocity.NorthQuad()) dir = 1; else if (Velocity.EastQuad()) dir = 2; else if (Velocity.SouthQuad()) dir = 3; for (var i = 0; i < 4; ++i) { var index = (i + dir) % 4; if (_walls.test_wall(GridPos, index) || thisPos < _walls.GetPathValue(GridPos + WallGrid.Order[index])) Brain.SetInput(_numEyes + extra++, 0); else Brain.SetInput(_numEyes + extra++, 1); } } if (_engineSettings.ThinkVelocity) { var magnitude = new CoordD(0, 0).ByAngle(Velocity.Angle, 1.0); Brain.SetInput(_numEyes + extra++, (float)magnitude.X); Brain.SetInput(_numEyes + extra++, (float)magnitude.Y); Brain.SetInput(_numEyes + extra, (float)_speed); } Brain.Think(); Act(Brain.GetOutput(0), Brain.GetOutput(1)); }
public void Move(CoordD pos) { Velocity.Origin.X = pos.X; Velocity.Origin.Y = pos.Y; GridPos = new CoordI(Velocity.Origin); for (int i = 0; i < _numEyes; ++i) _eyes[i].Move(Velocity.Origin); }
/// <summary> /// Initialise in a given position. /// </summary> /// <param name="pos">The position to Move to.</param> public void Init(CoordD pos) { _maxEnergy = _engineSettings.MazeTime; _numEyes = _engineSettings.BotEyes; _radius = _engineSettings.BotRadius; Alive = true; Goal = false; Energy = _maxEnergy; GridPos = new CoordI(pos); Move(pos); turn_to(0.0); }