Skip to content

Commit 57d5d0d

Browse files
Working Fibonacci!
Changed instructions to more formally follow Brainf**k Extended Type 1, including: @ exits the program or when in a function, ends the function and returns to main program. This replaces !. $ stores the value of memory into a storage byte. ! retrieves the value from storage and copies to current memory. Removed & (which used to define the start of a function, now obsolete due to @ effectively marking a function start and end). Removed % (which used to define the end of a function, now obsolete due to @ marking a function start and end). Optimizations. Added optional logging with Loggly.
1 parent c1e0e0c commit 57d5d0d

15 files changed

Lines changed: 155 additions & 71 deletions

File tree

AIProgrammer.Fitness/Base/FitnessBase.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ public double GetFitness(double[] weights)
7171
// Append any functions to the program.
7272
if (_appendFunctions != null)
7373
{
74-
Program += "!" + _appendFunctions;
74+
Program += "@" + _appendFunctions;
7575
}
7676

7777
// Get the fitness.

AIProgrammer.Fitness/Concrete/BottlesOfBeerFitness.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ public class BottlesOfBeerFitness : FitnessBase
2727
/// Previously generated BrainPlus functions for outputting the terms: bottles,of,beer,on,the,wall,bottles of beer,on the wall. The last two functions call sub-functions themselves. Generated using StrictStringFitness with StringFunction.
2828
/// To use, set _appendCode = BottlesOfBeerFitness.BottlesOfBeerFunctions in main program.
2929
/// </summary>
30-
public static string BottlesOfBeerFunctions = "&6++.+++++++++++++[.+++[++..--------.-------.++++++++++++++.-%&[]7[[-.---------.%&6++.+++..7++.%&+8[+7-.-.%&6+t+++i++[++-+[+++++[+++++++.-----[-[--[--[--.[-+----+.%&7++++++[+.------[--------[--------.+++++++-+++++..%&1+++++++++++++>a---<+++.>.---------.<.c%&d2.e2.f%";
30+
public static string BottlesOfBeerFunctions = "6++.+++++++++++++[.+++[++..--------.-------.++++++++++++++.-@[]7[[-.---------.@6++.+++..7++.@+8[+7-.-.@6+t+++i++[++-+[+++++[+++++++.-----[-[--[--[--.[-+----+.@7++++++[+.------[--------[--------.+++++++-+++++..@1+++++++++++++>a---<+++.>.---------.<.c@d2.e2.f@";
3131

3232
public BottlesOfBeerFitness(GA ga, int maxIterationCount, string appendFunctions = null)
3333
: base(ga, maxIterationCount, appendFunctions)

AIProgrammer.Fitness/Concrete/FibonacciFitness.cs

