[comp.sources.misc] v06i080: Random Weather Generator for RPGs

allbery@uunet.UU.NET (Brandon S. Allbery - comp.sources.misc) (03/26/89)

Posting-number: Volume 6, Issue 80
Submitted-by: slocum@hi-csc.UUCP
Archive-name: rndweather

This is a random weather generator for use with roleplaying games.
It is customizable, and contains several different climates and
calendars.  See README file for for info.  See Makefile for
instructions on making various versions.

Brett Slocum   UUCP: ...uunet!hi-csc!slocum
               Arpa: hi-csc!slocum@uunet.uu.net
"My name is Inigo Montoya. You killed my father. Prepare to die."

#--------------------------------CUT HERE-------------------------------------


# This is a shell archive.  Remove anything before this line, then
# unpack it by saving it in a file and typing "sh file".  (Files
# unpacked will be owned by you and have default permissions.)
#
# This archive contains:
# README Makefile weather.c gregorian.h gulf.h japan.h mid_atlantic.h middle_earth.h n_atlantic.h n_pacific.h s_atlantic.h weather.h

echo x - README
cat > "README" << '//E*O*F README//'
When playing roleplaying games (RPGs), it often adds some realism if the GM
can determine what kind of weather is occuring.  This program generates random
weather for a year that is tunable to various climates.  Several example
climates are included: north, south, and mid atlantic, gulf, and north
pacific.

In addition, several different calendars are included: Gregorian, medieval
Japanese, and the Middle Earth calendar detailed in the appendices of
Tolkien's The Lord of the Rings.

The details of these are provided so that the user can create his or her own
climate profiles or calendars.

Please send any improvements, new climate profiles, new calendars, or
better versions of the current climate profiles to one of the addresses below.

-----------------------------------------------------------------
Brett Slocum   UUCP: ...uunet!hi-csc!slocum
               Arpa: hi-csc!slocum@uunet.uu.net
"My name is Inigo Montoya. You killed my father. Prepare to die."
-----------------------------------------------------------------

//E*O*F README//

echo x - Makefile
cat > "Makefile" << '//E*O*F Makefile//'
# Makefile: makefile for weather.c
# 
# make <choice>
# will create a specific climate program.
#
# make
# will create 'england', an English climate program.
#
# make all
# will create all climate programs.
#
# To make addition climate programs, just add the calendar
# and climate choices as -D options.
#
# Calendar choices:
# 
# GREGORIAN - uses essentially modern calendar, without leap years.
#
# JAPAN     - uses medieval Japanese calendar.
#
# MIDDLE_EARTH - uses calendar described in appendices of Tolkien's
#                'The Lord of the Rings'.
#
# Climate choices:
#
# N_ATLANTIC   - useful for Scandinavia coastal or interior continential US
#                or Europe.
# MID_ATLANTIC - useful for England, European coastal, New England, etc.
# S_ATLANTIC   - useful for Spain, Southern coastal US
# GULF         - useful for Gulf States, Mediterranean, etc.
# N_PACIFIC    - useful for Japan, Korea, Southern Alaskan coast, etc.

england: weather.c weather.h gregorian.h mid_atlantic.h
	cc -DGREGORIAN -DMID_ATLANTIC -o england -g weather.c

minnesota: weather.c weather.h gregorian.h n_atlantic.h
	cc -DGREGORIAN -DN_ATLANTIC -o minnesota -g weather.c

japan: weather.c weather.h japan.h n_pacific.h
	cc -DJAPAN -DN_PACIFIC -o japan -g weather.c

florida: weather.c weather.h gregorian.h gulf.h
	cc -DGREGORIAN -DGULF -o florida -g weather.c

shire: weather.c weather.h middle_earth.h mid_atlantic.h
	cc -DMIDDLE_EARTH -DMID_ATLANTIC -o shire -g weather.c

georgia: weather.c weather.h gregorian.h s_atlantic.h
	cc -DGREGORIAN -DS_ATLANTIC -o georgia -g weather.c

all: england minnesota japan florida shire georgia

//E*O*F Makefile//

echo x - weather.c
cat > "weather.c" << '//E*O*F weather.c//'
/**************************************************************************
 *  Weather - generates random weather                                    *
 *                                                                        *
 *  Copyright 1988 by Brett Slocum.  All rights reserved.                 *
 *  Permission is granted to distribute or modify this program, or use    *
 *  portions of this program in other programs, as long as this notice    *
 *  remains intact.                                                       *
 *  This program or its derivatives may not be sold for profit without    *
 *  permission of the author.                                             *
 *                                                                        *
 *  Original UNIX Version: Brett Slocum UUCP: ...uunet!hi-csc!slocum      *
 *                                      ARPA: hi-csc!slocum@uunet.uu.net  *
 *                                                                        *
 **************************************************************************/

#include "weather.h"

typedef UBYTE MONTH_T;

/* Calendar choices */
#ifdef GREGORIAN
#include "gregorian.h"
#else
#ifdef JAPAN
#include "japan.h"
#else
#ifdef MIDDLE_EARTH
#include "middle_earth.h"
#endif
#endif
#endif

/* Climate choices */
#ifdef N_ATLANTIC
#include "n_atlantic.h"
#else
#ifdef MID_ATLANTIC
#include "mid_atlantic.h"
#else
#ifdef S_ATLANTIC
#include "s_atlantic.h"
#else
#ifdef GULF
#include "gulf.h"
#else
#ifdef N_PACIFIC
#include "n_pacific.h"
#endif
#endif
#endif
#endif
#endif

