Note that there are some explanatory texts on larger screens.

plurals
  1. POA more elegant way to write decision making code which evaluates multiple inputs with different priorities?
    primarykey
    data
    text
    <p>I'm writing some decision-making AI for a game, and I've come up with the following piece of code.</p> <pre><code>if(pushedLeft &amp;&amp; leftFree &amp;&amp; leftExists) GoLeft(); else if(pushedRight &amp;&amp; rightFree &amp;&amp; rightExists) GoRight(); else if(leftFree &amp;&amp; leftExists) GoLeft(); else if(rightFree &amp;&amp; rightExists) GoRight(); else if(pushedLeft &amp;&amp; leftExists) GoLeft(); else if(pushedRight &amp;&amp; rightExists) GoRight(); else if(leftExists) GoLeft(); else if(rightExists) GoRight(); // else do nothing... </code></pre> <p>That's a pretty long stream of <code>if</code> statements, with similar conditionals!</p> <p>Note that it makes this nice pattern:</p> <pre><code>L1 L2 L3 -&gt; L R1 R2 R3 -&gt; R L2 L3 -&gt; L R2 R3 -&gt; R L1 L3 -&gt; L R1 R3 -&gt; R L3 -&gt; L R3 -&gt; R (nothing) -&gt; 0 </code></pre> <p>The aim of this code is to decide whether the object should move left or right (or not at all), based on some incoming state information. Each piece of information has a different priority. I could write it in an ordered list like this:</p> <pre><code>Highest Priority ---------------- Don't ever move into an invalid space Prefer to move into an unoccupied space Prefer to move in the push direction Prefer to move left ---------------- Lowest Priority </code></pre> <p>It seems obvious that adding additional information inputs upon which to make this decision will double the number of conditionals. And doubling the number of potential values for those inputs (eg: allowing up/down/left/right) will double the number of conditionals as well. (So this is n×m<sup>2</sup> conditionals, right?)</p> <p>So my question is:</p> <p><strong>Is there a nice, satisfying, elegant way to code this?</strong></p> <p>I'm thinking that there must be a nice "n×m" way to do it (edit: I had "n+m" here originally, but that seems impossible as there are n×m input conditions). Something that is applicable to both my code here, and to the problem in general?</p> <p>Preferably something that will perform just as well or better than the conditional version above. Ideally something that avoids heap allocations - important for use in game development scenarios (although these can always be optimised away with caching and the like, if necessary).</p> <p>And also: Are there any "Googleable terms" for this problem? I suspect that this is not an uncommon problem - but I don't know of a name for it.</p> <hr> <p><strong>Update:</strong> An idea thanks to <a href="https://stackoverflow.com/a/10968740/165500">Superpig's answer</a>, is to calculate a score for the various options. Something like this:</p> <pre><code>int nothingScore = 1 &lt;&lt; 4; int leftScore = (1 &lt;&lt; 1) + (pushedLeft ? 1 &lt;&lt; 2 : 0) + (leftFree ? 1 &lt;&lt; 3 : 0) + (leftExists ? 1 &lt;&lt; 5 : 0); int rightScore = (pushedRight ? 1 &lt;&lt; 2 : 0) + (rightFree ? 1 &lt;&lt; 3 : 0) + (rightExists ? 1 &lt;&lt; 5 : 0); </code></pre> <p>There's certianly a nicer way to write the scoring code (and alternate ways to score it, too). And then there's still the matter of selecting what to do once the score is calculated. And, of course, there may be a better method entirely that doesn't involve scoring.</p> <hr> <p><strong>Update 2:</strong> I've <a href="https://stackoverflow.com/a/10974326/165500">posted and accepted my own answer here</a> (because Superpig's isn't a complete solution, and so far no other answer is even <em>remotely</em> on the right track). Rather than scoring the various outputs, I've chosen an option-elimination approach using a bit-field. This allows a decision to be made using only a single integer for memory.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload