Skip to content

Commit 5ec3706

Browse files
author
Bytekeeper
committed
Only use utility of un-finished children; more documentation
1 parent 01920f4 commit 5ec3706

File tree

7 files changed

+145
-3
lines changed

7 files changed

+145
-3
lines changed

src/main/java/org/bk/ass/bt/CompoundNode.java

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,11 @@ protected void execChild(TreeNode child, ExecutionContext context) {
2929
}
3030

3131
protected void abortRunningChildren() {
32-
children.stream().filter(it -> it.status == NodeStatus.RUNNING).forEach(TreeNode::abort);
32+
for (TreeNode it : children) {
33+
if (it.status == NodeStatus.RUNNING) {
34+
it.abort();
35+
}
36+
}
3337
}
3438

3539
@Override
@@ -44,9 +48,14 @@ public void close() {
4448
children.forEach(TreeNode::close);
4549
}
4650

51+
/**
52+
* Will return the highest utility of all children which are still running or not yet executed.
53+
*/
4754
@Override
4855
public double getUtility() {
49-
return children.stream().mapToDouble(TreeNode::getUtility).max().orElseGet(super::getUtility);
56+
return children.stream()
57+
.filter(it -> it.status == NodeStatus.INITIAL || it.status == NodeStatus.RUNNING)
58+
.mapToDouble(TreeNode::getUtility).max().orElseGet(super::getUtility);
5059
}
5160

5261
@Override

src/main/java/org/bk/ass/bt/Parallel.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,11 @@
22

33
import org.bk.ass.StopWatch;
44