UBYTE Stat_Table[N_MONTHS][N_STAT] = {
    {200,0,0}, {200,0,0}, {200,0,0}, {200,0,0}, {200,0,0}, {200,0,0}, 
    {200,0,0}, {200,0,0}, {200,0,0}, {200,0,0}, {200,0,0}, {200,0,0}
};

WIND_T     Wind = CALM;          /* today's wind conditions */
TEMP_T     Temp_Class = CHILLY;  /* today's temperature class */
PRECIP_T   Precip_Class = NONE;  /* today's precipitation */
WEATHER_T  Weather;              /* today's weather */
OVERCAST_T Sky;                  /* today's sky conditions */

UBYTE Temperature = 0,           /* today's actual temperature */
      Duration = 0;              /* today's precipitation duration */

BOOL Duration_Hours = TRUE,      /* flag that indicates whether precip lasted */
                                 /* hours (TRUE) or minutes (FALSE) */
     Catastrophe = FALSE,        /* flag that indicates whether a catastrophe */
                                 /* occurred today */
     Storm = FALSE,              /* flag that indicates whether precip was a storm */
     Long_Storm = FALSE,         /* flag that indicates whether precip was a */
                                 /* long storm lasting more than one day */
     Snow = FALSE;               /* flag that indicates whether snow fell today */

float Rainfall = 0.0,            /* yearly total rainfall */
      Snowfall = 0.0,            /* yearly total snowfall */
      Snow_Depth = 0.0;          /* today's snow depth, including new accumulations */
                                 /* and melting */

WEATHER_T 
gen_weather(month, ptr_catastrophe)
    MONTH_T month;
    BOOL *ptr_catastrophe;
    /* This routine generates the overall weather for the day. */
    /* It also determines whether a catastrophe has occurred.  */
    /* A catastrophe can be localized or wide-spread, natural  */
    /* or man-made. Such things as fires, earthquakes, floods, */
    /* etc. are possible.                                      */
{
     int       roll;
     WEATHER_T i, 
               return_val;

     /* get die-roll.  if catastrophe, set flag and roll again. */
     do {  
         roll = DIE(100);
         if (roll == 100)
             *ptr_catastrophe = TRUE;
     }
     while (roll == 100);
 
     /* if it rained more than a sprinkle yesterday, it more likely */
     /* to be at least overcast, if not rainy today. */
     if (Precip_Class > SPRINKLE) {
         roll = roll - 10;
         if (roll < 1)
             roll = 1;
     }

     /* find the type of weather from the die-roll */
     return_val = CLEAR;
     for (i = CLEAR; i >= PRECIPITATION; i--)
         if (roll <= Weather_Table[month][i])
             return_val = i;
     return(return_val);
}

TEMP_T 
gen_temp(month)
    MONTH_T month;
    /* generates the day's temperature and set the temp type */
{
     int roll, data, i;
     TEMP_T return_val;

     /* determine temperature variation from monthly average */
     /*   +/- 20 degrees */
     roll = DIE(100);
     data = 8;
     for (i = 8; i >= 0; i--)
         if (roll <= Temp_Variation[i])
             data = i;
     Temperature = Ave_Temp[month] + ((data-4) * 5);

     /* classify the temperature class */
     if (Temperature < 25) 
         return_val = COLD;
     else
     if ((Temperature >= 25) AND (Temperature < 40)) 
         return_val = CHILLY;
     else
     if ((Temperature >= 40) AND (Temperature < 65)) 
         return_val = FAIR;
     else
     if ((Temperature >= 65) AND (Temperature < 80)) 
         return_val = WARM;
     else
     if (Temperature >= 80) 
         return_val = HOT;

     /* accumulate monthly statistics */
     Stat_Table[month][HIGH] = MAX(Temperature, Stat_Table[month][HIGH]);
     Stat_Table[month][LOW] = MIN(Temperature, Stat_Table[month][LOW]);
     return(return_val);
}

WIND_T
gen_wind(month)
    MONTH_T month;
    /* generate the wind class */
{
     int roll;
     WIND_T return_val, i;

     /* modify the roll for current weather.  Clear weather is less likely */
     /* to be windy, and rainy weather is more likely. */
     roll = DIE(100);
     switch (Weather) {
     case CLEAR : 
         roll -= 20;
         break;
     case PRECIPITATION:
         roll += 20;
         break;
     } /* switch */

     /* if yesterday was very windy, today will be windier */
     if (Wind >= BLUSTERY) 
         roll += 20;

     /* limit to boundaries 1-100 */
     if (roll < 1) 
         roll = 1;
     if (roll > 100) 
         roll = 100;

     /* find wind type */
     return_val = GALE;
     for (i = GALE; i >= CALM; i--)
         if (roll <= Wind_Table[month][i]) 
             return_val = i;
     if (Weather == TAIFUN) 
         return_val = GALE;
     return(return_val);
 }

PRECIP_T
gen_precip(month)
    MONTH_T month;
    /* generate today's precipitation */
{
     int roll;
     PRECIP_T return_val, i;

     return_val = NONE;
     if (Weather == PRECIPITATION)
     {
         roll = DIE(100);
         return_val = STEADY;
         for (i = STEADY; i >= SPRINKLE; i--)
             if (roll <= Precip_Table[month][i])
                 return_val = i;
     }

     /* if yesterday had steady precipitation, there is a 1/3 chance */ 
     /* on the second day and 1/6 chance on succeeding days that today */
     /* also has steady precipitation */
     if ((Precip_Class == STEADY) AND (DIE(6) <= 2 - Long_Storm))
     {
         Weather = PRECIPITATION;
         return_val = STEADY;
     }

     return(return_val);
}

