Implementing Alts
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
First output. 1 1 0 1
|
||||
Second output. 1 1 1 1
|
||||
1 1 1 2
|
||||
1 1 1 2
|
||||
Third output.
|
||||
Fourth output.
|
||||
Fifth output.
|
||||
|
||||
@@ -13,6 +13,7 @@ enum AltBehavior {
|
||||
}
|
||||
|
||||
@:allow(hank.AltInstance)
|
||||
@:allow(hank.Output)
|
||||
class Alt {
|
||||
var behavior: AltBehavior;
|
||||
var outputs: Array<Output>;
|
||||
@@ -22,7 +23,7 @@ class Alt {
|
||||
'!' => OnceOnly,
|
||||
'&' => Cycle,
|
||||
'~' => Shuffle,
|
||||
'seq:' => Sequence,
|
||||
'sequence:' => Sequence,
|
||||
'once:' => OnceOnly,
|
||||
'cycle:' => Cycle,
|
||||
'shuffle:' => Shuffle
|
||||
|
||||
@@ -2,6 +2,8 @@ package hank;
|
||||
|
||||
import haxe.ds.Option;
|
||||
|
||||
import hank.Alt.AltInstance;
|
||||
|
||||
typedef Choice = {id: Int, onceOnly: Bool, label: Option<String>, condition: Option<String>, depth: Int, output: Output, divertTarget: Option<String>};
|
||||
|
||||
enum ExprType {
|
||||
|
||||
@@ -6,6 +6,7 @@ import haxe.ds.Option;
|
||||
using Extensions.Extensions;
|
||||
|
||||
import hank.StoryTree;
|
||||
import hank.Alt.AltInstance;
|
||||
|
||||
enum OutputType {
|
||||
Text(t: String); // Pure text that is always displayed
|
||||
@@ -150,7 +151,7 @@ class Output {
|
||||
|
||||
}
|
||||
|
||||
public function format(hInterface: HInterface, scope: Array<StoryNode>, displayToggles: Bool): String {
|
||||
public function format(story: Story, hInterface: HInterface, random: Random, altInstances: Map<Alt, AltInstance>, scope: Array<StoryNode>, displayToggles: Bool): String {
|
||||
var fullOutput = '';
|
||||
|
||||
for (part in parts) {
|
||||
@@ -158,14 +159,28 @@ class Output {
|
||||
case Text(t):
|
||||
fullOutput += t;
|
||||
case AltExpression(a):
|
||||
// TODO evaluate the alt expression deterministically
|
||||
// If this alt hasn't been evaluated yet, we need to make an instance for it
|
||||
if (!altInstances.exists(a)) {
|
||||
altInstances[a] = new AltInstance(a.behavior, a.outputs, random);
|
||||
}
|
||||
trace(a);
|
||||
trace([for(key in altInstances.keys()) key].length);
|
||||
trace(altInstances[a]);
|
||||
fullOutput += altInstances[a].next().format(story, hInterface, random, altInstances, scope, displayToggles);
|
||||
case HExpression(h):
|
||||
fullOutput += hInterface.evaluateExpr(h, scope);
|
||||
case InlineDivert(t):
|
||||
// TODO follow the divert. If the next expression is an output, concatenate the pieces together. Otherwise, terminate formatting
|
||||
// follow the divert. If the next expression is an output, concatenate the pieces together. Otherwise, terminate formatting
|
||||
story.divertTo(t);
|
||||
switch (story.nextFrame()) {
|
||||
case HasText(text):
|
||||
fullOutput += text;
|
||||
default:
|
||||
}
|
||||
|
||||
case ToggleOutput(o, b):
|
||||
if (b == displayToggles) {
|
||||
fullOutput += o.format(hInterface, scope, displayToggles);
|
||||
fullOutput += o.format(story, hInterface, random, altInstances, scope, displayToggles);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package hank;
|
||||
|
||||
using StringTools;
|
||||
import haxe.ds.Option;
|
||||
|
||||
using hank.Extensions;
|
||||
@@ -7,6 +8,7 @@ using HankAST.ASTExtension;
|
||||
using HankAST.Choice;
|
||||
import hank.HankAST.ExprType;
|
||||
import hank.StoryTree;
|
||||
import hank.Alt.AltInstance;
|
||||
|
||||
/**
|
||||
Possible states of the story being executed.
|
||||
@@ -31,6 +33,7 @@ class Story {
|
||||
var storyTree: StoryNode;
|
||||
var viewCounts: Map<StoryNode, Int>;
|
||||
var nodeScopes: Array<StoryNode>;
|
||||
var altInstances: Map<Alt, AltInstance> = new Map();
|
||||
|
||||
var parser: Parser;
|
||||
|
||||
@@ -109,7 +112,7 @@ class Story {
|
||||
switch (expr) {
|
||||
case EOutput(output):
|
||||
exprIndex += 1;
|
||||
return HasText(output.format(hInterface, nodeScopes, false));
|
||||
return HasText(output.format(this, hInterface, random, altInstances, nodeScopes, false).trim());
|
||||
case EHaxeLine(h):
|
||||
exprIndex += 1;
|
||||
|
||||
@@ -142,7 +145,7 @@ class Story {
|
||||
return nextFrame();
|
||||
}
|
||||
|
||||
var optionsText = [for(c in availableChoices()) c.output.format(hInterface, nodeScopes, false)];
|
||||
var optionsText = [for(c in availableChoices()) c.output.format(this, hInterface, random, altInstances, nodeScopes, false)];
|
||||
if (optionsText.length > 0) {
|
||||
return HasChoices(optionsText);
|
||||
} else {
|
||||
@@ -319,7 +322,7 @@ class Story {
|
||||
exprIndex = ast.indexOfChoice(choice.id)+1;
|
||||
}
|
||||
|
||||
var output = choice.output.format(hInterface, nodeScopes, true);
|
||||
var output = choice.output.format(this, hInterface, random, altInstances, nodeScopes, true);
|
||||
return output;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
package tests;
|
||||
|
||||
import haxe.CallStack;
|
||||
using StringTools;
|
||||
import utest.Assert;
|
||||
|
||||
class StoryTest extends hank.StoryTestCase {
|
||||
function testAllExamples() {
|
||||
@@ -19,7 +21,13 @@ class StoryTest extends hank.StoryTestCase {
|
||||
var partial = file.indexOf("partial") != -1;
|
||||
if (!disabled) {
|
||||
trace(' Running ${file}');
|
||||
validateAgainstTranscript('examples/${folder}/main.hank', 'examples/${folder}/${file}', !partial);
|
||||
try {
|
||||
validateAgainstTranscript('examples/${folder}/main.hank', 'examples/${folder}/${file}', !partial);
|
||||
} catch (e: Dynamic) {
|
||||
trace('Error testing $folder/$file: $e');
|
||||
trace(CallStack.exceptionStack());
|
||||
Assert.fail();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user