Lines changed: 27 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,15 @@ public class FibonacciFitness : FitnessBase
1616
{
1717
private int _trainingCount;
1818
private int _maxDigits; // number of fibonacci numbers to calculate.
19+
private static int _functionCount; // number of functions in the appeneded code.
1920

2021
/// <summary>
2122
/// Previously generated BrainPlus function for addition. Generated using AddFitness.
2223
/// To use, set _appendCode = FibonacciFitness.FibonacciFunctions in main program.
2324
/// </summary>
24-
public static string FibonacciFunctions = "&,>,-[-<+>]<+.%";
25+
public static string FibonacciFunctions = ",>,-[-<+>]<+.$@";
2526

26-
public FibonacciFitness(GA ga, int maxIterationCount, int maxDigits = 3, int maxTrainingCount = 2, string appendFunctions = null)
27+
public FibonacciFitness(GA ga, int maxIterationCount, int maxDigits = 3, int maxTrainingCount = 3, string appendFunctions = null)
2728
: base(ga, maxIterationCount, appendFunctions)
2829
{
2930
_maxDigits = maxDigits;
@@ -32,6 +33,7 @@ public FibonacciFitness(GA ga, int maxIterationCount, int maxDigits = 3, int max
3233
if (_targetFitness == 0)
3334
{
3435
_targetFitness = _trainingCount * 256 * _maxDigits;
36+
_functionCount = CommonManager.GetFunctionCount(appendFunctions);
3537
}
3638
}
3739

@@ -49,11 +51,9 @@ protected override double GetFitnessMethod(string program)
4951
{
5052
switch (i)
5153
{
52-
case 0: input1 = 1; input2 = 1; break;
53-
case 1: input1 = 1; input2 = 2; break;
54-
case 2: input1 = 2; input2 = 3; break;
55-
case 3: input1 = 3; input2 = 5; break;
56-
case 4: input1 = 5; input2 = 8; break;
54+
case 0: input1 = 1; input2 = 2; break;
55+
case 1: input1 = 3; input2 = 5; break;
56+
case 2: input1 = 8; input2 = 13; break;
5757
};
5858

5959
try
@@ -78,9 +78,9 @@ protected override double GetFitnessMethod(string program)
7878
else
7979
{
8080
// Not ready for input.
81-
//penalty++;
81+
penalty++;
8282

83-
return 255;
83+
return 0;
8484
}
8585
},
8686
(b) =>
@@ -90,11 +90,13 @@ protected override double GetFitnessMethod(string program)
9090
// Not ready for output.
9191
penalty++;
9292
}
93+
else
94+
{
95+
_console.Append(b);
96+
_console.Append(",");
9397

94-
_console.Append(b);
95-
_console.Append(",");
96-
97-
digits.Add(b);
98+
digits.Add(b);
99+
}
98100
});
99101
_bf.Run(_maxIterationCount);
100102
}
@@ -130,6 +132,18 @@ protected override double GetFitnessMethod(string program)
130132
// Bonus for less operations to optimize the code.
131133
countBonus += ((_maxIterationCount - _bf.m_Ticks) / 1000.0);
132134

135+
// Bonus for using functions.
136+
if (_functionCount > 0)
137+
{
138+
for (char functionName = 'a'; functionName < 'a' + _functionCount; functionName++)
139+
{
140+
if (program.Contains(functionName))
141+
{
142+
countBonus += 25;
143+
}
144+
}
145+
}
146+
133147
Ticks += _bf.m_Ticks;
134148
}
135149

AIProgrammer.Functions/Concrete/StringFunction.cs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,8 +66,7 @@ public string Generate(IGeneticAlgorithm ga)
6666
// Run the genetic algorithm and get the best brain.
6767
program = GAManager.Run(ga, _fitnessFunc, _generationFunc);
6868

69-
// For functions, replace ! with % return command.
70-
appendCode += "&" + program.Replace('!', '%') + "%";
69+
appendCode += program + "@";
7170

7271
// Reset the target fitness.
7372
myFitness.ResetTargetFitness();

AIProgrammer.Interpreter/Interpreter.cs