void
precip_statistics()
     /* determines various flags including Snow, Storm and Long_Storm. */
     /* Also determines precipitation duration and amount, updates */
     /* yearly Rainfall and Snowfall statistics, daily Snow_Depth, */
     /* and snow melting */
{
     float amount;

     if (Weather == PRECIPITATION)
     {
         /* set flags */
         if (Precip_Class != STEADY) 
             Long_Storm = FALSE;
         if (Temperature < 35)
             Snow = TRUE;
         else
             Snow = FALSE;
         if ((Temp_Class >= WARM) AND ((Precip_Class == SHOWER) OR (Precip_Class == HEAVY)))
             Storm = TRUE;
         else
             Storm = FALSE;
         if (Snow AND (Precip_Class >= HEAVY) AND (Wind >= BLUSTERY))
             Storm = TRUE;

         /* determine duration and amount of precipitation */
         switch (Precip_Class) {
         case SPRINKLE :
             Duration = 5 * DIE(6);
             Duration_Hours = FALSE;
             amount = 0.1;
             break;
         case SHOWER :
             Duration = 10 * (DIE(6) + DIE(6));
             Duration_Hours = FALSE;
             amount = Duration / 100;
             break;
         case HEAVY : 
             Duration = 1 + DIE(6);
             Duration_Hours = TRUE;
             amount = (DIE(4) + (Storm * Duration));
             break;
         case STEADY :
             Duration = 24;
             Duration_Hours = TRUE;
             amount = (DIE(6) + DIE(6)) + (Storm * (DIE(6) + DIE(6))); 
             break;
         }
         if (Storm)
             amount *= 2.0;

         /* update yearly and daily statistics */
         Rainfall += (amount / 10);
         if (Snow)
             {
                 Snow_Depth += amount;
                 Snowfall += amount;
             }
         else
             switch (Precip_Class) {
             case SHOWER : 
                 Snow_Depth -= Duration / 60;
                 break;
             case HEAVY : 
                 Snow_Depth -= Duration;
                 break;
             case STEADY :
                 Snow_Depth -= 12;
                 break;
             }
     }

     /* melt snow in weather above freezing */
     switch (Temp_Class) {
     case CHILLY :
         if (Temperature > 32) 
             Snow_Depth -= 1.0;
         break;
     case FAIR :
         Snow_Depth -= Temperature / 8;
         break;
     case WARM :
         Snow_Depth -= Temperature - 40;
         break;
     case HOT : 
         Snow_Depth -= Temperature - 20;
         break;
     }
     if (Snow_Depth < 0.1)
         Snow_Depth = 0.0;
}

OVERCAST_T
gen_overcast(weather)
    WEATHER_T weather;
    /* generate today's level of cloudiness */
{
     int roll;
     OVERCAST_T return_val, i;

     return_val = CLOUDY;
     switch (weather) {
     case PRECIPITATION:
     case OVERCAST :
          roll = DIE(100);
          return_val = CLOUDY;
          for (i = CLOUDY; i >= HEAVY_FOG; i--)
              if (roll <= Overcast_Table[i])
                  return_val = i;
          break;
     case TAIFUN : return_val = CLOUDY;
     }
     return(return_val);
}

void
print_notes(day, month)
    UBYTE day;
    MONTH_T month;
    /* print snow depth, precipitation type and duration, */
    /* catastrophe, and holidays */
{
     char *precip,
          *dur;

     if (Precip_Class != NONE) 
     {
         if (Snow) 
             precip = (Storm ? "Blizzard" : "Snow");
         else
             precip = (Storm ? "Storm" : "Rain");
         dur = (Duration_Hours ? "hours" : "minutes");
         printf(" %s - %2d %s,", precip, Duration, dur);
     }
     if (Catastrophe)
         printf(" Catastrophe,");
     print_holiday(day, month);
}

void
print_weather(day, month)
    UBYTE day;
    MONTH_T month;
    /* print today's weather */
{
     printf("%4d  %13s", day, Weather_Name[Weather]);
     printf("%11s", ((Weather==CLEAR) ? "Clear" : Overcast_Name[Sky]));
     printf("%8s (%3d)  %8s  %8s", Temp_Name[Temp_Class], Temperature, Precip_Name[Precip_Class], Wind_Name[Wind]);
     if (Snow_Depth > 0.0) 
         printf(" %5.1f\" ", Snow_Depth);
     else
         printf("%8c", ' ');
     print_notes(day, month);
     printf("\n");
 }

void
init_winter()
     /* initialize last year's winter */
{
     UBYTE day;
     MONTH_T month;

     /* calculate snow depth for Oct. thru Dec. */
     for (month = LAST_MONTH-2; month <= LAST_MONTH; month++)
         for (day = 1; day <= Day_Table[month]; day++)
         {
             Catastrophe = FALSE;
             if (DIE(100) > 50) 
                 Weather = gen_weather(month, &Catastrophe);
             Wind = gen_wind(month);
             Temp_Class = gen_temp(month);
             Precip_Class = gen_precip(month);
             precip_statistics();
             Sky = gen_overcast(Weather);
         }
}

