From: Eric S. Raymond Date: Tue, 30 Dec 2003 20:51:11 +0000 (+0000) Subject: Put the C version to bed. X-Git-Tag: 6-1~1 X-Git-Url: http://thyrsus.com/gitweb/?a=commitdiff_plain;h=6d3c55b3fa48bd3cdc2cbf321ab96c5882711538;p=ski.git Put the C version to bed. --- diff --git a/do_level.c b/do_level.c index 0e64f51..5578c6b 100644 --- a/do_level.c +++ b/do_level.c @@ -50,7 +50,7 @@ PRIVATE char *injuries[] = { /* ** Color support code ** -** hacked in on a whim by Eric Raymond (eric@snark.thyrsus.com) +** hacked in on a whim by Eric Raymond */ #ifdef A_COLOR #define MAXCOLORS 8 @@ -78,8 +78,7 @@ void init_colors() ** "draw_picture" */ -PUBLIC int draw_picture(current_level) -LEVEL *current_level; +PUBLIC int draw_picture(LEVEL *current_level) { char level_picture[LINE_LEN + 1]; #ifdef A_COLOR @@ -162,10 +161,7 @@ LEVEL *current_level; ** the severity. This function should never return. */ -PRIVATE int accident(current_level, msg, severity) -LEVEL *current_level; -char *msg; -short severity; +PRIVATE int accident(LEVEL *current_level, char *msg, short severity) { int degree; long score; @@ -236,8 +232,7 @@ short severity; ** "check_obstacles" */ -PRIVATE int check_obstacles(current_level) -LEVEL *current_level; +PRIVATE int check_obstacles(LEVEL *current_level) { short player_pos; char *slope; @@ -291,8 +286,7 @@ LEVEL *current_level; ** "do_command" gets a command from the player and performs it. */ -PRIVATE int do_command(current_level) -LEVEL *current_level; +PRIVATE int do_command(LEVEL *current_level) { register int player_pos; char command_buf[LINE_LEN + 1]; @@ -380,8 +374,7 @@ LEVEL *current_level; ** "do_user" */ -PUBLIC int do_user(current_level) -LEVEL *current_level; +PUBLIC int do_user(LEVEL *current_level) { /* ** If we are jumping, just finish the line. Otherwise, check for @@ -400,8 +393,7 @@ LEVEL *current_level; ** "manipulate_objects" */ -PUBLIC int manipulate_objects(current_level) -LEVEL *current_level; +PUBLIC int manipulate_objects(LEVEL *current_level) { /* ** If there is a Snoman, the player's jet-powered skis may melt him, @@ -500,4 +492,4 @@ LEVEL *current_level; } } - +/* end */ diff --git a/ski.c b/ski.c index 7cb7da4..342c67e 100644 --- a/ski.c +++ b/ski.c @@ -1,9 +1,10 @@ -/* 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 #include @@ -15,295 +16,212 @@ #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); - } -}