I got that wrong that's Equilikely distribution. It's very very similar (for large numbers they are the same) it just doesn't add the one.
Equilikely distribution: It basically means the numbers between a and b inclusive have an equal chance of occurring, if the random number generator has itself an equal distribution (which it usually does).
The +1 adds one to the number since Math.floor() always rounds a number down to the nearest whole number, even if it is at 3.999, eg:
Math.floor(3.999) == 3.
The (b - a) determines the range.
EXAMPLE:
The range of Equilikely(4, 10) is 6. Math.random()*6 will return a number between 0 and 6
exclusive. Adding one makes that from 0 to 7
exclusive. Flooring it will keep the numbers as whole numbers, turning it into 0 to 6
inclusive. And then the last step adds the first number, 4, making it between 4 and 10
inclusive like what you asked for. The math is very simple for uniform and equilikely, but you have to stumble upon this algorithm from somewhere. At my university I took a simulation course last term where we went over these things so it's still fresh in my head.
RANT:
There are other distributions other than uniform and equilikely, such as exponential. There are far, far more (poisson, student, normal, lognormal, geometric, bernoulli, erlang, chisquare, etc.) but are almost never used unless you are seriously trying to model certain real-world behaviors. Sometimes a game may need it, other times they may not. MMO's will tend to use those other ones more often to simulate market growth etc.
Equilikely:
function Equilikely(a, b)
{
return a + Math.floor((1 + b - a)*Math.random());
}
Uniform:
function Uniform(a, b)
{
return a + Math.floor((b - a)*Math.random());
}
Exponential:
function Exponential(target)
{
return Math.floor(-target * Math.log(1 - Math.random()));
}
Exponential is interesting, it tries to get random numbers that average to 'target' over a period of time. What it may do is tend to group numbers together. You might get a stream of low numbers or high numbers, but at the end of the day the average of all numbers is that target number. Of course this is a kind of features you'll have to run more than once to be beneficial. It's useful for markets in games where items and prices can come and go and sometimes they are high and sometimes they are low, but they always average out to the number you specify. So you can have a lot of fun with that kind of distribution. It's also great for damage formulas! Imagine a weapon that attacks on average 7 points of damage but can do damage anywhere between 1 and whatever. The math for that would be easy:
var damage = Exponential(7).
Question 2:
It slowed their movement because the 'false' on queued commands for facing should be true. That last variable determines if the action should happen instantly or not. Anyways, to get the correct faces you can create a helper function that translates move commands to face commands:
function FindFace(command)
{
switch(command) {
case: COMMAND_MOVE_NORTH: return COMMAND_FACE_NORTH;
case: COMMAND_MOVE_SOUTH: return COMMAND_FACE_SOUTH;
case: COMMAND_MOVE_EAST: return COMMAND_FACE_EAST;
case: COMMAND_MOVE_WEST: return COMMAND_FACE_WEST;
}
return null;
}
And use it like so:
function Move(Name, Tiles, Direction, Face) {
if (Direction == North) QueuePersonCommand(Name, Face_north, false);
if (Direction == South) QueuePersonCommand(Name, Face_south, false);
if (Direction == East) QueuePersonCommand(Name, Face_east, false);
if (Direction == West) QueuePersonCommand(Name, Face_west, false);
var face = FindFace(Direction);
if (face != null) QueuePersonCommand(Name, face, true);
for (var j = 0; j < Tiles; ++j) {
for (var i = 0; i < 16; ++i) { QueuePersonCommand(Name, Direction, false); }
SetPersonFrame(Name, 0); // this does nothing in your code. The reason: it's not queued. In fact it will happen before the above line.
}
}
If you use code to help you code you can use less code to code.
Notice that SetPersonFrame(Name, 0) will go first before movement. This is because the queue functions do that: queue commands. They don't make the person move right then and there the map engine does this later on down the line. So you can insted of fixing that, change it so you set the frame once:
function Move(Name, Tiles, Direction, Face) {
if (Direction == North) QueuePersonCommand(Name, Face_north, false);
if (Direction == South) QueuePersonCommand(Name, Face_south, false);
if (Direction == East) QueuePersonCommand(Name, Face_east, false);
if (Direction == West) QueuePersonCommand(Name, Face_west, false);
var face = FindFace(Direction);
if (face != null) QueuePersonCommand(Name, face, true);
SetPersonFrame(Name, 0); // now it 'feels' like it works better.
for (var j = 0; j < Tiles; ++j) {
for (var i = 0; i < 16; ++i) { QueuePersonCommand(Name, Direction, false); }
}
}
That all!