init_stat()
{
    MONTH_T month;
    STAT_T stat;

    for (month = FIRST_MONTH; month <= LAST_MONTH; month++)
    {
        Stat_Table[month][LOW] = 200;
        for (stat = AVERAGE; stat <= HIGH; stat++)
            Stat_Table[month][stat] = 0;
    }
}

main(argc, argv)  
int argc;
char *argv[];
{
     int cum_temp;               /* cumulative temp used for calculating average temp */
     unsigned int sunshine = 0;  /* number of days of sunshine */
     MONTH_T month;              /* month counter */
     UBYTE day,                  /* day counter */
           year,                 /* year counter */
           n_years = 1;          /* number of years */

     srandom((int)time(0));
     if (argc > 1)
         n_years = atoi(argv[1]);
     init_winter();
     for (year = 1; year <= n_years; year++)
     {
         Rainfall = 0.0;
         Snowfall = 0.0;
         sunshine = 0;
         init_stat();
         printf("%64c%6s\n", ' ',"Snow");
         printf("Year %3d%11s%11s%14s%10s%10s%7s%7s\n", year, "Weather", "Sky", "Temperature", "Precip", "Wind", "Depth", "Notes");
         for (month = FIRST_MONTH; month <= LAST_MONTH; month++)
         {
             cum_temp = 0;
             printf("%-9s\n", Month_Name[month]);
             for (day = 1; day <= Day_Table[month]; day++)
             {
                 Catastrophe = FALSE;
    
                 /* half the time, Weather is the same as yesterday */
                 if (DIE(100) > 50) 
                     Weather = gen_weather(month, &Catastrophe);
                 Wind = gen_wind(month);
                 Temp_Class = gen_temp(month);
                 cum_temp += Temperature;
                 Precip_Class = gen_precip(month);
                 precip_statistics();
                 Sky = gen_overcast(Weather);
    
                 /* count sunny days */
                 if (Weather == CLEAR) 
                     sunshine++;
                 print_weather(day, month);
             }
             Stat_Table[month][AVERAGE] = (cum_temp / Day_Table[month]);
             printf("High Temp = %3d, Low Temp = %3d, Average Temp = %3d\n\n", Stat_Table[month][HIGH], Stat_Table[month][LOW], Stat_Table[month][AVERAGE]);
         }
         /* print yearly statistics */
         printf("Sunshine = %3d days\n", sunshine);
         printf("Rainfall = %4.1f\"\n", Rainfall);
         printf("Snowfall = %4.1f\"\n\n", Snowfall);
     }
}

//E*O*F weather.c//

echo x - gregorian.h
cat > "gregorian.h" << '//E*O*F gregorian.h//'
/* Copyright 1988 by Brett D. Slocum - 12/12/88 */
/* All rights reserved */
/* This is the calendar include file is for weather generation */
/* It includes calendar and holiday information */

/* To create a new calendar file, 
       1) define month names for use by MONTH_T type,
       2) define FIRST_MONTH and LAST_MONTH,
       3) define string array Month_Name with printable version of month,
       4) define number of days per month array Day_Table,
       5) add printf statements in print_holidays for holidays
*/

/* Month types */
#define JANUARY   0
#define FEBRUARY  1
#define MARCH     2
#define APRIL     3
#define MAY       4
#define JUNE      5
#define JULY      6
#define AUGUST    7
#define SEPTEMBER 8
#define OCTOBER   9
#define NOVEMBER  10
#define DECEMBER  11

#define FIRST_MONTH JANUARY
#define LAST_MONTH  DECEMBER

#define N_MONTHS (LAST_MONTH - FIRST_MONTH) + 1

char *Month_Name[N_MONTHS] = {
    "January", 
    "February",
    "March",
    "April",
    "May",
    "June",
    "July",
    "August",
    "September",
    "October",
    "November",
    "December"
};

UBYTE Day_Table[N_MONTHS] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};

void
print_holiday(day, month)
    UBYTE day;
    MONTH_T month;
{
     switch (month) {
     case JANUARY : 
         if (day == 1) 
             printf(" New Years (s)");
         if (day == 6) 
             printf(" Twelfth Night");
         break;
     case FEBRUARY : 
         if (day == 2) 
             printf(" Candlemas");
         if (day == 14) 
             printf(" St. Valentine's Day");
         break;
     case MARCH : 
         if (day == 21) 
             printf(" Spring Equinox");
         break;
     case APRIL : 
         break;
     case MAY : 
         if (day == 1) 
             printf(" May Day");
         break;
     case JUNE : 
         if (day == 21) 
             printf(" Midsummer Day");
         break;
     case JULY : 
         break;
     case AUGUST : 
         if (day == 2) 
             printf(" Lammas");
         break;
     case SEPTEMBER : 
         if (day == 21) 
             printf(" Fall Equinox");
         break;
     case OCTOBER : 
         if (day == 31) 
             printf(" Halloween");
         break;
     case NOVEMBER : 
         break;
     case DECEMBER : 
         if (day == 21) 
             printf(" Winter Solstice");
         if (day == 25) 
             printf(" Christmas");
         break;
     }
}

//E*O*F gregorian.h//

echo x - gulf.h
cat > "gulf.h" << '//E*O*F gulf.h//'
/* Most of the info provided in this file could be found in an almanac. */

