source: branches/StackingProblems/HeuristicLab.Data.MoveVectorData/3.3/MoveVector.cs @ 14278

Last change on this file since 14278 was 14278, checked in by mzehetho, 5 years ago

Initial Commit for ticket #2605

Implemented:

  • Encoding
  • Moves
  • Views
  • Blocks World Problem
  • Blocks Relocation Problem
  • Stacking Problem
File size: 9.7 KB
Line 
1using HeuristicLab.Common;
2using HeuristicLab.Core;
3using HeuristicLab.Data.MoveVectorData.Interfaces;
4using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
5using System;
6using System.Collections;
7using System.Collections.Generic;
8using System.Drawing;
9using System.Linq;
10using System.Text;
11
12namespace HeuristicLab.Data.MoveVectorData
13{
14    [Item("MoveVector", "Represents a vector of moves.")]
15    [StorableClass]
16    public class MoveVector : Item, IEnumerable<IMove>, IStringConvertibleArray
17    {
18        private const int maximumToStringLength = 100;
19
20        public static new Image StaticItemImage
21        {
22            get { return HeuristicLab.Common.Resources.VSImageLibrary.Class; }
23        }
24
25        [Storable]
26        protected IMove[] array;
27
28        #region Parameters
29        [Storable]
30        protected List<string> elementNames;
31        public virtual IEnumerable<string> ElementNames
32        {
33            get { return this.elementNames; }
34            set
35            {
36                if (ReadOnly) throw new NotSupportedException("ElementNames cannot be set. ValueTypeArray is read-only.");
37                if (value == null || !value.Any())
38                    elementNames = new List<string>();
39                else if (value.Count() > Length)
40                    throw new ArgumentException("The number of element names must not exceed the array length.");
41                else
42                    elementNames = new List<string>(value);
43                OnElementNamesChanged();
44            }
45        }
46
47        public virtual int Length
48        {
49            get { return array.Length; }
50            protected set
51            {
52                if (ReadOnly) throw new NotSupportedException("Length cannot be set. StringArray is read-only.");
53                if (value != Length)
54                {
55                    Array.Resize<IMove>(ref array, value);
56                    while (elementNames.Count > value)
57                        elementNames.RemoveAt(elementNames.Count - 1);
58                    OnElementNamesChanged();
59                    OnReset();
60                }
61            }
62        }
63
64        [Storable]
65        protected bool readOnly;
66        public virtual bool ReadOnly
67        {
68            get { return readOnly; }
69        }
70
71        private IList<Type> moveTypes;
72        public IList<Type> MoveTypes
73        {
74            get
75            {
76                if (moveTypes == null) throw new NullReferenceException("MoveTypes must not be null");
77                return moveTypes;
78            }
79            set
80            {
81                moveTypes = value;
82            }
83        }
84
85        #endregion
86
87        #region Cloning
88        [StorableConstructor]
89        protected MoveVector(bool deserializing) : base(deserializing) { }
90        protected MoveVector(MoveVector original, Cloner cloner) : base(original, cloner)
91        {
92            this.array = (IMove[])original.array.Clone();
93            this.readOnly = original.readOnly;
94            this.elementNames = new List<string>(original.elementNames);
95            this.moveTypes = new List<Type>(original.moveTypes);
96        }
97        public override IDeepCloneable Clone(Cloner cloner)
98        {
99            return new MoveVector(this, cloner);
100        }
101        [StorableHook(HookType.AfterDeserialization)]
102        private void AfterDeserialization()
103        {
104            if (elementNames == null) { elementNames = new List<string>(); }
105        }
106        public virtual MoveVector AsReadOnly()
107        {
108            MoveVector readOnlyStringArray = (MoveVector)this.Clone();
109            readOnlyStringArray.readOnly = true;
110            return readOnlyStringArray;
111        }
112        #endregion
113
114        public MoveVector(IList<Type> moveTypes) : this(0, moveTypes) { }
115        public MoveVector(int length, IList<Type> moveTypes)
116        {
117            if (moveTypes == null) throw new NullReferenceException("MoveTypes must not be null");
118            array = new IMove[length];
119            readOnly = false;
120            elementNames = new List<string>();
121            MoveTypes = moveTypes;
122        }
123        public MoveVector(int length, IRandom random, IList<Type> moveTypes, int min, int max) : this(length, moveTypes)
124        {
125            Randomize(random, min, max);
126        }
127        public MoveVector(IMove[] elements, IList<Type> moveTypes) : this(elements.Length, moveTypes)
128        {
129            for (int i = 0; i < array.Length; i++)
130                array[i] = elements[i];
131        }
132
133        public override string ToString()
134        {
135            if (array.Length == 0) return "[]";
136
137            StringBuilder sb = new StringBuilder();
138            sb.Append("[");
139            sb.Append(array[0]);
140            for (int i = 1; i < array.Length; i++)
141            {
142                sb.Append(";").Append(array[i]);
143                if (sb.Length > maximumToStringLength)
144                {
145                    sb.Append("...");
146                    break;
147                }
148            }
149            sb.Append("]");
150            return sb.ToString();
151        }
152
153        public virtual IEnumerator<IMove> GetEnumerator()
154        {
155            return array.Cast<IMove>().GetEnumerator();
156        }
157
158        IEnumerator IEnumerable.GetEnumerator()
159        {
160            return GetEnumerator();
161        }
162
163        protected virtual bool Validate(string value, out string errorMessage)
164        {
165            if (value == null) //TODO
166            {
167                errorMessage = "Invalid Value (string must not be null)";
168                return false;
169            }
170            else {
171                errorMessage = string.Empty;
172                return true;
173            }
174        }
175
176        public virtual IMove this[int index]
177        {
178            get { return array[index]; }
179            set
180            {
181                if (ReadOnly) throw new NotSupportedException("Item cannot be set. StringArray is read-only.");
182                if (value != array[index])
183                {
184                    if (value != null)
185                    {
186                        array[index] = value;
187                        OnItemChanged(index);
188                    }
189                }
190            }
191        }
192
193        protected virtual string GetValue(int index)
194        {
195            return this[index].ToString();
196        }
197
198        protected virtual bool SetValue(string value, int index)
199        {
200            if (value != null)
201            {
202                this[index] = null; //TODO
203                return true;
204            }
205            else {
206                return false;
207            }
208        }
209
210        public virtual void Randomize(IRandom random, int startIndex, int length, int min, int max, int step = 1)
211        {
212            if (length > 0)
213            {
214                for (int i = startIndex; i < startIndex + length; i++)
215                {
216                    Type type = MoveTypes[random.Next(0, MoveTypes.Count)];
217                    IMove move = (IMove)Activator.CreateInstance(type);
218                    move.Randomize(random, min, max, step);
219                    array[i] = move;
220                }
221                OnReset();
222            }
223        }
224
225        public virtual void Randomize(IRandom random, int startIndex, int length, IntMatrix bounds)
226        {
227            if (length > 0)
228            {
229                int min = bounds[0, 0], max = bounds[0, 1], step = 1;
230                if (bounds.Columns > 2) step = bounds[0, 2];
231                Randomize(random, startIndex, length, min, max, step);
232            }
233        }
234
235        public void Randomize(IRandom random, int min, int max, int step = 1)
236        {
237            Randomize(random, 0, Length, min, max, step);
238        }
239
240        public void Randomize(IRandom random, IntMatrix bounds)
241        {
242            Randomize(random, 0, Length, bounds);
243        }
244
245        #region Events
246        public event EventHandler ElementNamesChanged;
247        protected virtual void OnElementNamesChanged()
248        {
249            EventHandler handler = ElementNamesChanged;
250            if (handler != null)
251                handler(this, EventArgs.Empty);
252        }
253
254        public event EventHandler<EventArgs<int>> ItemChanged;
255        protected virtual void OnItemChanged(int index)
256        {
257            if (ItemChanged != null)
258                ItemChanged(this, new EventArgs<int>(index));
259            if (index < maximumToStringLength)
260                OnToStringChanged();
261        }
262
263        public event EventHandler Reset;
264        public event EventHandler ResizableChanged;
265
266        protected virtual void OnReset()
267        {
268            if (Reset != null)
269                Reset(this, EventArgs.Empty);
270            OnToStringChanged();
271        }
272        #endregion
273
274        #region IStringConvertibleArray Members
275        int IValueTypeArray.Length
276        {
277            get { return Length; }
278            set { Length = value; }
279        }
280
281        public bool Resizable
282        {
283            get { return false; }
284            set { }
285        }
286
287        bool IStringConvertibleArray.Validate(string value, out string errorMessage)
288        {
289            return Validate(value, out errorMessage);
290        }
291        string IStringConvertibleArray.GetValue(int index)
292        {
293            return GetValue(index);
294        }
295        bool IStringConvertibleArray.SetValue(string value, int index)
296        {
297            return SetValue(value, index);
298        }
299
300        IValueTypeArray IValueTypeArray.AsReadOnly()
301        {
302            throw new NotImplementedException();
303        }
304        #endregion
305    }
306}
Note: See TracBrowser for help on using the repository browser.