From 52fd062a34dd94a2c4a7ac982b97bcd91145ef9f Mon Sep 17 00:00:00 2001 From: Joen van de Vorle Date: Thu, 11 Apr 2024 17:11:29 +0200 Subject: [PATCH 01/13] feat: add ExposedQueue skeleton --- Aplib.Core/ExposedQueue.cs | 188 +++++++++++++++++++++++++++++++++++++ 1 file changed, 188 insertions(+) create mode 100644 Aplib.Core/ExposedQueue.cs diff --git a/Aplib.Core/ExposedQueue.cs b/Aplib.Core/ExposedQueue.cs new file mode 100644 index 00000000..2446083e --- /dev/null +++ b/Aplib.Core/ExposedQueue.cs @@ -0,0 +1,188 @@ +using System.Collections; +using System.Collections.Generic; + +namespace Aplib.Core +{ + /// + /// A queue with all elements exposed. + /// Functionally works like a queue with indexing. + /// + public class ExposedQueue : ICollection + { + /// + /// The length of the array. + /// + public int MaxCount { get; private set; } + + /// + /// Actual number of elements in the array. + /// Limited to . + /// + public int Count + { + get => _count; + private set => _count = value > MaxCount ? MaxCount : value; + } + + /// + public bool IsReadOnly => false; + + private int _count; + + private readonly T[] _array; + private int _head; + + /// + /// Initializes a new instance of the class. + /// + /// The size of the array. + public ExposedQueue(int size) + { + MaxCount = size; + _array = new T[MaxCount]; + _head = MaxCount - 1; + } + + /// + /// Initializes a new instance of the class. + /// + /// An array to use as the circular array. + public ExposedQueue(T[] array) + { + MaxCount = array.Length; + _array = array; + _head = MaxCount - 1; + } + + /// + /// Gets the element at the specified index. + /// + /// The index of the element to get. + /// The element at the specified index. + public T this[int index] + { + get => _array[(index + _head + 1) % MaxCount]; + set => _array[(index + _head + 1) % MaxCount] = value; + } + + /// + /// Decrements the head of the array. + /// + private void DecrementHead() + { + _head = (_head - 1 + MaxCount) % MaxCount; + } + + /// + /// Puts an element at the start of the array. + /// + /// The element to add to the array + public void Put(T value) + { + _array[_head] = value; + DecrementHead(); + Count++; + } + + /// + public void Add(T item) => Put(item); + + /// + /// Gets the element at the head of the array. + /// + /// The element at the head of the array + public T GetHead() + { + return _array[_head]; + } + + /// + /// Gets the first element of the array. + /// + /// The last element of the array + public T GetFirst() + { + return this[0]; + } + + /// + /// Copies the circular array to an array. + /// The head should be the last element of the array. + /// Copies from start to end inclusive. + /// + /// The array to copy to." + /// The start index of the range to copy. + /// The end index of the range to copy. + /// The circular array as a normal array + public void CopyTo(T[] array, int arrayIndex, int endIndex) + { + if (arrayIndex < 0 || arrayIndex >= MaxCount) + throw new System.ArgumentOutOfRangeException(nameof(arrayIndex)); + if (endIndex < 0 || endIndex >= MaxCount) + throw new System.ArgumentOutOfRangeException(nameof(endIndex)); + if (arrayIndex > endIndex) + throw new System.ArgumentException("Start index must be less than or equal to end index."); + if (array.Length < endIndex - arrayIndex + 1) + throw new System.ArgumentException("Array is too small to copy the range."); + + for (int i = 0; i < endIndex - arrayIndex + 1; i++) + array[i] = this[arrayIndex + i]; + } + + /// + public void CopyTo(T[] array, int arrayIndex) => CopyTo(array, arrayIndex, arrayIndex + Count - 1); + + /// + /// Converts the ExposedQueue to an array. + /// + /// The start index of the range to convert. + /// The end index of the range to convert. + /// An array containing the elements within the specified range. + public T[] ToArray(int start = 0, int end = -1) + { + end = end == -1 ? Count - 1 : end; + T[] result = new T[end - start + 1]; + CopyTo(result, start, end); + return result; + } + + /// + public void Clear() + { + for (int i = 0; i < MaxCount; i++) + _array[i] = default!; + _head = MaxCount - 1; + Count = 0; + } + + /// + public bool Contains(T item) + { + for (int i = 0; i < Count; i++) + if (this[i]!.Equals(item)) + return true; + return false; + } + + /// + public bool Remove(T item) + { + for (int i = 0; i < Count; i++) + if (this[i]!.Equals(item)) + { + this[i] = default!; + return true; + } + return false; + } + + /// + public IEnumerator GetEnumerator() + { + for (int i = 0; i < Count; i++) + yield return this[i]; + } + + IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); + } +} From f8b5a1c19ef152f181d1fffc001b2c2af4e1072e Mon Sep 17 00:00:00 2001 From: Joen van de Vorle <90771356+JoenvandeVorle@users.noreply.github.com> Date: Wed, 8 May 2024 14:50:23 +0200 Subject: [PATCH 02/13] feat: count now works, all memorybelief tests pass --- Aplib.Core/Belief/MemoryBelief.cs | 13 +++---- Aplib.Core/ExposedQueue.cs | 47 ++++++++++++++----------- Aplib.Tests/Belief/ExposedQueueTests.cs | 17 +++++++++ Aplib.Tests/Belief/MemoryBeliefTests.cs | 2 +- 4 files changed, 48 insertions(+), 31 deletions(-) create mode 100644 Aplib.Tests/Belief/ExposedQueueTests.cs diff --git a/Aplib.Core/Belief/MemoryBelief.cs b/Aplib.Core/Belief/MemoryBelief.cs index df9021b1..49b82c0b 100644 --- a/Aplib.Core/Belief/MemoryBelief.cs +++ b/Aplib.Core/Belief/MemoryBelief.cs @@ -20,7 +20,7 @@ public class MemoryBelief : Belief /// A "memorized" resouce, from the last time the belief was updated. /// - private readonly CircularArray _memorizedObservations; + private readonly ExposedQueue _memorizedObservations; /// /// Initializes a new instance of the class with an object reference, @@ -73,12 +73,12 @@ public override void UpdateBelief() /// /// Gets the memorized observation at a specific index. /// A higher index means a memory further back in time. - /// If the index is out of bounds, returns the element closest to the index that is in bounds. + /// If the index is out of bounds, when clamped, returns the element closest to the index that is in bounds. /// /// The memory of the observation at the specified index. public TObservation GetMemoryAt(int index, bool clamp = false) { - int lastMemoryIndex = _memorizedObservations.Length - 1; + int lastMemoryIndex = _memorizedObservations.Count; if (clamp) index = Math.Clamp(index, 0, lastMemoryIndex); else if (index < 0 || index > lastMemoryIndex) @@ -91,12 +91,7 @@ public TObservation GetMemoryAt(int index, bool clamp = false) /// The first element is the newest memory. /// /// An array of all the memorized observations. - public TObservation[] GetAllMemories() - { - // For now, we return the entire array, but with empty elements for the unused slots - // TODO: make it return only the used slots - return _memorizedObservations.ToArray(); - } + public TObservation[] GetAllMemories() => _memorizedObservations.ToArray(); } } diff --git a/Aplib.Core/ExposedQueue.cs b/Aplib.Core/ExposedQueue.cs index 2446083e..bda0b6fe 100644 --- a/Aplib.Core/ExposedQueue.cs +++ b/Aplib.Core/ExposedQueue.cs @@ -1,3 +1,4 @@ +using System; using System.Collections; using System.Collections.Generic; @@ -45,10 +46,13 @@ public ExposedQueue(int size) /// /// Initializes a new instance of the class. + /// By default, assumes the array is filled. /// /// An array to use as the circular array. - public ExposedQueue(T[] array) + /// The number of actual elements in the array. + public ExposedQueue(T[] array, int count = -1) { + Count = count; MaxCount = array.Length; _array = array; _head = MaxCount - 1; @@ -68,10 +72,7 @@ public T this[int index] /// /// Decrements the head of the array. /// - private void DecrementHead() - { - _head = (_head - 1 + MaxCount) % MaxCount; - } + private void DecrementHead() => _head = (_head - 1 + MaxCount) % MaxCount; /// /// Puts an element at the start of the array. @@ -91,19 +92,13 @@ public void Put(T value) /// Gets the element at the head of the array. /// /// The element at the head of the array - public T GetHead() - { - return _array[_head]; - } + public T GetHead() => _array[_head]; /// /// Gets the first element of the array. /// /// The last element of the array - public T GetFirst() - { - return this[0]; - } + public T GetFirst() => this[0]; /// /// Copies the circular array to an array. @@ -116,14 +111,14 @@ public T GetFirst() /// The circular array as a normal array public void CopyTo(T[] array, int arrayIndex, int endIndex) { - if (arrayIndex < 0 || arrayIndex >= MaxCount) - throw new System.ArgumentOutOfRangeException(nameof(arrayIndex)); - if (endIndex < 0 || endIndex >= MaxCount) - throw new System.ArgumentOutOfRangeException(nameof(endIndex)); + if (arrayIndex < 0 || arrayIndex >= Count) + throw new ArgumentOutOfRangeException(nameof(arrayIndex)); + if (endIndex < 0 || endIndex >= Count) + throw new ArgumentOutOfRangeException(nameof(endIndex)); if (arrayIndex > endIndex) - throw new System.ArgumentException("Start index must be less than or equal to end index."); + throw new ArgumentException("Start index must be less than or equal to end index."); if (array.Length < endIndex - arrayIndex + 1) - throw new System.ArgumentException("Array is too small to copy the range."); + throw new ArgumentException("Array is too small to copy the range."); for (int i = 0; i < endIndex - arrayIndex + 1; i++) array[i] = this[arrayIndex + i]; @@ -138,14 +133,24 @@ public void CopyTo(T[] array, int arrayIndex, int endIndex) /// The start index of the range to convert. /// The end index of the range to convert. /// An array containing the elements within the specified range. - public T[] ToArray(int start = 0, int end = -1) + public T[] ToArray(int start, int end) { - end = end == -1 ? Count - 1 : end; + Console.WriteLine($"Start: {start}, End: {end}"); + if (start < 0 || start >= Count) + throw new ArgumentOutOfRangeException(nameof(start), "Start index must be within the bounds of the array."); + if (end < 0 || end >= Count) + throw new ArgumentOutOfRangeException(nameof(end), "End index must be within the bounds of the array."); T[] result = new T[end - start + 1]; CopyTo(result, start, end); return result; } + /// + /// Converts the ExposedQueue to an array. Only returns the used slots. + /// + /// An array containing the elements within the specified range. + public T[] ToArray() => ToArray(0, Count - 1); + /// public void Clear() { diff --git a/Aplib.Tests/Belief/ExposedQueueTests.cs b/Aplib.Tests/Belief/ExposedQueueTests.cs new file mode 100644 index 00000000..1e721db0 --- /dev/null +++ b/Aplib.Tests/Belief/ExposedQueueTests.cs @@ -0,0 +1,17 @@ +namespace Aplib.Core.Tests.Belief; + +public class ExposedQueueTests +{ + [Fact] + public void ExposedQueue_WhenInitialized_ShouldHaveCorrectMaxCount() + { + // Arrange + ExposedQueue queue = new(3); + + // Act + int maxCount = queue.MaxCount; + + // Assert + Assert.Equal(3, maxCount); + } +} diff --git a/Aplib.Tests/Belief/MemoryBeliefTests.cs b/Aplib.Tests/Belief/MemoryBeliefTests.cs index 04767912..9e292eef 100644 --- a/Aplib.Tests/Belief/MemoryBeliefTests.cs +++ b/Aplib.Tests/Belief/MemoryBeliefTests.cs @@ -89,6 +89,6 @@ public void GetAllMemories_ReturnsAllMemories() belief.UpdateBelief(); // Assert - Assert.Equal([3, 0, 0], belief.GetAllMemories()); + Assert.Equal([3], belief.GetAllMemories()); } } From 2b88180ca69de87989cfea6f409ada26866b67e4 Mon Sep 17 00:00:00 2001 From: Joen van de Vorle <90771356+JoenvandeVorle@users.noreply.github.com> Date: Wed, 8 May 2024 15:49:03 +0200 Subject: [PATCH 03/13] test: add unit tests --- Aplib.Core/ExposedQueue.cs | 4 +- Aplib.Tests/Belief/ExposedQueueTests.cs | 204 +++++++++++++++++++++++- 2 files changed, 205 insertions(+), 3 deletions(-) diff --git a/Aplib.Core/ExposedQueue.cs b/Aplib.Core/ExposedQueue.cs index bda0b6fe..82850fb0 100644 --- a/Aplib.Core/ExposedQueue.cs +++ b/Aplib.Core/ExposedQueue.cs @@ -52,10 +52,10 @@ public ExposedQueue(int size) /// The number of actual elements in the array. public ExposedQueue(T[] array, int count = -1) { - Count = count; MaxCount = array.Length; _array = array; _head = MaxCount - 1; + Count = count == -1 ? MaxCount : count; } /// @@ -66,7 +66,7 @@ public ExposedQueue(T[] array, int count = -1) public T this[int index] { get => _array[(index + _head + 1) % MaxCount]; - set => _array[(index + _head + 1) % MaxCount] = value; + private set => _array[(index + _head + 1) % MaxCount] = value; } /// diff --git a/Aplib.Tests/Belief/ExposedQueueTests.cs b/Aplib.Tests/Belief/ExposedQueueTests.cs index 1e721db0..10c03ede 100644 --- a/Aplib.Tests/Belief/ExposedQueueTests.cs +++ b/Aplib.Tests/Belief/ExposedQueueTests.cs @@ -1,17 +1,219 @@ +using System; +using System.Collections.Generic; + namespace Aplib.Core.Tests.Belief; public class ExposedQueueTests { [Fact] - public void ExposedQueue_WhenInitialized_ShouldHaveCorrectMaxCount() + public void ExposedQueue_WhenInitialized_ShouldHaveCorrectMaxCountAndCount() { // Arrange ExposedQueue queue = new(3); // Act int maxCount = queue.MaxCount; + int count = queue.Count; // Assert Assert.Equal(3, maxCount); + Assert.Equal(0, count); + } + + [Fact] + public void ExposedQueue_WhenInitializedWithArray_ShouldHaveCorrectMaxCountAndCount() + { + // Arrange + ExposedQueue queue = new([1, 2, 3]); + + // Act + int maxCount = queue.MaxCount; + int count = queue.Count; + + // Assert + Assert.Equal(3, maxCount); + Assert.Equal(3, count); + } + + [Fact] + public void Put_ArrayIsFull_WrapsAround() + { + // Arrange + ExposedQueue queue = new([4, 3, 2, 1]); + + // Act + queue.Put(5); + + // Assert + Assert.Equal(5, queue[0]); + Assert.Equal(4, queue[1]); + Assert.Equal(2, queue[3]); + } + + [Fact] + public void GetHead_HeadIsUpdated_ReturnsCorrectElement() + { + // Arrange + ExposedQueue queue = new([3, 2, 1]); + + // Act + queue.Put(4); + + // Assert + Assert.Equal(2, queue.GetHead()); + } + + [Fact] + public void GetFirst_HeadIsUpdated_ReturnsFirstElement() + { + // Arrange + ExposedQueue queue = new([3, 2, 1]); + + // Act + queue.Put(4); + + // Assert + Assert.Equal(4, queue.GetFirst()); + } + + [Fact] + public void CopyTo_WrongArguments_ThrowsException() + { + // Arrange + ExposedQueue queue = new([3, 2, 1]); + + // Act + void StartOutOfBounds() => queue.CopyTo(new int[3], -1, 2); + void EndOutOfOunds() => queue.CopyTo(new int[3], 0, 3); + void StartAfterEnd() => queue.CopyTo(new int[3], 2, 1); + void TargetArrayTooSmall() => queue.CopyTo(new int[2], 0, 2); + + // Assert + Assert.Throws(StartOutOfBounds); + Assert.Throws(EndOutOfOunds); + Assert.Throws(StartAfterEnd); + Assert.Throws(TargetArrayTooSmall); + } + + [Fact] + public void CopyTo_CopiesCorrectly() + { + // Arrange + ExposedQueue queue = new([3, 2, 1]); + + // Act + int[] array = new int[3]; + queue.CopyTo(array, 0, 2); + + // Assert + Assert.Equal(array, [3, 2, 1]); + } + + [Fact] + public void CopyTo_DefaultEndIndex_CopiesCorrectly() + { + // Arrange + ExposedQueue queue = new([3, 2, 1]); + + // Act + int[] array = new int[3]; + queue.CopyTo(array, 0); + + // Assert + Assert.Equal(array, [3, 2, 1]); + } + + [Fact] + public void ToArray_ReturnsCorrectArray() + { + // Arrange + ExposedQueue queue = new([3, 2, 1]); + + // Act + int[] array = queue.ToArray(); + + // Assert + Assert.Equal(array, [3, 2, 1]); + } + + [Fact] + public void Clear_QueueFilled_ClearsQueue() + { + // Arrange + ExposedQueue queue = new([3, 2, 1]); + + // Act + queue.Clear(); + + // Assert + Assert.Empty(queue); + } + + [Fact] + public void Contains_ElementExists_ReturnsTrue() + { + // Arrange + ExposedQueue queue = new([3, 2, 1]); + + // Act + bool contains = queue.Contains(2); + + // Assert + Assert.True(contains); + } + + [Fact] + public void Contains_ElementDoesNotExist_ReturnsFalse() + { + // Arrange + ExposedQueue queue = new([3, 2, 1]); + + // Act + bool contains = queue.Contains(4); + + // Assert + Assert.False(contains); + } + + [Fact] + public void Remove_ElementExists_RemovesElement() + { + // Arrange + ExposedQueue queue = new([3, 2, 1]); + + // Act + bool removed = queue.Remove(2); + + // Assert + Assert.True(removed); + Assert.Equal(queue.ToArray(), [3, 0, 1]); + } + + [Fact] + public void Remove_ElementDoesNotExist_ReturnsFalse() + { + // Arrange + ExposedQueue queue = new([3, 2, 1]); + + // Act + bool removed = queue.Remove(4); + + // Assert + Assert.False(removed); + } + + [Fact] + public void GetEnumerator_ReturnsCorrectEnumerator() + { + // Arrange + ExposedQueue queue = new([3, 2, 1]); + + // Act + List list = new(); + foreach (int item in queue) + list.Add(item); + + // Assert + Assert.Equal(list, [3, 2, 1]); } } From 5827c73e6cd7224e9c83afd2a2769a57a99a0d8e Mon Sep 17 00:00:00 2001 From: Joen van de Vorle <90771356+JoenvandeVorle@users.noreply.github.com> Date: Wed, 15 May 2024 10:23:28 +0200 Subject: [PATCH 04/13] chore: resolve some PR feedback move private method, remove debug log, add exception check. work in progress commit so I can work on it on my PC --- Aplib.Core/ExposedQueue.cs | 31 ++++++++++++------------- Aplib.Tests/Belief/ExposedQueueTests.cs | 12 ++++++++++ 2 files changed, 27 insertions(+), 16 deletions(-) diff --git a/Aplib.Core/ExposedQueue.cs b/Aplib.Core/ExposedQueue.cs index 82850fb0..09902197 100644 --- a/Aplib.Core/ExposedQueue.cs +++ b/Aplib.Core/ExposedQueue.cs @@ -19,17 +19,11 @@ public class ExposedQueue : ICollection /// Actual number of elements in the array. /// Limited to . /// - public int Count - { - get => _count; - private set => _count = value > MaxCount ? MaxCount : value; - } + public int Count { get; private set; } /// public bool IsReadOnly => false; - private int _count; - private readonly T[] _array; private int _head; @@ -50,12 +44,17 @@ public ExposedQueue(int size) /// /// An array to use as the circular array. /// The number of actual elements in the array. - public ExposedQueue(T[] array, int count = -1) + public ExposedQueue(T[] array, int? count = null) { + if (count > array.Length) + throw new ArgumentOutOfRangeException(nameof(count), "Count cannot exceed the length of the array."); + if (count < 0) + throw new ArgumentOutOfRangeException(nameof(count), "Count cannot be negative."); + MaxCount = array.Length; _array = array; _head = MaxCount - 1; - Count = count == -1 ? MaxCount : count; + Count = count ?? MaxCount; } /// @@ -69,11 +68,6 @@ public T this[int index] private set => _array[(index + _head + 1) % MaxCount] = value; } - /// - /// Decrements the head of the array. - /// - private void DecrementHead() => _head = (_head - 1 + MaxCount) % MaxCount; - /// /// Puts an element at the start of the array. /// @@ -82,7 +76,8 @@ public void Put(T value) { _array[_head] = value; DecrementHead(); - Count++; + if (Count < MaxCount) + Count++; } /// @@ -135,7 +130,6 @@ public void CopyTo(T[] array, int arrayIndex, int endIndex) /// An array containing the elements within the specified range. public T[] ToArray(int start, int end) { - Console.WriteLine($"Start: {start}, End: {end}"); if (start < 0 || start >= Count) throw new ArgumentOutOfRangeException(nameof(start), "Start index must be within the bounds of the array."); if (end < 0 || end >= Count) @@ -189,5 +183,10 @@ public IEnumerator GetEnumerator() } IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); + + /// + /// Decrements the head of the array. + /// + private void DecrementHead() => _head = (_head - 1 + MaxCount) % MaxCount; } } diff --git a/Aplib.Tests/Belief/ExposedQueueTests.cs b/Aplib.Tests/Belief/ExposedQueueTests.cs index 10c03ede..67102fea 100644 --- a/Aplib.Tests/Belief/ExposedQueueTests.cs +++ b/Aplib.Tests/Belief/ExposedQueueTests.cs @@ -35,6 +35,18 @@ public void ExposedQueue_WhenInitializedWithArray_ShouldHaveCorrectMaxCountAndCo Assert.Equal(3, count); } + [Fact] + public void ExposedQueue_WhenInitializedWithArrayAndCount_ShouldThrowExceptions() + { + // Arrange + void CountExceedsLength() => new ExposedQueue([1, 2, 3], 4); + void NegativeCount() => new ExposedQueue([1, 2, 3], -1); + + // Assert + Assert.Throws(CountExceedsLength); + Assert.Throws(NegativeCount); + } + [Fact] public void Put_ArrayIsFull_WrapsAround() { From a8c1c88dd335ddd23c6e23ed665ad736847c3237 Mon Sep 17 00:00:00 2001 From: JoenvandeVorle Date: Wed, 15 May 2024 17:18:00 +0200 Subject: [PATCH 05/13] chore: resolve PR feedback added exceptions and comments, moved some code, removed remove --- Aplib.Core/ExposedQueue.cs | 58 ++++++++++++++----------- Aplib.Tests/Belief/ExposedQueueTests.cs | 38 ++++++++-------- 2 files changed, 52 insertions(+), 44 deletions(-) diff --git a/Aplib.Core/ExposedQueue.cs b/Aplib.Core/ExposedQueue.cs index 09902197..5d5f27f3 100644 --- a/Aplib.Core/ExposedQueue.cs +++ b/Aplib.Core/ExposedQueue.cs @@ -17,7 +17,6 @@ public class ExposedQueue : ICollection /// /// Actual number of elements in the array. - /// Limited to . /// public int Count { get; private set; } @@ -34,6 +33,7 @@ public class ExposedQueue : ICollection public ExposedQueue(int size) { MaxCount = size; + Count = 0; _array = new T[MaxCount]; _head = MaxCount - 1; } @@ -58,20 +58,30 @@ public ExposedQueue(T[] array, int? count = null) } /// - /// Gets the element at the specified index. + /// Gets the element at the specified index. Throws an exception if the index is out of bounds. /// /// The index of the element to get. /// The element at the specified index. public T this[int index] { - get => _array[(index + _head + 1) % MaxCount]; - private set => _array[(index + _head + 1) % MaxCount] = value; + get + { + if (index < 0 || index >= Count) + throw new ArgumentOutOfRangeException(nameof(index)); + return _array[(index + _head + 1) % MaxCount]; + } + private set + { + if (index < 0 || index >= Count) + throw new ArgumentOutOfRangeException(nameof(index)); + _array[(index + _head + 1) % MaxCount] = value; + } } /// - /// Puts an element at the start of the array. + /// Puts an element at the start of the queue. /// - /// The element to add to the array + /// The element to add to the queue. public void Put(T value) { _array[_head] = value; @@ -84,26 +94,26 @@ public void Put(T value) public void Add(T item) => Put(item); /// - /// Gets the element at the head of the array. + /// Gets the element at the end of the queue. /// - /// The element at the head of the array - public T GetHead() => _array[_head]; + /// The element at the end of the queue. + public T GetLast() => _array[_head]; /// - /// Gets the first element of the array. + /// Gets the first element of the queue. /// - /// The last element of the array + /// The first element of the queue. public T GetFirst() => this[0]; /// - /// Copies the circular array to an array. + /// Copies the ExposedQueue to an array. /// The head should be the last element of the array. /// Copies from start to end inclusive. /// /// The array to copy to." /// The start index of the range to copy. /// The end index of the range to copy. - /// The circular array as a normal array + /// The ExposedQueue as a regular array. public void CopyTo(T[] array, int arrayIndex, int endIndex) { if (arrayIndex < 0 || arrayIndex >= Count) @@ -112,8 +122,6 @@ public void CopyTo(T[] array, int arrayIndex, int endIndex) throw new ArgumentOutOfRangeException(nameof(endIndex)); if (arrayIndex > endIndex) throw new ArgumentException("Start index must be less than or equal to end index."); - if (array.Length < endIndex - arrayIndex + 1) - throw new ArgumentException("Array is too small to copy the range."); for (int i = 0; i < endIndex - arrayIndex + 1; i++) array[i] = this[arrayIndex + i]; @@ -163,17 +171,15 @@ public bool Contains(T item) return false; } - /// - public bool Remove(T item) - { - for (int i = 0; i < Count; i++) - if (this[i]!.Equals(item)) - { - this[i] = default!; - return true; - } - return false; - } + /// + /// DOES NOT DO ANYTHING. + /// + /// False. + /// + /// Method is there to comply with the ICollection interface. + /// Does not actually do anything since this is a queue, and queues do not allow removal of specific elements. + /// + public bool Remove(T item) => false; /// public IEnumerator GetEnumerator() diff --git a/Aplib.Tests/Belief/ExposedQueueTests.cs b/Aplib.Tests/Belief/ExposedQueueTests.cs index 67102fea..758c0613 100644 --- a/Aplib.Tests/Belief/ExposedQueueTests.cs +++ b/Aplib.Tests/Belief/ExposedQueueTests.cs @@ -47,6 +47,22 @@ public void ExposedQueue_WhenInitializedWithArrayAndCount_ShouldThrowExceptions( Assert.Throws(NegativeCount); } + [Fact] + public void AccessIndex_WhenIndexIsOutOfBounds_ThrowsException() + { + // Arrange + ExposedQueue queue = new(3); + int elem; + + // Act + void AccessNegativeIndex() => elem = queue[-1]; + void AccessIndexGreaterThanCount() => elem = queue[queue.Count]; + + // Assert + Assert.Throws(AccessNegativeIndex); + Assert.Throws(AccessIndexGreaterThanCount); + } + [Fact] public void Put_ArrayIsFull_WrapsAround() { @@ -72,7 +88,7 @@ public void GetHead_HeadIsUpdated_ReturnsCorrectElement() queue.Put(4); // Assert - Assert.Equal(2, queue.GetHead()); + Assert.Equal(2, queue.GetLast()); } [Fact] @@ -108,7 +124,7 @@ public void CopyTo_WrongArguments_ThrowsException() } [Fact] - public void CopyTo_CopiesCorrectly() + public void CopyTo_WhenCalled_CopiesCorrectly() { // Arrange ExposedQueue queue = new([3, 2, 1]); @@ -136,7 +152,7 @@ public void CopyTo_DefaultEndIndex_CopiesCorrectly() } [Fact] - public void ToArray_ReturnsCorrectArray() + public void ToArray_WhenCalled_ReturnsCorrectArray() { // Arrange ExposedQueue queue = new([3, 2, 1]); @@ -188,21 +204,7 @@ public void Contains_ElementDoesNotExist_ReturnsFalse() } [Fact] - public void Remove_ElementExists_RemovesElement() - { - // Arrange - ExposedQueue queue = new([3, 2, 1]); - - // Act - bool removed = queue.Remove(2); - - // Assert - Assert.True(removed); - Assert.Equal(queue.ToArray(), [3, 0, 1]); - } - - [Fact] - public void Remove_ElementDoesNotExist_ReturnsFalse() + public void Remove_WhenCalled_ReturnsFalse() { // Arrange ExposedQueue queue = new([3, 2, 1]); From 3c44903e1b798e7619d1822e3d85a5856182d4ae Mon Sep 17 00:00:00 2001 From: JoenvandeVorle Date: Wed, 15 May 2024 17:39:44 +0200 Subject: [PATCH 06/13] fix: tests work again --- Aplib.Core/Belief/MemoryBelief.cs | 7 ++----- Aplib.Tests/Belief/ExposedQueueTests.cs | 2 -- Aplib.Tests/Belief/MemoryBeliefTests.cs | 13 +++++++------ 3 files changed, 9 insertions(+), 13 deletions(-) diff --git a/Aplib.Core/Belief/MemoryBelief.cs b/Aplib.Core/Belief/MemoryBelief.cs index a6f097a8..b7bb09c5 100644 --- a/Aplib.Core/Belief/MemoryBelief.cs +++ b/Aplib.Core/Belief/MemoryBelief.cs @@ -98,15 +98,12 @@ public override void UpdateBelief() /// /// Gets the memorized observation at a specific index. /// A higher index means a memory further back in time. - /// If the index is out of bounds, when clamped, returns the element closest to the index that is in bounds. /// /// The memory of the observation at the specified index. - public TObservation GetMemoryAt(int index, bool clamp = false) + public TObservation GetMemoryAt(int index) { int lastMemoryIndex = _memorizedObservations.Count; - if (clamp) - index = Math.Clamp(index, 0, lastMemoryIndex); - else if (index < 0 || index > lastMemoryIndex) + if (index < 0 || index > lastMemoryIndex) throw new ArgumentOutOfRangeException(nameof(index), $"Index must be between 0 and {lastMemoryIndex}."); return _memorizedObservations[index]; } diff --git a/Aplib.Tests/Belief/ExposedQueueTests.cs b/Aplib.Tests/Belief/ExposedQueueTests.cs index 758c0613..12e8b880 100644 --- a/Aplib.Tests/Belief/ExposedQueueTests.cs +++ b/Aplib.Tests/Belief/ExposedQueueTests.cs @@ -114,13 +114,11 @@ public void CopyTo_WrongArguments_ThrowsException() void StartOutOfBounds() => queue.CopyTo(new int[3], -1, 2); void EndOutOfOunds() => queue.CopyTo(new int[3], 0, 3); void StartAfterEnd() => queue.CopyTo(new int[3], 2, 1); - void TargetArrayTooSmall() => queue.CopyTo(new int[2], 0, 2); // Assert Assert.Throws(StartOutOfBounds); Assert.Throws(EndOutOfOunds); Assert.Throws(StartAfterEnd); - Assert.Throws(TargetArrayTooSmall); } [Fact] diff --git a/Aplib.Tests/Belief/MemoryBeliefTests.cs b/Aplib.Tests/Belief/MemoryBeliefTests.cs index 9e292eef..3cfc8aa8 100644 --- a/Aplib.Tests/Belief/MemoryBeliefTests.cs +++ b/Aplib.Tests/Belief/MemoryBeliefTests.cs @@ -1,4 +1,5 @@ using Aplib.Core.Belief; +using System; using System.Collections.Generic; namespace Aplib.Core.Tests.Belief; @@ -54,22 +55,22 @@ public void GetMemoryAt_WhenObservationIsUpdated_ShouldReturnObservationAtSpecif /// /// Given a MemoryBelief instance with an observation, /// When asking for an index that is out of bounds, - /// Then the closest element that is in bounds is returned. + /// Then an exception should be thrown. /// [Fact] - public void GetMemoryAt_IndexOutOfBounds_ShouldReturnClosestElement() + public void GetMemoryAt_IndexOutOfBounds_ShouldThrowException() { // Arrange List list = [1, 2, 3]; MemoryBelief, int> belief = new(list, reference => reference.Count, 3); // Act - list.Add(4); - belief.UpdateBelief(); + void GetMemoryAtNegativeIndex() => belief.GetMemoryAt(-1); + void GetMemoryAtIndexGreaterThanCount() => belief.GetMemoryAt(3); // Assert - Assert.Equal(3, belief.GetMemoryAt(-1, true)); - Assert.Equal(0, belief.GetMemoryAt(5, true)); + Assert.Throws(GetMemoryAtNegativeIndex); + Assert.Throws(GetMemoryAtIndexGreaterThanCount); } /// From 681ee5e7f0093666f6f6314a38d16e4a401373c3 Mon Sep 17 00:00:00 2001 From: JoenvandeVorle Date: Wed, 15 May 2024 18:32:45 +0200 Subject: [PATCH 07/13] fix: resolve Sonar issues --- Aplib.Core/ExposedQueue.cs | 6 ------ Aplib.Tests/Belief/ExposedQueueTests.cs | 4 ++-- 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/Aplib.Core/ExposedQueue.cs b/Aplib.Core/ExposedQueue.cs index 5d5f27f3..46a1bbbb 100644 --- a/Aplib.Core/ExposedQueue.cs +++ b/Aplib.Core/ExposedQueue.cs @@ -70,12 +70,6 @@ public T this[int index] throw new ArgumentOutOfRangeException(nameof(index)); return _array[(index + _head + 1) % MaxCount]; } - private set - { - if (index < 0 || index >= Count) - throw new ArgumentOutOfRangeException(nameof(index)); - _array[(index + _head + 1) % MaxCount] = value; - } } /// diff --git a/Aplib.Tests/Belief/ExposedQueueTests.cs b/Aplib.Tests/Belief/ExposedQueueTests.cs index 12e8b880..2626e50c 100644 --- a/Aplib.Tests/Belief/ExposedQueueTests.cs +++ b/Aplib.Tests/Belief/ExposedQueueTests.cs @@ -39,8 +39,8 @@ public void ExposedQueue_WhenInitializedWithArray_ShouldHaveCorrectMaxCountAndCo public void ExposedQueue_WhenInitializedWithArrayAndCount_ShouldThrowExceptions() { // Arrange - void CountExceedsLength() => new ExposedQueue([1, 2, 3], 4); - void NegativeCount() => new ExposedQueue([1, 2, 3], -1); + void CountExceedsLength() => _ = new ExposedQueue([1, 2, 3], 4); + void NegativeCount() => _ = new ExposedQueue([1, 2, 3], -1); // Assert Assert.Throws(CountExceedsLength); From 8af5c515d18cce7c8938d730e2be4038b8560573 Mon Sep 17 00:00:00 2001 From: JoenvandeVorle Date: Thu, 16 May 2024 14:24:39 +0200 Subject: [PATCH 08/13] feat: add remove implementation also added/improved tests and resolved some PR feedback --- Aplib.Core/ExposedQueue.cs | 63 +++++++++-- Aplib.Tests/Belief/ExposedQueueTests.cs | 144 +++++++++++++++++------- 2 files changed, 158 insertions(+), 49 deletions(-) diff --git a/Aplib.Core/ExposedQueue.cs b/Aplib.Core/ExposedQueue.cs index 46a1bbbb..8faf9fb5 100644 --- a/Aplib.Core/ExposedQueue.cs +++ b/Aplib.Core/ExposedQueue.cs @@ -7,7 +7,13 @@ namespace Aplib.Core /// /// A queue with all elements exposed. /// Functionally works like a queue with indexing. + /// It has a MaxCount and Count. MaxCount being the maximal length of the queue, + /// and Count being the actual number of elements in the queue. /// + /// + /// When adding an element to a full queue, all other elements are shifted one place like so: + /// [4, 3, 2, 1], Put(5) => [5, 4, 3, 2] + /// public class ExposedQueue : ICollection { /// @@ -27,9 +33,9 @@ public class ExposedQueue : ICollection private int _head; /// - /// Initializes a new instance of the class. + /// Initializes a new empty instance of the class. /// - /// The size of the array. + /// The maximum size of the queue. public ExposedQueue(int size) { MaxCount = size; @@ -39,11 +45,16 @@ public ExposedQueue(int size) } /// - /// Initializes a new instance of the class. - /// By default, assumes the array is filled. + /// Initializes a new instance of the class + /// with an array to use as basis for the queue. + /// By default, assumes the array is filled. /// /// An array to use as the circular array. /// The number of actual elements in the array. + /// + /// The MaxCount of the queue will be set to the length of the array. + /// If the array is not fully filled, the Count should be specified. + /// public ExposedQueue(T[] array, int? count = null) { if (count > array.Length) @@ -62,6 +73,9 @@ public ExposedQueue(T[] array, int? count = null) /// /// The index of the element to get. /// The element at the specified index. + /// + /// Thrown when the index is out of range. + /// public T this[int index] { get @@ -70,6 +84,12 @@ public T this[int index] throw new ArgumentOutOfRangeException(nameof(index)); return _array[(index + _head + 1) % MaxCount]; } + private set + { + if (index < 0 || index >= Count) + throw new ArgumentOutOfRangeException(nameof(index)); + _array[(index + _head + 1) % MaxCount] = value; + } } /// @@ -166,15 +186,28 @@ public bool Contains(T item) } /// - /// DOES NOT DO ANYTHING. + /// Removes the specified item from the queue and shifts remaining elements to the left. + /// For example, given the queue [4, 3, 2, 1], if you call Remove(3), the resulting queue will be [4, 2, 1]. /// - /// False. + /// The item to remove. + /// True if the item was successfully removed; otherwise, false. /// - /// Method is there to comply with the ICollection interface. - /// Does not actually do anything since this is a queue, and queues do not allow removal of specific elements. + /// The MaxCount will not change, but the Count will decrease by one. /// - public bool Remove(T item) => false; + public bool Remove(T item) + { + for (int i = 0; i < Count; i++) + { + if (this[i]!.Equals(item)) + { + RemoveAt(i); + return true; + } + } + return false; + } + /// public IEnumerator GetEnumerator() { @@ -188,5 +221,17 @@ public IEnumerator GetEnumerator() /// Decrements the head of the array. /// private void DecrementHead() => _head = (_head - 1 + MaxCount) % MaxCount; + + /// + /// Removes the element at the specified index. + /// Shifts all other elements to the left. + /// + /// The index of the element to remove. + private void RemoveAt(int index) + { + for (int i = index; i < Count - 1; i++) + this[i] = this[i + 1]; + Count--; + } } } diff --git a/Aplib.Tests/Belief/ExposedQueueTests.cs b/Aplib.Tests/Belief/ExposedQueueTests.cs index 2626e50c..bb7260c1 100644 --- a/Aplib.Tests/Belief/ExposedQueueTests.cs +++ b/Aplib.Tests/Belief/ExposedQueueTests.cs @@ -20,66 +20,96 @@ public void ExposedQueue_WhenInitialized_ShouldHaveCorrectMaxCountAndCount() Assert.Equal(0, count); } - [Fact] - public void ExposedQueue_WhenInitializedWithArray_ShouldHaveCorrectMaxCountAndCount() + [Theory] + [InlineData(new int[] {1, 2, 3}, null, 3, 3)] + [InlineData(new int[] {1, 2, 0, 0}, 2, 4, 2)] + public void ExposedQueue_WhenInitializedWithArray_ShouldHaveCorrectMaxCountAndCount(int[] array, int? countParam, int expectedMaxCount, int expectedCount) { // Arrange - ExposedQueue queue = new([1, 2, 3]); + ExposedQueue queue = new(array, countParam); // Act int maxCount = queue.MaxCount; int count = queue.Count; // Assert - Assert.Equal(3, maxCount); - Assert.Equal(3, count); + Assert.Equal(expectedMaxCount, maxCount); + Assert.Equal(expectedCount, count); } [Fact] - public void ExposedQueue_WhenInitializedWithArrayAndCount_ShouldThrowExceptions() + public void ExposedQueue_WhenInitializedWithArrayAndCount_ShouldSetHeadCorrectly() { // Arrange - void CountExceedsLength() => _ = new ExposedQueue([1, 2, 3], 4); - void NegativeCount() => _ = new ExposedQueue([1, 2, 3], -1); + ExposedQueue queue = new([1,0,0], 1); + ExposedQueue expected = new([3,2,1]); + + // Act + queue.Put(2); + queue.Put(3); // Assert + Assert.Equal(expected, queue); + } + + [Fact] + public void ExposedQueue_WhenInitializedWithCountExceedingLength_ShouldThrowException() + { + // Arrange + void CountExceedsLength() => _ = new ExposedQueue([1, 2, 3], 4); + + // Act & Assert Assert.Throws(CountExceedsLength); - Assert.Throws(NegativeCount); } [Fact] - public void AccessIndex_WhenIndexIsOutOfBounds_ThrowsException() + public void ExposedQueue_WhenInitializedWithNegativeCount_ShouldThrowException() { // Arrange - ExposedQueue queue = new(3); - int elem; + void NegativeCount() => _ = new ExposedQueue([1, 2, 3], -1); - // Act - void AccessNegativeIndex() => elem = queue[-1]; - void AccessIndexGreaterThanCount() => elem = queue[queue.Count]; + // Act & Assert + Assert.Throws(NegativeCount); + } + + [Fact] + public void AccessIndex_WhenIndexIsNegative_ThrowsException() + { + // Arrange + void AccessNegativeIndex() => _ = new ExposedQueue(3)[-1]; - // Assert + // Act & Assert Assert.Throws(AccessNegativeIndex); + } + + [Fact] + public void AccessIndex_WhenIndexIsGreaterThanCount_ThrowsException() + { + // Arrange + void AccessIndexGreaterThanCount() => _ = new ExposedQueue(3)[4]; + + // Act & Assert Assert.Throws(AccessIndexGreaterThanCount); } + [Fact] public void Put_ArrayIsFull_WrapsAround() { // Arrange ExposedQueue queue = new([4, 3, 2, 1]); + ExposedQueue expected = new([5, 4, 3, 2]); // Act queue.Put(5); // Assert - Assert.Equal(5, queue[0]); - Assert.Equal(4, queue[1]); - Assert.Equal(2, queue[3]); + Assert.Equal(expected.Count, queue.Count); + Assert.Equal(expected, queue); } [Fact] - public void GetHead_HeadIsUpdated_ReturnsCorrectElement() + public void GetLast_HeadIsUpdated_ReturnsCorrectElement() { // Arrange ExposedQueue queue = new([3, 2, 1]); @@ -105,20 +135,33 @@ public void GetFirst_HeadIsUpdated_ReturnsFirstElement() } [Fact] - public void CopyTo_WrongArguments_ThrowsException() + public void CopyTo_WhenStartIndexIsNegative_ThrowsException() { // Arrange - ExposedQueue queue = new([3, 2, 1]); + ExposedQueue queue = new([3,2,1]); - // Act - void StartOutOfBounds() => queue.CopyTo(new int[3], -1, 2); - void EndOutOfOunds() => queue.CopyTo(new int[3], 0, 3); - void StartAfterEnd() => queue.CopyTo(new int[3], 2, 1); + // Assert + Assert.Throws(() => queue.CopyTo(new int[3], -1, 2)); + } + + [Fact] + public void CopyTo_WhenEndIndexIsOutOfBounds_ThrowsException() + { + // Arrange + ExposedQueue queue = new([3,2,1]); + + // Assert + Assert.Throws(() => queue.CopyTo(new int[3], 0, 3)); + } + + [Fact] + public void CopyTo_WhenStartIndexIsAfterEndIndex_ThrowsException() + { + // Arrange + ExposedQueue queue = new([3,2,1]); // Assert - Assert.Throws(StartOutOfBounds); - Assert.Throws(EndOutOfOunds); - Assert.Throws(StartAfterEnd); + Assert.Throws(() => queue.CopyTo(new int[3], 2, 1)); } [Fact] @@ -175,43 +218,64 @@ public void Clear_QueueFilled_ClearsQueue() Assert.Empty(queue); } - [Fact] - public void Contains_ElementExists_ReturnsTrue() + [Theory] + [InlineData(2, true)] + [InlineData(4, false)] + public void Contains_OnElement_ReturnsCorrectAnswer(int element, bool expected) { // Arrange ExposedQueue queue = new([3, 2, 1]); // Act - bool contains = queue.Contains(2); + bool contains = queue.Contains(element); // Assert - Assert.True(contains); + Assert.Equal(expected, contains); } [Fact] - public void Contains_ElementDoesNotExist_ReturnsFalse() + public void Remove_WhenCalledOnMissingElement_ReturnsFalse() { // Arrange ExposedQueue queue = new([3, 2, 1]); // Act - bool contains = queue.Contains(4); + bool removed = queue.Remove(4); // Assert - Assert.False(contains); + Assert.False(removed); } [Fact] - public void Remove_WhenCalled_ReturnsFalse() + public void Remove_WhenCalledOnExistingElement_RemovesElement() { // Arrange - ExposedQueue queue = new([3, 2, 1]); + ExposedQueue queue = new([4, 3, 2, 1]); + ExposedQueue expected = new([4, 2, 1]); // Act - bool removed = queue.Remove(4); + bool removed = queue.Remove(3); // Assert - Assert.False(removed); + Assert.True(removed); + Assert.Equal(expected.Count, queue.Count); + Assert.Equal(expected, queue); + } + + [Fact] + public void Put_AfterRemoval_StillHasCorrectHead() + { + // Arrange + ExposedQueue queue = new([4, 3, 1, 2]); + ExposedQueue expected = new([5, 4, 3, 2]); + + // Act + queue.Remove(1); + queue.Put(5); + + // Assert + Assert.Equal(expected.Count, queue.Count); + Assert.Equal(expected, queue); } [Fact] From a9f1a32b815c5e686949a37789a1dbe5595132be Mon Sep 17 00:00:00 2001 From: JoenvandeVorle Date: Thu, 16 May 2024 14:37:12 +0200 Subject: [PATCH 09/13] chore: conform to sonar --- Aplib.Tests/Belief/ExposedQueueTests.cs | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/Aplib.Tests/Belief/ExposedQueueTests.cs b/Aplib.Tests/Belief/ExposedQueueTests.cs index bb7260c1..0d5bed0e 100644 --- a/Aplib.Tests/Belief/ExposedQueueTests.cs +++ b/Aplib.Tests/Belief/ExposedQueueTests.cs @@ -20,9 +20,15 @@ public void ExposedQueue_WhenInitialized_ShouldHaveCorrectMaxCountAndCount() Assert.Equal(0, count); } + public static readonly object?[][] ArrayAndCountParams = + [ + // array, count, expectedMaxCount, expectedCount + [new int[] {1, 2, 3}, null, 3, 3], + [new int[] {1, 2, 0, 0}, 2, 4, 2] + ]; + [Theory] - [InlineData(new int[] {1, 2, 3}, null, 3, 3)] - [InlineData(new int[] {1, 2, 0, 0}, 2, 4, 2)] + [MemberData(nameof(ArrayAndCountParams))] public void ExposedQueue_WhenInitializedWithArray_ShouldHaveCorrectMaxCountAndCount(int[] array, int? countParam, int expectedMaxCount, int expectedCount) { // Arrange From 8da808518ac0184b9b3123b15efe9d07375c9fde Mon Sep 17 00:00:00 2001 From: Joen van de Vorle <90771356+JoenvandeVorle@users.noreply.github.com> Date: Mon, 20 May 2024 10:22:17 +0200 Subject: [PATCH 10/13] feat: add back clamping --- Aplib.Core/Belief/MemoryBelief.cs | 8 ++++++-- Aplib.Core/ExposedQueue.cs | 6 +++--- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/Aplib.Core/Belief/MemoryBelief.cs b/Aplib.Core/Belief/MemoryBelief.cs index b7bb09c5..4f8d5fc0 100644 --- a/Aplib.Core/Belief/MemoryBelief.cs +++ b/Aplib.Core/Belief/MemoryBelief.cs @@ -100,10 +100,14 @@ public override void UpdateBelief() /// A higher index means a memory further back in time. /// /// The memory of the observation at the specified index. - public TObservation GetMemoryAt(int index) + /// The index of the memory to get. + /// If true, the index will be clamped between 0 and the last memory index. + public TObservation GetMemoryAt(int index, bool clamp = false) { int lastMemoryIndex = _memorizedObservations.Count; - if (index < 0 || index > lastMemoryIndex) + if (clamp) + index = Math.Clamp(index, 0, lastMemoryIndex); + else if (index < 0 || index > lastMemoryIndex) throw new ArgumentOutOfRangeException(nameof(index), $"Index must be between 0 and {lastMemoryIndex}."); return _memorizedObservations[index]; } diff --git a/Aplib.Core/ExposedQueue.cs b/Aplib.Core/ExposedQueue.cs index 8faf9fb5..9b1035ba 100644 --- a/Aplib.Core/ExposedQueue.cs +++ b/Aplib.Core/ExposedQueue.cs @@ -78,13 +78,13 @@ public ExposedQueue(T[] array, int? count = null) /// public T this[int index] { - get + get { if (index < 0 || index >= Count) throw new ArgumentOutOfRangeException(nameof(index)); return _array[(index + _head + 1) % MaxCount]; } - private set + private set { if (index < 0 || index >= Count) throw new ArgumentOutOfRangeException(nameof(index)); @@ -207,7 +207,7 @@ public bool Remove(T item) return false; } - + /// public IEnumerator GetEnumerator() { From 83b5459b140d2de91692a1fa1eb8097869ebb8d6 Mon Sep 17 00:00:00 2001 From: Joen van de Vorle <90771356+JoenvandeVorle@users.noreply.github.com> Date: Mon, 27 May 2024 10:24:39 +0200 Subject: [PATCH 11/13] chore: move files according to new structure --- Aplib.Core.Tests/Collections/ExposedQueueTests.cs | 1 + Aplib.Core/{ => Collections}/ExposedQueue.cs | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) rename Aplib.Core/{ => Collections}/ExposedQueue.cs (99%) diff --git a/Aplib.Core.Tests/Collections/ExposedQueueTests.cs b/Aplib.Core.Tests/Collections/ExposedQueueTests.cs index ee878e9f..57812986 100644 --- a/Aplib.Core.Tests/Collections/ExposedQueueTests.cs +++ b/Aplib.Core.Tests/Collections/ExposedQueueTests.cs @@ -1,3 +1,4 @@ +using Aplib.Core.Collections; using System; using System.Collections.Generic; diff --git a/Aplib.Core/ExposedQueue.cs b/Aplib.Core/Collections/ExposedQueue.cs similarity index 99% rename from Aplib.Core/ExposedQueue.cs rename to Aplib.Core/Collections/ExposedQueue.cs index 9b1035ba..cbdc4f06 100644 --- a/Aplib.Core/ExposedQueue.cs +++ b/Aplib.Core/Collections/ExposedQueue.cs @@ -2,7 +2,7 @@ using System.Collections; using System.Collections.Generic; -namespace Aplib.Core +namespace Aplib.Core.Collections { /// /// A queue with all elements exposed. From d805138ee8ceccd6429724fb0b9686f68eb15e68 Mon Sep 17 00:00:00 2001 From: Joen van de Vorle <90771356+JoenvandeVorle@users.noreply.github.com> Date: Mon, 27 May 2024 10:32:20 +0200 Subject: [PATCH 12/13] fix: tests work again --- Aplib.Core.Tests/Belief/MemoryBeliefTests.cs | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/Aplib.Core.Tests/Belief/MemoryBeliefTests.cs b/Aplib.Core.Tests/Belief/MemoryBeliefTests.cs index 3f80150e..b640a4a4 100644 --- a/Aplib.Core.Tests/Belief/MemoryBeliefTests.cs +++ b/Aplib.Core.Tests/Belief/MemoryBeliefTests.cs @@ -1,4 +1,5 @@ using Aplib.Core.Belief.Beliefs; +using System; using System.Collections.Generic; namespace Aplib.Core.Tests.Belief; @@ -54,22 +55,22 @@ public void GetMemoryAt_WhenObservationIsUpdated_ShouldReturnObservationAtSpecif /// /// Given a MemoryBelief instance with an observation, /// When asking for an index that is out of bounds, - /// Then the closest element that is in bounds is returned. + /// Then an exception should be thrown. /// [Fact] - public void GetMemoryAt_IndexOutOfBounds_ShouldReturnClosestElement() + public void GetMemoryAt_IndexOutOfBounds_ShouldThrowException() { // Arrange List list = [1, 2, 3]; MemoryBelief, int> belief = new(list, reference => reference.Count, 3); // Act - list.Add(4); - belief.UpdateBelief(); + void GetMemoryAtNegativeIndex() => belief.GetMemoryAt(-1); + void GetMemoryAtIndexGreaterThanCount() => belief.GetMemoryAt(3); // Assert - Assert.Equal(3, belief.GetMemoryAt(-1, true)); - Assert.Equal(0, belief.GetMemoryAt(5, true)); + Assert.Throws(GetMemoryAtNegativeIndex); + Assert.Throws(GetMemoryAtIndexGreaterThanCount); } /// @@ -89,6 +90,6 @@ public void GetAllMemories_ReturnsAllMemories() belief.UpdateBelief(); // Assert - Assert.Equal([3, 0, 0], belief.GetAllMemories()); + Assert.Equal([3], belief.GetAllMemories()); } } From da344b3ae383bbfc52981675eadb346434e1edc2 Mon Sep 17 00:00:00 2001 From: Joen van de Vorle <90771356+JoenvandeVorle@users.noreply.github.com> Date: Mon, 27 May 2024 14:47:20 +0200 Subject: [PATCH 13/13] chore: rename folder --- Aplib.Core/Belief/{BeliefSet => BeliefSets}/BeliefSet.cs | 0 Aplib.Core/Belief/{BeliefSet => BeliefSets}/IBeliefSet.cs | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename Aplib.Core/Belief/{BeliefSet => BeliefSets}/BeliefSet.cs (100%) rename Aplib.Core/Belief/{BeliefSet => BeliefSets}/IBeliefSet.cs (100%) diff --git a/Aplib.Core/Belief/BeliefSet/BeliefSet.cs b/Aplib.Core/Belief/BeliefSets/BeliefSet.cs similarity index 100% rename from Aplib.Core/Belief/BeliefSet/BeliefSet.cs rename to Aplib.Core/Belief/BeliefSets/BeliefSet.cs diff --git a/Aplib.Core/Belief/BeliefSet/IBeliefSet.cs b/Aplib.Core/Belief/BeliefSets/IBeliefSet.cs similarity index 100% rename from Aplib.Core/Belief/BeliefSet/IBeliefSet.cs rename to Aplib.Core/Belief/BeliefSets/IBeliefSet.cs