/* * Copyright (c) 1991 Paul J. Drongowski. * Copyright (c) 1992 Joe Dellinger. * Copyright (c) 2005 Eric S. Raymond. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ /* * Return-Path: * Received: from cadillac.siemens.com by montebello.soest.hawaii.edu (4.1/montebello-MX-1.9) * id AA01487; Mon, 10 Aug 92 03:21:41 HST * Received: from kevin.siemens.com by cadillac.siemens.com (4.1/SMI-4.0) * id AA25847; Mon, 10 Aug 92 09:21:37 EDT * Date: Mon, 10 Aug 92 09:21:37 EDT * From: pjd@cadillac.siemens.com (paul j. drongowski) * Message-Id: <9208101321.AA25847@cadillac.siemens.com> * To: joe@montebello.soest.hawaii.edu * Status: RO */ /* * This copy is slightly hacked by Joe Dellinger, August 1992 * And some more... November 1992 * * Partially re-written by "murray@vs6.scri.fsu.edu" * to use better grammar and to avoid some nonsensical * responses (like claiming to be a person who's been licensed * longer than they've been alive!), Jan 1994 * * Those improvements merged with others by Joe Dellinger, Oct 1994 */ /* * Generate QSO */ /* * When run, this program generates a single QSO. The form of the * QSO is similar to QSO's one would expect to hear at a code test. * It begins with a series of V's (commented out in this version), * callsigns of the receiver and * sender, followed by a few sentences about weather, name, * occupation, etc. The QSO ends with the callsigns of the receiver * and sender. * * All output is produced using "printf." This should make the * program easy to port. Output can be piped into another program * such as sparc-morse on the Sun or it can be redirected into * a file (without viewing the contents of course!) * * The program design is similar to a "random poetry generator" * or "mad-libs." Each QSO form is generated by its own C function, * such as "PutForm1." Each function calls other C functions to * produce the sentences in the QSO. The sentence forms are * selected somewhat randomly as well as any blanks to be filled. * Words and phrases are selected from several lists such as * "Transceiver," "Antenna," "Job," etc. Sometimes this scheme is * clever as in the formation of city names. Sometimes it is * stupidly simple-minded and grammatical agreement is lost. * By the way, the callsigns are real and were picked from * rec.radio.amateur.misc on USENET. * * The program was constructed in C for Sun workstations. It uses * the library function "drand48" in function "Roll" to produce * pseudo-random numbers. The library function "srand48" and "time" * in "main" are used to set the pseudo-random number seed. * * Known problems and caveats? Hey, it`s software! All Morse * training programs handle the procedural signs (e.g., AR, SK) * differently. The function "PutQSO" currently prints "+ %" * for the AR and SK at the end of the QSO. These may be ignored, * mapped into something else, or just plain cause your training * program to roll over and play dead. I don`t know. This is a * cheap hack. * * And speaking of cheap... The program will not generate all * characters and pro-signs that are found on an "official" code * test. This program is for practice only and should be supplemented * with lots of random code. * * Always have fun! */ #include #include #include char *A_Or_An (char *); char *Choose (char *Words[], int Number); int License_Seed (void); int their_age; /* PERSON'S AGE, SO THEY AREN'T LICENSED MORE * THAN THEIR AGE */ extern char *Transceiver[]; extern char *Antenna[]; extern char *UpFeet[]; extern char *Weather1[]; extern char *Weather2[]; extern char *Power[]; extern char *Job[]; extern char *Name[]; extern char *CallSign[]; extern char *License[]; extern char *City[]; extern char *NewCity[]; extern char *CityHeights[]; extern char *New[]; extern char *Heights[]; extern char *State[]; extern char *Frqmisc[]; extern char *Callmisc[]; extern char *NumMisc[]; extern char *Miscellaneous[]; extern char *RST[]; int NXCVR; int NANTENNA; int NUPFEET; int NWX1; int NWX2; int NPOWER; int NJOB; int NNAME; int NCALLSIGN; char *Sender, *Receiver; int NLICENSE; int NCITY; int NNEWCITY; int NCITYHTS; int NNEW; int NHEIGHTS; int NSTATE; int NFRQMISC; int NFRQCALLMISC; char *FrqCallmisc[] = { "QRW %s %d", "QRZ %s %d", "QSN %s %d", "QSX %s %d", "QRW %s %d?", "QRZ %s %d?", "QSN %s %d?", "QSX %s %d?", 0 }; int NCALLMISC; int NNUMMISC; int NMISC; int NRST; /* ************************************* * Routines to put sentences/clauses * ************************************* */ void PutMisc (void) { printf ("%s\n", Choose (Miscellaneous, NMISC)); } void PutThanks (void) { switch (Roll (6)) { case 2: printf ("Thanks for your call.\n"); break; case 3: printf ("Tnx for ur call.\n"); break; case 4: printf ("Tnx for the call.\n"); break; case 5: printf ("Thanks for the call.\n"); break; default: printf ("Thanks %s for the call.\n", Choose (Name, NNAME)); break; } } void PutName (void) { switch (Roll (6)) { case 2: printf ("Name is %s.\n", Choose (Name, NNAME)); break; case 4: printf ("This is %s.\n", Choose (Name, NNAME)); break; case 5: printf ("%s here.\n", Choose (Name, NNAME)); break; default: printf ("My name is %s.\n", Choose (Name, NNAME)); break; } } void PutJob (void) { switch (Roll (20)) { case 2: case 3: printf ("My occupation is %s.\n", Choose (Job, NJOB)); break; case 4: case 5: printf ("I work as %s.\n", A_Or_An (Choose (Job, NJOB))); break; case 6: printf ("I was %s, now unemployed.\n", A_Or_An (Choose (Job, NJOB))); break; case 11: case 12: printf ("Occupation is %s.\n", Choose (Job, NJOB)); break; default: printf ("I am %s.\n", A_Or_An (Choose (Job, NJOB))); break; } } void PutAge (void) { their_age = Roll (60) + 16; switch (Roll (5)) { case 3: printf ("My age is %d.\n", their_age); break; case 4: printf ("I am %d years old.\n", their_age); break; default: printf ("Age is %d.\n", their_age); break; } } void PutLicense (void) { int get_years_licence; get_years_licence = Roll (License_Seed ()); if (get_years_licence < 2) get_years_licence = 2; switch (Roll (12)) { case 1: printf ("I have %s class licence.\n", A_Or_An (Choose (License, NLICENSE))); break; case 2: printf ("I am %s license ham.\n", A_Or_An (Choose (License, NLICENSE))); break; case 3: printf ("I am %s licence ham.\n", A_Or_An (Choose (License, NLICENSE))); break; case 4: printf ("I have been licenced %d years as %s class.\n", get_years_licence, Choose (License, NLICENSE)); break; case 5: printf ("I have %s class license.\n", A_Or_An (Choose (License, NLICENSE))); break; case 6: printf ("I am %s class ham.\n", A_Or_An (Choose (License, NLICENSE))); break; case 7: printf ("I have been licensed %d years as %s class.\n", get_years_licence, Choose (License, NLICENSE)); break; default: printf ("I have been %s class ham for %d years.\n", A_Or_An (Choose (License, NLICENSE)), get_years_licence); break; } } void PutTemperature (void) { printf ("Temperature is %d.\n", Roll (80) + 10); } void PutWeather1 (void) { switch (Roll (17)) { case 2: printf ("WX is %s.\n", Choose (Weather1, NWX1)); PutTemperature (); break; case 3: printf ("Weather here is %s.\n", Choose (Weather1, NWX1)); break; case 4: printf ("Weather is %s.\n", Choose (Weather1, NWX1)); break; case 5: printf ("WX is %s.\n", Choose (Weather1, NWX1)); break; case 6: PutTemperature (); printf ("Weather here is %s.\n", Choose (Weather1, NWX1)); break; case 7: PutTemperature (); printf ("Weather is %s.\n", Choose (Weather1, NWX1)); break; case 8: PutTemperature (); printf ("WX is %s.\n", Choose (Weather1, NWX1)); break; case 9: printf ("Weather here is %s and temperature is %d.\n", Choose (Weather1, NWX1), Roll (80) + 10); break; case 10: printf ("Weather is %s, temperature %d.\n", Choose (Weather1, NWX1), Roll (80) + 10); break; case 11: printf ("WX is %d degrees and %s.\n", Roll (80) + 10, Choose (Weather1, NWX1)); break; case 12: printf ("The WX is %s and the temp is %d degrees.\n", Choose (Weather1, NWX1), Roll (80) + 10); break; case 14: printf ("Weather is %s.\n", Choose (Weather1, NWX1)); PutTemperature (); break; case 15: printf ("Weather here is %s.\n", Choose (Weather1, NWX1)); PutTemperature (); break; default: printf ("WX is %s and %d degrees.\n", Choose (Weather1, NWX1), Roll (80) + 10); } } void PutWeather2 (void) { switch (Roll (10)) { case 0: printf ("It is %s.\n", Choose (Weather2, NWX2)); break; case 1: printf ("It is %s and %d degrees.\n", Choose (Weather2, NWX2), Roll (80) + 10); break; case 2: printf ("The WX is %s and the temp is %d degrees.\n", Choose (Weather2, NWX2), Roll (80) + 10); break; case 3: printf ("WX is %s and the temp is %d degrees.\n", Choose (Weather2, NWX2), Roll (80) + 10); break; case 4: printf ("It is %s today.\n", Choose (Weather2, NWX2)); break; case 5: printf ("It is %s and %d degrees.\n", Choose (Weather2, NWX2), Roll (100) + 3); break; case 6: printf ("The WX is %s and the temp is %d degrees.\n", Choose (Weather2, NWX2), Roll (90) + 10); break; case 7: printf ("WX is %s and the temp is %d degrees.\n", Choose (Weather2, NWX2), Roll (80) + 10); break; default: printf ("It is %s here.\n", Choose (Weather2, NWX2)); break; } } void PutWeather (void) { switch (Roll (4)) { case 3: PutWeather1 (); break; default: PutWeather2 (); break; } } void PutCityState (void) { switch (Roll (6)) { case 4: printf ("%s %s, ", Choose (CityHeights, NCITYHTS), Choose (Heights, NHEIGHTS)); break; case 5: printf ("%s %s, ", Choose (New, NNEW), Choose (NewCity, NNEWCITY)); break; default: printf ("%s, ", Choose (City, NCITY)); break; } printf ("%s.\n", Choose (State, NSTATE)); } void PutLocation (void) { switch (Roll (5)) { case 3: printf ("My QTH is "); break; case 4: printf ("My location is "); break; default: printf ("QTH is "); break; } PutCityState (); } void PutRig (void) { switch (Roll (19)) { case 0: case 1: printf ("My rig runs %s watts into %s up %s feet.\n", Choose (Power, NPOWER), A_Or_An (Choose (Antenna, NANTENNA)), Choose (UpFeet, NUPFEET)); break; case 2: case 3: printf ("Rig is a %s watt %s and antenna is %s.\n", Choose (Power, NPOWER), Choose (Transceiver, NXCVR), A_Or_An (Choose (Antenna, NANTENNA))); break; case 4: case 5: printf ("My transceiver is %s.\n", A_Or_An (Choose (Transceiver, NXCVR))); printf ("It runs %s watts into %s.\n", Choose (Power, NPOWER), A_Or_An (Choose (Antenna, NANTENNA))); break; case 6: case 7: printf ("The rig is %s running %s watts.\n", A_Or_An (Choose (Transceiver, NXCVR)), Choose (Power, NPOWER)); printf ("Antenna is %s up %s m.\n", A_Or_An (Choose (Antenna, NANTENNA)), Choose (UpFeet, NUPFEET)); break; case 8: case 9: case 10: case 11: printf ("My rig runs %s watts into %s up %s meters.\n", Choose (Power, NPOWER), A_Or_An (Choose (Antenna, NANTENNA)), Choose (UpFeet, NUPFEET)); break; case 12: printf ("My rig runs %s watts into %s up %s feet, but\nthe antenna has partly fallen.\n", Choose (Power, NPOWER), A_Or_An (Choose (Antenna, NANTENNA)), Choose (UpFeet, NUPFEET)); break; case 13: printf ("Rig is %s running %s watts into %s up %s ft.\n", A_Or_An (Choose (Transceiver, NXCVR)), Choose (Power, NPOWER), A_Or_An (Choose (Antenna, NANTENNA)), Choose (UpFeet, NUPFEET)); break; case 14: printf ("My rig runs %s watts into %s up %s feet.\n", Choose (Power, NPOWER), A_Or_An (Choose (Antenna, NANTENNA)), Choose (UpFeet, NUPFEET)); break; case 15: printf ("Rig is %s watt %s and antenna is %s.\n", A_Or_An (Choose (Power, NPOWER)), Choose (Transceiver, NXCVR), Choose (Antenna, NANTENNA)); break; case 16: printf ("My transceiver is %s.\n", A_Or_An (Choose (Transceiver, NXCVR))); printf ("It runs %s watts into %s.\n", Choose (Power, NPOWER), A_Or_An (Choose (Antenna, NANTENNA))); break; case 17: printf ("The rig is %s running %s watts.\n", A_Or_An (Choose (Transceiver, NXCVR)), Choose (Power, NPOWER)); printf ("Antenna is %s up %s feet.\n", A_Or_An (Choose (Antenna, NANTENNA)), Choose (UpFeet, NUPFEET)); break; default: printf ("Rig is %s ", A_Or_An (Choose (Transceiver, NXCVR))); printf ("running %s watts into %s up %s feet.\n", Choose (Power, NPOWER), A_Or_An (Choose (Antenna, NANTENNA)), Choose (UpFeet, NUPFEET)); break; } } void PutRST (void) { register char *TheRST; TheRST = Choose (RST, NRST); switch (Roll (8)) { case 0: printf ("UR RST %s=%s.\n", TheRST, TheRST); break; case 1: printf ("RST is %s=%s.\n", TheRST, TheRST); break; case 2: printf ("RST %s=%s.\n", TheRST, TheRST); break; case 3: printf ("Your RST %s=%s.\n", TheRST, TheRST); break; case 4: printf ("Your RST is %s=%s.\n", TheRST, TheRST); break; case 5: printf ("Your signal is RST %s/%s.\n", TheRST, TheRST); break; case 6: printf ("UR signal is RST %s,%s.\n", TheRST, TheRST); break; default: printf ("Your RST is %s/%s.\n", TheRST, TheRST); break; } } void PutQ_And_Freq (void) { switch (Roll (8)) { case 2: printf (Frqmisc[Roll (NFRQMISC)], make_freq ()); printf ("\n"); break; case 3: printf (Callmisc[Roll (NFRQMISC)], Choose (CallSign, NCALLSIGN)); printf ("\n"); break; case 4: printf (FrqCallmisc[Roll (NFRQCALLMISC)], Choose (CallSign, NCALLSIGN), make_freq ()); printf ("\n"); break; case 5: printf (NumMisc[Roll (NNUMMISC)], Roll (3) + Roll (2) + 1); printf ("\n"); break; default: break; } } void PutFirstCallsign (void) { Sender = Choose (CallSign, NCALLSIGN); Receiver = Choose (CallSign, NCALLSIGN); printf ("%s de %s\n", Receiver, Sender); } void PutLastCallsign (void) { printf ("%s de %s\n", Receiver, Sender); } main (int argc, char **argv) { NXCVR = CountStrings (Transceiver); NANTENNA = CountStrings (Antenna); NUPFEET = CountStrings (UpFeet); NPOWER = CountStrings (Power); NRST = CountStrings (RST); NWX1 = CountStrings (Weather1); NWX2 = CountStrings (Weather2); NJOB = CountStrings (Job); NNAME = CountStrings (Name); NSTATE = CountStrings (State); NCITY = CountStrings (City); NCITYHTS = CountStrings (CityHeights); NNEW = CountStrings (New); NHEIGHTS = CountStrings (Heights); NNEWCITY = CountStrings (NewCity); NLICENSE = CountStrings (License); NMISC = CountStrings (Miscellaneous); NCALLSIGN = CountStrings (CallSign); NFRQMISC = CountStrings (Frqmisc); NFRQCALLMISC = CountStrings (FrqCallmisc); NCALLMISC = CountStrings (Callmisc); NNUMMISC = CountStrings (NumMisc); srand48 ((long) time (0)); PutQSO (); return 0; }