Try to imlement [ and ], but it's not quite right yet?
This commit is contained in:
parent
f7393f3949
commit
8fcadb007f
4 changed files with 90 additions and 53 deletions
19
SimpleTurtle/Area.cs
Normal file
19
SimpleTurtle/Area.cs
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
using System;
|
||||||
|
namespace SBRL.SimpleTurtle
|
||||||
|
{
|
||||||
|
public class Area
|
||||||
|
{
|
||||||
|
public double X;
|
||||||
|
public double Y;
|
||||||
|
public double Width;
|
||||||
|
public double Height;
|
||||||
|
|
||||||
|
public Area(double inX, double inY, double inWidth, double inHeight)
|
||||||
|
{
|
||||||
|
X = inX;
|
||||||
|
Y = inY;
|
||||||
|
Width = inWidth;
|
||||||
|
Height = inHeight;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -23,6 +23,8 @@ Input File Format:
|
||||||
h Also move forwards
|
h Also move forwards
|
||||||
+ Turn clockwise
|
+ Turn clockwise
|
||||||
- Turn anti-clockwise
|
- Turn anti-clockwise
|
||||||
|
[ Save position & heading to stack
|
||||||
|
] Restore position & heading from stack
|
||||||
|
|
||||||
Turtle Directives:
|
Turtle Directives:
|
||||||
angle Sets the angle by which the turtle should turn. Note that this is specified in radians.
|
angle Sets the angle by which the turtle should turn. Note that this is specified in radians.
|
||||||
|
|
|
@ -42,6 +42,7 @@
|
||||||
<Compile Include="LSystemEngine.cs" />
|
<Compile Include="LSystemEngine.cs" />
|
||||||
<Compile Include="Utilities\EmbeddedFiles.cs" />
|
<Compile Include="Utilities\EmbeddedFiles.cs" />
|
||||||
<Compile Include="Utilities\Timer.cs" />
|
<Compile Include="Utilities\Timer.cs" />
|
||||||
|
<Compile Include="Area.cs" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<EmbeddedResource Include="Help.txt">
|
<EmbeddedResource Include="Help.txt">
|
||||||
|
|
|
@ -6,44 +6,40 @@ using System.Collections.Generic;
|
||||||
|
|
||||||
namespace SBRL.SimpleTurtle
|
namespace SBRL.SimpleTurtle
|
||||||
{
|
{
|
||||||
public class Area
|
public class TurtleState : ICloneable {
|
||||||
{
|
public PointD Position;
|
||||||
public double X;
|
public double Heading;
|
||||||
public double Y;
|
|
||||||
public double Width;
|
|
||||||
public double Height;
|
|
||||||
|
|
||||||
public Area(double inX, double inY, double inWidth, double inHeight)
|
public TurtleState(PointD inPosition, double inHeading) {
|
||||||
{
|
Position = inPosition;
|
||||||
X = inX;
|
Heading = inHeading;
|
||||||
Y = inY;
|
}
|
||||||
Width = inWidth;
|
|
||||||
Height = inHeight;
|
public object Clone() {
|
||||||
|
return new TurtleState(Position, Heading);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class Turtle
|
public class Turtle
|
||||||
{
|
{
|
||||||
private bool strictMode = false;
|
public bool StrictMode = false;
|
||||||
private string commandQueue;
|
private string commandQueue;
|
||||||
|
|
||||||
private PointD position;
|
private readonly Stack<TurtleState> states = new Stack<TurtleState>();
|
||||||
|
public PointD Position {
|
||||||
|
get => states.Peek().Position;
|
||||||
|
protected set => states.Peek().Position = value;
|
||||||
|
}
|
||||||
|
public double Heading {
|
||||||
|
get => states.Peek().Heading;
|
||||||
|
protected set => states.Peek().Heading = value;
|
||||||
|
}
|
||||||
private Area bounds;
|
private Area bounds;
|
||||||
private double heading;
|
|
||||||
private double headingStep;
|
|
||||||
public double HeadingStep
|
|
||||||
{
|
|
||||||
get { return headingStep; }
|
|
||||||
set { headingStep = value; }
|
|
||||||
}
|
|
||||||
private double movementStep ;
|
|
||||||
public double MovementStep
|
|
||||||
{
|
|
||||||
get { return movementStep; }
|
|
||||||
set { movementStep = value; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public Turtle ()
|
public double HeadingStep { get; set; }
|
||||||
{
|
public double MovementStep { get; set; }
|
||||||
|
|
||||||
|
public Turtle () {
|
||||||
Reset();
|
Reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -83,15 +79,21 @@ namespace SBRL.SimpleTurtle
|
||||||
case '-':
|
case '-':
|
||||||
Turn(true);
|
Turn(true);
|
||||||
break;
|
break;
|
||||||
|
case '[':
|
||||||
|
Save();
|
||||||
|
break;
|
||||||
|
case ']':
|
||||||
|
Restore();
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
if (strictMode) {
|
if (StrictMode) {
|
||||||
Console.WriteLine("The unexpected character '{0}' slipped through the net!", ch);
|
Console.WriteLine("The unexpected character '{0}' slipped through the net!", ch);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if(strictMode)
|
else if(StrictMode)
|
||||||
{
|
{
|
||||||
Console.Error.WriteLine("Error: unexpected character '{0}'", ch);
|
Console.Error.WriteLine("Error: unexpected character '{0}'", ch);
|
||||||
return false;
|
return false;
|
||||||
|
@ -105,28 +107,28 @@ namespace SBRL.SimpleTurtle
|
||||||
{
|
{
|
||||||
ImageSurface canvas = new ImageSurface(Format.ARGB32, (int)Math.Ceiling(bounds.Width + 10), (int)Math.Ceiling(bounds.Height + 10));
|
ImageSurface canvas = new ImageSurface(Format.ARGB32, (int)Math.Ceiling(bounds.Width + 10), (int)Math.Ceiling(bounds.Height + 10));
|
||||||
Context context = new Context(canvas);
|
Context context = new Context(canvas);
|
||||||
position = new PointD(-bounds.X + 5, -bounds.Y + 5);
|
Position = new PointD(-bounds.X + 5, -bounds.Y + 5);
|
||||||
heading = 0;
|
Heading = 0;
|
||||||
|
|
||||||
context.LineWidth = 3;
|
context.LineWidth = 3;
|
||||||
context.MoveTo(position);
|
context.MoveTo(Position);
|
||||||
foreach(char ch in commandQueue)
|
foreach(char ch in commandQueue)
|
||||||
{
|
{
|
||||||
switch(ch)
|
switch(ch)
|
||||||
{
|
{
|
||||||
case 'f':
|
case 'f':
|
||||||
PointD newPosition = new PointD(
|
PointD newPosition = new PointD(
|
||||||
position.X + movementStep * Math.Sin(heading),
|
Position.X + MovementStep * Math.Sin(Heading),
|
||||||
position.Y + movementStep * Math.Cos(heading)
|
Position.Y + MovementStep * Math.Cos(Heading)
|
||||||
);
|
);
|
||||||
context.LineTo(newPosition);
|
context.LineTo(newPosition);
|
||||||
position = newPosition;
|
Position = newPosition;
|
||||||
break;
|
break;
|
||||||
case '+':
|
case '+':
|
||||||
heading += headingStep;
|
Heading += HeadingStep;
|
||||||
break;
|
break;
|
||||||
case '-':
|
case '-':
|
||||||
heading -= headingStep;
|
Heading -= HeadingStep;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -142,44 +144,57 @@ namespace SBRL.SimpleTurtle
|
||||||
public void Forwards()
|
public void Forwards()
|
||||||
{
|
{
|
||||||
PointD newPosition = new PointD(
|
PointD newPosition = new PointD(
|
||||||
position.X + MovementStep * Math.Sin(heading),
|
Position.X + MovementStep * Math.Sin(Heading),
|
||||||
position.Y + MovementStep * Math.Cos(heading)
|
Position.Y + MovementStep * Math.Cos(Heading)
|
||||||
);
|
);
|
||||||
|
|
||||||
if (newPosition.X > bounds.X + bounds.Width)
|
if (newPosition.X > bounds.X + bounds.Width)
|
||||||
bounds.Width += newPosition.X - position.X;
|
bounds.Width += newPosition.X - Position.X;
|
||||||
if (newPosition.Y > bounds.Y + bounds.Height)
|
if (newPosition.Y > bounds.Y + bounds.Height)
|
||||||
bounds.Height += newPosition.Y - position.Y;
|
bounds.Height += newPosition.Y - Position.Y;
|
||||||
if (newPosition.X < bounds.X)
|
if (newPosition.X < bounds.X)
|
||||||
{
|
{
|
||||||
bounds.X = newPosition.X;
|
bounds.X = newPosition.X;
|
||||||
bounds.Width += position.X - newPosition.X;
|
bounds.Width += Position.X - newPosition.X;
|
||||||
}
|
}
|
||||||
if (newPosition.Y < bounds.Y)
|
if (newPosition.Y < bounds.Y)
|
||||||
{
|
{
|
||||||
bounds.Y = newPosition.Y;
|
bounds.Y = newPosition.Y;
|
||||||
bounds.Height += position.Y - newPosition.Y;
|
bounds.Height += Position.Y - newPosition.Y;
|
||||||
}
|
}
|
||||||
|
|
||||||
position = newPosition;
|
Position = newPosition;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Turn(bool anticlockwise = false)
|
public void Turn(bool anticlockwise = false)
|
||||||
{
|
{
|
||||||
if (!anticlockwise)
|
if (!anticlockwise)
|
||||||
heading += HeadingStep;
|
Heading += HeadingStep;
|
||||||
else
|
else
|
||||||
heading -= HeadingStep;
|
Heading -= HeadingStep;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Save()
|
||||||
|
{
|
||||||
|
states.Push(states.Peek().Clone() as TurtleState);
|
||||||
|
}
|
||||||
|
public bool Restore() {
|
||||||
|
if (states.Count <= 1)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
states.Pop();
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Reset()
|
public void Reset()
|
||||||
{
|
{
|
||||||
|
states.Clear();
|
||||||
|
states.Push(new TurtleState(new PointD(0, 0), 0));
|
||||||
|
|
||||||
commandQueue = string.Empty;
|
commandQueue = string.Empty;
|
||||||
position = new PointD(0, 0);
|
bounds = new Area(Position.X, Position.Y, 1, 1);
|
||||||
bounds = new Area(position.X, position.Y, 1, 1);
|
HeadingStep = Math.PI / 2;
|
||||||
heading = 0;
|
MovementStep = 25;
|
||||||
headingStep = Math.PI / 2;
|
|
||||||
movementStep = 25;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue