		       How to Add New Schedules

			   George Ferguson
		      ferguson@cs.rochester.edu

			     15 Mar 1994


NOTE: When reporting bugs, please include the version information from
      patchlevel.h (or from running with the -v option). If the
      problem is with the schedule information, as opposed to the
      program itself, please contact the person listed as
      VERSION_ENTERER in the datafile (and printed by -v).

The driver program "schedule.c" should never have to be changed.  All
league- and season-specific data is contained in another file which is
#include'd in schedule.c. This filename is the value of the constant
DATAFILE, set in the Makefile or by hand when schedule.c is compiled.

This section describes what you have to do to create a new data file
and, in part, why. Your best bet is probably to copy one of the files
contained in this distribution and modify it appropriately.  Please
share your updates with the rest of the world by posting them.

1. I suggest modifying the comments at the top of the file to reflect
   your situation. 

2. Define VERSION_SEASON to be a short term identifying the data and
   VERSION_ENTERER to be a string identifying you and whoever helped
   you out. 

3. Define START_DATE and END_DATE to be strings of the form
   "MM/DD/YYYY". They must be strings (i.e., enclosed in
   double-quotes) and the year must have four digits. These are parsed
   into variables when nhl starts; the startup cost is small compared
   to how easy this makes it to update them. The constant START_DOW
   should be a capitalized string representing the day-of-the-week for
   the START_DATE. Check dow[] in schedule.c for spelling if
   you're not sure. This is used as a base for day-of-the-week
   calculations that would otherwise require use of true Julian dates
   (which is no doubt overkill). Don't forget the double-quotes on
   this one either.

   Note that START_DATE and END_DATE must be in the American format
   (month first) even if you defined EUROPEAN_DATES in schedule.c.

4. For a new league or after expansion, you will have to change the
   constant NUM_TEAMS and the teams[] array. This array should
   contain an entry for each team consisting of the city name, team
   nickname, and three-letter code, all of which should be strings.
   Actually, the codes don't have to be three letters, but it helps.

   There must be a unique code for each team, which means that if
   there are two teams in a city, you may have to settle for
   something less than intuitive. C'est la vie. The codes are
   printed by the help message, so people will be able to figure it
   out.

5. For a new league, or after realignment or expansion, you will have
   to change the constant NUM_DIVISIONS and the divisions[]
   array. This array should contain an entry for each division
   consisting of the division name, a list of the team codes for teams
   in the division, and a division code to be specified on the command
   line in head-to-head mode.

   Just so you know, the list of teams is parsed into a flags[] array
   for each division to make testing whether a team is in a division
   faster. Again, the startup cost of the parsing the list is
   outweighed by the ease of updating.

6. The array special_dates[] contains entries for days for which there
   are no games scheduled and for which we would like to print a
   special message. These are typically things like the All-Star
   Game. Specify them with integers for month and day, and a string to
   print on that day. End the array with a NULL string entry.  Note
   that this array is only checked if there are no games scheduled.

7. The extra_info[] array contains strings that can be used to provide
   extra information about games. For example, the NHL schedule uses
   this to print the location of neutral site games and the MLB
   schedule uses it to indicate doubleheaders.

8. Finally, the big one, the schedule[] array. This array contains a
   string for each day of the season, each character of which
   specifies what the team in the corresponding location of the
   teams[] array is doing that day. A set of macros is defined for
   testing the meaning of the characters. Team codes index the teams[]
   array, info codes index the extra_info[] array.

   ISIDLECODE : Specifies what character in a schedule[] string
     denotes that the team is idle (i.e., the default). This could be
     space (' '), but I found that hard to debug with.
   ISHOMECODE : When a team is at home and no extra information
     applies, this character should be at that team's position in the
     schedule[] string.
   ISAWAYCODE : If a team is on the road, then one of these codes
     (corresponding to the team they are visiting) should be used.
     The macro TEAMCODETOINDEX maps from these codes back to the index
     in the teams[] array and the macro INDEXTOTEAMCODE creates the
     character from the index. These don't have to be contiguous, but
     it makes testing for them easier.
   ISINFOCODE : If a team is at home and some extra information
     applies, then one of these codes (corresponding to which piece of
     extra information) should be used. The macro INFOCODETOINDEX maps
     from these codes back to the index in the extra_info[] array and
     the macro INDEXTOINFOCODE creates the character from the
     index. These don't have to be contiguous, but it makes testing
     for them easier.

   If the number of teams changes, you'll need to assign codes to the
   new teams and change the accessor and tester macros to handle them
   and properly map them into indices into the teams[] array.  For
   example, the following will handle up to 36 teams:

   #define ISAWAYCODE(C)    (((C)>='a' && (C)<='z') || (C)>='0' && (C)<='9'))
   #define TEAMCODETOINDEX(C) ((int)(((C)>='a') ? ((C)-'a') : ((C)-'0'+26)))
   #define INDEXTOTEAMCODE(N) ((char)(((N)>=26) ? ((N)-26+'0') : ((N)+'a')))

   With these macros, you would use letter `a' to `z' for the first 26
   teams in teams[], then `0' to `9' for the next ten teams. That
   ought to tide you over for a while.

   Similar considerations apply to the extra_info codes, but here
   there are less likely to be many items (see step (7), above), so
   you should be able to figure it out from the examples.

-> FINALLY: You need the data itself (i.e., the strings). I have
   included in this distribution Perl scripts that I used to create
   the NHL93-94 and MLB94 schedule[] arrays from files with entries
   of the form
	      MON DAY HOME AWAY EXTRA
   The scripts are identical except for some data definitions at the
   top. They test for conflicts and output strings ready to insert in
   your data file. You'd need to tweak it for a different league, but
   it's a start.

9. Try to build and run with your new schedule. This will make sure
   that all the run-time parsing of constants is ok. Once you've done
   that, tell the world!