/* Ave_Temp       - the average temperature for each month */
/* Weather_Table  - each entry in the table is the weather profile for each month */
/*                  for a random 1-100 die roll. */
/*  month profile - {precipitation, overcast, taifun/hurricane, clear} */        
/*        example - {30,35,0,100} means that in this month a roll of : */
/*                  1-30  = precipitation        */
/*                 31-35  = overcast             */
/*                 no chance of taifun/hurricane */
/*                 36-100 = clear                */

/* Wind_Table     - is structured like the Weather_Table. */
/*  month profile - {Calm, Light, Brisk, Blustery, Gale}  */

/* Precip_Table   - as above */
/*  month profile - {None, Sprinkle, Shower, Heavy, Steady} */

/* Overcast_Table - {Heavy Fog, Light Fog, Mist, Cloudy} */

UBYTE Ave_Temp[N_MONTHS] = {65, 70, 75, 80, 85, 95, 95, 90, 85, 75, 70, 65};

UBYTE Weather_Table[N_MONTHS][N_WEATHER] = {
    {30,35,0,100}, {25,35,0,100}, {20,30,0,100}, {35,50,0,100}, {25,40,0,100}, {15,25,0,100}, 
    {10,15,0,100}, {10,15,0,100}, {15,25,0,100}, {25,35,0,100}, {25,40,0,100}, {30,45,0,100}
};

UBYTE Wind_Table[N_MONTHS][N_WIND] = {
    {60,80,90,100,0}, {50,70,85,100,0}, {40,60,75,99,100}, {60,85,95,100,0}, {70,90,100,0,0}, {80,90,100,0,0}, 
    {80,100,0,0,0}, {80,100,0,0,0}, {60,80,95,100,0}, {40,65,85,97,100}, {40,60,80,95,100}, {60,80,90,100,0}
};

UBYTE Precip_Table[N_MONTHS][N_PRECIP] = {
    {0,40,70,80,100},
    {0,50,80,95,100},
    {0,60,80,100,0},
    {0,40,70,90,100},
    {0,50,80,100,0},
    {0,60,90,100,0},
    {0,80,95,100,0},
    {0,80,95,100,0},
    {0,60,80,90,100},
    {0,50,80,90,100},
    {0,40,70,85,100},
    {0,40,70,80,100}
};

UBYTE Overcast_Table[N_OVERCAST] = {10,20,70,100};


//E*O*F gulf.h//

echo x - japan.h
cat > "japan.h" << '//E*O*F japan.h//'
/* Copyright 1988 by Brett D. Slocum - 12/12/88 */
/* All rights reserved */
/* This is the calendar include file is for weather generation */
/* It includes calendar and holiday information */

/* To create a new calendar file, 
       1) define month names for use by MONTH_T type,
       2) define FIRST_MONTH and LAST_MONTH,
       3) define string array Month_Name with printable version of month,
       4) define number of days per month array Day_Table,
       5) add printf statements in print_holidays for holidays
*/

/* Month types */
#define RAT    0
#define BULL   1
#define TIGER  2
#define HARE   3
#define DRAGON 4
#define SNAKE  5
#define HORSE  6
#define SHEEP  7
#define MONKEY 8
#define BIRD   9
#define DOG    10
#define BOAR   11

#define FIRST_MONTH RAT
#define LAST_MONTH  BOAR

#define N_MONTHS (LAST_MONTH - FIRST_MONTH) + 1

/* text version of month names */
char *Month_Name[N_MONTHS] = {
    "Rat",
    "Bull",
    "Tiger",
    "Hare",
    "Dragon",
    "Snake",
    "Horse",
    "Sheep",
    "Monkey",
    "Bird",
    "Dog",
    "Boar"
};

/* table of days per month */
UBYTE Day_Table[N_MONTHS] = {29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30};

void
print_holiday(day,month)
    UBYTE day;
    MONTH_T month;
    /* prints holidays that fall on a given day */
{
     if (day == 15)
         printf(" Full Moon,");
     if (day == Day_Table[month])
         printf(" New Moon,");
     switch (day) { 
     case 1:
     case 15 : printf(" Shinto,");
          break;
     case 8:
     case 18 : printf(" Buddhist,");
          break;
     case 28 : printf(" Buddhist, Shinto,");
          break;
     }
     switch (month) {
     case RAT : 
         if ((day >= 1) AND (day <= 6))
             printf(" New Years (s)");
         break;
     case BULL :
         switch (day) { 
         case 1: case 2: case 4: case 5: case 6: case 7:
             printf(" Equinox (b)");
             break;
         case 3: 
             printf(" Setsuban (1st Day of Spring) (s)");
             break;
         }
         break;
     case TIGER :
         if (day == 3) 
             printf(" Doll Festival (c)");
         break;
     case HARE :
         if (day == 8)
             printf(" Buddha's Birthday (b)");
         break;
     case DRAGON :
         if (day == 5) 
             printf(" Boy's Day (c)");
         break;
     case SNAKE :
         switch (day) {
         case 1: case 2: case 3: case 4: case 5: case 6: case 7: 
             printf(" Rice Planting Festival (p)");
             break;
         case 30 : 
             printf(" All debts paid (p)");
         }
         break;
     case HORSE :
         switch (day) {
         case 1 : 
             printf(" Midyear (p)");
             break;
         case 7 : 
             printf(" Tanabata (Star Festival) (c)");
             break;
         case 13: case 14: case 15: 
             printf(" Bon Festival (for the dead) (b)");
         }
         break;
     case SHEEP :
         if ((day >= 1) AND (day <= 7)) 
             printf(" Equinox (b)");
         break;
     case BIRD :
         switch (day) { 
         case 15 : 
              printf(" Rice Harvest Festival (p)");
              break;
         case 20 : 
              printf(" Festival of Ebishu (s)");
         } 
         break;
     case DOG :
         if (day == 8) 
             printf(" Feast of the Bellows (s)");
         break;
     case BOAR :
         if (day == 30) 
             printf(" All debts paid (p)");
     }
}

