├── CellLifeGame1
├── App.ico
├── SaveFile.cs
├── Model.cs
├── Model
│ ├── Link.cs
│ ├── Position.cs
│ └── Node.cs
├── UniqueID.cs
├── AssemblyInfo.cs
├── StateRule.cs
├── CellLifeGame1.csproj
├── StateRule.resx
├── StatesOutput.resx
├── UIForm.resx
├── StatesOutput.cs
├── Modeling.cs
└── UIForm.cs
├── ThesisAaronShumaker.pdf
├── ClassLibrary1
├── Historical.cs
├── AssemblyInfo.cs
└── ClassLibrary1.csproj
├── Command
├── Command.cs
├── AssemblyInfo.cs
└── Command.csproj
├── NNModel
├── Neuron.cs
├── UniqueID.cs
├── AssemblyInfo.cs
├── NeuralNet.cs
└── NNModel.csproj
├── .gitattributes
├── Modeling.sln
├── ThreadSafe
├── ThreadSafe.cs
├── AssemblyInfo.cs
└── ThreadSafe.csproj
├── Recording
├── AssemblyInfo.cs
├── Recording.csproj
└── Recording.cs
├── .gitignore
└── README.md
/CellLifeGame1/App.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AaronLS/CellularAutomataAsNeuralNetwork/HEAD/CellLifeGame1/App.ico
--------------------------------------------------------------------------------
/ThesisAaronShumaker.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AaronLS/CellularAutomataAsNeuralNetwork/HEAD/ThesisAaronShumaker.pdf
--------------------------------------------------------------------------------
/ClassLibrary1/Historical.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace ClassLibrary1
4 | {
5 | ///
6 | /// Summary description for Class1.
7 | ///
8 | public class Class1
9 | {
10 | public Class1()
11 | {
12 | //
13 | // TODO: Add constructor logic here
14 | //
15 | }
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/Command/Command.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace ErsatzAcumen
4 | {
5 | ///
6 | /// Summary description for Class1.
7 | ///
8 | public class Command
9 | {
10 | public Command()
11 | {
12 | //
13 | // TODO: Add constructor logic here
14 | //
15 | }
16 | }
17 |
18 | public interface ICommandable
19 | {
20 | }
21 |
22 |
23 |
24 |
25 | }
26 |
--------------------------------------------------------------------------------
/NNModel/Neuron.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections;
3 |
4 |
5 |
6 |
7 | namespace ErsatzAcumen
8 | {
9 | ///
10 | /// Stores and provides threadsafe access
11 | /// to the properties of neurons.
12 | ///
13 | public class Neuron
14 | {
15 |
16 |
17 |
18 |
19 |
20 | public Neuron()
21 | {
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 | //
30 | // TODO: Add constructor logic here
31 | //
32 | }
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/CellLifeGame1/SaveFile.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections;
3 | using System.Collections.Generic;
4 | using System.Text;
5 |
6 | namespace CellLifeGame1
7 | {
8 | [Serializable]
9 | class SaveFile
10 | {
11 | internal ArrayList nodes;
12 | internal ArrayList activationValues;
13 |
14 | public SaveFile(ArrayList nodes, ArrayList activationValues)
15 | {
16 | this.nodes = nodes;
17 | this.activationValues = activationValues;
18 | }
19 |
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | # Auto detect text files and perform LF normalization
2 | * text=auto
3 |
4 | # Custom for Visual Studio
5 | *.cs diff=csharp
6 | *.sln merge=union
7 | *.csproj merge=union
8 | *.vbproj merge=union
9 | *.fsproj merge=union
10 | *.dbproj merge=union
11 |
12 | # Standard to msysgit
13 | *.doc diff=astextplain
14 | *.DOC diff=astextplain
15 | *.docx diff=astextplain
16 | *.DOCX diff=astextplain
17 | *.dot diff=astextplain
18 | *.DOT diff=astextplain
19 | *.pdf diff=astextplain
20 | *.PDF diff=astextplain
21 | *.rtf diff=astextplain
22 | *.RTF diff=astextplain
23 |
--------------------------------------------------------------------------------
/CellLifeGame1/Model.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections;
3 |
4 |
5 | namespace ErsatzAcumen
6 | {
7 |
8 |
9 |
10 | ///
11 | /// Summary description for Model.
12 | ///
13 | public class Model
14 | {
15 | private System.Threading.Thread thread;
16 |
17 | private Queue updates;
18 |
19 | public object GetNextUpdate()
20 | {
21 | return updates.Dequeue();
22 | }
23 |
24 | private class Item
25 | {
26 | public UniqueID ID;
27 |
28 |
29 |
30 | }
31 |
32 | public Model()
33 | {
34 | Item item = new Item();
35 | //item
36 | }
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 | //
45 | // TODO: Add constructor logic here
46 | //
47 |
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/CellLifeGame1/Model/Link.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 |
5 | namespace CellLifeGame1.Model
6 | {
7 |
8 | [Serializable]
9 | public class Link
10 | {
11 | public Node Destin;//Destination, where the link points to
12 |
13 | //an optional weight for use in applications such as neural nets
14 | private double weight;
15 |
16 | public double Weight
17 | {
18 | get
19 | {
20 | return this.weight;
21 | }
22 | set
23 | {
24 | this.weight = value;
25 | }
26 | }
27 |
28 | public Link(Node node, double initWeight)
29 | {
30 | this.Weight = initWeight;
31 | this.Destin = node;
32 | }
33 |
34 | public Link(Node node) : this(node, 1) { }
35 |
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/Modeling.sln:
--------------------------------------------------------------------------------
1 | Microsoft Visual Studio Solution File, Format Version 12.00
2 | # Visual Studio 2012
3 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CellLifeGame1", "CellLifeGame1\CellLifeGame1.csproj", "{F2D678D5-E7D3-483A-90B3-A2A4019098DA}"
4 | EndProject
5 | Global
6 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
7 | Debug|Any CPU = Debug|Any CPU
8 | Release|Any CPU = Release|Any CPU
9 | EndGlobalSection
10 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
11 | {F2D678D5-E7D3-483A-90B3-A2A4019098DA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
12 | {F2D678D5-E7D3-483A-90B3-A2A4019098DA}.Debug|Any CPU.Build.0 = Debug|Any CPU
13 | {F2D678D5-E7D3-483A-90B3-A2A4019098DA}.Release|Any CPU.ActiveCfg = Release|Any CPU
14 | {F2D678D5-E7D3-483A-90B3-A2A4019098DA}.Release|Any CPU.Build.0 = Release|Any CPU
15 | EndGlobalSection
16 | GlobalSection(SolutionProperties) = preSolution
17 | HideSolutionNode = FALSE
18 | EndGlobalSection
19 | EndGlobal
20 |
--------------------------------------------------------------------------------
/NNModel/UniqueID.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace ErsatzAcumen
4 | {
5 |
6 | /*
7 | ///
8 | /// UniqueID was an idea to provide IDs that were unique.
9 | /// But the default hashcodes of references are sufficient
10 | /// for most applications.
11 | ///
12 | public class UniqueID
13 | {
14 | ///
15 | /// A list of IDs available previously used IDs
16 | /// This is to avoid an object ID value from overflowing
17 | /// an integer when many objects are created and destroyed,
18 | /// which would result in new objects getting higher and
19 | /// higher ID values.
20 | ///
21 | private static Queue recycledIDs;
22 |
23 | ///
24 | /// The value of the next node ID to be issued, if
25 | /// there are none available in recycledIDs.
26 | ///
27 | private static int nextID=0;
28 |
29 | private static int getNextID()
30 | {
31 |
32 | if(recycledIDs==null)
33 | {
34 | int useID = this.nextID;
35 | ++this.nextID;
36 | return useID;
37 | }
38 | //else there are recylcedIDs to be used
39 | return (int) recycledIDs.Dequeue();
40 | }
41 |
42 | private readonly int id;
43 |
44 | public int ID
45 | {
46 | get
47 | {
48 | return id;
49 | }
50 | }
51 |
52 | public UniqueID()
53 | {
54 | this.id = getNextID();
55 | }
56 |
57 | public override int GetHashCode()
58 | {
59 | return ID;
60 | }
61 | }*/
62 | }
63 |
--------------------------------------------------------------------------------
/CellLifeGame1/UniqueID.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace ErsatzAcumen
4 | {
5 |
6 | /*
7 | ///
8 | /// UniqueID was an idea to provide IDs that were unique.
9 | /// But the default hashcodes of references are sufficient
10 | /// for most applications.
11 | ///
12 | public class UniqueID
13 | {
14 | ///
15 | /// A list of IDs available previously used IDs
16 | /// This is to avoid an object ID value from overflowing
17 | /// an integer when many objects are created and destroyed,
18 | /// which would result in new objects getting higher and
19 | /// higher ID values.
20 | ///
21 | private static Queue recycledIDs;
22 |
23 | ///
24 | /// The value of the next node ID to be issued, if
25 | /// there are none available in recycledIDs.
26 | ///
27 | private static int nextID=0;
28 |
29 | private static int getNextID()
30 | {
31 |
32 | if(recycledIDs==null)
33 | {
34 | int useID = this.nextID;
35 | ++this.nextID;
36 | return useID;
37 | }
38 | //else there are recylcedIDs to be used
39 | return (int) recycledIDs.Dequeue();
40 | }
41 |
42 | private readonly int id;
43 |
44 | public int ID
45 | {
46 | get
47 | {
48 | return id;
49 | }
50 | }
51 |
52 | public UniqueID()
53 | {
54 | this.id = getNextID();
55 | }
56 |
57 | public override int GetHashCode()
58 | {
59 | return ID;
60 | }
61 | }*/
62 | }
63 |
--------------------------------------------------------------------------------
/CellLifeGame1/Model/Position.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 |
5 | namespace CellLifeGame1.Model
6 | {
7 | [Serializable]
8 | public class Position : IComparable
9 | {
10 | //position on an X/Y plane
11 | public int x;
12 | public int y;
13 |
14 | public Position()
15 | { }
16 |
17 | public Position(int x, int y)
18 | {
19 | this.x = x;
20 | this.y = y;
21 | }
22 |
23 | #region IComparable Members
24 |
25 | ///
26 | /// Performs lexicographical comparison of a position, with
27 | /// Position.x being the primary comparison, and Position.y
28 | /// the secondary comparison.
29 | ///
30 | /// Position to compare this instance to.
31 | ///
32 | /// Returns less than 0 if this instance is less than
33 | /// obj, greater than 0 for greater than, and 0 for equality.
34 | ///
35 | public int CompareTo(object obj)
36 | {
37 | if (obj is Position)
38 | {
39 | Position position = (Position)obj;
40 | int xResult = this.x.CompareTo(position.x);
41 | if (xResult != 0)
42 | {
43 | return xResult;
44 | }
45 | //else x is equal, thus we use y comparison
46 | return this.y.CompareTo(position.y);
47 | }
48 | throw new ArgumentException("object is not a Position");
49 | }
50 |
51 | #endregion
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/ThreadSafe/ThreadSafe.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Threading;
3 |
4 | namespace ErsatzAcumen
5 | {
6 | ///
7 | /// Utilities for locking class types.
8 | /// Potential-deadlock checking is provided
9 | /// in debug mode, while release code does not.
10 | ///
11 | public class ThreadSafe
12 | {
13 | #if DEBUG
14 |
15 | static TimeSpan maxWaited;
16 | static long TimesWaited;
17 |
18 | static ThreadSafe()
19 | {
20 | maxWaited = TimeSpan.Zero;
21 | TimesWaited = 0;
22 | }
23 |
24 | static public void Enter(object obj)
25 | {
26 | try
27 | {
28 | bool isOk = true;
29 | for(TimeSpan Wait = new TimeSpan(0,0,1);
30 | isOk == true;
31 | Wait.Add(TimeSpan.FromSeconds(10)) )
32 | {
33 | if(Monitor.TryEnter(obj, Wait) == true)
34 | {//lock acquired
35 | return;
36 | }
37 | else
38 | {//lock not acquired
39 |
40 | Interlocked.Increment(ref TimesWaited);
41 | lock(maxWaited)
42 | {
43 | if(maxWaited < Wait)
44 | {
45 | maxWaited = Wait;
46 | Console.Write("Potential deadlock, maxWaited is now {0} seconds. Waiting more...",maxWaited.Seconds);
47 | }
48 | }
49 | }
50 | }
51 | }
52 | catch
53 | {
54 | throw;
55 | }
56 |
57 | }
58 |
59 | static public void Exit(object obj)
60 | {
61 | Monitor.Exit(obj);
62 | }
63 |
64 | #else
65 | static public void Enter(object obj)
66 | {
67 | try
68 | {
69 | Monitor.Enter(obj);
70 | }
71 | catch
72 | {
73 | throw;
74 | }
75 | }
76 |
77 | static public void Exit(object obj)
78 | {
79 | try
80 | {
81 | Monitor.Exit(obj);
82 | }
83 | catch
84 | {
85 | throw;
86 | }
87 | }
88 |
89 | #endif
90 |
91 | }
92 | }
93 |
94 |
--------------------------------------------------------------------------------
/CellLifeGame1/Model/Node.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections;
3 | using System.Collections.Generic;
4 | using System.Text;
5 |
6 | namespace CellLifeGame1.Model
7 | {
8 | [Serializable]
9 | public class Node : IComparable
10 | {
11 |
12 | public double inputSum;
13 |
14 | //on or off, firing or not-firing
15 | private bool active;
16 | public bool IsActive
17 | {
18 | get
19 | {
20 | return active;
21 | }
22 | set
23 | {
24 | active = value;
25 | }
26 | }
27 |
28 | //position of node on an X/Y plane
29 | public Position position;
30 |
31 | //list of nodes to which this one connects
32 | public ArrayList links;
33 |
34 | ///
35 | /// Creates a link from this to node.
36 | ///
37 | /// The Node to link to.
38 | public void AddLink(Link link)
39 | {
40 | if (links == null)
41 | {
42 | links = new ArrayList();
43 | }
44 |
45 | links.Add(link);
46 | }
47 |
48 | public Node(int positionX, int positionY)
49 | {
50 | position = new Position();
51 |
52 | this.position.x = positionX;
53 | this.position.y = positionY;
54 | inputSum = 0;
55 | }
56 |
57 | #region IComparable Members
58 | ///
59 | /// Performs lexigraphical comparison based on position.
60 | ///
61 | /// Node or position
62 | /// to compare this instance to.
63 | /// Returns result of position comparison.
64 | public int CompareTo(object obj)
65 | {
66 |
67 | if (obj is Node)
68 | {
69 | Node node = (Node)obj;
70 | return this.position.CompareTo(node.position);
71 | }
72 | else//let Position try to compare the type
73 | {
74 | try
75 | {
76 | return this.position.CompareTo(obj);
77 | }
78 | catch (ArgumentException e)
79 | {
80 | throw new ArgumentException(e + "and object is not a Node");
81 | }
82 | }
83 | }
84 | #endregion
85 |
86 | }
87 | }
88 |
--------------------------------------------------------------------------------
/Command/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 |
4 | //
5 | // General Information about an assembly is controlled through the following
6 | // set of attributes. Change these attribute values to modify the information
7 | // associated with an assembly.
8 | //
9 | [assembly: AssemblyTitle("")]
10 | [assembly: AssemblyDescription("")]
11 | [assembly: AssemblyConfiguration("")]
12 | [assembly: AssemblyCompany("")]
13 | [assembly: AssemblyProduct("")]
14 | [assembly: AssemblyCopyright("")]
15 | [assembly: AssemblyTrademark("")]
16 | [assembly: AssemblyCulture("")]
17 |
18 | //
19 | // Version information for an assembly consists of the following four values:
20 | //
21 | // Major Version
22 | // Minor Version
23 | // Build Number
24 | // Revision
25 | //
26 | // You can specify all the values or you can default the Revision and Build Numbers
27 | // by using the '*' as shown below:
28 |
29 | [assembly: AssemblyVersion("1.0.*")]
30 |
31 | //
32 | // In order to sign your assembly you must specify a key to use. Refer to the
33 | // Microsoft .NET Framework documentation for more information on assembly signing.
34 | //
35 | // Use the attributes below to control which key is used for signing.
36 | //
37 | // Notes:
38 | // (*) If no key is specified, the assembly is not signed.
39 | // (*) KeyName refers to a key that has been installed in the Crypto Service
40 | // Provider (CSP) on your machine. KeyFile refers to a file which contains
41 | // a key.
42 | // (*) If the KeyFile and the KeyName values are both specified, the
43 | // following processing occurs:
44 | // (1) If the KeyName can be found in the CSP, that key is used.
45 | // (2) If the KeyName does not exist and the KeyFile does exist, the key
46 | // in the KeyFile is installed into the CSP and used.
47 | // (*) In order to create a KeyFile, you can use the sn.exe (Strong Name) utility.
48 | // When specifying the KeyFile, the location of the KeyFile should be
49 | // relative to the project output directory which is
50 | // %Project Directory%\obj\. For example, if your KeyFile is
51 | // located in the project directory, you would specify the AssemblyKeyFile
52 | // attribute as [assembly: AssemblyKeyFile("..\\..\\mykey.snk")]
53 | // (*) Delay Signing is an advanced option - see the Microsoft .NET Framework
54 | // documentation for more information on this.
55 | //
56 | [assembly: AssemblyDelaySign(false)]
57 | [assembly: AssemblyKeyFile("")]
58 | [assembly: AssemblyKeyName("")]
59 |
--------------------------------------------------------------------------------
/NNModel/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 |
4 | //
5 | // General Information about an assembly is controlled through the following
6 | // set of attributes. Change these attribute values to modify the information
7 | // associated with an assembly.
8 | //
9 | [assembly: AssemblyTitle("")]
10 | [assembly: AssemblyDescription("")]
11 | [assembly: AssemblyConfiguration("")]
12 | [assembly: AssemblyCompany("")]
13 | [assembly: AssemblyProduct("")]
14 | [assembly: AssemblyCopyright("")]
15 | [assembly: AssemblyTrademark("")]
16 | [assembly: AssemblyCulture("")]
17 |
18 | //
19 | // Version information for an assembly consists of the following four values:
20 | //
21 | // Major Version
22 | // Minor Version
23 | // Build Number
24 | // Revision
25 | //
26 | // You can specify all the values or you can default the Revision and Build Numbers
27 | // by using the '*' as shown below:
28 |
29 | [assembly: AssemblyVersion("1.0.*")]
30 |
31 | //
32 | // In order to sign your assembly you must specify a key to use. Refer to the
33 | // Microsoft .NET Framework documentation for more information on assembly signing.
34 | //
35 | // Use the attributes below to control which key is used for signing.
36 | //
37 | // Notes:
38 | // (*) If no key is specified, the assembly is not signed.
39 | // (*) KeyName refers to a key that has been installed in the Crypto Service
40 | // Provider (CSP) on your machine. KeyFile refers to a file which contains
41 | // a key.
42 | // (*) If the KeyFile and the KeyName values are both specified, the
43 | // following processing occurs:
44 | // (1) If the KeyName can be found in the CSP, that key is used.
45 | // (2) If the KeyName does not exist and the KeyFile does exist, the key
46 | // in the KeyFile is installed into the CSP and used.
47 | // (*) In order to create a KeyFile, you can use the sn.exe (Strong Name) utility.
48 | // When specifying the KeyFile, the location of the KeyFile should be
49 | // relative to the project output directory which is
50 | // %Project Directory%\obj\. For example, if your KeyFile is
51 | // located in the project directory, you would specify the AssemblyKeyFile
52 | // attribute as [assembly: AssemblyKeyFile("..\\..\\mykey.snk")]
53 | // (*) Delay Signing is an advanced option - see the Microsoft .NET Framework
54 | // documentation for more information on this.
55 | //
56 | [assembly: AssemblyDelaySign(false)]
57 | [assembly: AssemblyKeyFile("")]
58 | [assembly: AssemblyKeyName("")]
59 |
--------------------------------------------------------------------------------
/CellLifeGame1/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 |
4 | //
5 | // General Information about an assembly is controlled through the following
6 | // set of attributes. Change these attribute values to modify the information
7 | // associated with an assembly.
8 | //
9 | [assembly: AssemblyTitle("")]
10 | [assembly: AssemblyDescription("")]
11 | [assembly: AssemblyConfiguration("")]
12 | [assembly: AssemblyCompany("")]
13 | [assembly: AssemblyProduct("")]
14 | [assembly: AssemblyCopyright("")]
15 | [assembly: AssemblyTrademark("")]
16 | [assembly: AssemblyCulture("")]
17 |
18 | //
19 | // Version information for an assembly consists of the following four values:
20 | //
21 | // Major Version
22 | // Minor Version
23 | // Build Number
24 | // Revision
25 | //
26 | // You can specify all the values or you can default the Revision and Build Numbers
27 | // by using the '*' as shown below:
28 |
29 | [assembly: AssemblyVersion("1.0.*")]
30 |
31 | //
32 | // In order to sign your assembly you must specify a key to use. Refer to the
33 | // Microsoft .NET Framework documentation for more information on assembly signing.
34 | //
35 | // Use the attributes below to control which key is used for signing.
36 | //
37 | // Notes:
38 | // (*) If no key is specified, the assembly is not signed.
39 | // (*) KeyName refers to a key that has been installed in the Crypto Service
40 | // Provider (CSP) on your machine. KeyFile refers to a file which contains
41 | // a key.
42 | // (*) If the KeyFile and the KeyName values are both specified, the
43 | // following processing occurs:
44 | // (1) If the KeyName can be found in the CSP, that key is used.
45 | // (2) If the KeyName does not exist and the KeyFile does exist, the key
46 | // in the KeyFile is installed into the CSP and used.
47 | // (*) In order to create a KeyFile, you can use the sn.exe (Strong Name) utility.
48 | // When specifying the KeyFile, the location of the KeyFile should be
49 | // relative to the project output directory which is
50 | // %Project Directory%\obj\. For example, if your KeyFile is
51 | // located in the project directory, you would specify the AssemblyKeyFile
52 | // attribute as [assembly: AssemblyKeyFile("..\\..\\mykey.snk")]
53 | // (*) Delay Signing is an advanced option - see the Microsoft .NET Framework
54 | // documentation for more information on this.
55 | //
56 | [assembly: AssemblyDelaySign(false)]
57 | [assembly: AssemblyKeyFile("")]
58 | [assembly: AssemblyKeyName("")]
59 |
--------------------------------------------------------------------------------
/ClassLibrary1/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 |
4 | //
5 | // General Information about an assembly is controlled through the following
6 | // set of attributes. Change these attribute values to modify the information
7 | // associated with an assembly.
8 | //
9 | [assembly: AssemblyTitle("")]
10 | [assembly: AssemblyDescription("")]
11 | [assembly: AssemblyConfiguration("")]
12 | [assembly: AssemblyCompany("")]
13 | [assembly: AssemblyProduct("")]
14 | [assembly: AssemblyCopyright("")]
15 | [assembly: AssemblyTrademark("")]
16 | [assembly: AssemblyCulture("")]
17 |
18 | //
19 | // Version information for an assembly consists of the following four values:
20 | //
21 | // Major Version
22 | // Minor Version
23 | // Build Number
24 | // Revision
25 | //
26 | // You can specify all the values or you can default the Revision and Build Numbers
27 | // by using the '*' as shown below:
28 |
29 | [assembly: AssemblyVersion("1.0.*")]
30 |
31 | //
32 | // In order to sign your assembly you must specify a key to use. Refer to the
33 | // Microsoft .NET Framework documentation for more information on assembly signing.
34 | //
35 | // Use the attributes below to control which key is used for signing.
36 | //
37 | // Notes:
38 | // (*) If no key is specified, the assembly is not signed.
39 | // (*) KeyName refers to a key that has been installed in the Crypto Service
40 | // Provider (CSP) on your machine. KeyFile refers to a file which contains
41 | // a key.
42 | // (*) If the KeyFile and the KeyName values are both specified, the
43 | // following processing occurs:
44 | // (1) If the KeyName can be found in the CSP, that key is used.
45 | // (2) If the KeyName does not exist and the KeyFile does exist, the key
46 | // in the KeyFile is installed into the CSP and used.
47 | // (*) In order to create a KeyFile, you can use the sn.exe (Strong Name) utility.
48 | // When specifying the KeyFile, the location of the KeyFile should be
49 | // relative to the project output directory which is
50 | // %Project Directory%\obj\. For example, if your KeyFile is
51 | // located in the project directory, you would specify the AssemblyKeyFile
52 | // attribute as [assembly: AssemblyKeyFile("..\\..\\mykey.snk")]
53 | // (*) Delay Signing is an advanced option - see the Microsoft .NET Framework
54 | // documentation for more information on this.
55 | //
56 | [assembly: AssemblyDelaySign(false)]
57 | [assembly: AssemblyKeyFile("")]
58 | [assembly: AssemblyKeyName("")]
59 |
--------------------------------------------------------------------------------
/Recording/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 |
4 | //
5 | // General Information about an assembly is controlled through the following
6 | // set of attributes. Change these attribute values to modify the information
7 | // associated with an assembly.
8 | //
9 | [assembly: AssemblyTitle("")]
10 | [assembly: AssemblyDescription("")]
11 | [assembly: AssemblyConfiguration("")]
12 | [assembly: AssemblyCompany("")]
13 | [assembly: AssemblyProduct("")]
14 | [assembly: AssemblyCopyright("")]
15 | [assembly: AssemblyTrademark("")]
16 | [assembly: AssemblyCulture("")]
17 |
18 | //
19 | // Version information for an assembly consists of the following four values:
20 | //
21 | // Major Version
22 | // Minor Version
23 | // Build Number
24 | // Revision
25 | //
26 | // You can specify all the values or you can default the Revision and Build Numbers
27 | // by using the '*' as shown below:
28 |
29 | [assembly: AssemblyVersion("1.0.*")]
30 |
31 | //
32 | // In order to sign your assembly you must specify a key to use. Refer to the
33 | // Microsoft .NET Framework documentation for more information on assembly signing.
34 | //
35 | // Use the attributes below to control which key is used for signing.
36 | //
37 | // Notes:
38 | // (*) If no key is specified, the assembly is not signed.
39 | // (*) KeyName refers to a key that has been installed in the Crypto Service
40 | // Provider (CSP) on your machine. KeyFile refers to a file which contains
41 | // a key.
42 | // (*) If the KeyFile and the KeyName values are both specified, the
43 | // following processing occurs:
44 | // (1) If the KeyName can be found in the CSP, that key is used.
45 | // (2) If the KeyName does not exist and the KeyFile does exist, the key
46 | // in the KeyFile is installed into the CSP and used.
47 | // (*) In order to create a KeyFile, you can use the sn.exe (Strong Name) utility.
48 | // When specifying the KeyFile, the location of the KeyFile should be
49 | // relative to the project output directory which is
50 | // %Project Directory%\obj\. For example, if your KeyFile is
51 | // located in the project directory, you would specify the AssemblyKeyFile
52 | // attribute as [assembly: AssemblyKeyFile("..\\..\\mykey.snk")]
53 | // (*) Delay Signing is an advanced option - see the Microsoft .NET Framework
54 | // documentation for more information on this.
55 | //
56 | [assembly: AssemblyDelaySign(false)]
57 | [assembly: AssemblyKeyFile("")]
58 | [assembly: AssemblyKeyName("")]
59 |
--------------------------------------------------------------------------------
/ThreadSafe/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 |
4 | //
5 | // General Information about an assembly is controlled through the following
6 | // set of attributes. Change these attribute values to modify the information
7 | // associated with an assembly.
8 | //
9 | [assembly: AssemblyTitle("")]
10 | [assembly: AssemblyDescription("")]
11 | [assembly: AssemblyConfiguration("")]
12 | [assembly: AssemblyCompany("")]
13 | [assembly: AssemblyProduct("")]
14 | [assembly: AssemblyCopyright("")]
15 | [assembly: AssemblyTrademark("")]
16 | [assembly: AssemblyCulture("")]
17 |
18 | //
19 | // Version information for an assembly consists of the following four values:
20 | //
21 | // Major Version
22 | // Minor Version
23 | // Build Number
24 | // Revision
25 | //
26 | // You can specify all the values or you can default the Revision and Build Numbers
27 | // by using the '*' as shown below:
28 |
29 | [assembly: AssemblyVersion("1.0.*")]
30 |
31 | //
32 | // In order to sign your assembly you must specify a key to use. Refer to the
33 | // Microsoft .NET Framework documentation for more information on assembly signing.
34 | //
35 | // Use the attributes below to control which key is used for signing.
36 | //
37 | // Notes:
38 | // (*) If no key is specified, the assembly is not signed.
39 | // (*) KeyName refers to a key that has been installed in the Crypto Service
40 | // Provider (CSP) on your machine. KeyFile refers to a file which contains
41 | // a key.
42 | // (*) If the KeyFile and the KeyName values are both specified, the
43 | // following processing occurs:
44 | // (1) If the KeyName can be found in the CSP, that key is used.
45 | // (2) If the KeyName does not exist and the KeyFile does exist, the key
46 | // in the KeyFile is installed into the CSP and used.
47 | // (*) In order to create a KeyFile, you can use the sn.exe (Strong Name) utility.
48 | // When specifying the KeyFile, the location of the KeyFile should be
49 | // relative to the project output directory which is
50 | // %Project Directory%\obj\. For example, if your KeyFile is
51 | // located in the project directory, you would specify the AssemblyKeyFile
52 | // attribute as [assembly: AssemblyKeyFile("..\\..\\mykey.snk")]
53 | // (*) Delay Signing is an advanced option - see the Microsoft .NET Framework
54 | // documentation for more information on this.
55 | //
56 | [assembly: AssemblyDelaySign(false)]
57 | [assembly: AssemblyKeyFile("")]
58 | [assembly: AssemblyKeyName("")]
59 |
--------------------------------------------------------------------------------
/NNModel/NeuralNet.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections;
3 |
4 |
5 | namespace ErsatzAcumen
6 | {
7 |
8 | /*
9 | * pseudo code:
10 | *
11 | * public neuron collection
12 | *
13 | * private queue of collections of updated nuerons, one collection per timestep
14 | * accessable through method for getting updates that prevents client from changing queue
15 | *
16 | * time granularity
17 | *
18 | * subscribe to each neuron's onneuronupdate event
19 | *
20 | * onneuronupdatehandler will add senderobject to clientupdatedneurons collection
21 | * NNModel should wake if sleeping, or immedietely halt processing and make updates
22 | * determine if procesing should be backed out due to being made obselete by a user
23 | * update
24 | *
25 | *
26 | *
27 | * history stack or deque of historycollections
28 | * each collection showing the pre-updated values of neurons that were
29 | * updated during a timestep, any user editing done between timesteps
30 | * is stored as a collection between the appropriate timesteps
31 | *
32 | * each history item is a shallow copy of the object at the beginning of the timestep
33 | * algorithm for adding item to history
34 | *
35 | *
36 | * class historycollection
37 | * {
38 | * timeframe
39 | * collection of historyitems
40 | * }
41 | *
42 | * public delegate void HistoryAction(object obj);
43 | * class HistoryItem
44 | * {
45 | * object Do;//delegate
46 | * object DoParams;//collection or array of parameters, or null if none needed
47 | * object Undo;//if null, then use Do with UndoParams
48 | * object UndoParams;//if null, then use DoParams for Undo
49 | * }
50 | *
51 | * objects that are historical have an event that is fired when an archivable state change
52 | * has occured, which passes through the event a HistoryItem that the object produces
53 | * the handler for the event can use the history item for stepping backwards in time
54 | * through the objects state and then forward again. Undo/Do.
55 | * Any state defining fields should be private, and the methods/properties through which
56 | * they are accessed should
57 | * Historyitems should be serilizable, but are not valid if the object they are for
58 | * no longer exists. This shouldn't be a problem since delegates maintain a reference
59 | * to the underlying object
60 | *
61 | * stepping back in history can only take you as far as when you first subscribed to the
62 | * state changed event
63 | * it is not practical to have a historyitem that indicates the creation or desctruction
64 | * of an object, as the object won't really be garbage collected as long as a history item
65 | * exists for it due to the fact that delegates maintain a reference to the object
66 | *
67 | * collections will need historical overloads that subscribers can track their state with.
68 | * With many apps, you will have some collection holding objects, and when you no longer
69 | * need an object, then you will remove it from the collection, if that is the only
70 | * reference to the object, then it will get garbage collected(GCed). Keeping a historyitem
71 | * for an object will prevent it from being GCed, or keeping a historyitem for that collection
72 | * in which a param of the history item is a reference to that object will also prevent the
73 | * object from being GCed. For example, if the history item is to undo the removal of an
74 | * item from a collection, then the undo delegate will likely be a call to Add on the
75 | * collection, with the object as the param.
76 | *
77 | *
78 | *
79 | *
80 |
81 |
82 | */
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 | }
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | #################
2 | ## Eclipse
3 | #################
4 |
5 | *.pydevproject
6 | .project
7 | .metadata
8 | bin/
9 | tmp/
10 | *.tmp
11 | *.bak
12 | *.swp
13 | *~.nib
14 | local.properties
15 | .classpath
16 | .settings/
17 | .loadpath
18 |
19 | # External tool builders
20 | .externalToolBuilders/
21 |
22 | # Locally stored "Eclipse launch configurations"
23 | *.launch
24 |
25 | # CDT-specific
26 | .cproject
27 |
28 | # PDT-specific
29 | .buildpath
30 |
31 |
32 | #################
33 | ## Visual Studio
34 | #################
35 |
36 | ## Ignore Visual Studio temporary files, build results, and
37 | ## files generated by popular Visual Studio add-ons.
38 |
39 | # User-specific files
40 | *.suo
41 | *.user
42 | *.sln.docstates
43 |
44 | # Build results
45 |
46 | [Dd]ebug/
47 | [Rr]elease/
48 | x64/
49 | build/
50 | [Bb]in/
51 | [Oo]bj/
52 |
53 | # MSTest test Results
54 | [Tt]est[Rr]esult*/
55 | [Bb]uild[Ll]og.*
56 |
57 | *_i.c
58 | *_p.c
59 | *.ilk
60 | *.meta
61 | *.obj
62 | *.pch
63 | *.pdb
64 | *.pgc
65 | *.pgd
66 | *.rsp
67 | *.sbr
68 | *.tlb
69 | *.tli
70 | *.tlh
71 | *.tmp
72 | *.tmp_proj
73 | *.log
74 | *.vspscc
75 | *.vssscc
76 | .builds
77 | *.pidb
78 | *.log
79 | *.scc
80 |
81 | # Visual C++ cache files
82 | ipch/
83 | *.aps
84 | *.ncb
85 | *.opensdf
86 | *.sdf
87 | *.cachefile
88 |
89 | # Visual Studio profiler
90 | *.psess
91 | *.vsp
92 | *.vspx
93 |
94 | # Guidance Automation Toolkit
95 | *.gpState
96 |
97 | # ReSharper is a .NET coding add-in
98 | _ReSharper*/
99 | *.[Rr]e[Ss]harper
100 |
101 | # TeamCity is a build add-in
102 | _TeamCity*
103 |
104 | # DotCover is a Code Coverage Tool
105 | *.dotCover
106 |
107 | # NCrunch
108 | *.ncrunch*
109 | .*crunch*.local.xml
110 |
111 | # Installshield output folder
112 | [Ee]xpress/
113 |
114 | # DocProject is a documentation generator add-in
115 | DocProject/buildhelp/
116 | DocProject/Help/*.HxT
117 | DocProject/Help/*.HxC
118 | DocProject/Help/*.hhc
119 | DocProject/Help/*.hhk
120 | DocProject/Help/*.hhp
121 | DocProject/Help/Html2
122 | DocProject/Help/html
123 |
124 | # Click-Once directory
125 | publish/
126 |
127 | # Publish Web Output
128 | *.Publish.xml
129 | *.pubxml
130 |
131 | # NuGet Packages Directory
132 | ## TODO: If you have NuGet Package Restore enabled, uncomment the next line
133 | #packages/
134 |
135 | # Windows Azure Build Output
136 | csx
137 | *.build.csdef
138 |
139 | # Windows Store app package directory
140 | AppPackages/
141 |
142 | # Others
143 | sql/
144 | *.Cache
145 | ClientBin/
146 | [Ss]tyle[Cc]op.*
147 | ~$*
148 | *~
149 | *.dbmdl
150 | *.[Pp]ublish.xml
151 | *.pfx
152 | *.publishsettings
153 |
154 | # RIA/Silverlight projects
155 | Generated_Code/
156 |
157 | # Backup & report files from converting an old project file to a newer
158 | # Visual Studio version. Backup files are not needed, because we have git ;-)
159 | _UpgradeReport_Files/
160 | Backup*/
161 | UpgradeLog*.XML
162 | UpgradeLog*.htm
163 |
164 | # SQL Server files
165 | App_Data/*.mdf
166 | App_Data/*.ldf
167 |
168 | #############
169 | ## Windows detritus
170 | #############
171 |
172 | # Windows image file caches
173 | Thumbs.db
174 | ehthumbs.db
175 |
176 | # Folder config file
177 | Desktop.ini
178 |
179 | # Recycle Bin used on file shares
180 | $RECYCLE.BIN/
181 |
182 | # Mac crap
183 | .DS_Store
184 |
185 |
186 | #############
187 | ## Python
188 | #############
189 |
190 | *.py[co]
191 |
192 | # Packages
193 | *.egg
194 | *.egg-info
195 | dist/
196 | build/
197 | eggs/
198 | parts/
199 | var/
200 | sdist/
201 | develop-eggs/
202 | .installed.cfg
203 |
204 | # Installer logs
205 | pip-log.txt
206 |
207 | # Unit test / coverage reports
208 | .coverage
209 | .tox
210 |
211 | #Translations
212 | *.mo
213 |
214 | #Mr Developer
215 | .mr.developer.cfg
216 |
--------------------------------------------------------------------------------
/CellLifeGame1/StateRule.cs:
--------------------------------------------------------------------------------
1 | //Begin file StateRule.cs
2 | using System;
3 | using System.Collections;
4 | using System.ComponentModel;
5 | using System.Drawing;
6 | using System.Data;
7 | using System.Windows.Forms;
8 |
9 | namespace CellLifeGame1
10 | {
11 | ///
12 | /// A case in a set of rules with a checkbox for the user to
13 | /// specify whether the result in that case is dead or alive.
14 | ///
15 | public class StateRule : System.Windows.Forms.UserControl
16 | {
17 | internal System.Windows.Forms.CheckBox result;
18 |
19 | private System.Windows.Forms.Label lblNeighborsAlive;
20 | private System.Windows.Forms.Label lblCenterAlive;
21 | ///
22 | /// Required designer variable.
23 | ///
24 | private System.ComponentModel.Container components = null;
25 |
26 | public readonly int NeighborsAlive;
27 | public readonly bool CenterIsAlive;
28 | public readonly bool IsOuter;
29 | //public readonly double ActivationValue;
30 |
31 | public StateRule(int neighborsCnt, bool isOuter, bool centerIsAlive)
32 | {
33 | // This call is required by the Windows.Forms Form Designer.
34 | InitializeComponent();
35 |
36 | this.NeighborsAlive = neighborsCnt;
37 | this.CenterIsAlive = centerIsAlive;
38 | this.IsOuter = isOuter;
39 |
40 | lblNeighborsAlive.Text += neighborsCnt;
41 |
42 | if(isOuter == false)
43 | {
44 | lblCenterAlive.Visible = false;
45 | }
46 | else
47 | {
48 | if(centerIsAlive == true)
49 | {
50 | lblCenterAlive.Text += "Yes";
51 | }
52 | else
53 | {
54 | lblCenterAlive.Text += "No";
55 | }
56 | }
57 | }
58 |
59 | public bool ResultIsAlive
60 | {
61 | get
62 | {
63 | return result.Checked;
64 | }
65 | set
66 | {
67 | result.Checked = value;
68 | }
69 | }
70 |
71 | ///
72 | /// Clean up any resources being used.
73 | ///
74 | protected override void Dispose( bool disposing )
75 | {
76 | if( disposing )
77 | {
78 | if(components != null)
79 | {
80 | components.Dispose();
81 | }
82 | }
83 | base.Dispose( disposing );
84 | }
85 |
86 | #region Component Designer generated code
87 | ///
88 | /// Required method for Designer support - do not modify
89 | /// the contents of this method with the code editor.
90 | ///
91 | private void InitializeComponent()
92 | {
93 | this.result = new System.Windows.Forms.CheckBox();
94 | this.lblNeighborsAlive = new System.Windows.Forms.Label();
95 | this.lblCenterAlive = new System.Windows.Forms.Label();
96 | this.SuspendLayout();
97 | //
98 | // result
99 | //
100 | this.result.CheckAlign =
101 | System.Drawing.ContentAlignment.MiddleRight;
102 | this.result.Location = new System.Drawing.Point(256, 8);
103 | this.result.Name = "result";
104 | this.result.Size = new System.Drawing.Size(104, 16);
105 | this.result.TabIndex = 0;
106 | this.result.Text = "Results in life?";
107 | this.result.TextAlign =
108 | System.Drawing.ContentAlignment.MiddleRight;
109 | //
110 | // lblNeighborsAlive
111 | //
112 | this.lblNeighborsAlive.Location = new System.Drawing.Point(8, 8);
113 | this.lblNeighborsAlive.Name = "lblNeighborsAlive";
114 | this.lblNeighborsAlive.Size = new System.Drawing.Size(128, 16);
115 | this.lblNeighborsAlive.TabIndex = 1;
116 | this.lblNeighborsAlive.Text = "Neighbors alive: ";
117 | //
118 | // lblCenterAlive
119 | //
120 | this.lblCenterAlive.Location = new System.Drawing.Point(144, 8);
121 | this.lblCenterAlive.Name = "lblCenterAlive";
122 | this.lblCenterAlive.Size = new System.Drawing.Size(112, 16);
123 | this.lblCenterAlive.TabIndex = 0;
124 | this.lblCenterAlive.Text = "Center is alive? ";
125 | //
126 | // StateRule
127 | //
128 | this.Controls.Add(this.lblCenterAlive);
129 | this.Controls.Add(this.lblNeighborsAlive);
130 | this.Controls.Add(this.result);
131 | this.Name = "StateRule";
132 | this.Size = new System.Drawing.Size(368, 32);
133 | this.ResumeLayout(false);
134 |
135 | }
136 | #endregion
137 | }
138 | }
139 | //End file StateRule.cs
--------------------------------------------------------------------------------
/Command/Command.csproj:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
25 |
45 |
65 |
66 |
67 |
72 |
77 |
82 |
83 |
84 |
85 |
86 |
91 |
96 |
97 |
98 |
99 |
100 |
101 |
--------------------------------------------------------------------------------
/Recording/Recording.csproj:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
25 |
45 |
65 |
66 |
67 |
72 |
77 |
82 |
83 |
84 |
85 |
86 |
91 |
96 |
97 |
98 |
99 |
100 |
101 |
--------------------------------------------------------------------------------
/ThreadSafe/ThreadSafe.csproj:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
25 |
45 |
65 |
66 |
67 |
72 |
77 |
82 |
83 |
84 |
85 |
86 |
91 |
96 |
97 |
98 |
99 |
100 |
101 |
--------------------------------------------------------------------------------
/ClassLibrary1/ClassLibrary1.csproj:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
25 |
45 |
65 |
66 |
67 |
72 |
77 |
82 |
83 |
84 |
85 |
86 |
91 |
96 |
97 |
98 |
99 |
100 |
101 |
--------------------------------------------------------------------------------
/NNModel/NNModel.csproj:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
25 |
45 |
65 |
66 |
67 |
72 |
77 |
82 |
83 |
84 |
85 |
86 |
91 |
96 |
101 |
106 |
107 |
108 |
109 |
110 |
111 |
--------------------------------------------------------------------------------
/Recording/Recording.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace Recording
4 | {
5 | ///
6 | /// Summary description for Class1.
7 | ///
8 | public interface IRecordable
9 | {
10 |
11 | }
12 |
13 | public class Record
14 | {
15 | public Record()
16 | {
17 | //
18 | // TODO: Add constructor logic here
19 | //
20 | }
21 |
22 | ///
23 | /// Winds the record time forwards by timespan(or backwards if timespan is negative).
24 | ///
25 | ///
26 | ///
27 | public object WindForwards( TimeSpan timeSpan);
28 |
29 | ///
30 | /// Winds the record time backwards by timespan(or forwards if timespan is positive).
31 | ///
32 | /// Example:
33 | ///
34 | public object WindBackwards( TimeSpan timeSpan);
35 |
36 | public object WindForwards( TimeSpan timeSpan, object external);
37 |
38 | public object WindBackwards( TimeSpan timeSpan, object external);
39 |
40 | public object GetState( object external );//RETURN the state of the internal copy that correlates with the external object
41 |
42 | public object Do();//undoes the most recent undo
43 |
44 | public object Undo();//undoes the most recently performed action(s), performed either by a call to any of the Do methods or an action performed on an object by the client
45 |
46 | public object Do( object external );//steps an internal object forward by one action, returns a copy of internal
47 |
48 | public object Undo( object external );//steps an internal object backwards by one action, returns a copy of internal
49 |
50 | //Todo: add do and undo that operate on a collection of items
51 |
52 | public object DoAll();//steps all internal objects by one action
53 | //Todo: Return should be void or maybe some type of colletion
54 |
55 | public object UndoAll();//steps all internal objects backwards by one action
56 | //Todo: Return should be void or maybe some type of collection
57 |
58 | //+= operator
59 | //GetState and add object "+=" could be implemented with the indexer operator if appropriate.
60 |
61 |
62 |
63 | }
64 | }
65 |
66 |
67 | /*
68 | *
69 | * Usability Goals:
70 | *1.Allow the client to declare an object that will maintain a record of the changes of the state of a set of objects:
71 | * Record aRecord = new Record( ***TBD*** );
72 | *
73 | *2.Allow the client to add objects to the record and have their state tracked from the point they were added forward until a point where they are removed:
74 | * objectType anObject = new objectType();
75 | * myRecord += anObject;//add object to Record to be recorded, a snapshot of it's current state is copied into the record and the object referenced is marked to be watched for changes
76 | * anObject.DoSomething(someParams);//this call will be added to the entry in myRecord for the object referenced by anObject
77 | * Implementation Issues:
78 | * a. A member call that involves outparams may be difficult to record.
79 | *
80 | *3.Allow recording to be stopped for an object:
81 | * myRecord -= anObject;
82 | *
83 | *4.Allow the client to go back to a point in a records timeline by rewinding, and later set the record at current time again.
84 | *
85 | * Design Issues:
86 | * a. Two options:
87 | * I. Set the state of the client's objects to the past state.
88 | * Pro:Memory saved because we don't keep a copy of the objects in the record.
89 | * Con:Any instability or bug in our class or the client's implementation of IRecordable could corrupt the client object's state.
90 | * II.Set the state of a copy of the object to the past state and allow the client access to the past objects.
91 | * Pro:Avoid corruption of client data.
92 | * Con:The client object's state is not updated which the client may desire so that they can rewind the state of their application.
93 | * The second option better because a client can use a Record for not-critical purposes and not worry about data corruption. It also allows them to only stub out IRecordable implementations and put off full implementation if their application is not dependent on the Record, thus allowing easier incremental development. The con of the second option may be avoidable, and will be addressed if a viable implementation is found. The phrases internal object(s) and external object(s) refer respectively to the copy object internal to the Record and the external object of the client.
94 | *
95 | *
96 | *
97 | *
98 | *
99 | *
100 | *
101 | *
102 | *
103 | *
104 | * */
--------------------------------------------------------------------------------
/CellLifeGame1/CellLifeGame1.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Local
5 | 8.0.50727
6 | 2.0
7 | {F2D678D5-E7D3-483A-90B3-A2A4019098DA}
8 | Debug
9 | AnyCPU
10 | App.ico
11 |
12 |
13 | CellLifeGame1
14 |
15 |
16 | JScript
17 | Grid
18 | IE50
19 | false
20 | Exe
21 | CellLifeGame1
22 | OnBuildSuccess
23 |
24 |
25 |
26 |
27 |
28 |
29 | v2.0
30 | 2.0
31 |
32 |
33 | bin\Debug\
34 | false
35 | 285212672
36 | false
37 |
38 |
39 | DEBUG;TRACE
40 |
41 |
42 | true
43 | 4096
44 | false
45 |
46 |
47 | false
48 | false
49 | false
50 | false
51 | 4
52 | full
53 | prompt
54 |
55 |
56 | bin\Release\
57 | false
58 | 285212672
59 | false
60 |
61 |
62 | TRACE
63 |
64 |
65 | false
66 | 4096
67 | false
68 |
69 |
70 | true
71 | false
72 | false
73 | false
74 | 4
75 | none
76 | prompt
77 |
78 |
79 |
80 | System
81 |
82 |
83 | System.Data
84 |
85 |
86 | System.Drawing
87 |
88 |
89 | System.Windows.Forms
90 |
91 |
92 | System.XML
93 |
94 |
95 |
96 |
97 |
98 | Code
99 |
100 |
101 | Code
102 |
103 |
104 |
105 |
106 |
107 |
108 | UserControl
109 |
110 |
111 | Form
112 |
113 |
114 | Form
115 |
116 |
117 | StateRule.cs
118 |
119 |
120 | StatesOutput.cs
121 |
122 |
123 | UIForm.cs
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
--------------------------------------------------------------------------------
/CellLifeGame1/StateRule.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 | text/microsoft-resx
90 |
91 |
92 | 1.3
93 |
94 |
95 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
96 |
97 |
98 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
99 |
100 |
101 | False
102 |
103 |
104 | Private
105 |
106 |
107 | Private
108 |
109 |
110 | False
111 |
112 |
113 | Private
114 |
115 |
116 | Private
117 |
118 |
119 | False
120 |
121 |
122 | Private
123 |
124 |
125 | Private
126 |
127 |
128 | False
129 |
130 |
131 | False
132 |
133 |
134 | True
135 |
136 |
137 | True
138 |
139 |
140 | 80
141 |
142 |
143 | (Default)
144 |
145 |
146 | False
147 |
148 |
149 | StateRule
150 |
151 |
152 | Private
153 |
154 |
155 | 8, 8
156 |
157 |
--------------------------------------------------------------------------------
/CellLifeGame1/StatesOutput.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 | text/microsoft-resx
90 |
91 |
92 | 1.3
93 |
94 |
95 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
96 |
97 |
98 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
99 |
100 |
101 | False
102 |
103 |
104 | True
105 |
106 |
107 | Private
108 |
109 |
110 | 8, 8
111 |
112 |
113 | True
114 |
115 |
116 | Private
117 |
118 |
119 | False
120 |
121 |
122 | Private
123 |
124 |
125 | Private
126 |
127 |
128 | False
129 |
130 |
131 | Private
132 |
133 |
134 | Private
135 |
136 |
137 | False
138 |
139 |
140 | Private
141 |
142 |
143 | Private
144 |
145 |
146 | Private
147 |
148 |
149 | False
150 |
151 |
152 | Private
153 |
154 |
155 | Private
156 |
157 |
158 | False
159 |
160 |
161 | Private
162 |
163 |
164 | False
165 |
166 |
167 | True
168 |
169 |
170 | Private
171 |
172 |
173 | 8, 8
174 |
175 |
176 | True
177 |
178 |
179 | Private
180 |
181 |
182 | False
183 |
184 |
185 | Private
186 |
187 |
188 | Private
189 |
190 |
191 | Private
192 |
193 |
194 | False
195 |
196 |
197 | Private
198 |
199 |
200 | False
201 |
202 |
203 | StatesOutput
204 |
205 |
206 | (Default)
207 |
208 |
209 | False
210 |
211 |
212 | False
213 |
214 |
215 | 8, 8
216 |
217 |
218 | True
219 |
220 |
221 | 80
222 |
223 |
224 | True
225 |
226 |
227 | Private
228 |
229 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | Source: See Github "Download Zip" link on the right.
2 |
3 | Program(already compiled EXE): https://github.com/AaronLS/CellularAutomataAsNeuralNetwork/releases
4 |
5 | CellularAutomataAsNeuralNetwork
6 | ===============================
7 | This was the project I wrote while learning C# for the first time, many years ago, and I also wrote an undergraduate thesis on the mathematics of converting outer totalistic cellular automata into a neural network. It is pretty common to convert one computational system into another, for various reasons(perhaps the tools you have at hand are better at processing the second computational system), therefore it is potentially useful to know how to convert one system to another. Whether this particular conversion has practical applications is unknown to me. One possible application would be if you had a system that you were able to model satisfactorily with a cellular automata, but wanted to use a specialized neural network chip(a chip specialized for processing neural networks which would perform many times faster than a conventional chip at the same task) or perhaps in the future a similar memristor chip. This is pure speculation on my part, as the firing function my neural network uses is not a simple threshold. It has several thresholds firing zones. For Conway's Game of Life, the firing threshold is between .28 and .4, so the input neuron connections must be within that range, as opposed to a more traditional firing theshold of just bein grater than an amount. More complex cellular automata that you design with my program might have several zones.
8 |
9 | Runs John Conway's Game of Life or any other outer totalistic cellular automata you define, but internally cells states are represented as neuron firing states, and rules are converted to neuron waits and firing function thresholds.
10 |
11 | Disclaimer
12 | ==========
13 | This application was originally written against .NET 1.1, and therefore by today's standards might be considered poorly written, as there is a good bit of non-generic collections which aren't typesafe(I actually had an internal conflict about this, as I was remotely familiar with Java which at the time DID have generics, and I was frustrated by the lack in C#). It was also my very first C# application, and I am posting only because it 1) Is pretty fun to play with and make your own cellular automata 2) I spent alot of time optimizing it so it would run with exceptable performance 3) Many people who have seen it in action have asked for the source code.
14 |
15 | Additionally, modelling neural networks varies by a great degree in terms of both artificial vs natural modelling, as well as simplistic to complex/accurate modelling. Natural neurons usually do not have quite so distinct states as firing and not firing, My usage of the term neural network refers as at the simplistic artificial end of the spectrum.
16 |
17 | If you flame me for coding style or architecture, I will point you to this disclaimer and you must admit you are an idiot for basically flaming someone for something that any sane person would expect to have mistakes(given that it was my first C# application and also written before many of today's C# language constructs existed).
18 |
19 | Known Bug
20 | =========
21 | The process often remains open when the window is closed. I never bothered to fix this as I wasn't planning to release to the public, and it is easy enough to Ctrl+Shift+Esc and close the process.
22 |
23 | Architecture
24 | ============
25 | Platform: Windows 32bit/x86
26 | UI: Windows Forms
27 | IDE: Visual Studio, current *sln file opens in VS 2012 Express for Desktop or VS 2012 Standard or greater. I created the project originally under VS 2003 with .NET 1.1, so there is no reason you shouldn't be able to make a older sln and csproj files for an older VS.
28 | Language: C#
29 | Framework: Code is compatible with Microsoft .NET 1.1, in the current solution I have tested against both 2.0 and 4.5
30 |
31 | The main challenge was getting all those squares to update each time step in a smoothly and quickly. This was initially painfully slow on computer hardware 10 years ago. This simple architecture resolved this issue.
32 |
33 | A background thread(Modelling.cs) models the neural network and adds updates to a queue, while the UI(UIForm.cs) thread consumes that queue and displays the updates via double buffered GDI. Even though I had a single core processor at the time you might think multithreading would convey no benefits, but updating a UI thread from a background thread usually requires marshaling the calls, which degrades performance. Additionally, if this application were single threaded, the UI would often freeze while the neural network was updating(this can be mitigated in a *hackish* way by judicial use of DoWork). However, using a queue to communicate updates from one thread to another avoids making marshaled UI thread calls and allows the UI to remain responsive while the other thread performs neural network modelling.
34 |
35 | Both neural networks(see disclaimer on terminology) and simple cellular automata operate in 2 distinct state of alive/firing and dead/not-firing. Both also consist of many identical units, neurons and cells, which all operate simultaneously. Since a 64x64 grid of cells consists of over 4000 cells, we cannot have simultaneous execution of all 4000 cells without a 4000 core processor. In the absence of such a processor, we must simulate this simultaneous execution by maintaining two models of the system: the current time step, and the next time step(or previous and current depending on how you look at it). The current time step has the states of all 4000 cells, whether they are alive or dead. As we calculate the state of the cell in the next time step, we must use the states of neighbors in the current time step, but update the state of the cell only in the next time step. Otherwise, if we didn't have a next and current, imagine if
36 | -We must go cell by cell to update the states of all cells from timestep 1 to timestep 2.
37 | -Cell A in time step 1 is alive, but in timestep 2 we calculate that it is dead based on inputs from neighboring cells, and update its state.
38 | -Cell B in time step 1 is dead, and based on the inputs of its neighbors, we calculate its state in timestep 2. The states we use from its neighbors should all be their states in timestep 1, however, we already updated Cell A, and therefore are using an invalid future state for the calculation.
39 | Thus you see why it is so important to "buffer" these changes until you have processed all cells, then swap the next time step with the current.
40 |
41 | There are some thread synchronization techniques demonstrated in this project. Most of them I learned from reading articles at the time, so hopefully they are not poor examples. However, I will say in my many years of programming, while I have used background threads, I have usually designed my applications to avoid any need for this kind of low level thread synchronization *because it is painful, tedious, and error prone to write*. I generally avoid writing low level thread sync code by instead using constructs of background threads of the .NET framework and events like ProgressChanged/RunWorkercompleted, or the new async/await constructs added to C#. I'm not saying low level thread sync' is obsolete, but many common scenarios are more easily implemented using other techniques. Low level thread synchronization is probably still applicable where your needs don't fit one of those scenarios, and you feel you could *significantly improve performance*. This implies your that there is both a large potential performance gain to be had, *and* your skills make you capable of realizing those gains without also introducing thread safety bugs. For example, this application has a bug that causes the process to often remain open when the window is closed, which I suspect is related to the background thread.
42 |
43 | Binary serialization is demonstrated, showing how to save the state of the cells and rules to a file, and then later load that file to restore those cells/rules. It is generally a better practice to use some other serialization such as XML or JSON(my personal favorite) which is human readable. The reason this is favored over binary is because it allows others look at the file and easily see its structure, and thus create programs to read these files and modify them in an automated way, or even manually edit them in a text editor. Perhaps you wanted to make a HTML5 or java applet that can load rules created in my application, and display the cellular automata in a browser. If the file is in a human readable format, it makes it much easier for you to determine its structure and thus write code to load it. Additionally most other languages have libraries that support JSON and XML. A binary format, while not impossible to figure out, would be much more time consuming and error prone to reverse engineer. However, binary formats load/save generally faster and take up less space, but some of today's JSON processors are very fast and the performance benefits of binary are becoming negligible.
44 |
45 | Usage
46 | =====
47 | Once you have compiled and run the program:
48 | Left click a blue square to turn it red. Right click to turn it back blue. Both left/right click support dragging to draw cells. Note that this is somewhat imperfect, and fast drags will miss cells, since it does not interpolate skipped cells(i.e. when you drag very quickly Windows does not trigger the event on some cells, and you would need to write code to calculate a line between previous cell to know which cells inbetween to update).
49 |
50 | **Start**: Begins stepping the neural network/cellular automata at a rate controlled by the slider on the left. Slider: Moving the slider all the way down attempts to process one step per millisecond, but it is unlikely to run quite that fast even on newer hardware(there are 4000 neurons and over 30000 neuron connections to process each timestep).
51 |
52 | **Stop**: Pauses processing until you click Start again.
53 |
54 | **Step**: Steps forward a number of steps in the box on the right. Since the UI is not updated during this processing, it allows faster processing to occur over a large number of steps. Or if you are wanting to study how a cellular automata progresses step by step, allows you to control stepping one step at a time.
55 |
56 | **Clear**: Clears the cells setting them to dead/not-firing, but leaves existing rules in place.
57 |
58 | **Save**: Saves the existing cell states and rules to a file.
59 |
60 | **Load**: Load a previously saved file.
61 |
62 | **New**: Clears current rules and allows you to define a new outer totalistic cellular automata.
63 |
64 | -Totalistic Automata basically have rules that are based on a count of the number of neighboring cells that are in a certain state. My program only supports 2 states: alive and dead("asleep" if you want to keep it G rated).
65 |
66 | -After clicking new, you will be in a totally different mode(although the UI does not change much to indicate this), presented with a single white square, and red squares define the *relative* position of neighbors. This allows you to define the neighborhood, where cells are counted for rules. For example, the Game of Life only counts the immediate neighbors of each cell, including those diagonal, so initially you will see that 8 red squares around the white square are selected, as this is the default for the Game of Life. You could define your own cellular automata that includes the next outer layer of neighbors by left clicking those blue squares to turn them red. (Tip: for some really odd behavior, try a lopsided/assymetric neighborhood).
67 |
68 | **Current**: Same as New, except it keeps existing neighborhood and rule definitions, instead of clearing them and resetting to the Game of Life definition.
69 |
70 | **Done**: Click this after you finish defining your neighborhood. You will then be asked one or two questions about your automata.
71 |
72 | -"Is your automata Outer Totalistic?" is asking whether you want seperate distinct rules based on whether the current cell(center) is alive. (I'm not sure my use of the term Outer Totalistic in this way is completely accurate). For the Game of Life you would choose Yes, as you need to be able to make the distinction that when 2 neighbors are alive, nothing changes, thus you need two different rules (If center is alive & two neighbors are alive, then result is alive) (If center is dead & two neighbors are alive, then result is dead). If you choose No to this question, then whether the center is alive or not is not a distinct condition, in other words the rule can be no more complicated than (If 2 neighboring cells are alive, then the cell is dead.) which doesn't provide enough complexity to model Conway's Game of Life.
73 |
74 | -"Is the center cell part of the neighborhood?" is asked only if you choose No to the above question, and is essentially asking if when counting up the total number of alive cells in the neighborhood, if the current center cell should contribute to that count.
75 |
76 | -You are then presented with a dialog that lists all the possible scenarios for a cell in your automata. For each, you select the checkbox on the right if that scenario should result in life for the cell. So checking the box next to "Neighbors alive: 3" indicates that if a cell has 3 cells in its neighborhood which are alive, then it to should be alive in the next time step(perhaps it was already alive, and hence the rule ensures it remains alive, or it was dead and will become alive in the next time step).
77 |
78 | -The three disabled box at the top simply show you the properties of the neural network that will be generated based on your selected rules.
79 |
80 | -"Neighbor Link Weight": The link weights between neighboring neurons in the generated neural network(neighboring being defined by the neighborhood you defined previously)
81 |
82 | -"Center Link Weight": If greater than 0, indicates that eveery neuron will have a link to itself, i.e. if it is in a firing state, then in the next time step it will contribute that much to it's own input signal.
83 |
84 | -"Activation Values": When calculating the next time step, all input signals must add to one of these amounts for the current neuron to fire.
85 |
86 | The magic of cellular automata is in the way that you get a system that appears to be relatively complex, from fairly simple rules. I liken this to the complexity of an ant colony, despite the relative simplicity of the individual ants(although in defense of the ant, it does have 250,000 neurons).
87 |
88 |
89 |
--------------------------------------------------------------------------------
/CellLifeGame1/UIForm.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 | text/microsoft-resx
90 |
91 |
92 | 1.3
93 |
94 |
95 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
96 |
97 |
98 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
99 |
100 |
101 | 8, 8
102 |
103 |
104 | True
105 |
106 |
107 | False
108 |
109 |
110 | Private
111 |
112 |
113 | True
114 |
115 |
116 | Private
117 |
118 |
119 | False
120 |
121 |
122 | Private
123 |
124 |
125 | Private
126 |
127 |
128 | False
129 |
130 |
131 | Private
132 |
133 |
134 | Private
135 |
136 |
137 | False
138 |
139 |
140 | Private
141 |
142 |
143 | Private
144 |
145 |
146 | False
147 |
148 |
149 | Private
150 |
151 |
152 | Private
153 |
154 |
155 | False
156 |
157 |
158 | Private
159 |
160 |
161 | Private
162 |
163 |
164 | False
165 |
166 |
167 | Private
168 |
169 |
170 | Private
171 |
172 |
173 | False
174 |
175 |
176 | Private
177 |
178 |
179 | Private
180 |
181 |
182 | False
183 |
184 |
185 | Private
186 |
187 |
188 | Private
189 |
190 |
191 | False
192 |
193 |
194 | Private
195 |
196 |
197 | Private
198 |
199 |
200 | False
201 |
202 |
203 | Private
204 |
205 |
206 | Private
207 |
208 |
209 | Private
210 |
211 |
212 | 4, 4
213 |
214 |
215 | True
216 |
217 |
218 | False
219 |
220 |
221 | True
222 |
223 |
224 | Private
225 |
226 |
227 | False
228 |
229 |
230 | (Default)
231 |
232 |
233 | False
234 |
235 |
236 | False
237 |
238 |
239 | 8, 8
240 |
241 |
242 | True
243 |
244 |
245 | 80
246 |
247 |
248 | True
249 |
250 |
251 | UIForm
252 |
253 |
254 | Private
255 |
256 |
--------------------------------------------------------------------------------
/CellLifeGame1/StatesOutput.cs:
--------------------------------------------------------------------------------
1 | //Begin file StatesOutput.cs
2 | using System;
3 | using System.Drawing;
4 | using System.Collections;
5 | using System.ComponentModel;
6 | using System.Windows.Forms;
7 |
8 | namespace CellLifeGame1
9 | {
10 | ///
11 | /// Summary description for StatesOutput.
12 | ///
13 |
14 | public class StatesOutput : System.Windows.Forms.Form
15 | {
16 | private ArrayList stateRules;
17 | double neighborWeight;
18 | double centerWeight;
19 | private System.Windows.Forms.Panel panel1;
20 | private System.Windows.Forms.Button btnDone;
21 | ///
22 | /// Required designer variable.
23 | ///
24 | private System.ComponentModel.Container components = null;
25 | private System.Windows.Forms.Label labelNWeight;
26 | private System.Windows.Forms.Label labelCWeight;
27 | private System.Windows.Forms.TextBox textNWeight;
28 | private System.Windows.Forms.TextBox textCWeight;
29 | private System.Windows.Forms.Panel pnlActivationVals;
30 | private System.Windows.Forms.Label lblActivationValues;
31 | private System.Windows.Forms.TextBox textActivationValues;
32 |
33 | private ArrayList activationValues;
34 |
35 | public ArrayList ActivationValues
36 | {
37 | get
38 | {
39 | return activationValues;
40 | }
41 | }
42 |
43 | public double NeighborWeight
44 | {
45 | get
46 | {
47 | return neighborWeight;
48 | }
49 | set
50 | {
51 | neighborWeight = value;
52 | textNWeight.Text = value.ToString();
53 | }
54 | }
55 | public double CenterWeight
56 | {
57 | get
58 | {
59 | return centerWeight;
60 | }
61 | set
62 | {
63 | centerWeight = value;
64 | textCWeight.Text = value.ToString();
65 | }
66 | }
67 |
68 | public StatesOutput(int neighborhoodSize,
69 | double nWeight, double cWeight, ArrayList activationValues)
70 | {
71 | this.activationValues = activationValues;
72 |
73 | Console.WriteLine(
74 | "neighborhoodsize in StatesOutput constructor: {0}",
75 | neighborhoodSize);
76 |
77 | //
78 | // Required for Windows Form Designer support
79 | //
80 | InitializeComponent();
81 |
82 | stateRules = new ArrayList();
83 |
84 | NeighborWeight = nWeight;
85 | CenterWeight = cWeight;
86 |
87 | bool isOuter = false;
88 | if(cWeight == .04D)
89 | {
90 | isOuter = true;
91 | }
92 |
93 | for(int i=0; i<=neighborhoodSize; ++i)
94 | {
95 | StateRule stateRule = new StateRule(i,isOuter,false);
96 | stateRules.Add(stateRule);
97 |
98 | foreach(double actVal in activationValues)
99 | {
100 | if(
101 | Math.Abs(actVal - ( ((double)i) * this.NeighborWeight ))
102 | <= (0.0001D))
103 | {
104 | stateRule.ResultIsAlive = true;
105 | }
106 | }
107 |
108 | if(Math.Abs(CenterWeight - .04D ) <= (0.0001D))
109 | {
110 | stateRule = new StateRule(i,isOuter,true);
111 | stateRules.Add(stateRule);
112 |
113 | foreach(double actVal in activationValues)
114 | {
115 | double linksSummation =
116 | ((double)i) * this.NeighborWeight + this.CenterWeight;
117 |
118 | if( Math.Abs(actVal - linksSummation ) <= (0.00001D))
119 | {
120 | stateRule.ResultIsAlive = true;
121 | }
122 | }
123 | }
124 | Console.WriteLine("i in States add is {0}",i);
125 | Console.WriteLine(
126 | "neighborhoodsize in States add: {0}",neighborhoodSize);
127 | }
128 |
129 | this.SuspendLayout();
130 |
131 | int j=0;
132 | foreach(StateRule stateRule in stateRules)
133 | {
134 | Console.WriteLine("j in States attributes is {0}",j);
135 | stateRule.Location = new System.Drawing.Point(0, 32*j);
136 | stateRule.Name = "stateRule" + 1;
137 | //stateRule.Size = new System.Drawing.Size(400, 32);
138 | stateRule.TabIndex = j;
139 | panel1.Controls.Add(stateRule);
140 | stateRule.result.CheckedChanged +=
141 | new EventHandler(outputChange);
142 | ++j;
143 | }
144 |
145 | int calculatedHeight =
146 | ((StateRule)stateRules[1]).Size.Height*
147 | (neighborhoodSize+1)*
148 | (isOuter?2:1);
149 |
150 | if(calculatedHeight < 600)
151 | {
152 | panel1.Size = new Size(416, calculatedHeight);
153 | }
154 | else
155 | {
156 | panel1.Size = new Size(416, 600);
157 | }
158 |
159 | this.ClientSize = new System.Drawing.Size(
160 | panel1.Size.Width + panel1.Location.X*2,
161 | panel1.Size.Height + panel1.Location.Y);
162 |
163 | this.ResumeLayout(false);
164 | }
165 |
166 |
167 | public StatesOutput(int neighborhoodSize)
168 | {
169 |
170 | Console.WriteLine(
171 | "neighborhoodsize in StatesOutput constructor: {0}"
172 | ,neighborhoodSize);
173 | //
174 | // Required for Windows Form Designer support
175 | //
176 | InitializeComponent();
177 |
178 | stateRules = new ArrayList();
179 |
180 | // Initializes the variables to pass to the MessageBox.Show method.
181 | string message = "Is your automaton Outer Totalistic?";
182 | string caption = "Outer";
183 | MessageBoxButtons buttons = MessageBoxButtons.YesNo;
184 | DialogResult outerResult;
185 |
186 | // Displays the MessageBox.
187 | outerResult = MessageBox.Show(this, message, caption, buttons,
188 | MessageBoxIcon.Question, MessageBoxDefaultButton.Button1);
189 |
190 | bool isOuter;
191 | DialogResult centerResult;
192 |
193 | if(outerResult == DialogResult.Yes)
194 | {
195 | isOuter = true;
196 | CenterWeight = .04D;
197 | }
198 | else
199 | {
200 | isOuter = false;
201 | message = "Is the center cell part of the neighborhood?";
202 | caption = "Center Cell";
203 |
204 | centerResult = MessageBox.Show(this, message, caption, buttons,
205 | MessageBoxIcon.Question, MessageBoxDefaultButton.Button1);
206 |
207 | if(centerResult == DialogResult.Yes)
208 | {
209 | CenterWeight = .12D;
210 | neighborhoodSize += 1;
211 | }
212 | else
213 | {
214 | CenterWeight = .0D;
215 | }
216 | }
217 |
218 | NeighborWeight = .12D;
219 |
220 | for(int i=0; i<=neighborhoodSize; ++i)
221 | {
222 | stateRules.Add(new StateRule(i,isOuter,false));
223 | if(isOuter)
224 | {
225 | stateRules.Add(new StateRule(i,isOuter,true));
226 | }
227 | Console.WriteLine("i in States add is {0}",i);
228 | Console.WriteLine("neighborhoodsize in States add: {0}",
229 | neighborhoodSize);
230 | }
231 |
232 | this.SuspendLayout();
233 |
234 | int j=0;
235 | foreach(StateRule stateRule in stateRules)
236 | {
237 | Console.WriteLine("j in States attributes is {0}",j);
238 | stateRule.Location = new System.Drawing.Point(0, 32*j);
239 | stateRule.Name = "stateRule" + 1;
240 | //stateRule.Size = new System.Drawing.Size(400, 32);
241 | stateRule.TabIndex = j;
242 | panel1.Controls.Add(stateRule);
243 | stateRule.result.CheckedChanged +=
244 | new EventHandler(outputChange);
245 | ++j;
246 | }
247 |
248 | int calculatedHeight =
249 | ((StateRule)stateRules[1]).Size.Height*
250 | (neighborhoodSize+1)*
251 | (isOuter?2:1);
252 |
253 | if(calculatedHeight < 600)
254 | {
255 | panel1.Size = new Size(416, calculatedHeight);
256 | }
257 | else
258 | {
259 | panel1.Size = new Size(416, 600);
260 | }
261 |
262 | this.ClientSize = new System.Drawing.Size(
263 | panel1.Size.Width + panel1.Location.X*2,
264 | panel1.Size.Height + panel1.Location.Y);
265 |
266 | this.ResumeLayout(false);
267 | }
268 |
269 | public StatesOutput()
270 | {
271 | int neighborhoodSize = 8;
272 |
273 | Console.WriteLine(
274 | "neighborhoodsize in StatesOutput constructor: {0}",
275 | neighborhoodSize);
276 | //
277 | // Required for Windows Form Designer support
278 | //
279 | InitializeComponent();
280 |
281 | stateRules = new ArrayList();
282 |
283 | bool isOuter = true;
284 |
285 | for(int i=0; i<=neighborhoodSize; ++i)
286 | {
287 | StateRule stateRule = new StateRule(i,isOuter,false);
288 |
289 | if(i == 3)
290 | {
291 | stateRule.ResultIsAlive = true;
292 | }
293 |
294 | stateRules.Add(stateRule);
295 |
296 | if(isOuter)
297 | {
298 | stateRule = new StateRule(i,isOuter,true);
299 | if(i == 2 || i == 3)
300 | {
301 | stateRule.ResultIsAlive = true;
302 | }
303 | stateRules.Add(stateRule);
304 |
305 |
306 | }
307 | Console.WriteLine("i in States add is {0}",i);
308 | Console.WriteLine("neighborhoodsize in States add: {0}",
309 | neighborhoodSize);
310 | }
311 |
312 | if(isOuter)
313 | {
314 | CenterWeight = .04D;
315 | }
316 | else
317 | {
318 | CenterWeight = .0D;
319 | }
320 |
321 | NeighborWeight = .12D;
322 |
323 | this.SuspendLayout();
324 |
325 | int j=0;
326 |
327 | foreach(StateRule stateRule in stateRules)
328 | {
329 | Console.WriteLine("j in States attributes is {0}",j);
330 | stateRule.Location = new System.Drawing.Point(0, 32*j);
331 | stateRule.Name = "stateRule" + 1;
332 | stateRule.TabIndex = j;
333 | panel1.Controls.Add(stateRule);
334 |
335 | stateRule.result.CheckedChanged +=
336 | new EventHandler(outputChange);
337 |
338 | ++j;
339 | }
340 |
341 | int calculatedHeight =
342 | ((StateRule)stateRules[1]).Size.Height*
343 | (neighborhoodSize+1)*
344 | (isOuter?2:1);
345 |
346 | if(calculatedHeight < 600)
347 | {
348 | panel1.Size = new Size(416, calculatedHeight);
349 | }
350 | else
351 | {
352 | panel1.Size = new Size(416, 600);
353 | }
354 |
355 | this.ClientSize = new System.Drawing.Size(
356 | panel1.Size.Width + panel1.Location.X*2,
357 | panel1.Size.Height + panel1.Location.Y);
358 |
359 | this.ResumeLayout(false);
360 | }
361 |
362 | ///
363 | /// Clean up any resources being used.
364 | ///
365 | protected override void Dispose( bool disposing )
366 | {
367 | if( disposing )
368 | {
369 | if(components != null)
370 | {
371 | components.Dispose();
372 | }
373 | }
374 | base.Dispose( disposing );
375 | }
376 |
377 | #region Windows Form Designer generated code
378 | ///
379 | /// Required method for Designer support - do not modify
380 | /// the contents of this method with the code editor.
381 | ///
382 | private void InitializeComponent()
383 | {
384 | this.panel1 = new System.Windows.Forms.Panel();
385 | this.btnDone = new System.Windows.Forms.Button();
386 | this.labelNWeight = new System.Windows.Forms.Label();
387 | this.labelCWeight = new System.Windows.Forms.Label();
388 | this.textNWeight = new System.Windows.Forms.TextBox();
389 | this.textCWeight = new System.Windows.Forms.TextBox();
390 | this.pnlActivationVals = new System.Windows.Forms.Panel();
391 | this.lblActivationValues = new System.Windows.Forms.Label();
392 | this.textActivationValues = new System.Windows.Forms.TextBox();
393 | this.pnlActivationVals.SuspendLayout();
394 | this.SuspendLayout();
395 | //
396 | // panel1
397 | //
398 | this.panel1.AutoScroll = true;
399 | this.panel1.Location = new System.Drawing.Point(0, 64);
400 | this.panel1.Name = "panel1";
401 | this.panel1.Size = new System.Drawing.Size(448, 32);
402 | this.panel1.TabIndex = 0;
403 | //
404 | // btnDone
405 | //
406 | this.btnDone.Location = new System.Drawing.Point(8, 8);
407 | this.btnDone.Name = "btnDone";
408 | this.btnDone.Size = new System.Drawing.Size(56, 24);
409 | this.btnDone.TabIndex = 1;
410 | this.btnDone.Text = "Done";
411 | this.btnDone.Click += new System.EventHandler(this.btnDone_Click);
412 | //
413 | // labelNWeight
414 | //
415 | this.labelNWeight.Location = new System.Drawing.Point(72, 8);
416 | this.labelNWeight.Name = "labelNWeight";
417 | this.labelNWeight.Size = new System.Drawing.Size(120, 16);
418 | this.labelNWeight.TabIndex = 2;
419 | this.labelNWeight.Text = "Neighbor Link Weight: ";
420 | this.labelNWeight.TextAlign =
421 | System.Drawing.ContentAlignment.TopRight;
422 | //
423 | // labelCWeight
424 | //
425 | this.labelCWeight.Location = new System.Drawing.Point(264, 8);
426 | this.labelCWeight.Name = "labelCWeight";
427 | this.labelCWeight.Size = new System.Drawing.Size(108, 16);
428 | this.labelCWeight.TabIndex = 3;
429 | this.labelCWeight.Text = "Center Link Weight: ";
430 | this.labelCWeight.TextAlign =
431 | System.Drawing.ContentAlignment.TopRight;
432 | //
433 | // textNWeight
434 | //
435 | this.textNWeight.Location = new System.Drawing.Point(192, 8);
436 | this.textNWeight.Name = "textNWeight";
437 | this.textNWeight.ReadOnly = true;
438 | this.textNWeight.Size = new System.Drawing.Size(64, 20);
439 | this.textNWeight.TabIndex = 4;
440 | this.textNWeight.Text = "";
441 | //
442 | // textCWeight
443 | //
444 | this.textCWeight.Location = new System.Drawing.Point(376, 8);
445 | this.textCWeight.Name = "textCWeight";
446 | this.textCWeight.ReadOnly = true;
447 | this.textCWeight.Size = new System.Drawing.Size(64, 20);
448 | this.textCWeight.TabIndex = 5;
449 | this.textCWeight.Text = "";
450 | //
451 | // pnlActivationVals
452 | //
453 | this.pnlActivationVals.AutoScroll = true;
454 | this.pnlActivationVals.Controls.Add(this.textActivationValues);
455 | this.pnlActivationVals.Controls.Add(this.lblActivationValues);
456 | this.pnlActivationVals.Location = new System.Drawing.Point(0, 32);
457 | this.pnlActivationVals.Name = "pnlActivationVals";
458 | this.pnlActivationVals.Size = new System.Drawing.Size(448, 32);
459 | this.pnlActivationVals.TabIndex = 6;
460 | //
461 | // lblActivationValues
462 | //
463 | this.lblActivationValues.Location = new System.Drawing.Point(8, 8);
464 | this.lblActivationValues.Name = "lblActivationValues";
465 | this.lblActivationValues.Size = new System.Drawing.Size(96, 16);
466 | this.lblActivationValues.TabIndex = 0;
467 | this.lblActivationValues.Text = "Activation Values:";
468 | //
469 | // textActivationValues
470 | //
471 | this.textActivationValues.Location =
472 | new System.Drawing.Point(104, 8);
473 | this.textActivationValues.Name = "textActivationValues";
474 | this.textActivationValues.ReadOnly = true;
475 | this.textActivationValues.Size = new System.Drawing.Size(336, 20);
476 | this.textActivationValues.TabIndex = 1;
477 | this.textActivationValues.Text = "";
478 | //
479 | // StatesOutput
480 | //
481 | this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
482 | this.ClientSize = new System.Drawing.Size(448, 405);
483 | this.Controls.Add(this.pnlActivationVals);
484 | this.Controls.Add(this.textCWeight);
485 | this.Controls.Add(this.textNWeight);
486 | this.Controls.Add(this.labelCWeight);
487 | this.Controls.Add(this.labelNWeight);
488 | this.Controls.Add(this.btnDone);
489 | this.Controls.Add(this.panel1);
490 | this.Name = "StatesOutput";
491 | this.Text = "StatesOutput";
492 | this.Load += new System.EventHandler(this.load);
493 | this.pnlActivationVals.ResumeLayout(false);
494 | this.ResumeLayout(false);
495 |
496 | }
497 | #endregion
498 |
499 | private void btnDone_Click(object sender, System.EventArgs e)
500 | {
501 | activationValues = new ArrayList();
502 | foreach(StateRule stateRule in stateRules)
503 | {
504 | if(stateRule.ResultIsAlive)
505 | {
506 | activationValues.Add(
507 | ( ((double)stateRule.NeighborsAlive) *
508 | this.NeighborWeight ) +
509 | (stateRule.CenterIsAlive?this.CenterWeight:0.0D)
510 | );
511 | }
512 | }
513 | this.Close();
514 | }
515 |
516 | private void outputChange(object sender, System.EventArgs e)
517 | {
518 | textActivationValues.Text = "";
519 | foreach(StateRule stateRule in stateRules)
520 | {
521 | if(stateRule.ResultIsAlive)
522 | {
523 | double activationValue =
524 | ( ((double)stateRule.NeighborsAlive) *
525 | this.NeighborWeight ) +
526 | (stateRule.CenterIsAlive?this.CenterWeight:0.0D);
527 |
528 | textActivationValues.Text +=
529 | activationValue.ToString() + ';';
530 | }
531 | }
532 | }
533 |
534 | private void load(object sender, System.EventArgs e)
535 | {
536 | textActivationValues.Text = "";
537 | foreach(StateRule stateRule in stateRules)
538 | {
539 | if(stateRule.ResultIsAlive)
540 | {
541 | double activationValue =
542 | ( ((double)stateRule.NeighborsAlive) *
543 | this.NeighborWeight ) +
544 | (stateRule.CenterIsAlive?this.CenterWeight:0.0D);
545 |
546 | textActivationValues.Text += activationValue.ToString() + ';';
547 | }
548 | }
549 | }
550 | }
551 | }
552 | //End file StatesOutput.cs
--------------------------------------------------------------------------------
/CellLifeGame1/Modeling.cs:
--------------------------------------------------------------------------------
1 | //Begin file Modeling.cs
2 | using System;
3 | using System.IO;
4 | using System.Threading;
5 | using System.Collections;
6 | using System.Runtime.Serialization;
7 | using System.Runtime.Serialization.Formatters.Binary;
8 | using CellLifeGame1.Model;
9 |
10 |
11 | namespace CellLifeGame1
12 | {
13 |
14 |
15 |
16 | ///
17 | /// Maintains a representation of the game modeled in internal data.
18 | ///
19 | /// A Modeling object maintains the data model through its own thread.
20 | ///
21 | /// Requests are made from client objects, which are queued, and
22 | /// the Modeling object will process those requests in a loop.
23 | ///
24 | /// When the modeling thread is TimeStepping the data model, any
25 | /// changes made to the model are queued to an updates object, which
26 | /// the client can access and consume.
27 | ///
28 | /// When this thread initially starts, it will load an initial default
29 | /// model, and then wait for some sort of signal
30 | /// from the UIForm which will prompt ModelThread to load a model by
31 | /// some means, from a file, etc., or respond to user editing of the
32 | /// displayed UI model by updating the internal model. At some point
33 | /// the user may signal the model to begin function of time
34 | /// computations.
35 | ///
36 | public class Modeling
37 | {
38 | ///
39 | /// A queue of updates available for the UI to consume.
40 | /// Each item in the queue is itself a collection listing nodes or
41 | /// properties of the model that have changed during an iteration of
42 | /// modeling computation.
43 | ///
44 | /// The client must take care not to modify objects in the Q, as they
45 | /// are references to actual objects in the data model.
46 | ///
47 | public Queue updates;
48 |
49 | ///
50 | /// Minimum time to complete a processing loop, in milliseconds
51 | ///
52 | private int loopMin;
53 |
54 | private Thread modelingThread;
55 |
56 | #region Operational State Management
57 | ///
58 | /// OpStateFlag defines the possible states that the
59 | /// ModelThread can operate in. Either TimeStepping
60 | /// when the model is being updated through each time step,
61 | /// Paused when the ModelThread is blocked awaiting commands,
62 | /// or UpdatePaused or UpdateTimeStepping when the
63 | /// model is processing a request to update the model recieved while,
64 | /// respectively, Paused or TimeStepping.
65 | [Flags()]
66 | public enum OpStateFlag
67 | {
68 | Paused = 1, TimeStepping = 2, Updating = 4, Starting = 8,
69 | Exiting = 16, UpdateTimeStepping = TimeStepping | Updating,
70 | UpdatePaused = Paused | Updating
71 | };
72 |
73 | ///
74 | /// opState defines the current operational state.
75 | ///
76 | private OpStateFlag opState;
77 | //locking object since value types cannot be locked.
78 | private object opStateLock;
79 |
80 | ///
81 | /// OpState indicates the current operational state that
82 | /// Modeling is in.
83 | ///
84 | public OpStateFlag OpState
85 | {
86 | get
87 | {
88 | lock(opStateLock)
89 | {
90 | return opState;
91 | }
92 | }
93 | }
94 |
95 | private void OpStateChange(OpStateFlag newOpState)
96 | {
97 | lock(opStateLock)
98 | {
99 | opState=newOpState;
100 | }
101 | }
102 |
103 | private Queue requests;
104 |
105 | ///
106 | /// RequestTimeStepping will set Modeling to change
107 | /// OpState at the next most convenient point.
108 | ///
109 | public void RequestTimeStepping()
110 | {
111 | lock(requests)
112 | {
113 | requests.Enqueue(OpStateFlag.TimeStepping);
114 | Monitor.Pulse(requests);
115 | }
116 | }
117 |
118 | public void RequestPause()
119 | {
120 | lock(requests)
121 | {
122 | requests.Enqueue(OpStateFlag.Paused);
123 | }
124 | }
125 |
126 | public void RequestExit()
127 | {
128 | lock(requests)
129 | {
130 | requests.Enqueue(OpStateFlag.Exiting);
131 | }
132 | }
133 |
134 | //sets activation state of node at position p
135 | public void RequestUpdate(Position p, bool a)
136 | {
137 | lock(requests)
138 | {
139 | requests.Enqueue(OpStateFlag.Updating);
140 | requests.Enqueue(p);
141 | requests.Enqueue(a);
142 | Monitor.Pulse(requests);
143 | }
144 | Console.WriteLine("after pulse");
145 |
146 | }
147 |
148 | private void ProcessUpdate()
149 | {
150 | Position p;
151 | if(requests.Peek() is Position)
152 | {
153 | p = (Position)requests.Dequeue();
154 | }
155 | else
156 | {
157 | Console.WriteLine("Error, not position");
158 | return;
159 | }
160 |
161 | bool a;
162 | if(! (requests.Peek() is bool) )
163 | {
164 | Console.WriteLine("Error, not bool");
165 | return;
166 | }
167 | else
168 | {
169 | a = (bool)requests.Dequeue();
170 | }
171 |
172 | int nodeIndex = nodes.BinarySearch( p );
173 |
174 | if(nodeIndex >= 0)//if found
175 | {
176 | Node node = ( (Node) nodes[nodeIndex] );
177 | node.IsActive = a;
178 | updates.Enqueue(node);
179 | OnUpdate(EventArgs.Empty);//fire event
180 | }
181 | else
182 | {
183 | Console.WriteLine("\nError, node not found for RequestUpdate\n");
184 | return;
185 | }
186 | }
187 |
188 | private void ProcessRequests()
189 | {
190 | lock(requests)
191 | {
192 | //while OpState request has not been satisfied, it is possible
193 | //that while waiting in paused mode, we may be awoken to find
194 | //a new request or multiple requests may be made before
195 | //ProcessRequests is called.
196 |
197 | while( requests.Count>0 )
198 | {
199 | if( requests.Peek() is OpStateFlag )
200 | {
201 | OpStateFlag request = (OpStateFlag)requests.Dequeue();
202 | switch (request)
203 | {
204 | case OpStateFlag.Paused:
205 | opState=OpStateFlag.Paused;
206 |
207 | //if there are still requests remaining, then
208 | //we should set state to pause, but continue
209 | //processing requests since there will likely
210 | //be requests for TimeStepping or Updating which
211 | //would normally cancel a pause.
212 | if( requests.Count == 0 )
213 | {
214 | Monitor.Wait(requests);
215 | }
216 | break;
217 |
218 | case OpStateFlag.Updating:
219 | opState=OpStateFlag.Updating | opState;
220 | ProcessUpdate();
221 | if(requests.Count==0)
222 | {
223 | requests.Enqueue(
224 | (~OpStateFlag.Updating) & opState );
225 | break;
226 | }
227 | else
228 | {
229 | opState = ( (~OpStateFlag.Updating) & opState );
230 | }
231 | break;
232 |
233 | case OpStateFlag.TimeStepping:
234 | opState=OpStateFlag.TimeStepping;
235 | break;
236 |
237 | case OpStateFlag.Exiting:
238 | opState=OpStateFlag.Exiting;
239 | break;
240 |
241 | default:
242 | Console.WriteLine
243 | ("Error, default reached in ProcessRequest");
244 | break;
245 | }
246 | }
247 | //add else if statement for other object types in queue
248 | }
249 | }
250 | }
251 | #endregion
252 |
253 | ///
254 | /// The model data as a collection of Node objects.
255 | ///
256 | private ArrayList nodes;
257 |
258 | ///
259 | /// List of values on which nodes should fire.
260 | ///
261 | private ArrayList activationValues;
262 |
263 | public ArrayList ActivationValues
264 | {
265 | get
266 | {
267 | return activationValues;
268 | }
269 | }
270 |
271 | #region Update event fields and methods.
272 | ///
273 | /// Update is fired when new data has been flipped to public.
274 | ///
275 | public event EventHandler Update;
276 |
277 | protected virtual void OnUpdate(EventArgs e)
278 | {
279 | if (Update != null)
280 | Update(this,e);
281 | }
282 | #endregion
283 |
284 | ///
285 | /// Loads square grid model into nodes collection.
286 | ///
287 | ///
288 |
289 | ///
290 | /// Loads a grid of nodes and builds links between adjacent and
291 | /// diagonally adjacent nodes(the nearest 8). Most applicable for
292 | /// John Conway's "Game of Life."
293 | ///
294 | /// Minimum (x,y) origin of grid
295 | /// construction
296 | /// Width of grid in x direction.
297 | /// Height of grid in y direction
298 | /// IsActive state to initialize each
299 | /// node at.
300 | private void LoadNodesGrid(Position initPosition,
301 | int width, int height, bool initialActivity)
302 | {
303 | for( int i = initPosition.x; i= 0)//if found
356 | {
357 | node.AddLink( new Link(
358 | (Node) nodes[adjacentNodeIndex], .12D ) );
359 | }
360 | else
361 | {
362 | Console.WriteLine("Error, adjacent node not found");
363 | }
364 | }
365 | }
366 | }
367 | node.AddLink( new Link((Node) node, .04D) );
368 | node.IsActive = initialActivity;//set initial state
369 | }
370 |
371 |
372 | #if DEBUG
373 | foreach (Node node in nodes)
374 | {
375 | foreach (Link link in node.links)
376 | {
377 | Console.WriteLine("Node at ({0},{1}) linked to ({2},{3})",
378 | node.position.x, node.position.y,
379 | link.Destin.position.x, link.Destin.position.y);
380 | }
381 | }
382 | #endif
383 |
384 | }
385 |
386 | ///
387 | /// Loads a (0,0) origin grid.
388 | ///
389 | /// Width of grid in x direction.
390 | /// Height of grid in y direction
391 | /// IsActive state to initialize each
392 | /// node at.
393 | private void LoadNodesGrid(int width, int height, bool initialActivity)
394 | {
395 | LoadNodesGrid(new Position(0,0), width, height, initialActivity);
396 | }
397 |
398 | ///
399 | /// Loads a (0,0) origin grid with random activities for cells.
400 | ///
401 | /// Width of grid in x direction.
402 | /// Height of grid in y direction
403 | private void LoadNodesGrid(int width, int height)
404 | {
405 | LoadNodesGrid(new Position(0,0), width, height, true);
406 | }
407 |
408 | //requests a new NN to simulate a CA
409 | public void RequestAutomaton(
410 | ArrayList neighborhood, ArrayList activationValues,
411 | double neighborWeight, double centerWeight)
412 | {
413 | this.activationValues = (ArrayList)activationValues.Clone();
414 | RedoLinks(neighborhood, neighborWeight, centerWeight);
415 | }
416 |
417 | ///
418 | /// Returns(via update Q) and sets active a list of nodes that
419 | /// link to the node at pos
420 | ///
421 | public void RequestActivateNeighbors(Position pos)
422 | {
423 | int nodeIndex = nodes.BinarySearch(pos);
424 |
425 | if(nodeIndex >= 0)//if found
426 | {
427 | foreach(Node node in nodes)
428 | {
429 | foreach(Link link in node.links)
430 | {
431 | if( link.Destin.Equals((Node)nodes[nodeIndex]) )
432 | {
433 | node.IsActive = true;
434 | updates.Enqueue(node);
435 | }
436 | }
437 | }
438 |
439 | OnUpdate(EventArgs.Empty);//fire event
440 | }
441 | else
442 | {
443 | Console.WriteLine("\nError, node not found!\n");
444 | }
445 | }
446 |
447 | public void RedoLinks(ArrayList neighborhood, double neighborWeight,
448 | double centerWeight)
449 | {
450 | foreach(Node node in nodes)
451 | {
452 | node.links = new ArrayList();
453 |
454 | if(centerWeight != 0.0D)
455 | {
456 | node.AddLink( new Link((Node) node, centerWeight) );
457 | }
458 |
459 | foreach(Position pos in neighborhood)
460 | {
461 | int width = 1 + ( (Node)(nodes[nodes.Count-1]) ).position.x;
462 | int height = 1 + ( (Node)(nodes[nodes.Count-1]) ).position.y;
463 |
464 | int relX = (node.position.x - pos.x)%width;
465 | int relY = (node.position.y - pos.y)%height;
466 |
467 | if(relX < 0)
468 | {
469 | relX += width;
470 | }
471 |
472 | if(relY < 0)
473 | {
474 | relY += height;
475 | }
476 |
477 | int adjacentNodeIndex = nodes.BinarySearch(
478 | new Position(relX, relY)
479 | );
480 |
481 | if(adjacentNodeIndex >= 0)//if found
482 | {
483 | node.AddLink( new Link(
484 | (Node) nodes[adjacentNodeIndex], neighborWeight ) );
485 | }
486 | else
487 | {
488 | Console.WriteLine("\nError, adjacent node not found!\n");
489 | }
490 | }
491 | }
492 | }
493 |
494 |
495 | private void CalculateWeightedSum()
496 | {
497 | foreach (Node node in nodes)
498 | {
499 | if(node.IsActive)
500 | {
501 | foreach (Link link in node.links)
502 | {
503 | link.Destin.inputSum += link.Weight;
504 | }
505 | }
506 | }
507 | }
508 |
509 |
510 | public void RequestLoopTime(int loopTime)
511 | {
512 | loopMin = loopTime;
513 | }
514 |
515 | private void CalculateActivation()
516 | {
517 | foreach (Node node in nodes)
518 | {
519 |
520 | bool deactivate = true;
521 | foreach(double dble in activationValues)
522 | {
523 | //if input sum == activationvalue, with tolerance 0.0001
524 | if( Math.Abs(dble - node.inputSum) <= (0.0001D))
525 | {
526 | //for efficiency we only change node state
527 | //if it is not already that state
528 | if( !node.IsActive )
529 | {
530 | node.IsActive = true;
531 | updates.Enqueue(node);
532 | }
533 | deactivate = false;
534 | break;
535 | }
536 | }
537 |
538 | //if we are active, and did not find activationValue in loop
539 | if(node.IsActive && deactivate)
540 | {//then deactivate
541 | node.IsActive = false;
542 | updates.Enqueue(node);
543 | }
544 |
545 | //reset input to 0 so that totals can begin accumulating again
546 | node.inputSum = 0;
547 | }
548 |
549 | }
550 |
551 | private void TimeStep()
552 | {
553 | this.CalculateWeightedSum();
554 | this.CalculateActivation();
555 | }
556 |
557 | public void ProcessSave(String filename)
558 | {
559 | using( FileStream fileStream = new FileStream(filename,
560 | FileMode.Create, FileAccess.Write, FileShare.None) )
561 | {
562 | IFormatter formatter = new BinaryFormatter();
563 | formatter.Serialize(
564 | fileStream, new SaveFile(nodes, activationValues) );
565 | }
566 | }
567 |
568 | public void ProcessLoad(String filename)
569 | {
570 | using( FileStream fileStream = new FileStream(filename,
571 | FileMode.Open, FileAccess.Read, FileShare.Read) )
572 | {
573 | IFormatter formatter = new BinaryFormatter();
574 |
575 | Object loaded = formatter.Deserialize(fileStream);
576 | if(loaded is ArrayList)
577 | {
578 | nodes = (ArrayList)loaded;
579 | }
580 | else
581 | {
582 | SaveFile loadedDual = (SaveFile)loaded;
583 | nodes = loadedDual.nodes;
584 | activationValues = loadedDual.activationValues;
585 | }
586 | }
587 |
588 | foreach(Node node in nodes)
589 | {
590 | updates.Enqueue(node);
591 | }
592 | OnUpdate(EventArgs.Empty);
593 | }
594 |
595 | public void RequestSteps(int steps)
596 | {
597 | this.RequestPause();
598 | //wait for pause
599 | while(OpState != OpStateFlag.Paused){}
600 |
601 | bool updatesCleared = false;
602 | for(int i = 0; i < steps; ++i)
603 | {
604 | TimeStep();
605 |
606 | //to prevent emory being overused, we clear updates
607 | if(updates.Count > 2*nodes.Count)
608 | {
609 | updatesCleared = true;
610 | updates.Clear();
611 | }
612 | }
613 |
614 | //if we cleared updates, then we need to add all cells to updates
615 | if(updatesCleared)
616 | {
617 | updates.Clear();
618 | foreach(Node node in nodes)
619 | {
620 | updates.Enqueue(node);
621 | }
622 | }
623 |
624 | OnUpdate(EventArgs.Empty);//fire event
625 | }
626 |
627 | public Modeling():this(40,40)
628 | {}
629 |
630 | public Modeling(int height, int width)
631 | {
632 | requests = new Queue();
633 | opStateLock = new object();
634 | nodes = new ArrayList();
635 | updates = new Queue();
636 | loopMin = 100;
637 |
638 | LoadNodesGrid(height,width);
639 |
640 | System.Random randGen =
641 | new Random( unchecked((int)System.DateTime.Now.Ticks) );
642 |
643 | foreach (Node node in nodes)
644 | {
645 | //random activity
646 | node.IsActive = Convert.ToBoolean(randGen.Next(2));
647 | }
648 |
649 | //activation values corresponding to Conway's Life
650 | this.activationValues =
651 | new ArrayList( new double[3] {0.28D, 0.36D, 0.40D} );
652 |
653 | foreach (Node node in nodes)
654 | {
655 | updates.Enqueue(node);
656 | }
657 |
658 | modelingThread = new Thread(
659 | new ThreadStart(this.ModelingThreadEntryPoint)
660 | );
661 |
662 | modelingThread.Name = "modelingThread";
663 |
664 | opState = OpStateFlag.Starting;
665 | RequestPause();
666 |
667 | modelingThread.Start();
668 | }
669 |
670 | public void ModelingThreadEntryPoint()
671 | {
672 | DateTime timed = DateTime.Now;
673 | DateTime timed2 = DateTime.Now;
674 | OnUpdate(EventArgs.Empty);
675 |
676 | while(opState != OpStateFlag.Exiting)
677 | {
678 | Console.Write("while loop took: ");
679 | timed2 = DateTime.Now;
680 | Console.WriteLine("{0}",timed2-timed);
681 | timed = DateTime.Now;
682 |
683 | ProcessRequests();
684 | #if DEBUG
685 | timed2 = DateTime.Now;
686 | Console.WriteLine("{0}",timed2-timed);
687 | timed = DateTime.Now;
688 | Console.WriteLine("Entering TimeStep");
689 | #endif
690 | TimeStep();
691 |
692 | #if DEBUG
693 |
694 | timed2 = DateTime.Now;
695 | Console.WriteLine("{0}",timed2-timed);
696 | timed = DateTime.Now;
697 |
698 | Console.WriteLine("Entering OnUpdate");
699 | #endif
700 | OnUpdate(EventArgs.Empty);//fire event
701 |
702 | #if DEBUG
703 | timed2 = DateTime.Now;
704 | Console.WriteLine("{0}",timed2-timed);
705 | timed = DateTime.Now;
706 | Console.WriteLine("Sleeping");
707 | #endif
708 | //loopMin milliseconds later
709 | timed2 = timed.AddMilliseconds(loopMin);
710 |
711 | //only if less than loopMin milliseconds have passed do we sleep
712 | if(DateTime.Now<=timed2)
713 | {
714 | Thread.Sleep(timed2-DateTime.Now);
715 | }
716 |
717 | #if DEBUG
718 | timed2 = DateTime.Now;
719 | Console.WriteLine("{0}",timed2-timed);
720 | timed = DateTime.Now;
721 | #endif
722 |
723 |
724 | }
725 | }
726 |
727 | public Node GetNode(int index)
728 | {
729 | return (Node)nodes[index];
730 |
731 | }
732 |
733 | }//class
734 | }//namespace
735 | //End file Modeling.cs
736 |
--------------------------------------------------------------------------------
/CellLifeGame1/UIForm.cs:
--------------------------------------------------------------------------------
1 | //Begin file UIForm.cs
2 | using System;
3 | using System.Drawing;
4 | using System.Drawing.Drawing2D;
5 | using System.Collections;
6 | using System.ComponentModel;
7 | using System.Windows.Forms;
8 | using System.Data;
9 | using System.Threading;
10 | using CellLifeGame1.Model;
11 |
12 |
13 | namespace CellLifeGame1
14 | {
15 |
16 | ///
17 | /// Summary description for Form1.
18 | ///
19 | public class UIForm : System.Windows.Forms.Form
20 | {
21 | public class RectGrid : System.Windows.Forms.Panel
22 | {
23 | private void InitializeComponent()
24 | {}
25 |
26 | protected override void OnPaintBackground(PaintEventArgs pevent)
27 | {
28 | //disable background painting by not calling base
29 | }
30 | }
31 |
32 | ///
33 | /// Programmer Added Declarations
34 | ///
35 | private Modeling modeling;//computation and data model
36 |
37 | ///
38 | /// Form Designer Generated Declarations
39 | ///
40 | private RectGrid panel1;
41 | private StatesOutput crntStatesOutput;
42 |
43 | private Cell[,] cells;
44 | private System.Windows.Forms.Button StartStop;
45 |
46 | ///
47 | /// Required designer variable.
48 | ///
49 | private System.ComponentModel.Container components = null;
50 |
51 | private int cellSize=8;
52 | private int cellsWide=64;
53 | private System.Windows.Forms.Button btnClear;
54 | private System.Windows.Forms.Button btnSave;
55 | private System.Windows.Forms.Button btnLoad;
56 | private System.Windows.Forms.Button btnDone;
57 | private System.Windows.Forms.Button automaton;
58 | private System.Windows.Forms.TrackBar sldrSpeed;
59 | private System.Windows.Forms.NumericUpDown numSteps;
60 | private System.Windows.Forms.Button btnStep;
61 | private System.Windows.Forms.Button btnCurrentAuto;
62 | private System.Windows.Forms.GroupBox groupAutomaton;
63 | private int cellsHigh=64;
64 |
65 | public UIForm()
66 | {
67 | //
68 | // Required for Windows Form Designer support
69 | //
70 | InitializeComponent();
71 |
72 | ProgrammaticInit();
73 | }
74 |
75 | ///
76 | /// Clean up any resources being used.
77 | ///
78 | protected override void Dispose( bool disposing )
79 | {
80 | if( disposing )
81 | {
82 | if (components != null)
83 | {
84 | components.Dispose();
85 | }
86 | }
87 | base.Dispose( disposing );
88 | }
89 |
90 | private void ProgrammaticInit()
91 | {
92 | SetStyle(ControlStyles.UserPaint, true);
93 | SetStyle(ControlStyles.AllPaintingInWmPaint, true);
94 | SetStyle(ControlStyles.DoubleBuffer, true);
95 |
96 | crntStatesOutput = new StatesOutput();
97 |
98 | cells= new Cell[cellsWide, cellsHigh];
99 |
100 | for(int i=0;i0)
122 | {
123 | Node node = (Node)modeling.updates.Dequeue();
124 |
125 | Cell cell = cells[node.position.x, node.position.y];
126 |
127 | if(node.IsActive)
128 | {
129 | cell.Color = Color.Crimson;
130 | }
131 | else
132 | {
133 | cell.Color = Color.DarkBlue;
134 | }
135 |
136 | cell.X = node.position.x*cellSize;
137 | cell.Y = node.position.y*cellSize;
138 | cell.Size = cellSize;
139 | }
140 |
141 | if(this.StartStop.Text == "Stop")
142 | {
143 | modeling.RequestPause();
144 | }
145 | this.panel1.Invalidate();
146 | }
147 |
148 |
149 | #region Windows Form Designer generated code
150 | ///
151 | /// Required method for Designer support - do not modify
152 | /// the contents of this method with the code editor.
153 | ///
154 | private void InitializeComponent()
155 | {
156 | this.panel1 = new CellLifeGame1.UIForm.RectGrid();
157 | this.StartStop = new System.Windows.Forms.Button();
158 | this.btnClear = new System.Windows.Forms.Button();
159 | this.btnSave = new System.Windows.Forms.Button();
160 | this.btnLoad = new System.Windows.Forms.Button();
161 | this.automaton = new System.Windows.Forms.Button();
162 | this.btnDone = new System.Windows.Forms.Button();
163 | this.sldrSpeed = new System.Windows.Forms.TrackBar();
164 | this.numSteps = new System.Windows.Forms.NumericUpDown();
165 | this.btnStep = new System.Windows.Forms.Button();
166 | this.btnCurrentAuto = new System.Windows.Forms.Button();
167 | this.groupAutomaton = new System.Windows.Forms.GroupBox();
168 | ((System.ComponentModel.ISupportInitialize)
169 | (this.sldrSpeed)).BeginInit();
170 | ((System.ComponentModel.ISupportInitialize)
171 | (this.numSteps)).BeginInit();
172 | this.groupAutomaton.SuspendLayout();
173 | this.SuspendLayout();
174 | //
175 | // panel1
176 | //
177 | this.panel1.Location = new System.Drawing.Point(56, 40);
178 | this.panel1.Name = "panel1";
179 | this.panel1.Size = new System.Drawing.Size(512, 512);
180 | this.panel1.TabIndex = 0;
181 | this.panel1.MouseUp += new
182 | System.Windows.Forms.MouseEventHandler(this.panel1_MouseUp);
183 | this.panel1.Paint += new
184 | System.Windows.Forms.PaintEventHandler(this.panel1_Paint);
185 | this.panel1.DragLeave += new
186 | System.EventHandler(this.panel1_DragLeave);
187 | this.panel1.MouseMove += new
188 | System.Windows.Forms.MouseEventHandler(this.panel1_MouseMove);
189 | this.panel1.MouseDown += new
190 | System.Windows.Forms.MouseEventHandler(this.panel1_MouseDown);
191 | //
192 | // StartStop
193 | //
194 | this.StartStop.Location = new System.Drawing.Point(72, 8);
195 | this.StartStop.Name = "StartStop";
196 | this.StartStop.Size = new System.Drawing.Size(40, 24);
197 | this.StartStop.TabIndex = 2;
198 | this.StartStop.Text = "Start";
199 | this.StartStop.Click += new
200 | System.EventHandler(this.StartStop_Click);
201 | //
202 | // btnClear
203 | //
204 | this.btnClear.Location = new System.Drawing.Point(256, 8);
205 | this.btnClear.Name = "btnClear";
206 | this.btnClear.Size = new System.Drawing.Size(40, 24);
207 | this.btnClear.TabIndex = 3;
208 | this.btnClear.Text = "Clear";
209 | this.btnClear.Click += new System.EventHandler(this.btnClear_Click);
210 | //
211 | // btnSave
212 | //
213 | this.btnSave.Location = new System.Drawing.Point(304, 8);
214 | this.btnSave.Name = "btnSave";
215 | this.btnSave.Size = new System.Drawing.Size(40, 24);
216 | this.btnSave.TabIndex = 4;
217 | this.btnSave.Text = "Save";
218 | this.btnSave.Click += new System.EventHandler(this.btnSave_Click);
219 | //
220 | // btnLoad
221 | //
222 | this.btnLoad.Location = new System.Drawing.Point(352, 8);
223 | this.btnLoad.Name = "btnLoad";
224 | this.btnLoad.Size = new System.Drawing.Size(40, 24);
225 | this.btnLoad.TabIndex = 5;
226 | this.btnLoad.Text = "Load";
227 | this.btnLoad.Click += new System.EventHandler(this.btnLoad_Click);
228 | //
229 | // automaton
230 | //
231 | this.automaton.Location = new System.Drawing.Point(4, 16);
232 | this.automaton.Name = "automaton";
233 | this.automaton.Size = new System.Drawing.Size(36, 20);
234 | this.automaton.TabIndex = 6;
235 | this.automaton.Text = "New";
236 | this.automaton.Click += new
237 | System.EventHandler(this.automaton_Click);
238 | //
239 | // btnDone
240 | //
241 | this.btnDone.Enabled = false;
242 | this.btnDone.Location = new System.Drawing.Point(108, 16);
243 | this.btnDone.Name = "btnDone";
244 | this.btnDone.Size = new System.Drawing.Size(40, 20);
245 | this.btnDone.TabIndex = 7;
246 | this.btnDone.Text = "Done";
247 | this.btnDone.Click += new
248 | System.EventHandler(this.btnDone_Click);
249 | //
250 | // sldrSpeed
251 | //
252 | this.sldrSpeed.Location = new System.Drawing.Point(8, 8);
253 | this.sldrSpeed.Maximum = 1000;
254 | this.sldrSpeed.Minimum = 1;
255 | this.sldrSpeed.Name = "sldrSpeed";
256 | this.sldrSpeed.Orientation =
257 | System.Windows.Forms.Orientation.Vertical;
258 | this.sldrSpeed.Size = new System.Drawing.Size(45, 544);
259 | this.sldrSpeed.TabIndex = 9;
260 | this.sldrSpeed.TickStyle = System.Windows.Forms.TickStyle.None;
261 | this.sldrSpeed.Value = 200;
262 | this.sldrSpeed.ValueChanged += new
263 | System.EventHandler(this.sldSpeed_Changed);
264 | //
265 | // numSteps
266 | //
267 | this.numSteps.Location = new System.Drawing.Point(168, 8);
268 | this.numSteps.Maximum = new System.Decimal(new int[] {
269 | 5000,
270 | 0,
271 | 0,
272 | 0});
273 | this.numSteps.Minimum = new System.Decimal(new int[] {
274 | 1,
275 | 0,
276 | 0,
277 | 0});
278 | this.numSteps.Name = "numSteps";
279 | this.numSteps.Size = new System.Drawing.Size(80, 20);
280 | this.numSteps.TabIndex = 10;
281 | this.numSteps.Value = new System.Decimal(new int[] {
282 | 1,
283 | 0,
284 | 0,
285 | 0});
286 | //
287 | // btnStep
288 | //
289 | this.btnStep.Location = new System.Drawing.Point(120, 8);
290 | this.btnStep.Name = "btnStep";
291 | this.btnStep.Size = new System.Drawing.Size(40, 24);
292 | this.btnStep.TabIndex = 8;
293 | this.btnStep.Text = "Step";
294 | this.btnStep.Click += new System.EventHandler(this.btnStep_Click);
295 | //
296 | // btnCurrentAuto
297 | //
298 | this.btnCurrentAuto.Location = new System.Drawing.Point(48, 16);
299 | this.btnCurrentAuto.Name = "btnCurrentAuto";
300 | this.btnCurrentAuto.Size = new System.Drawing.Size(52, 20);
301 | this.btnCurrentAuto.TabIndex = 11;
302 | this.btnCurrentAuto.Text = "Current";
303 | this.btnCurrentAuto.Click += new
304 | System.EventHandler(this.btnCurrentAuto_Click);
305 | //
306 | // groupAutomaton
307 | //
308 | this.groupAutomaton.Controls.Add(this.btnDone);
309 | this.groupAutomaton.Controls.Add(this.btnCurrentAuto);
310 | this.groupAutomaton.Controls.Add(this.automaton);
311 | this.groupAutomaton.Location = new System.Drawing.Point(400, 0);
312 | this.groupAutomaton.Name = "groupAutomaton";
313 | this.groupAutomaton.Size = new System.Drawing.Size(152, 40);
314 | this.groupAutomaton.TabIndex = 13;
315 | this.groupAutomaton.TabStop = false;
316 | this.groupAutomaton.Text = "Automaton";
317 | //
318 | // UIForm
319 | //
320 | this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
321 | this.ClientSize = new System.Drawing.Size(576, 557);
322 | this.Controls.Add(this.groupAutomaton);
323 | this.Controls.Add(this.numSteps);
324 | this.Controls.Add(this.sldrSpeed);
325 | this.Controls.Add(this.btnStep);
326 | this.Controls.Add(this.btnLoad);
327 | this.Controls.Add(this.btnSave);
328 | this.Controls.Add(this.btnClear);
329 | this.Controls.Add(this.StartStop);
330 | this.Controls.Add(this.panel1);
331 | this.FormBorderStyle =
332 | System.Windows.Forms.FormBorderStyle.FixedToolWindow;
333 | this.Name = "UIForm";
334 | this.RightToLeft = System.Windows.Forms.RightToLeft.No;
335 | this.Text =
336 | "Cellular Automata Computer Aided Design and Conversion (CACADAC)";
337 | ((System.ComponentModel.ISupportInitialize)
338 | (this.sldrSpeed)).EndInit();
339 | ((System.ComponentModel.ISupportInitialize)
340 | (this.numSteps)).EndInit();
341 | this.groupAutomaton.ResumeLayout(false);
342 | this.ResumeLayout(false);
343 |
344 | }
345 | #endregion
346 |
347 | ///
348 | /// The main entry point for the application.
349 | ///
350 | [STAThread]
351 | static void Main()
352 | {
353 | Application.Run(new UIForm());
354 | Application.ExitThread();//allow other threads to continue
355 | }
356 |
357 | private bool tempPause = false;
358 |
359 | private void panel1_MouseDown(
360 | object sender, System.Windows.Forms.MouseEventArgs e)
361 | {
362 | if(this.StartStop.Text == "Stop")
363 | {
364 | this.StartStop.Text = "Start";
365 | tempPause = true;
366 | modeling.RequestPause();
367 | }
368 |
369 | if(e.Button == MouseButtons.Left)
370 | {
371 | Position position = new Position(e.X/cellSize,e.Y/cellSize);
372 | modeling.RequestUpdate(position,true);
373 | }
374 | else if(e.Button == MouseButtons.Right)
375 | {
376 | Position position = new Position(e.X/cellSize,e.Y/cellSize);
377 | modeling.RequestUpdate(position,false);
378 | }
379 | }
380 |
381 | private void panel1_MouseUp(
382 | object sender, System.Windows.Forms.MouseEventArgs e)
383 | {
384 | if(this.StartStop.Text == "Start" && tempPause==true)
385 | {
386 | this.StartStop.Text = "Stop";
387 | tempPause = false;
388 | modeling.RequestTimeStepping();
389 | }
390 |
391 | if(e.Button == MouseButtons.Left)
392 | {
393 | Position position = new Position(e.X/cellSize,e.Y/cellSize);
394 | modeling.RequestUpdate(position,true);
395 | }
396 | else if(e.Button == MouseButtons.Right)
397 | {
398 | Position position = new Position(e.X/cellSize,e.Y/cellSize);
399 | modeling.RequestUpdate(position,false);
400 | }
401 |
402 | }
403 |
404 | private void panel1_Paint(
405 | object sender, System.Windows.Forms.PaintEventArgs a)
406 | {
407 | for(int i=0;i