home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1992 March / Source_Code_CD-ROM_Walnut_Creek_March_1992.iso / usenet / altsrcs / 1 / 1996 / ski.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-12-28  |  6.3 KB  |  294 lines

  1. /*                                  S K I !
  2. **
  3. **                       Version 6.0 of October 14, 1990
  4. **
  5. **           Copyright 1983-1990 by Mark Stevans for Roy's Games, Inc.
  6. */
  7.  
  8. #include <stdio.h>
  9. #include <ctype.h>
  10. #include "ski.h"
  11.  
  12. /*
  13. **
  14. ** Constants controlling the multiple cellular growth automatons that are
  15. ** executed in parallel to generate hazards.
  16. **
  17. ** Each cellular growth automaton probability element tends to control a
  18. ** different facet of hazard generation:
  19. **
  20. **    [0] appearance of new hazards in clear snow
  21. **    [1] hazards edge growth
  22. **    [2] hazards edge stability
  23. **    [3] appearance of holes in solid hazards (this allows the Snoman to
  24. **        work his way through forests)
  25. */
  26.  
  27. PRIVATE float prob_tree[] = { 0.0, 30.0, 70.0, 90.0 };
  28. PRIVATE float prob_ice[] = { 0.0, 30.0, 70.0, 90.0 };
  29. PRIVATE float prob_ground[] = { 0.0, 30.0, 70.0, 90.0 };
  30. PRIVATE float prob_snoman_appearance;
  31.  
  32. /*
  33. ** "init" performs various initialization functions.
  34. */
  35.  
  36. PRIVATE int init(level_ptr)
  37. LEVEL *level_ptr;
  38. {
  39.     register int i;
  40.  
  41.     /*
  42.     ** Print the game version.
  43.     */
  44.  
  45.     printf("SKI!  Version 6.0!\n");
  46.  
  47.     /*
  48.     ** Initialize the random number generator.
  49.     */
  50.  
  51.     RANDOM_INITIALIZE((int) time(NIL(long *)));
  52.  
  53.     /*
  54.     ** Initialize the player's position.
  55.     */
  56.  
  57.     level_ptr->player_pos = RANDOM_GENERATE() % LINE_LEN;
  58.  
  59.     /*
  60.     ** Initialize the current level.
  61.     */
  62.  
  63.     for (i = 0; i < LINE_LEN; ++i)
  64.         level_ptr->slope[i] = REP_SNOW;
  65.  
  66.     level_ptr->slope[LINE_LEN] = EOS;
  67.  
  68.     level_ptr->meters_travelled = 0;
  69.     level_ptr->jump_count = -1;
  70.     level_ptr->level_num = 0;
  71.     level_ptr->num_snomen_melted = 0;
  72.     level_ptr->num_jumps_attempted = 0.0;
  73.     level_ptr->player_pos = RANDOM_GENERATE() % LINE_LEN;
  74.     level_ptr->snoman_pos = NO_POSITION;
  75.     level_ptr->icbm_pos = NO_POSITION;
  76.     level_ptr->demon_pos = NO_POSITION;
  77.     level_ptr->player_speed = 0;
  78.  
  79.     /*
  80.     ** Randomize the appearance probabilities.
  81.     */
  82.  
  83.     prob_tree[0] = (RANDOM_GENERATE() % 100) / 500.0 + 0.05;
  84.     prob_ice[0] = (RANDOM_GENERATE() % 100) / 500.0 + 0.05;
  85.     prob_ground[0] = (RANDOM_GENERATE() % 100) / 500.0 + 0.05;
  86.     prob_snoman_appearance = (RANDOM_GENERATE() % 100) / 25.0 + 1.0;
  87.  
  88.     /*
  89.     ** Return a code indicating successful completion.
  90.     */
  91.  
  92.     return (SUCCESS);
  93. }
  94.  
  95. /*
  96. ** "main" is the top level function of the game.
  97. */
  98.  
  99. PUBLIC int main()
  100. {
  101.     LEVEL level;
  102.  
  103.     /*
  104.     ** Initialize the game.
  105.     */
  106.  
  107.     if (init(&level) != SUCCESS)
  108.         exit(1);
  109.  
  110.     /*
  111.     ** Perform the game loop until the game is over.
  112.     */
  113.  
  114.     for (;;) {
  115.         draw_picture(&level);
  116.         do_user(&level);
  117.         manipulate_objects(&level);
  118.         update_level(&level);
  119.     }
  120. }
  121.  
  122. /*
  123. ** "gen_next_slope" generates the slope of the next level, dependent upon
  124. ** the characteristics of the current level, the probabilities, and the
  125. ** position of the player.
  126. */
  127.  
  128. PRIVATE int gen_next_slope(current_level, next_level)
  129. LEVEL *current_level;
  130. LEVEL *next_level;
  131. {
  132.     register int i;
  133.     register char *current_slope;
  134.     register char *next_slope;
  135.     register int player_pos;
  136.     short num_nearby_trees, num_nearby_ice, num_nearby_ground;
  137.  
  138.     /*
  139.     ** Cache some convenient values.
  140.     */
  141.  
  142.     current_slope = current_level->slope;
  143.     next_slope = next_level->slope;
  144.     player_pos = current_level->player_pos;
  145.  
  146.     /*
  147.     ** Generate each character of the next level.
  148.     */
  149.  
  150.     for (i = 0; i < LINE_LEN; ++i) {
  151.         /*
  152.         ** Count the number of nearby trees, ice patches, and
  153.         ** ground patches on the current level.
  154.         */
  155.  
  156.         num_nearby_trees = 0;
  157.         num_nearby_ice = 0;
  158.         num_nearby_ground = 0;
  159.  
  160.         if (current_slope[i] == REP_TREE)
  161.             ++num_nearby_trees;
  162.         if (current_slope[i] == REP_ICE)
  163.             ++num_nearby_ice;
  164.         if (current_slope[i] == REP_GROUND)
  165.             ++num_nearby_ground;
  166.  
  167.         if (i > 0) {
  168.             if (current_slope[i - 1] == REP_TREE)
  169.                 ++num_nearby_trees;
  170.             else if (current_slope[i - 1] == REP_ICE)
  171.                 ++num_nearby_ice;
  172.             else if (current_slope[i - 1] == REP_GROUND)
  173.                 ++num_nearby_ground;
  174.         }
  175.  
  176.         if (i < (LINE_LEN - 1)) {
  177.             if (current_slope[i + 1] == REP_TREE)
  178.                 ++num_nearby_trees;
  179.             else if (current_slope[i + 1] == REP_ICE)
  180.                 ++num_nearby_ice;
  181.             else if (current_slope[i + 1] == REP_GROUND)
  182.                 ++num_nearby_ground;
  183.         }
  184.  
  185.         /*
  186.         ** Generate this character of the next level based upon
  187.         ** the characteristics of the nearby characters on the
  188.         ** current level.
  189.         */
  190.  
  191.         if (PROB(prob_tree[num_nearby_trees]) &&
  192.                 ((i != player_pos) || (num_nearby_trees > 0)))
  193.             next_slope[i] = REP_TREE;
  194.         else if (PROB(prob_ice[num_nearby_ice]) &&
  195.                 ((i != player_pos) || (num_nearby_ice > 0)))
  196.             next_slope[i] = REP_ICE;
  197.         else if (PROB(prob_ground[num_nearby_ground]) &&
  198.                 ((i != player_pos) || (num_nearby_ground > 0)))
  199.             next_slope[i] = REP_GROUND;
  200.         else
  201.             next_slope[i] = REP_SNOW;
  202.     }
  203.  
  204.     /*
  205.     ** Terminate the slope string.
  206.     */
  207.  
  208.     next_slope[LINE_LEN] = EOS;
  209.  
  210.     /*
  211.     ** Return a code indicating successful completion.
  212.     */
  213.  
  214.     return (SUCCESS);
  215. }
  216.  
  217. /*
  218. ** "update_level" moves to the next level.
  219. */
  220.  
  221. PRIVATE int update_level(current_level)
  222. LEVEL *current_level;
  223. {
  224.     LEVEL next_level;
  225.  
  226.     /*
  227.     ** Go to the next level, and move the player.
  228.     */
  229.  
  230.     ++current_level->level_num;
  231.  
  232.     current_level->meters_travelled += ABS(current_level->player_speed) + 1;
  233.  
  234.     /*
  235.     ** Figure out the new player position based on a modulo
  236.     ** addition.  Note that we must add the line length into the
  237.     ** expression before taking the modulus to make sure that we
  238.     ** are not taking the modulus of a negative integer.
  239.     */
  240.  
  241.     current_level->player_pos = (current_level->player_pos +
  242.             current_level->player_speed + LINE_LEN) % LINE_LEN;
  243.  
  244.     /*
  245.     ** Generate the updated slope.
  246.     */
  247.  
  248.     gen_next_slope(current_level, &next_level);
  249.  
  250.     strcpy(current_level->slope, next_level.slope);
  251.  
  252.     /*
  253.     ** If the player was jumping, decrement the jump count.
  254.     */
  255.  
  256.     if (current_level->jump_count >= 0)
  257.         --current_level->jump_count;
  258.  
  259.     /*
  260.     ** If there is no Snoman, one might be created.
  261.     */
  262.  
  263.     if (!EXISTS(current_level->snoman_pos)) {
  264.         if (PROB(prob_snoman_appearance)) {
  265.             /*
  266.             ** Make sure that the Snoman does not appear too
  267.             ** close to the player.
  268.             */
  269.  
  270.             do {
  271.                 current_level->snoman_pos = RANDOM_GENERATE() % LINE_LEN;
  272.             } while (ABS(current_level->snoman_pos -
  273.                     current_level->player_pos) <=
  274.                     MIN_SNOMAN_APPEARANCE_DISTANCE);
  275.         }
  276.     }
  277.  
  278.     /*
  279.     ** Increase the initial appearance probabilities of all obstacles and
  280.     ** the Snoman.
  281.     */
  282.  
  283.     prob_tree[0] *= LEVEL_MULTIPLIER;
  284.     prob_ice[0] *= LEVEL_MULTIPLIER;
  285.     prob_ground[0] *= LEVEL_MULTIPLIER;
  286.     prob_snoman_appearance *= LEVEL_MULTIPLIER;
  287.  
  288.     /*
  289.     ** Return a code indicating successful completion.
  290.     */
  291.  
  292.     return (SUCCESS);
  293. }
  294.