Introduce ThingPicker.

Things work best as hardwired, atomic pieces of "stuff", so fitting RNG
into the framework is a little difficult. We could have a RandomThing,
but the issue with that is that the entropy has to live inside of it for
it to be random every time it is given, taken, or checked. This makes it
impossible to make a well-defined, atomic Thing with entropy involved.

Enter the pickers.

The ThingPicker is an early stage extension to the Things framework that
encapsulates the possibilities of entropy and grouping _around_ Things,
a type of Factory pattern.

This introductory stage consists of a "leaf picker" that can only ever
pick a single Thing, a Composite Pattern "group picker" that wraps a
list of other pickers and shoves their resulting Thing instances into a
ThingGroup (introduced in the previous commit).

These simple constructs should now make it possible to introduce entropy
without placing the responsibility on the Thing framework itself. Using
this extension requires adapting code to using the ThingPicker interface
instead of using Thing directly.
This commit is contained in:
Andreas Troelsen
2020-08-22 16:10:07 +02:00
parent e1784552de
commit e8bb8a9e4d
6 changed files with 190 additions and 0 deletions
@@ -0,0 +1,45 @@
package com.garbagemule.MobArena.things;
import org.junit.Before;
import org.junit.Test;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
public class RandomThingPickerTest {
private RandomThingPicker subject;
private List<ThingPicker> pickers;
private Random random;
@Before
public void setup() {
pickers = new ArrayList<>();
random = mock(Random.class);
subject = new RandomThingPicker(pickers, random);
}
@Test
public void invokesOnlyChosenPicker() {
ThingPicker decoy = mock(ThingPicker.class);
ThingPicker chosen = mock(ThingPicker.class);
pickers.add(decoy);
pickers.add(decoy);
pickers.add(chosen);
pickers.add(decoy);
when(random.nextInt(pickers.size())).thenReturn(2);
subject.pick();
verify(decoy, never()).pick();
verify(chosen, times(1)).pick();
}
}
@@ -0,0 +1,40 @@
package com.garbagemule.MobArena.things;
import org.junit.Before;
import org.junit.Test;
import java.util.ArrayList;
import java.util.List;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
public class ThingGroupPickerTest {
private ThingGroupPicker subject;
private List<ThingPicker> pickers;
@Before
public void setup() {
pickers = new ArrayList<>();
subject = new ThingGroupPicker(pickers);
}
@Test
public void invokesAllPickers() {
ThingPicker first = mock(ThingPicker.class);
ThingPicker second = mock(ThingPicker.class);
ThingPicker third = mock(ThingPicker.class);
pickers.add(first);
pickers.add(second);
pickers.add(third);
subject.pick();
verify(first, times(1)).pick();
verify(second, times(1)).pick();
verify(third, times(1)).pick();
}
}