...
 
Commits (5)
  • Terence Martin's avatar
    Allow for the notion of no gray bricks · d4a3f817
    Terence Martin authored
    This is probably only of use when debugging, but as originally written
    the code would get stuck and not be able to enter the final ball drop
    if there are no gray bricks in the level because in that case there
    are none to reap.
    
    This is fixed by having the method that would normally remove such a
    brick return false if there are none left to remove; when this happens
    the code can immediately jump to the next phase.
    d4a3f817
  • Terence Martin's avatar
    Fix final ball drop bug · c3da8655
    Terence Martin authored
    It turns out that the reason for this failure was entirely because I
    incorrectly stopped the search for balls to remove for being vanished
    one column short of the edge.
    
    This means that any final ball dropped in the last column of the maze
    will vanish but not be reaped. Thus the flag for the ball being done
    will never get set and everything stalls out.
    
    Whoops.
    c3da8655
  • Terence Martin's avatar
    Clean up pushed ball marking · 366ba91e
    Terence Martin authored
    Now that we know the dropping of balls works for removing balls from
    the two player arrays, remove the debug logging.
    
    This was particulary annoying in that it would warn about pushing a
    ball not in one of those arrays when the final ball drops were going
    on.
    366ba91e
  • Terence Martin's avatar
    Fix possible premature state change · 05a53006
    Terence Martin authored
    The code for starting the next ball dropping in the final ball drop
    was incorrectly only checking to see if a ball is hidden without also
    checking to see if it's still actively hiding; fixed.
    05a53006
  • Terence Martin's avatar
    Hide players before final ball drop · cd982101
    Terence Martin authored
    Now when we enter the phase for the final ball drop, we make sure that
    the human and computer Player entities are hidden.
    cd982101