//E*O*F japan.h//

echo x - mid_atlantic.h
cat > "mid_atlantic.h" << '//E*O*F mid_atlantic.h//'
/* Most of the info provided in this file could be found in an almanac. */

/* Ave_Temp       - the average temperature for each month */
/* Weather_Table  - each entry in the table is the weather profile for each month */
/*                  for a random 1-100 die roll. */
/*  month profile - {precipitation, overcast, taifun/hurricane, clear} */        
/*        example - {30,35,0,100} means that in this month a roll of : */
/*                  1-30  = precipitation        */
/*                 31-35  = overcast             */
/*                 no chance of taifun/hurricane */
/*                 36-100 = clear                */

/* Wind_Table     - is structured like the Weather_Table. */
/*  month profile - {Calm, Light, Brisk, Blustery, Gale}  */

/* Precip_Table   - as above */
/*  month profile - {None, Sprinkle, Shower, Heavy, Steady} */

/* Overcast_Table - {Heavy Fog, Light Fog, Mist, Cloudy} */

UBYTE Ave_Temp[N_MONTHS] = {20, 35, 45, 55, 65, 75, 85, 80, 65, 50, 35, 25};

UBYTE Weather_Table[N_MONTHS][N_WEATHER] = {
    {30,35,0,100}, {25,35,0,100}, {20,30,0,100}, {35,50,0,100}, {25,40,0,100}, {15,25,0,100}, 
    {10,15,0,100}, {10,15,0,100}, {15,25,0,100}, {25,35,0,100}, {25,40,0,100}, {30,45,0,100}
};

UBYTE Wind_Table[N_MONTHS][N_WIND] = {
    {60,80,90,100,0}, {50,70,85,100,0}, {40,60,75,95,100}, {60,85,95,100,0}, {70,90,100,0,0}, {80,90,100,0,0}, 
    {80,100,0,0,0}, {80,100,0,0,0}, {60,80,95,100,0}, {40,65,85,95,100}, {40,60,80,90,100}, {60,80,90,95,100}
};

UBYTE Precip_Table[N_MONTHS][N_PRECIP] = {
    {0,40,70,80,100},
    {0,50,80,95,100},
    {0,60,80,100,0},
    {0,40,70,90,100},
    {0,50,80,100,0},
    {0,60,90,100,0},
    {0,80,95,100,0},
    {0,80,95,100,0},
    {0,60,80,90,100},
    {0,50,80,90,100},
    {0,40,70,85,100},
    {0,40,70,80,100}
};

UBYTE Overcast_Table[N_OVERCAST] = {10,20,70,100};


//E*O*F mid_atlantic.h//

echo x - middle_earth.h
cat > "middle_earth.h" << '//E*O*F middle_earth.h//'
/* Copyright 1988 by Brett D. Slocum - 12/12/88 */
/* All rights reserved */
/* This is the calendar include file is for weather generation */
/* It includes calendar and holiday information */

/* To create a new calendar file, 
       1) define month names for use by MONTH_T type,
       2) define FIRST_MONTH and LAST_MONTH,
       3) define string array Month_Name with printable version of month,
       4) define number of days per month array Day_Table,
       5) add printf statements in print_holidays for holidays
*/

/* Month types */
#define AFTERYULE   0
#define SOLMATH     1
#define RETHE       2
#define ASTRON      3
#define THRIMIDGE   4
#define FORELITHE   5
#define AFTERLITHE  6
#define WEDMATH     7
#define HALIMATH    8
#define WINTERFILTH 9
#define BLOTMATH    10
#define FOREYULE    11

#define FIRST_MONTH AFTERYULE
#define LAST_MONTH  FOREYULE

#define N_MONTHS (LAST_MONTH - FIRST_MONTH) + 1

char *Month_Name[N_MONTHS] = {
    "Afteryule",
    "Solmath",
    "Rethe",
    "Astron",
    "Thrimidge",
    "Forelithe",
    "Afterlithe",
    "Wedmath",
    "Halimath",
    "Winterfilth",
    "Blotmath",
    "Foreyule",
};

UBYTE Day_Table[N_MONTHS] = {30, 30, 30, 30, 30, 31, 30, 30, 30, 30, 30, 34};

void
print_holiday(day, month)
    UBYTE day;
    MONTH_T month;
{
     switch (month) {
     case AFTERYULE:
         break;
     case SOLMATH:
         break;
     case RETHE:
         break;
     case ASTRON:
         break;
     case THRIMIDGE:
         break;
     case FORELITHE:
         if (day == 31) 
             printf(" Midsummer Day");
         break;
     case AFTERLITHE:
         break;
     case WEDMATH:
         break;
     case HALIMATH:
         break;
     case WINTERFILTH:
         break;
     case BLOTMATH:
         break;
     case FOREYULE:
         if ((day >= 31) AND (day <= 34))
             printf(" Yule");
         break;
     }
}

//E*O*F middle_earth.h//

