-/* S K I !
-**
-** Version 6.0 of October 14, 1990
-**
-** Copyright 1983-1990 by Mark Stevans for Roy's Games, Inc.
-*/
+// S K I !
+//
+// Version 6.0 of October 14, 1990
+// Copyright 1983-1990 by Mark Stevans for Roy's Games, Inc.
+//
+// Version 6.1 of December 30 2003
+// Copright 2003 by Eric S. Raymond
#include <stdio.h>
#include <ctype.h>
#endif /* NCURSES */
#include "ski.h"
-/*
-**
-** Constants controlling the multiple cellular growth automatons that are
-** executed in parallel to generate hazards.
-**
-** Each cellular growth automaton probability element tends to control a
-** different facet of hazard generation:
-**
-** [0] appearance of new hazards in clear snow
-** [1] hazards edge growth
-** [2] hazards edge stability
-** [3] appearance of holes in solid hazards (this allows the Snoman to
-** work his way through forests)
-*/
-
-PRIVATE float prob_tree[] = { 0.0, 30.0, 70.0, 90.0 };
-PRIVATE float prob_ice[] = { 0.0, 30.0, 70.0, 90.0 };
-PRIVATE float prob_ground[] = { 0.0, 30.0, 70.0, 90.0 };
-PRIVATE float prob_snoman_appearance;
-
-/*
-** "init" performs various initialization functions.
-*/
-
-PRIVATE int init(level_ptr)
-LEVEL *level_ptr;
+// Constants controlling the multiple cellular growth automatons that are
+// executed in parallel to generate hazards.
+//
+// Each cellular growth automaton probability element tends to control a
+// different facet of hazard generation:
+//
+// [0] appearance of new hazards in clear snow
+// [1] hazards edge growth
+// [2] hazards edge stability
+// [3] appearance of holes in solid hazards (this allows the Snoman to
+// work his way through forests)
+
+static float prob_tree[] = { 0.0, 30.0, 70.0, 90.0 };
+static float prob_ice[] = { 0.0, 30.0, 70.0, 90.0 };
+static float prob_ground[] = { 0.0, 30.0, 70.0, 90.0 };
+static float prob_snoman_appearance;
+
+static int init(LEVEL *level_ptr)
+// Initialize the zero level
{
- register int i;
-
- /*
- ** Print the game version.
- */
-
- printf("SKI! Version 6.0!\n");
-
- /*
- ** Initialize the random number generator.
- */
-
- RANDOM_INITIALIZE((int) time(NIL(long *)));
-
- /*
- ** Initialize the player's position.
- */
-
- level_ptr->player_pos = RANDOM_GENERATE() % LINE_LEN;
-
- /*
- ** Initialize the current level.
- */
-
- for (i = 0; i < LINE_LEN; ++i)
- level_ptr->slope[i] = REP_SNOW;
-
- level_ptr->slope[LINE_LEN] = EOS;
-
- level_ptr->meters_travelled = 0;
- level_ptr->jump_count = -1;
- level_ptr->level_num = 0;
- level_ptr->num_snomen_melted = 0;
- level_ptr->num_jumps_attempted = 0.0;
- level_ptr->player_pos = RANDOM_GENERATE() % LINE_LEN;
- level_ptr->snoman_pos = NO_POSITION;
- level_ptr->icbm_pos = NO_POSITION;
- level_ptr->demon_pos = NO_POSITION;
- level_ptr->player_speed = 0;
-
- /*
- ** Randomize the appearance probabilities.
- */
-
- prob_tree[0] = (RANDOM_GENERATE() % 100) / 500.0 + 0.05;
- prob_ice[0] = (RANDOM_GENERATE() % 100) / 500.0 + 0.05;
- prob_ground[0] = (RANDOM_GENERATE() % 100) / 500.0 + 0.05;
- prob_snoman_appearance = (RANDOM_GENERATE() % 100) / 25.0 + 1.0;
-
- /*
- ** Return a code indicating successful completion.
- */
-
- return (SUCCESS);
+ register int i;
+
+ // Print the game version.
+ printf("SKI! Version 6.1!\n");
+
+ // Initialize the random number generator.
+ RANDOM_INITIALIZE((int) time(NIL(long *)));
+
+ // Initialize the player's position.
+ level_ptr->player_pos = RANDOM_GENERATE() % LINE_LEN;
+
+ // Initialize the current level.
+ for (i = 0; i < LINE_LEN; ++i)
+ level_ptr->slope[i] = REP_SNOW;
+
+ level_ptr->slope[LINE_LEN] = EOS;
+
+ level_ptr->meters_travelled = 0;
+ level_ptr->jump_count = -1;
+ level_ptr->level_num = 0;
+ level_ptr->num_snomen_melted = 0;
+ level_ptr->num_jumps_attempted = 0.0;
+ level_ptr->player_pos = RANDOM_GENERATE() % LINE_LEN;
+ level_ptr->snoman_pos = NO_POSITION;
+ level_ptr->icbm_pos = NO_POSITION;
+ level_ptr->demon_pos = NO_POSITION;
+ level_ptr->player_speed = 0;
+
+ // Randomize the appearance probabilities.
+ prob_tree[0] = (RANDOM_GENERATE() % 100) / 500.0 + 0.05;
+ prob_ice[0] = (RANDOM_GENERATE() % 100) / 500.0 + 0.05;
+ prob_ground[0] = (RANDOM_GENERATE() % 100) / 500.0 + 0.05;
+ prob_snoman_appearance = (RANDOM_GENERATE() % 100) / 25.0 + 1.0;
+
+ // Return a code indicating successful completion.
+ return (SUCCESS);
}
-/*
-** "gen_next_slope" generates the slope of the next level, dependent upon
-** the characteristics of the current level, the probabilities, and the
-** position of the player.
-*/
-PRIVATE int gen_next_slope(current_level, next_level)
-LEVEL *current_level;
-LEVEL *next_level;
+static int gen_next_slope(LEVEL *current_level, LEVEL *next_level)
+// Generates the slope of the next level, dependent upon
+// the characteristics of the current level, the probabilities, and the
+// position of the player.
{
- register int i;
- register char *current_slope;
- register char *next_slope;
- register int player_pos;
- short num_nearby_trees, num_nearby_ice, num_nearby_ground;
-
- /*
- ** Cache some convenient values.
- */
-
- current_slope = current_level->slope;
- next_slope = next_level->slope;
- player_pos = current_level->player_pos;
-
- /*
- ** Generate each character of the next level.
- */
-
- for (i = 0; i < LINE_LEN; ++i) {
- /*
- ** Count the number of nearby trees, ice patches, and
- ** ground patches on the current level.
- */
-
- num_nearby_trees = 0;
- num_nearby_ice = 0;
- num_nearby_ground = 0;
-
- if (current_slope[i] == REP_TREE)
- ++num_nearby_trees;
- if (current_slope[i] == REP_ICE)
- ++num_nearby_ice;
- if (current_slope[i] == REP_GROUND)
- ++num_nearby_ground;
-
- if (i > 0) {
- if (current_slope[i - 1] == REP_TREE)
- ++num_nearby_trees;
- else if (current_slope[i - 1] == REP_ICE)
- ++num_nearby_ice;
- else if (current_slope[i - 1] == REP_GROUND)
- ++num_nearby_ground;
- }
-
- if (i < (LINE_LEN - 1)) {
- if (current_slope[i + 1] == REP_TREE)
- ++num_nearby_trees;
- else if (current_slope[i + 1] == REP_ICE)
- ++num_nearby_ice;
- else if (current_slope[i + 1] == REP_GROUND)
- ++num_nearby_ground;
- }
-
- /*
- ** Generate this character of the next level based upon
- ** the characteristics of the nearby characters on the
- ** current level.
- */
-
- if (PROB(prob_tree[num_nearby_trees]) &&
- ((i != player_pos) || (num_nearby_trees > 0)))
- next_slope[i] = REP_TREE;
- else if (PROB(prob_ice[num_nearby_ice]) &&
- ((i != player_pos) || (num_nearby_ice > 0)))
- next_slope[i] = REP_ICE;
- else if (PROB(prob_ground[num_nearby_ground]) &&
- ((i != player_pos) || (num_nearby_ground > 0)))
- next_slope[i] = REP_GROUND;
- else
- next_slope[i] = REP_SNOW;
+ register int i;
+ register char *current_slope;
+ register char *next_slope;
+ register int player_pos;
+ short num_nearby_trees, num_nearby_ice, num_nearby_ground;
+
+ // Cache some convenient values.
+ current_slope = current_level->slope;
+ next_slope = next_level->slope;
+ player_pos = current_level->player_pos;
+
+ // Generate each character of the next level.
+ for (i = 0; i < LINE_LEN; ++i) {
+ // Count the number of nearby trees, ice patches, and
+ // ground patches on the current level.
+ num_nearby_trees = 0;
+ num_nearby_ice = 0;
+ num_nearby_ground = 0;
+
+ if (current_slope[i] == REP_TREE)
+ ++num_nearby_trees;
+ if (current_slope[i] == REP_ICE)
+ ++num_nearby_ice;
+ if (current_slope[i] == REP_GROUND)
+ ++num_nearby_ground;
+
+ if (i > 0) {
+ if (current_slope[i - 1] == REP_TREE)
+ ++num_nearby_trees;
+ else if (current_slope[i - 1] == REP_ICE)
+ ++num_nearby_ice;
+ else if (current_slope[i - 1] == REP_GROUND)
+ ++num_nearby_ground;
}
- /*
- ** Terminate the slope string.
- */
-
- next_slope[LINE_LEN] = EOS;
-
- /*
- ** Return a code indicating successful completion.
- */
+ if (i < (LINE_LEN - 1)) {
+ if (current_slope[i + 1] == REP_TREE)
+ ++num_nearby_trees;
+ else if (current_slope[i + 1] == REP_ICE)
+ ++num_nearby_ice;
+ else if (current_slope[i + 1] == REP_GROUND)
+ ++num_nearby_ground;
+ }
- return (SUCCESS);
+ // Generate this character of the next level based upon
+ // the characteristics of the nearby characters on the
+ // current level.
+ if (PROB(prob_tree[num_nearby_trees]) &&
+ ((i != player_pos) || (num_nearby_trees > 0)))
+ next_slope[i] = REP_TREE;
+ else if (PROB(prob_ice[num_nearby_ice]) &&
+ ((i != player_pos) || (num_nearby_ice > 0)))
+ next_slope[i] = REP_ICE;
+ else if (PROB(prob_ground[num_nearby_ground]) &&
+ ((i != player_pos) || (num_nearby_ground > 0)))
+ next_slope[i] = REP_GROUND;
+ else
+ next_slope[i] = REP_SNOW;
+ }
+
+ // Terminate the slope string.
+ next_slope[LINE_LEN] = EOS;
+
+ // Return a code indicating successful completion.
+ return (SUCCESS);
}
-/*
-** "update_level" moves to the next level.
-*/
-
-PRIVATE int update_level(current_level)
+static int update_level(current_level)
+// Move to the next level
LEVEL *current_level;
{
- LEVEL next_level;
-
- /*
- ** Go to the next level, and move the player.
- */
-
- ++current_level->level_num;
-
- current_level->meters_travelled += ABS(current_level->player_speed) + 1;
-
- /*
- ** Figure out the new player position based on a modulo
- ** addition. Note that we must add the line length into the
- ** expression before taking the modulus to make sure that we
- ** are not taking the modulus of a negative integer.
- */
-
- current_level->player_pos = (current_level->player_pos +
- current_level->player_speed + LINE_LEN) % LINE_LEN;
-
- /*
- ** Generate the updated slope.
- */
-
- gen_next_slope(current_level, &next_level);
-
- strcpy(current_level->slope, next_level.slope);
-
- /*
- ** If the player was jumping, decrement the jump count.
- */
-
- if (current_level->jump_count >= 0)
- --current_level->jump_count;
-
- /*
- ** If there is no Snoman, one might be created.
- */
-
- if (!EXISTS(current_level->snoman_pos)) {
- if (PROB(prob_snoman_appearance)) {
- /*
- ** Make sure that the Snoman does not appear too
- ** close to the player.
- */
-
- do {
- current_level->snoman_pos = RANDOM_GENERATE() % LINE_LEN;
- } while (ABS(current_level->snoman_pos -
- current_level->player_pos) <=
- MIN_SNOMAN_APPEARANCE_DISTANCE);
- }
+ LEVEL next_level;
+
+ // Go to the next level, and move the player.
+ ++current_level->level_num;
+
+ current_level->meters_travelled += ABS(current_level->player_speed) + 1;
+
+ // Figure out the new player position based on a modulo
+ // addition. Note that we must add the line length into the
+ // expression before taking the modulus to make sure that we
+ // are not taking the modulus of a negative integer.
+ current_level->player_pos = (current_level->player_pos +
+ current_level->player_speed + LINE_LEN) % LINE_LEN;
+
+ // Generate the updated slope.
+ gen_next_slope(current_level, &next_level);
+ strcpy(current_level->slope, next_level.slope);
+
+ // If the player was jumping, decrement the jump count.
+ if (current_level->jump_count >= 0)
+ --current_level->jump_count;
+
+ // If there is no Snoman, one might be created.
+ if (!EXISTS(current_level->snoman_pos)) {
+ if (PROB(prob_snoman_appearance)) {
+ // Make sure that the Snoman does not appear too
+ // close to the player.
+ do {
+ current_level->snoman_pos = RANDOM_GENERATE() % LINE_LEN;
+ } while (ABS(current_level->snoman_pos -
+ current_level->player_pos) <=
+ MIN_SNOMAN_APPEARANCE_DISTANCE);
}
+ }
- /*
- ** Increase the initial appearance probabilities of all obstacles and
- ** the Snoman.
- */
-
- prob_tree[0] *= LEVEL_MULTIPLIER;
- prob_ice[0] *= LEVEL_MULTIPLIER;
- prob_ground[0] *= LEVEL_MULTIPLIER;
- prob_snoman_appearance *= LEVEL_MULTIPLIER;
+ // Increase the initial appearance probabilities of all obstacles and
+ // the Snoman.
+ prob_tree[0] *= LEVEL_MULTIPLIER;
+ prob_ice[0] *= LEVEL_MULTIPLIER;
+ prob_ground[0] *= LEVEL_MULTIPLIER;
+ prob_snoman_appearance *= LEVEL_MULTIPLIER;
- /*
- ** Return a code indicating successful completion.
- */
-
- return (SUCCESS);
+ // Return a code indicating successful completion.
+ return (SUCCESS);
}
-/*
-** "main" is the top level function of the game.
-*/
+// Main sequence
-PUBLIC int main()
+int main(int argc, char **argv)
{
- LEVEL level;
+ LEVEL level;
#ifdef A_COLOR
- /*
- ** Initialize the color support.
- */
-
- init_colors();
+ // Initialize the color support.
+ init_colors();
#endif /* A_COLOR */
- /*
- ** Initialize the game.
- */
-
- if (init(&level) != SUCCESS)
- exit(1);
+ // Initialize the game.
+ if (init(&level) != SUCCESS)
+ exit(1);
+
+ // Perform the game loop until the game is over.
+ for (;;) {
+ draw_picture(&level);
+ do_user(&level);
+ manipulate_objects(&level);
+ update_level(&level);
+ }
+}
- /*
- ** Perform the game loop until the game is over.
- */
+// end
- for (;;) {
- draw_picture(&level);
- do_user(&level);
- manipulate_objects(&level);
- update_level(&level);
- }
-}