......@@ -571,21 +571,18 @@ var nurdz;
* @param {Ball} ball the ball to remove
*/
MazeContents.prototype.markBallPlayed = function (ball) {
// Try it first as a player ball.
var index = this._playerBalls.indexOf(ball);
if (index != -1) {
console.log("Marking a player ball as played");
if (index != -1)
this._playerBalls[index] = null;
return;
}
index = this._computerBalls.indexOf(ball);
if (index != -1) {
console.log("Marking a computer ball as played");
this._computerBalls[index] = null;
return;
else {
index = this._computerBalls.indexOf(ball);
if (index != -1)
this._computerBalls[index] = null;
}
// Theoretically this can only happen when the debug code inserts a
// ball into the top row that the generator did not insert there.
console.log("Played a ball that is not in either of the two ball arrays");
// The code can get here if the debug code starts a ball moving or
// during the final ball drop, where this method gets called but
// the ball pushed is not contained in either of the arrays.
};
/**
* Replace the top row contents of the maze with the list of balls that
......@@ -4184,9 +4181,10 @@ var nurdz;
Maze.prototype.clearHiddenBalls = function () {
var retVal = 0;
for (var row = 0; row < game.MAZE_HEIGHT - 1; row++) {
for (var col = 1; col < game.MAZE_WIDTH - 2; col++) {
for (var col = 1; col < game.MAZE_WIDTH - 1; col++) {
var ball = this._contents.getCellAt(col, row);
if (ball != null && ball.name == "ball" && ball.isHidden) {
if (ball != null && ball.name == "ball" &&
ball.isHidden && ball.animations.isPlaying == false) {
this._contents.clearCellAt(col, row);
retVal++;
}
......@@ -4194,10 +4192,6 @@ var nurdz;
}
return retVal;
};
/**
* Select the next ball on the screen that should start it's final
* descent through the maze.
*/
/**
* Select the next ball in the maze that should start it's final descent
* through the maze.
......@@ -4233,29 +4227,50 @@ var nurdz;
};
/**
* Scan through the maze (left to right, bottom to top) looking for the
* first gray brick entity that has not already been told to vanish
* and tell it to.
* first gray brick entity that has not already been told to vanish and
* tell it to.
*
* If there are no gray bricks at all in the maze, this will return
* false to indicate that there can be no brick removal.
*
* If there are no such bricks, this does nothing. This is currently
* rather brute force; it might be better to sort the live entity list
* somehow or do a random selection, but that gets tricky when we have
* run out the list of bricks.
* The return value will be true if a brick was told to vanish OR we ran
* across a brick that is hidden but still in the maze; in this case we
* know that it has not vanished yet, so we can wait.
*
* This allows calling code to detect when there are no gray bricks at
* all (debugging) so that it can skip over the state where we remove
* gray bricks, but still make sure that we can naturally trigger the
* "all gray bricks are now vanished" event once the last of them
* vanishes away and is reaped.
*
* @returns {boolean} false if there are no gray bricks in the maze at
* all or true otherwise
*/
Maze.prototype.removeNextGrayBrick = function () {
// Assume be default we did not see any gray bricks at all.
var sawBrick = false;
// Scan from the bottom up.
for (var row = game.MAZE_HEIGHT - 2; row >= 0; row--) {
for (var col = 1; col < game.MAZE_WIDTH - 1; col++) {
// Get the cell as a brick (it may not be).
var cell = this._contents.getCellAt(col, row);
// If it is a gray brick that is not already hidden, call
// the vanish method.
// If we got a cell and it's a gray brick, it might be
// interesting.
if (cell != null && cell.name == "brick" &&
cell.brickType == game.BrickType.BRICK_GRAY &&
cell.isHidden == false) {
cell.vanish();
return;
cell.brickType == game.BrickType.BRICK_GRAY) {
// If the brick is not already hidden, hide it and return
// true right away.
if (cell.isHidden == false) {
cell.vanish();
return true;
}
// It's already hidden so we need to ignore it, but at
// least we saw it.
sawBrick = true;
}
}
}
return sawBrick;
};
/**
* This is called every frame update (tick tells us how many times this
......@@ -5010,6 +5025,12 @@ var nurdz;
// Tell the computer that they're starting their turn now.
this._computer.ai_startingTurn();
break;
// When we enter the final ball drop, hide the player and
// computer characters.
case game.GameState.FINAL_BALL_DROP:
this._player.visible = false;
this._computer.visible = false;
break;
}
};
/**
......@@ -5060,8 +5081,12 @@ var nurdz;
// When we are in the remove gray bricks state, use the state
// timer to remove a brick every so often.
case game.GameState.REMOVE_GRAY_BRICKS:
if (this._state.timerTrigger(ROUND_BRICK_VANISH_TIME))
this._maze.removeNextGrayBrick();
if (this._state.timerTrigger(ROUND_BRICK_VANISH_TIME)) {
// If there is no brick to remove, trigger the state
// change right away.
if (this._maze.removeNextGrayBrick() == false)
this.grayBrickRemovalComplete();
}
break;
// We are dropping the final balls through the maze now. Select
// one and drop it; if there are none left to drop, set the
......
......@@ -478,25 +478,20 @@ module nurdz.game
*/
markBallPlayed (ball : Ball) : void
{
// Try it first as a player ball.
let index = this._playerBalls.indexOf (ball);
if (index != -1)
{
console.log("Marking a player ball as played");
this._playerBalls[index] = null;
return;
}
index = this._computerBalls.indexOf (ball)
if (index != -1)
else
{
console.log("Marking a computer ball as played");
this._computerBalls[index] = null;
return;
index = this._computerBalls.indexOf (ball)
if (index != -1)
this._computerBalls[index] = null;
}
// Theoretically this can only happen when the debug code inserts a
// ball into the top row that the generator did not insert there.
console.log("Played a ball that is not in either of the two ball arrays");
// The code can get here if the debug code starts a ball moving or
// during the final ball drop, where this method gets called but
// the ball pushed is not contained in either of the arrays.
}
/**
......
......@@ -752,10 +752,11 @@ module nurdz.game
for (let row = 0 ; row < MAZE_HEIGHT - 1 ; row++)
{
for (let col = 1 ; col < MAZE_WIDTH - 2 ; col++)
for (let col = 1 ; col < MAZE_WIDTH - 1 ; col++)
{
let ball = <Ball> this._contents.getCellAt (col, row);
if (ball != null && ball.name == "ball" && ball.isHidden)
if (ball != null && ball.name == "ball" &&
ball.isHidden && ball.animations.isPlaying == false)
{
this._contents.clearCellAt (col, row);
retVal++;
......@@ -766,11 +767,6 @@ module nurdz.game
return retVal;
}
/**
* Select the next ball on the screen that should start it's final
* descent through the maze.
*/
/**
* Select the next ball in the maze that should start it's final descent
* through the maze.
......@@ -814,16 +810,31 @@ module nurdz.game
/**
* Scan through the maze (left to right, bottom to top) looking for the
* first gray brick entity that has not already been told to vanish
* and tell it to.
* first gray brick entity that has not already been told to vanish and
* tell it to.
*
* If there are no gray bricks at all in the maze, this will return
* false to indicate that there can be no brick removal.
*
* If there are no such bricks, this does nothing. This is currently
* rather brute force; it might be better to sort the live entity list
* somehow or do a random selection, but that gets tricky when we have
* run out the list of bricks.
* The return value will be true if a brick was told to vanish OR we ran
* across a brick that is hidden but still in the maze; in this case we
* know that it has not vanished yet, so we can wait.
*
* This allows calling code to detect when there are no gray bricks at
* all (debugging) so that it can skip over the state where we remove
* gray bricks, but still make sure that we can naturally trigger the
* "all gray bricks are now vanished" event once the last of them
* vanishes away and is reaped.
*
* @returns {boolean} false if there are no gray bricks in the maze at
* all or true otherwise
*/
removeNextGrayBrick () : void
removeNextGrayBrick () : boolean
{
// Assume be default we did not see any gray bricks at all.
let sawBrick = false;
// Scan from the bottom up.
for (let row = MAZE_HEIGHT - 2 ; row >= 0 ; row--)
{
for (let col = 1 ; col < MAZE_WIDTH - 1 ; col++)
......@@ -831,17 +842,27 @@ module nurdz.game
// Get the cell as a brick (it may not be).
let cell = <Brick> this._contents.getCellAt (col, row);
// If it is a gray brick that is not already hidden, call
// the vanish method.
// If we got a cell and it's a gray brick, it might be
// interesting.
if (cell != null && cell.name == "brick" &&
cell.brickType == BrickType.BRICK_GRAY &&
cell.isHidden == false)
cell.brickType == BrickType.BRICK_GRAY)
{
cell.vanish ();
return;
// If the brick is not already hidden, hide it and return
// true right away.
if (cell.isHidden == false)
{
cell.vanish ();
return true;
}
// It's already hidden so we need to ignore it, but at
// least we saw it.
sawBrick = true;
}
}
}
return sawBrick;
}
/**
......
......@@ -593,6 +593,13 @@ module nurdz.game
// Tell the computer that they're starting their turn now.
this._computer.ai_startingTurn ();
break;
// When we enter the final ball drop, hide the player and
// computer characters.
case GameState.FINAL_BALL_DROP:
this._player.visible = false;
this._computer.visible = false;
break;
}
}
......@@ -651,7 +658,12 @@ module nurdz.game
// timer to remove a brick every so often.
case GameState.REMOVE_GRAY_BRICKS:
if (this._state.timerTrigger (ROUND_BRICK_VANISH_TIME))
this._maze.removeNextGrayBrick ();
{
// If there is no brick to remove, trigger the state
// change right away.
if (this._maze.removeNextGrayBrick () == false)
this.grayBrickRemovalComplete ();
}
break;
// We are dropping the final balls through the maze now. Select
......