echo x - n_atlantic.h
cat > "n_atlantic.h" << '//E*O*F n_atlantic.h//'
/* Most of the info provided in this file could be found in an almanac. */

/* Ave_Temp       - the average temperature for each month */
/* Weather_Table  - each entry in the table is the weather profile for each month */
/*                  for a random 1-100 die roll. */
/*  month profile - {precipitation, overcast, taifun/hurricane, clear} */        
/*        example - {30,35,0,100} means that in this month a roll of : */
/*                  1-30  = precipitation        */
/*                 31-35  = overcast             */
/*                 no chance of taifun/hurricane */
/*                 36-100 = clear                */

/* Wind_Table     - is structured like the Weather_Table. */
/*  month profile - {Calm, Light, Brisk, Blustery, Gale}  */

/* Precip_Table   - as above */
/*  month profile - {None, Sprinkle, Shower, Heavy, Steady} */

/* Overcast_Table - {Heavy Fog, Light Fog, Mist, Cloudy} */

UBYTE Ave_Temp[N_MONTHS] = {10, 15, 25, 40, 55, 70, 85, 80, 60, 35, 20, 15};

UBYTE Weather_Table[N_MONTHS][N_WEATHER] = {
    {30,40,0,100}, /* January or the first month in non-Gregorian calendar */
    {25,35,0,100}, /* February */
    {20,30,0,100}, /* March */
    {35,50,0,100}, /* April */
    {25,40,0,100}, /* May */
    {15,25,0,100}, /* June */
    {10,15,0,100}, /* July */
    {10,15,0,100}, /* August */
    {15,30,0,100}, /* September */
    {25,40,0,100}, /* October */
    {25,40,0,100}, /* November */
    {30,45,0,100}  /* December */
};

UBYTE Wind_Table[N_MONTHS][N_WIND] = {
    {60,80,90,100,0},    /* January */
    {50,70,85,100,0},    /* February */  
    {40,60,75,95,100},   /* March */     
    {60,85,95,100,0},    /* April */     
    {70,90,100,0,0},     /* May */       
    {80,90,100,0,0},     /* June */      
    {80,100,0,0,0},      /* July */      
    {80,100,0,0,0},      /* August */    
    {60,80,95,100,0},    /* September */ 
    {40,65,85,95,100},   /* October */   
    {40,60,80,90,100},   /* November */  
    {60,80,90,95,100}    /* December */  
};

UBYTE Precip_Table[N_MONTHS][N_PRECIP] = {
    {0,40,70,80,100},   /* January */  
    {0,50,80,95,100},   /* February */ 
    {0,60,80,100,0},    /* March */    
    {0,40,70,90,100},   /* April */    
    {0,50,80,100,0},    /* May */      
    {0,60,90,100,0},    /* June */     
    {0,80,95,100,0},    /* July */     
    {0,80,95,100,0},    /* August */   
    {0,60,80,90,100},   /* September */
    {0,50,80,90,100},   /* October */  
    {0,40,70,85,100},   /* November */ 
    {0,40,70,80,100}    /* December */ 
};

UBYTE Overcast_Table[N_OVERCAST] = {10,20,70,100};


//E*O*F n_atlantic.h//

echo x - n_pacific.h
cat > "n_pacific.h" << '//E*O*F n_pacific.h//'
/* Most of the info provided in this file could be found in an almanac. */

/* Ave_Temp       - the average temperature for each month */
/* Weather_Table  - each entry in the table is the weather profile for each month */
/*                  for a random 1-100 die roll. */
/*  month profile - {precipitation, overcast, taifun/hurricane, clear} */        
/*        example - {30,35,0,100} means that in this month a roll of : */
/*                  1-30  = precipitation        */
/*                 31-35  = overcast             */
/*                 no chance of taifun/hurricane */
/*                 36-100 = clear                */

/* Wind_Table     - is structured like the Weather_Table. */
/*  month profile - {Calm, Light, Brisk, Blustery, Gale}  */

/* Precip_Table   - as above */
/*  month profile - {None, Sprinkle, Shower, Heavy, Steady} */

/* Overcast_Table - {Heavy Fog, Light Fog, Mist, Cloudy} */

UBYTE Ave_Temp[N_MONTHS] = {40, 50, 60, 65, 70, 80, 85, 75, 65, 50, 40, 35};

UBYTE Weather_Table[N_MONTHS][N_WEATHER] = {
    {10,15,0,100}, {35,45,0,100}, {50,70,0,100}, {50,70,0,100}, {50,60,0,100}, {50,60,0,100}, 
    {35,40,0,100}, {40,45,55,100}, {40,45,55,100}, {10,15,17,100}, {10,15,0,100}, {10,15,0,100}
};

UBYTE Wind_Table[N_MONTHS][N_WIND] = {
    {40,70,90,100,0}, {40,70,90,100,0}, {40,70,90,100,0}, {40,70,90,100,0}, {40,70,90,100,0}, {40,70,90,100,0}, 
    {40,70,90,100,0}, {40,70,90,100,0}, {40,70,90,100,0}, {40,70,90,100,0}, {40,70,90,100,0}, {40,70,90,100,0}
};

UBYTE Precip_Table[N_MONTHS][N_PRECIP] = {
    {0,40,70,80,100},
    {0,50,80,95,100},
    {0,60,80,100,0},
    {0,40,70,90,100},
    {0,50,80,100,0},
    {0,60,90,100,0},
    {0,80,95,100,0},
    {0,80,95,100,0},
    {0,60,80,90,100},
    {0,50,80,90,100},
    {0,40,70,85,100},
    {0,40,70,80,100}
};