Lines changed: 49 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
namespace AIProgrammer
88
{
99
/// <summary>
10-
/// This the brainfuck interpreter
10+
/// This is the brainfuck interpreter.
1111
///
1212
/// > Increment the pointer.
1313
/// < Decrement the pointer.
@@ -19,9 +19,9 @@ namespace AIProgrammer
1919
/// ] Jump backward to the matching [ unless the byte at the pointer is zero.
2020
///
2121
/// Extended commands, included in BrainPlus.
22-
/// ! Exits the program.
23-
/// & Defines a new function a,b,c .. z.
24-
/// % Return to last position in main program and restore state. Current memory value of function is set in current program memory value.
22+
/// @ Exits the program or if inside a function, return to last position in main program and restore state.
23+
/// $ Overwrites the byte in storage with the byte at the pointer.
24+
/// ! Overwrites the byte at the pointer with the byte in storage.
2525
/// a,b Call function a - z.
2626
/// 0-F Sets the value of the current memory pointer to a multiple of 16.
2727
/// </summary>
@@ -114,15 +114,20 @@ public class FunctionCallObj
114114

115115
/// <summary>
116116
/// Pointer to a function's parent memory. When an input (,) command is executed from within a function, the function's current memory cell gets a copy of the value of the parent memory at this pointer. This allows passing multiple values as input to a function.
117-
// For example: ++>++++>+<<a.!&,>,-[-<+>]<+%
118-
/// Parent memory contains: 2, 4, 1. Function will contain: 2, 4 and return a value of 6. Resulting parent memory contains: 6, 4, 1.
117+
/// For example: ++>++++>+<<a!.@,>,-[-<+>]<+$@
118+
/// Parent memory contains: 2, 4, 1. Function will contain: 2, 4 and store a value of 6 in storage. Resulting parent memory remains: 2, 4, 1. Upon next command !, parent memory will contain: 6, 4, 1. The value 6 is then displayed as output.
119119
/// </summary>
120120
private int m_FunctionInputPointer;
121121

122122
/// <summary>
123-
/// Number of cells available to functions for memory. When a function is executed, an array of cells are allocated in upper-memory addresses (eg., 1000-1999, 2000-2999, etc.) for usage.
123+
/// Number of cells available to functions. When a function is executed, an array of cells are allocated in upper-addresses (eg., 1000-1999, 2000-2999, etc.) for usage.
124124
/// </summary>
125-
private const int _memoryAvailableForFunctions = 255;
125+
private const int _functionSize = 256;
126+
127+
/// <summary>
128+
/// Storage memory value. Usually used to hold return values from function calls.
129+
/// </summary>
130+
private byte m_Storage;
126131

127132
/// <summary>
128133
/// Number of instructions executed.
@@ -225,34 +230,36 @@ public Interpreter(string programCode, Func<byte> input, Action<byte> output)
225230
this.m_InstructionSet.Add('D', () => { if (!m_ExitLoop) this.m_Memory[this.m_DataPointer] = 208; });
226231
this.m_InstructionSet.Add('E', () => { if (!m_ExitLoop) this.m_Memory[this.m_DataPointer] = 224; });
227232
this.m_InstructionSet.Add('F', () => { if (!m_ExitLoop) this.m_Memory[this.m_DataPointer] = 240; });
228-
229-
// Create the instruction set for BrainPlus.
230-
this.m_InstructionSet.Add('!', () => { this.m_Stop = true; });
231-
this.m_InstructionSet.Add('&', () => { m_Functions.Add(m_NextFunctionCharacter++, this.m_InstructionPointer); });
232-
this.m_InstructionSet.Add('%', () =>
233+
this.m_InstructionSet.Add('@', () =>
233234
{
234-
var temp = m_FunctionCallStack.Pop();
235-
236-
// Get the result from the function call.
237-
var result = this.m_Memory[this.m_DataPointer];
238-
239-
// Restore the data pointer.
240-
this.m_DataPointer = temp.DataPointer;
241-
// Set the value of memory equal to the function result.
242-
this.m_Memory[this.m_DataPointer] = result;
243-
// Restore the call stack.
244-
this.m_CurrentCallStack = temp.CallStack;
245-
// Restore exit loop status.
246-
this.m_ExitLoop = temp.ExitLoop;
247-
// Restore exit loop instruction pointer.
248-
this.m_ExitLoopInstructionPointer = temp.ExitLoopInstructionPointer;
249-
// Restore ticks.
250-
this.m_Ticks = temp.Ticks;
251-
// Restore the instruction pointer.
252-
this.m_InstructionPointer = temp.InstructionPointer;
253-
// Restore function input pointer.
254-
this.m_FunctionInputPointer = temp.FunctionInputPointer;
235+
if (m_FunctionCallStack.Count > 0)
236+
{
237+
// Exit function.
238+
var temp = m_FunctionCallStack.Pop();
239+
240+
// Restore the data pointer.
241+
this.m_DataPointer = temp.DataPointer;
242+
// Restore the call stack.
243+
this.m_CurrentCallStack = temp.CallStack;
244+
// Restore exit loop status.
245+
this.m_ExitLoop = temp.ExitLoop;
246+
// Restore exit loop instruction pointer.
247+
this.m_ExitLoopInstructionPointer = temp.ExitLoopInstructionPointer;
248+
// Restore ticks.
249+
this.m_Ticks = temp.Ticks;
250+
// Restore the instruction pointer.
251+
this.m_InstructionPointer = temp.InstructionPointer;
252+
// Restore function input pointer.
253+
this.m_FunctionInputPointer = temp.FunctionInputPointer;
254+
}
255+
else
256+
{
257+
// Exit program.
258+
this.m_Stop = true;
259+
}
255260
});
261+
this.m_InstructionSet.Add('$', () => { this.m_Storage = this.m_Memory[this.m_DataPointer]; });
262+
this.m_InstructionSet.Add('!', () => { this.m_Memory[this.m_DataPointer] = this.m_Storage; });
256263

257264
// Scan code for function definitions and store their starting memory addresses.
258265
ScanFunctions(programCode);
@@ -276,10 +283,10 @@ public Interpreter(string programCode, Func<byte> input, Action<byte> output)
276283
this.m_FunctionInputPointer = this.m_DataPointer;
277284

278285
// Set the data pointer to the functions starting memory address.
279-
this.m_DataPointer = _memoryAvailableForFunctions * (instruction - 96); // each function gets a space of 1000 memory slots.
286+
this.m_DataPointer = _functionSize * (instruction - 96); // each function gets a space of 1000 memory slots.
280287

281288
// Clear function memory.
282-
Array.Clear(this.m_Memory, this.m_DataPointer, _memoryAvailableForFunctions);
289+
Array.Clear(this.m_Memory, this.m_DataPointer, _functionSize);
283290

284291
// Set the instruction pointer to the beginning of the function.
285292
this.m_InstructionPointer = m_Functions[instruction];
@@ -334,7 +341,7 @@ private void RunLimited(int maxInstructions)
334341
if (m_FunctionCallStack.Count > 0)
335342
{
336343
// We're inside a function, but ran out of instructions. Exit the function, but continue.
337-
if (this.m_InstructionSet.TryGetValue('%', out action))
344+
if (this.m_InstructionSet.TryGetValue('@', out action))
338345
{
339346
action();
340347
this.m_InstructionPointer++;
@@ -381,20 +388,13 @@ private void RunUnlimited()
381388
/// </summary>
382389
private void ScanFunctions(string source)
383390
{
384-
this.m_InstructionPointer = source.IndexOf('&');
385-
while (this.m_InstructionPointer > -1 && this.m_InstructionPointer < source.Length && !m_Stop)
391+
this.m_InstructionPointer = source.IndexOf('@');
392+
while (this.m_InstructionPointer > -1 && this.m_InstructionPointer < source.Length - 1 && !m_Stop)
386393
{
387-
// Fetch the next instruction
388-
char instruction = this.m_Source[this.m_InstructionPointer];
389-
390-
Action action;
391-
if (this.m_InstructionSet.TryGetValue(instruction, out action))
392-
{
393-
// Store the function.
394-
action();
395-
}
394+
// Store the function.
395+
m_Functions.Add(m_NextFunctionCharacter++, this.m_InstructionPointer);
396396

397-
this.m_InstructionPointer = source.IndexOf('&', this.m_InstructionPointer + 1);
397+
this.m_InstructionPointer = source.IndexOf('@', this.m_InstructionPointer + 1);
398398
}
399399

400400
this.m_InstructionPointer = 0;

AIProgrammer.Managers/AIProgrammer.Managers.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
<ItemGroup>
4343
<Compile Include="CommonManager.cs" />
4444
<Compile Include="GAManager.cs" />
45+
<Compile Include="LogManager.cs" />
4546
<Compile Include="Properties\AssemblyInfo.cs" />
4647
</ItemGroup>
4748
<ItemGroup>

0 commit comments

Comments
 (0)