HPCU Bi-Weekly Challenge
Precipitate Algorithm: A 'Recipe' for Success
Author: Aaron Weeden, April 6, 2014
main function:
1. [Read data from user] Call the readData function.
2. [Randomize particle positions] Call the randomizePositions function.
3. [Start the time] Set current time step to 0.
4. [Loop over time steps] For each time step,
4a. [Pick directions] Call the pickDirections function.
4b. [Move particles] Call the moveParticles function.
4c. [Check for collisions] Call the checkCollisions function.
4d. [Display] Display the time step.
readData function:
1. [Set container wall positions] Read in environment width and height.
2. [Set particle data] Read in particle width and height as well as the number
of particles.
3. [Set time data] Read in the number of time steps.
4. [Set % chance] Read in the percent chance of collision.
randomizePositions function:
1. [Loop over particles] For each particle,
1a. [Generate random number for x] generate a random number between 0
exclusive and (the width of the container minus the width of a
particle) inclusive.
1b. [Set x] Set the random number as the x position of the particle.
1c. [Generate random number for y] generate a random number between 0
exclusive and (the height of the container minus the height of a
particle) inclusive.
1d. [Set y] Set the random number as the y position of the particle.
pickDirections function:
1. [Loop over particles] For each particle,
1a. [Skip precipitating particles] If the state of the particle is not
'precipitating',
1a1. [Generate random number for direction] generate a random number
between 0 exclusive and 4 inclusive.
1a2. [Try direction] If the random number is 0, call the tryMove
function with the particle and 'left' as parameters. Otherwise, if
the random number is 1, call the tryMove function with the particle
and 'right' as parameters. Otherwise, if the random number is 2,
call the tryMove function with the particle and 'up' as parameters.
Otherwise, call the tryMove function with the particle and 'down' as
parameters.
1a3. [Prepare for move] If the tryMove function returned true, store the
direction in the particle, and set the particle's state to 'moving'.
Otherwise, set the particle's state to 'blocked'.
tryMove function:
1. [Check for wall] If the direction is 'left' and the particle's x position is
0, return false. Otherwise, if the direction is 'right' and the particle's
x position is the width of the container minus the width of a particle,
return false. Otherwise, if the direction is 'up' and the particle's y
position is 0, return false. Otherwise, if the direction is 'down' and the
particle's y position is the height of the container minus the height of
a particle, return false.
2. [Check for other particle] If the direction is 'left' and there is a particle
to the left of the current particle (the x position is 1 less than the
particle's, the y position is the same as the particle's), return false.
Otherwise, if the direction is 'right' and there is a particle to the right
of the current particle (the x position is 1 more than the particle's, the
y position is the same as the particle's), return false.
Otherwise, if the direction is 'up' and there is a particle above the
current particle (the y position is 1 less than the particle's, the x
position is the same), return false. Otherwise, if the direction
is 'down' and there is a particle below the current particle (the y position
is 1 more than the particle's, the x position is the same), return false.
3. [No obstructions found] Return true.
moveParticles function:
1. [Loop over particles] For each particle,
1a. [Is particle moving?] If the particle's state is 'moving',
1a1. [Set new position] If the particle's direction is 'left', set the
new x position of the particle to be 1 less than its current x
position, and keep the y position the same.
Otherwise, if the particle's direction is 'right', set the new x
position of the particle to be 1 more than its current x position,
and keep the y position the same.
Otherwise, if the particle's direction is 'up', set the new y
position of the particle to be 1 less than its current y position,
and keep the x position the same.
Otherwise, if the particle's direction is 'down',
set the new y position of the particle to be 1 more than its
current y position, and keep the x position the same.
1b. [Check for precipitate forming at bottom] Otherwise, call the
checkPrecipitate function with the particle as its argument. If it
returns true, set the particle's state as 'precipitate'.
checkCollisions function:
1. [Loop over particles] For each particle,
1a. [Loop over other particles] For each other particle,
1a1. [Check for left/right adjacency] If the first particle's y position
is the same as the second particle's y position, and the first
particle's x position is 1 less than the second particle's x
position, then
1a1a. [Calculate random number for % chance] Calculate a random
number between 0 inclusive and 100 exclusive.
1a1b. [Apply % chance] If the random number is less than the percent
chance, set the state of both particles to 'colliding', and the
direction of both particles to 'down'.
1a2. [Check for top/bottom adjacency] If the second particle's state is
'precipitating', and the y position of the second particle is 1 less
than the y position of the first particle, and their x positions are
the same, set the state of the first particle to 'precipitating',
and set its direction to 'down'.
checkPrecipitate function:
1. [Check for floor] If the particle's y position is the height of the container
minus the height of a particle, return true.
2. [Loop over other particles] Otherwise, for each of the other particles,
2a. [Is precipitate?] If the other particle's state is 'precipitate', and
the other particle's y position is 1 more than the first particle's y
value, and the two particles have the same x position, return true.
3. [None found] Return false.