The routines for updating mobile characters are in place and working, so I now have a Meanie moving around on the screen. I also have the stubs ready to hook-up movement rules for the Repair Bot and the Fuel Ship, though the 'bot movement will have to wait until I have the logic written to process user keypresses, since it only moves in response to those. I didn't quite get around to doing collision-detection yet, so I'll hold-off on posting a demo until that's in place - which is next on the list, but first I have to revisit the Random Number Generator.
The RNG itself is working fine, but I want to write a little 'wrapper' around it to make it easier to use. The game actually only calls it in two places, both for Meanie movement - once to determine whether the Meanie moves horizontally at all (one or two positions to the left, or right, or not at all) and then again to find out if it moves down a line. In other words, there's a call asking for a 1-in-5 response (left two, left one, no movement, right one, right two) and another asking for a 1-in-2 response (move down, don't move down). So that equates to a 20% chance for horizontal movement of some kind - including no movement - and 50% for a vertical drop.
The RNG returns 256 possible values in the range 0-255, so the code currently does a simple series of tests to see where the return value is in that range. For the 50% test, that's just a case of checking the value to see if it's greater than 127 - if it is, the Meanie drops a line; if not, it stays on the same line. The code gets a bit nastier when checking the 20% response though, as it has to test a series of four values (51, 102, 153, 204) to see which fifth of the range the value is in, and determine horizontal movement based on that. What I want is a neater way of calling the RNG so that I can pass a value in (e.g. 5 or 2) and have a simple value returned in the range of 1 to 'n', where 'n' is the number I gave it. A 50/50 test would then call the RNG with a value of 2, and get either 1 or 2 back; passing a value of 5 would return a value in the range 1 to 5.
This means the wrapper has to automatically calculate where in the 0-255 range the actual RNG result occurs based on the number of 'slices' the range has been asked to divide by. This is a matter of dividing 256 by the passed-in value, finding out how many 'slices' that equates to, and then figuring-out which 'slice' the RNG result falls into and returning that as the output value. For the 50/50 test where a value of 2 would be passed in, it would divide 256 by 2 (giving 128) and then ask the RNG for a result - which would then map into either the 0-127 band, giving 1 as an output, or the 128-255 band, giving 2. It's a bit more complicated for the 20%-chance test, but the same basic principle.
I've decided that since this game is making limited use of the RNG, there's not much point writing a sophisticated routine to handle any given range value - we're only using 2 and 5, after all. So instead I'll pre-calculate the boundary values in a table and have the wrapper just look them up to decide where the RNG result falls, and return the appropriate value. It's not a fully-generalised solution, but there seems little advantage to writing an all-singing-and-dancing version when I only actually need two cases handled. If and when I re-use the code and need a more flexible solution, I can drop the auto-calculation logic into it and chop-out the table lookup. For now, it does what I need and is fairly efficient, so it'll suffice.

0 comments:
Post a Comment