5+
/**
6+
* Using a {@link Policy}, a behavior similar to {@link Sequence} or {@link Selector}. But Parallel
7+
* will not wait for a {@link NodeStatus#RUNNING} node to complete and just {@link
8+
* #exec(ExecutionContext)} the next child node.
9+
*/
510
public class Parallel extends CompoundNode {
611

712
private Policy policy;

src/main/java/org/bk/ass/bt/Selector.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,13 @@
22

33
import org.bk.ass.StopWatch;
44

5+
/**
6+
* Reactive Selector node: Every time {@link #exec(ExecutionContext)} is called all nodes are
7+
* executed in order. Even if they are in a non-running state. {@link NodeStatus#SUCCESS} will be
8+
* returned, as soon as any child node succeeds.
9+
*
10+
* <p>In case it succeeds, all children in state {@link NodeStatus#RUNNING} will get aborted.
11+
*/
512
public class Selector extends CompoundNode {
613

714
public Selector(TreeNode... children) {

src/main/java/org/bk/ass/bt/Sequence.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,14 @@
22

33
import org.bk.ass.StopWatch;
44

5+
/**
6+
* Reactive Sequence node: Every time {@link #exec(ExecutionContext)} is called all nodes are
7+
* executed in order. Even if they are in a non-running state. {@link NodeStatus#SUCCESS} will only
8+
* be returned, if all child nodes return that value.
9+
*
10+
* <p>If any child fails, the Sequence will also fail. In that case, all children in state {@link
11+
* NodeStatus#RUNNING} will get aborted.
12+
*/
513
public class Sequence extends CompoundNode {
614

715
public Sequence(TreeNode... children) {

src/main/java/org/bk/ass/bt/TreeNode.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package org.bk.ass.bt;
22

33
public abstract class TreeNode {
4+
45
String name = getClass().getSimpleName();
56
NodeStatus status;
67

@@ -16,6 +17,11 @@ public void exec(ExecutionContext executionContext) {
1617

1718
public abstract void exec();
1819

20+
/**
21+
* Used by {@link CompoundNode}s to determine order of execution. Generally, nodes with {@link
22+
* Selector} like behavior will run children in decreasing order of utility. Nodes with {@link
23+
* Sequence} like behavior will not change the order of children unless explicitly stated.
24+
*/
1925
public double getUtility() {
2026
return 0;
2127
}
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
package org.bk.ass.bt;
2+
3+
import static org.assertj.core.api.Assertions.assertThat;
4+
5+
import org.junit.jupiter.api.Test;
6+
7+
class CompoundNodeTest {
8+
9+
@Test
10+
void shouldReturnUtilityOfChildInInitialState() {
11+
// GIVEN
12+
DummyCompound sut = new DummyCompound(
13+
new NodeWithUtility(1.0, NodeStatus.SUCCESS),
14+
new NodeWithUtility(0.5, NodeStatus.INITIAL)
15+
);
16+
17+
// WHEN
18+
double utility = sut.getUtility();
19+
20+
// THEN
21+
assertThat(utility).isEqualTo(0.5);
22+
}
23+
24+
@Test
25+
void shouldReturnUtilityOfChildInRunningState() {
26+
// GIVEN
27+
DummyCompound sut = new DummyCompound(
28+
new NodeWithUtility(1.0, NodeStatus.SUCCESS),
29+
new NodeWithUtility(0.5, NodeStatus.RUNNING)
30+
);
31+
32+
// WHEN
33+
double utility = sut.getUtility();
34+
35+
// THEN
36+
assertThat(utility).isEqualTo(0.5);
37+
}
38+
39+
@Test
40+
void shouldReturnHighestUtilityOfChildren() {
41+
// GIVEN
42+
DummyCompound sut = new DummyCompound(
43+
new NodeWithUtility(1.0, NodeStatus.INITIAL),
44+
new NodeWithUtility(0.5, NodeStatus.RUNNING)
45+
);
46+
47+
// WHEN
48+
double utility = sut.getUtility();
49+
50+
// THEN
51+
assertThat(utility).isEqualTo(1.0);
52+
}
53+
54+
private static class DummyCompound extends CompoundNode {
55+
56+
public DummyCompound(TreeNode... children) {
57+
super(children);
58+
}
59+
60+
@Override
61+
public void exec(ExecutionContext context) {
62+
63+
}
64+
}
65+
66+
private static class NodeWithUtility extends TreeNode {
67+
68+
private final double utility;
69+
70+
NodeWithUtility(double utility, NodeStatus status) {
71+
this.utility = utility;
72+
this.status = status;
73+
}
74+
75+
@Override
76+
public double getUtility() {
77+
return utility;
78+
}
79+
80+
@Override
81+
public void exec() {
82+
83+
}
84+
}
85+
}

src/test/java/org/bk/ass/sim/SimulatorTest.java

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -519,7 +519,29 @@ void _8DragoonsVs6Hydras() {
519519
simulator.simulate(-1);
520520

521521
// THEN
522-
assertThat(simulator.getAgentsA()).size().isLessThanOrEqualTo(3);
522+
assertThat(simulator.getAgentsA()).hasSizeLessThanOrEqualTo(3);
523+
assertThat(simulator.getAgentsB()).isEmpty();
524+
}
525+
526+
@Test
527+
void _8DragoonsWithRangeUpgradeVs6Hydras() {
528+
// GIVEN
529+
for (int i = 0; i < 8; i++) {
530+
simulator.addAgentA(factory.of(UnitType.Protoss_Dragoon, 0, 0, 64, 64, false, false, false).setX(1000 + i * 8).setY(800));
531+
}
532+
for (int i = 0; i < 6; i++) {
533+
simulator.addAgentB(
534+
factory
535+
.of(UnitType.Zerg_Hydralisk, 0, 0, 0, 0, false, false, false)
536+
.setX(1000 + i * 8)
537+
.setY(1200));
538+
}
539+
540+
// WHEN
541+
simulator.simulate(-1);
542+
543+
// THEN
544+
assertThat(simulator.getAgentsA()).hasSize(8);
523545
assertThat(simulator.getAgentsB()).isEmpty();
524546
}
525547

0 commit comments

Comments
 (0)