UBYTE Overcast_Table[N_OVERCAST] = {10,20,70,100};


//E*O*F n_pacific.h//

echo x - s_atlantic.h
cat > "s_atlantic.h" << '//E*O*F s_atlantic.h//'
/* Most of the info provided in this file could be found in an almanac. */

/* Ave_Temp       - the average temperature for each month */
/* Weather_Table  - each entry in the table is the weather profile for each month */
/*                  for a random 1-100 die roll. */
/*  month profile - {precipitation, overcast, taifun/hurricane, clear} */        
/*        example - {30,35,0,100} means that in this month a roll of : */
/*                  1-30  = precipitation        */
/*                 31-35  = overcast             */
/*                 no chance of taifun/hurricane */
/*                 36-100 = clear                */

/* Wind_Table     - is structured like the Weather_Table. */
/*  month profile - {Calm, Light, Brisk, Blustery, Gale}  */

/* Precip_Table   - as above */
/*  month profile - {None, Sprinkle, Shower, Heavy, Steady} */

/* Overcast_Table - {Heavy Fog, Light Fog, Mist, Cloudy} */

UBYTE Ave_Temp[N_MONTHS] = {50, 60, 65, 70, 75, 80, 85, 80, 75, 65, 55, 50};

UBYTE Weather_Table[N_MONTHS][N_WEATHER] = {
    {30,35,0,100}, {25,35,0,100}, {20,30,0,100}, {35,50,0,100}, {25,40,0,100}, {15,25,0,100}, 
    {10,15,0,100}, {10,15,0,100}, {15,25,0,100}, {25,35,0,100}, {25,40,0,100}, {30,45,0,100}
};

UBYTE Wind_Table[N_MONTHS][N_WIND] = {
    {60,80,90,100,0}, {50,70,85,100,0}, {40,60,75,99,100}, {60,85,95,100,0}, {70,90,100,0,0}, {80,90,100,0,0}, 
    {80,100,0,0,0}, {80,100,0,0,0}, {60,80,95,100,0}, {40,65,85,97,100}, {40,60,80,95,100}, {60,80,90,100,0}
};

UBYTE Precip_Table[N_MONTHS][N_PRECIP] = {
    {0,40,70,80,100},
    {0,50,80,95,100},
    {0,60,80,100,0},
    {0,40,70,90,100},
    {0,50,80,100,0},
    {0,60,90,100,0},
    {0,80,95,100,0},
    {0,80,95,100,0},
    {0,60,80,90,100},
    {0,50,80,90,100},
    {0,40,70,85,100},
    {0,40,70,80,100}
};

UBYTE Overcast_Table[N_OVERCAST] = {10,20,70,100};


//E*O*F s_atlantic.h//

echo x - weather.h
cat > "weather.h" << '//E*O*F weather.h//'
#ifdef SYSV
#define srandom srand48
#define random lrand48
#endif

#define DIE(n) ((int)(random() % (unsigned)n)+1)
#define MIN(a,b) ((a<b) ? a : b)
#define MAX(a,b) ((a>b) ? a : b)

#define AND &&
#define OR  ||

typedef unsigned char UBYTE;
typedef UBYTE BOOL;

typedef short STAT_T;
typedef short WEATHER_T;
typedef short OVERCAST_T;
typedef short WIND_T;
typedef short TEMP_T;
typedef short PRECIP_T;

/* Boolean types */
#define FALSE 0
#define TRUE  1

/* Statistics types */
#define N_STAT  3
#define LOW     0
#define AVERAGE 1
#define HIGH    2

/* Weather types */
#define N_WEATHER     4
#define PRECIPITATION 0
#define OVERCAST      1
#define TAIFUN        2
#define CLEAR         3

char *Weather_Name[N_WEATHER] = {
    "Precipitation",
    "Overcast",
    "Typhoon",
    "Clear"
};

/* Overcast types */
#define N_OVERCAST 4
#define HEAVY_FOG  0
#define LIGHT_FOG  1
#define MIST       2
#define CLOUDY     3

char *Overcast_Name[N_OVERCAST] = {
    "Heavy Fog",
    "Light Fog",
    "Mist",
    "Cloudy",
};

/* Wind types */
#define N_WIND   5
#define CALM     0
#define LIGHT    1
#define BRISK    2
#define BLUSTERY 3
#define GALE     4

char *Wind_Name[N_WIND] = {
    "Calm",
    "Light",
    "Brisk",
    "Blustery",
    "Gale",
};

/* Temperature types */
#define N_TEMP 5
#define COLD   0
#define CHILLY 1
#define FAIR   2
#define WARM   3
#define HOT    4

char *Temp_Name[N_TEMP] = {
    "Cold",
    "Chilly",
    "Fair",
    "Warm",
    "Hot",
};

/* Precipitation types */
#define N_PRECIP 5
#define NONE     0
#define SPRINKLE 1
#define SHOWER   2
#define HEAVY    3
#define STEADY   4

char *Precip_Name[N_PRECIP] = {
    "None",
    "Sprinkle",
    "Shower",
    "Heavy",
    "Steady",
};

UBYTE Temp_Variation[9] = {1, 5, 13, 25, 75, 87, 95, 99, 100};
//E*O*F weather.h//

exit 0