13 #define DPRINTF(...) dprintf(2, __VA_ARGS__)
15 #define DPRINTF(...) do { } while(0)
19 #define SU(x) ((x)*SCALE)
20 #define ARRAY_SIZE(X) (sizeof(X)/sizeof(X[0]))
22 #define cursor(X,Y) cursorit(X,Y,__FUNCTION__, __LINE__)
23 #define Move(X,Y,Z) Moveit(X,Y,Z,__FUNCTION__, __LINE__)
25 #define vmode vmodeitt
26 #define getkb getkbitt
34 #define BONDVALUE 1000
35 #define STOCKLIMIT 9 /* max number of stocks one can hold */
36 #define AUTOLIMIT 9 /* max number of autos and options */
38 #define SPLITPRICE 200
50 #define ERASE_CH "'\08' '\08'"
57 #define CHANGEOVERTIME 10 /* 10 seconds to complete command */
58 #define CLICK_CHANGE '\021'
59 #define NO_YRLY_MESSAGES 15
60 #define NO_STD_MESSAGES 30
80 #define F10 -80 /** for JUMPing. Added 11/22/85 **/
85 static bmp4
*bmp_font
, *bmp_black_font
;
86 static struct spritesheet ss_font
, ss_black_font
;
88 #define BOTTOM_START 76
89 #define FONT "topaz.raw"
92 static void init_gfx() {
93 bmp_font
= bmp4_from_file(FONT
);
94 bmp_black_font
= bmp4_from_file(FONT
);
96 for(x
=0;x
<bmp_black_font
->width
* bmp_black_font
->height
;x
++)
97 bmp_black_font
->data
[x
] = bmp_black_font
->data
[x
] == RGB(0,0,0) ? RGB(255,255,255) : RGB(0,0,0);
98 if(!spritesheet_init(&ss_font
, bmp_font
, FONT_W
, FONT_H
)) dprintf(2, "oops\n");
99 if(!spritesheet_init(&ss_black_font
, bmp_black_font
, FONT_W
, FONT_H
)) dprintf(2, "oops\n");
102 static int get_font_width(char letter
) {
103 return ss_font
.sprite_w
;
106 static unsigned get_font_render_length(const char* text
) {
108 for(;*text
&& *text
!= '\n';x
+=get_font_width(*(text
++)));
112 static void draw_font(const char* text
, struct spritesheet
*font
, unsigned x
, unsigned y
) {
113 for(;*text
;x
+=get_font_width(*(text
++))) if(*text
!= '\n') ezsdl_draw_sprite(font
, *text
, SU(x
), SU(y
), SCALE
);
116 typedef struct stock
{
130 static ASTOCK stock_array
[] = {
131 [ 0] = {.price
= 100, .name
= "KM", .b1
= 1.4, .b2
= .8, .b3
= 0, .e
= .2},
132 [ 1] = {.price
= 100, .name
= "GE", .b1
= 1.3, .b2
= .4, .b3
= -.2, .e
= .3},
133 [ 2] = {.price
= 100, .name
= "AMR", .b1
= 2.1, .b2
= .9, .b3
= .2, .e
= .5},
134 [ 3] = {.price
= 100, .name
= "ZE", .b1
= 1.7, .b2
= .0, .b3
= 0, .e
= .5},
135 [ 4] = {.price
= 100, .name
= "MYG", .b1
= 1.4, .b2
= .5, .b3
= 0, .e
= .3},
136 [ 5] = {.price
= 100, .name
= "GM", .b1
= 1.3, .b2
= .8, .b3
= .3, .e
= .2},
137 [ 6] = {.price
= 100, .name
= "SOI", .b1
= 1., .b2
= .4, .b3
= -.3, .e
= .3},
138 [ 7] = {.price
= 100, .name
= "USS", .b1
= 1.1, .b2
= .6, .b3
= 0, .e
= .3},
139 [ 8] = {.price
= 100, .name
= "ITT", .b1
= 1.6, .b2
= .0, .b3
= 0, .e
= 1.2},
140 [ 9] = {.price
= 100, .name
= "MOB", .b1
= .9, .b2
= .2, .b3
= .8, .e
= .2},
141 [10] = {.price
= 100, .name
= "PG", .b1
= .85, .b2
= .3, .b3
= 0, .e
= 1.2},
142 [11] = {.price
= 100, .name
= "EK", .b1
= 1.2, .b2
= 0., .b3
= 0, .e
= .4},
143 [12] = {.price
= 100, .name
= "AH", .b1
= 1., .b2
= 1., .b3
= .2, .e
= .3},
144 [13] = {.price
= 100, .name
= "KMB", .b1
= .7, .b2
= .1, .b3
= 0, .e
= .1},
145 [14] = {.price
= 100, .name
= "DE", .b1
= 1.3, .b2
= 1.3, .b3
= 0, .e
= .4},
146 [15] = {.price
= 100, .name
= "ED", .b1
= .65, .b2
= 1.1, .b3
= 0, .e
= .1},
147 [16] = {.price
= 100, .name
= "AA", .b1
= 1.7, .b2
= 1.2, .b3
= .1, .e
= .3},
148 [17] = {.price
= 100, .name
= "PGL", .b1
= .2, .b2
= 0., .b3
= -.4, .e
= 1.5},
149 [18] = {.price
= 100, .name
= "MD", .b1
= 2., .b2
= .2, .b3
= -.5, .e
= .8},
150 [19] = {.price
= 100, .name
= "T", .b1
= 1.2, .b2
= 0., .b3
= 0., .e
= .7},
151 [20] = {.price
= 100, .name
= "MTC", .b1
= 1., .b2
= .2, .b3
= 0, .e
= .4},
152 [21] = {.price
= 100, .name
= "UNP", .b1
= 1.7, .b2
= 1.4, .b3
= 0, .e
= .9},
153 [22] = {.price
= 100, .name
= "HM", .b1
= -.2, .b2
= .3, .b3
= -.5, .e
= .8},
154 [23] = {.price
= 100, .name
= "SMC", .b1
= 2.2, .b2
= 1.4, .b3
= 0, .e
= 1.1},
155 [24] = {.price
= 100, .name
= "NOM", .b1
= 1.3, .b2
= 1., .b3
= -.3, .e
= 1.6},
156 [25] = {.price
= 100, .name
= "RES", .b1
= .05, .b2
= .9, .b3
= 0, .e
= .25},
157 [26] = {.price
= 100, .name
= "GLD", .b1
= -.1, .b2
= 1.1, .b3
= -.3, .e
= .6},
158 [27] = {.price
= 100, .name
= "WU", .b1
= -.2, .b2
= -.4, .b3
= 0, .e
= .6},
159 [28] = {.price
= 100, .name
= "BND", .b1
= .05, .b2
= .7, .b3
= 0, .e
= .0},
160 [29] = {.price
= 100, .name
= "IBM", .b1
= .9, .b2
= .3, .b3
= 1.2, .e
= .6},
161 [30] = {.price
= 100, .name
= "IMF", .b1
= .0, .b2
= .0, .b3
= 0, .e
= .0},
164 #define NO_OF_STOCKS ARRAY_SIZE(stock_array)
165 static HISTORY history
[NO_OF_STOCKS
];
167 static char alpha
[] =
168 { 16, 12, 2, 28, 14, 15, 11, 1, 26, 5, 22, 29, 8, 0, 13, 18, 9, 20, 4, 24, 10, 17, 25, 23, 6, 19, 21, 7, 27, 3, 30 };
177 static SCREEN screen
[STOCKLIMIT
];
178 static SCREEN
*scr_ptr
[STOCKLIMIT
];
179 static int screen_count
;
192 YMESS item
[NO_YRLY_MESSAGES
];
195 static YMESSS yrly_mssgs
;
197 static int y_mssg_count
;
209 SMESS item
[NO_STD_MESSAGES
];
212 static SMESSS std_mssgs
;
228 static const char commands
[][9] = {
236 "BONDS", /* original: "T-BILLS" */
237 "SAVE", /* original "KEEP" */
245 static float ndis
[24] = {
272 typedef struct tick_item
{
274 struct tick_item
*next
;
275 struct tick_item
*previous
;
278 static TICK_ITEM
*cur_tick
;
279 static TICK_ITEM ticker
[TICK_SIZE
];
281 static int load_stock
= TICK_SIZE
; /* the number of the next stock to be loaded into
284 static char newsline
[82]; /* holds current news message */
286 static int cur_news_line
= -1; /* the number of the last position in the newline
287 array to be put on screen */
288 typedef struct autos
{
289 int minus_price
; /* price to exercise auto buy */
290 int plus_price
; /* price to exercise auto sell */
291 int option_type
; /* CALL or PUT option? */
292 int option_price
; /* price option is exerciseable at */
293 int units
; /* number of shares */
294 int stock_no
; /* stock id number */
295 int cur_price
; /* the last price posted */
296 int pur_price
; /* how much the option cost per lot */
300 typedef struct node
{
305 struct node
*previous
;
316 typedef struct player
{
319 STOCKS portfolio
[NO_OF_STOCKS
];
322 AUTOS
*auto_ptr
[AUTOLIMIT
]; /* pointers to the auto exec structures */
323 AUTOS auto_array
[AUTOLIMIT
]; /* the actual auto exec structures */
325 int name_length
; /* characters in the person's name */
329 float other_earnings
;
334 static PLAYER players
[MAXPLAYERS
];
335 static PLAYER
*cur_player
;
338 int status
; /* 1 if ON 2 if OFF */
339 int count
; /* seconds since hour when initialized */
340 int hour_changed
; /* flag set if timer approaching hour change */
343 static TIMER timer1
; /* for game time timing */
344 static TIMER timer2
; /* for changing player timing */
345 static TIMER timer3
; /* for event gap timing */
347 static char message
; /* true if program message displayed */
348 static char scr_status
= STOCKSUP
; /* either stocks,autos,or rankings are up */
349 static char in_progress
; /* in the middle of a news event ? */
350 static char mess_type
; /* yearly or standard message in use */
351 static char q_break
; /* true at end of quarter */
352 static int no_of_players
; /* how many players we have, set at beginning */
353 static int player
= 1; /* the current player */
354 static int tmp_player
; /* holds the new player while we wait */
355 static float prime_rate
= .5; /* actually will be read in initially */
356 static float high_prime
; /* highest prime rate allowed */
357 static float low_prime
; /* lowest prime rate allowed */
358 static float q_int_rate
= .049; /* the quarterly interest rate */
359 static float wk_int_rate
= .001; /* quarterly divided by 13 */
360 static float bond_rate
; /* quarterly rate at beginning of quarter */
361 static int quarter
= 1; /* what the current quarter is */
362 static int week
= 1; /* the current week of the year */
363 static int year
= 1938; /* actually will be read in initially */
364 static char stop
; /* flag to indicate end of quarter break */
365 static int com_char_count
; /* how many chars in the buffer */
366 static char delay
; /* scroll another news char or not */
367 static char year_over
; /* paused at end of year ? */
368 static int event_week
= 1; /* the week of the last event */
369 static char com_array
[30]; /* holds user input */
370 static int time_count
; /* 0 to 3600 replaces real time */
371 static int make_call
; /* do a margin call at end of week ? */
373 static float factor1
, factor2
, factor3
, factor4
;
374 static float x1
, x2
, x3
, instd1
, instd2
, instd3
, instd4
, the_interest
, gnp
, pol
, intr
, var
;
377 static int jump_weeks
; /* number of weeks left in JUMP */
378 /* added: 11/22/85 */
380 static char newsch
; /* the next newsline char to scroll */
381 static int units
; /* how many to buy,sell,etc. */
382 static int com_no
; /* the digit corres. to the command */
383 static int stock_no
; /* the number corres. to the stock */
384 static int trans_price
; /* the price at which the transaction
386 static int autobuy
; /* the price to execute an auto buy */
387 static int autosell
; /* the price to execute an auto sell */
388 static int tick_position
; /* the position in the current ticker
390 static int click_on
; /* flag to turn on clicking */
391 static int time
; /* current time seconds + minutes */
392 static int messno
; /* message selected */
393 static int loop_to
; /* when to end the event */
394 static int half_way
= -2; /* half thru reset message */
395 static int g
; /* junk */
396 static char emphasis
;
398 static float vx1
, vx2
, vx3
, vx4
; /* variances for option use */
399 //input wave for audio ticker
400 //static signed char si[] = {0,49,90,117,127,117,90,49,0,-49,-90,-117,-127,-117,-90,-49};
402 static struct RastPort
*rp
;
405 static void quit(void);
406 static void graph(int stockno
, int year
);
407 static void bonds(int units
);
408 static void add_auto_exec(int auto_minus
, int auto_plus
, int option
, int opt_price
, int units
, int stockno
, int player
,
410 static void write_auto(int position
);
411 static float opt_value(int player
, int position
);
412 static void del_auto(int position
, int player
);
413 static void upd_coh(void);
414 static void upd_netw(void);
415 static void upd_bonds(void);
416 static void upd_quarter(void);
417 static void upd_year(void);
418 static void upd_prime(void);
419 static void upd_stock(int stockno
);
420 static void write_stock(int line_inc
, int element
);
421 static void clear_stock(int line_inc
);
422 static void load_screen(void);
423 static void screen_upd(void);
424 static double calc_netw(int player
);
426 #define STUB(X) static long X () { dprintf(2, "warning: %s unimplemented\n", __FUNCTION__); return 0;}
428 /* clib/dos_protos.h */
429 static void Delay( long timeout
) {
431 ezsdl_sleep(timeout
*10);
433 /* clib/graphics_protos.h */
434 static void SetDrMd( struct RastPort
*rp
, unsigned long drawMode
) {
435 rp
->DrawMode
= drawMode
;
437 static void Moveit( struct RastPort
*rp
, long x
, long y
, const char*fn
, int line
) {
439 dprintf(2, "%s called from %s:%d\n", __FUNCTION__
, fn
, line
);
446 #define MIN(a,b) ((a)<(b)) ? (a) : (b)
447 #define ABS(a) ((a) < 0) ? -(a) : (a)
449 /* Set the primary drawing pen for lines, fills, and text. */
450 static void SetAPen( struct RastPort
*rp
, unsigned long pen
) {
453 /* Set the secondary drawing pen for lines, fills, and text. */
454 static void SetBPen( struct RastPort
*rp
, unsigned long pen
) {
457 static unsigned GetAPen(struct RastPort
*rp
) {
460 static unsigned GetBPen(struct RastPort
*rp
) {
463 static unsigned GetPenColor(struct RastPort
*rp
, unsigned pen
) {
464 assert(pen
< sizeof(rp
->custom
.pencolors
) / sizeof (rp
->custom
.pencolors
[0]));
465 return rp
->custom
.pencolors
[pen
];
467 /* original uses ViewPort instead of RastPort */
468 static void SetRGB4( struct RastPort
*vp
, long index
, unsigned long red
, unsigned long green
, unsigned long blue
) {
469 assert(index
< sizeof(rp
->custom
.pencolors
) / sizeof (rp
->custom
.pencolors
[0]));
470 rp
->custom
.pencolors
[index
] = RGB(red
*17, green
*17, blue
*17);
472 void RectFill( struct RastPort
*rp
, long xMin
, long yMin
, long xMax
, long yMax
) {
473 ezsdl_fill_rect(SU(xMin
), SU(yMin
), xMax
- xMin
, yMax
-yMin
, GetPenColor(rp
, GetAPen(rp
)), SCALE
);
476 // draw a line and move there
477 static void Draw( struct RastPort
*rp
, long x
, long y
) {
478 //only implement straight lines
479 assert(x
== rp
->custom
.x
|| y
== rp
->custom
.y
);
481 if(y
!= rp
->custom
.y
)
482 ezsdl_draw_vline(SU(rp
->custom
.x
), SU(MIN(y
,rp
->custom
.y
)), ABS(y
-rp
->custom
.y
), GetPenColor(rp
, GetAPen(rp
)), SCALE
);
484 ezsdl_draw_hline(SU(MIN(x
,rp
->custom
.x
)), SU(rp
->custom
.y
), ABS(x
-rp
->custom
.x
), GetPenColor(rp
, GetAPen(rp
)), SCALE
);
494 long Text( struct RastPort
*rp
, STRPTR string
, unsigned long count
) {
496 snprintf(buf
, sizeof buf
, "%*s", (int) count
, string
);
497 unsigned rl
= get_font_render_length(buf
);
498 assert(rp
->custom
.x
+rl
<=SCREENW
);
499 if(rp
->DrawMode
== JAM2
)
500 ezsdl_fill_rect(SU(rp
->custom
.x
), SU(rp
->custom
.y
), rl
, FONT_H
, GetPenColor(rp
, GetBPen(rp
)), SCALE
);
501 struct spritesheet
*font
= GetPenColor(rp
, GetAPen(rp
)) == RGB(0,0,0) ? &ss_black_font
: &ss_font
;
502 draw_font(buf
, font
, rp
->custom
.x
, rp
->custom
.y
);
508 /* clib/intuition_protos.h */
509 void DisplayBeep(void) {
510 /* makes the screen flash for an instant */
511 bmp4
*tmp
= ezsdl_get_screenshot();
512 ezsdl_fill_rect(0, 0, SCREENW
, SCREENH
, RGB(255,255,255), SCALE
);
515 ezsdl_draw(tmp
, 0, 0, 1);
523 /* supposed to clear either the actual line or the line in which commands can be entered */
524 static void clear_line(void) {
525 ezsdl_fill_rect(0, SU(rp
->custom
.y
), SCREENW
, FONT_H
, RGB(0,0,0), SCALE
);
529 static void clear_top(void) {
530 ezsdl_fill_rect(0, 0, SCREENW
, BOTTOM_START
, RGB(0,0,0), SCALE
);
533 static void clear_bottom(void) {
534 ezsdl_fill_rect(0, SU(BOTTOM_START
), SCREENW
, SCREENH
-BOTTOM_START
, RGB(0,0,0), SCALE
);
538 STUB(earnings_display
)
541 static size_t word(char* s
, int*end
) {
543 while(s
[c
] && !isspace(s
[c
])) c
++;
548 static char* skip_whitespace(char *s
, int*end
) {
549 while(*s
&& isspace(*s
)) s
++;
554 static int find_stock(char* sym
) {
556 for(i
=0;i
<ARRAY_SIZE(stock_array
);i
++)
557 if(!strcmp(sym
, stock_array
[i
].name
)) return i
;
561 static void TxWrite(struct RastPort
*rp
, const char *ch
);
563 static void TxWritef(struct RastPort
*rp
, const char* fmt
, ...) {
567 vsnprintf(buf
, sizeof buf
, fmt
, ap
);
572 static int TxWriteNoMove(struct RastPort
*rp
, const char *s
) {
573 int x
= rp
->custom
.x
;
579 static int TxWriteMsg(struct RastPort
*rp
, const char* fmt
, ...) {
583 vsnprintf(buf
, sizeof buf
, fmt
, ap
);
586 return TxWriteNoMove(rp
, buf
);
589 static void cursorit(int y
, int x
, const char*fn
, int line
) {
591 dprintf(2, "%s called from %s:%d\n", __FUNCTION__
, fn
, line
);
593 //Move(rp, x * 8, y * 8 + 6);
597 static void display_rankings(void) {
598 static const int rankingstarty
= 10;
603 cursor(rankingstarty
, 0);
604 TxWrite(rp
, " ""NET WORTH"" "" ");
605 cursor(rankingstarty
+1,0);
606 TxWrite(rp
, " ----------""----------""----------""--");
607 for(i
=0;i
<no_of_players
;i
++) {
608 cursor(rankingstarty
+2+i
, 4);
609 TxWrite(rp
, players
[i
].name
);
611 int l
= snprintf(buf
, sizeof buf
, "%.0f", players
[i
].net_worth
);
612 cursor(rankingstarty
+2+i
, 40-4-l
);
615 cursor(rankingstarty
+14,0);
618 //validity_check: supposed to check whether a user-entered command can be executed
619 // translates the command number
620 // prints "INVALID COMMAND WORD" if command is not known
621 // prints "YOU HAVEN'T GOT ENOUGH CASH" if not enough money
622 // returns TRUE or FALSE
624 static int validity_check(char *cmd
, int *com_char_count
,
625 int *com_no
, int *units
, int *stock_no
,
626 int *trans_price
, int *autobuy
, int *autosell
) {
627 // for weird reasons, the first char is always 0
630 if(!*com_char_count
) return FALSE
;
633 int end
, si
, numberonly
= 0;
636 for(i
=0;i
<ARRAY_SIZE(commands
);i
++) if(!strcmp(cmd
, commands
[i
])) goto found
;
637 return TxWriteMsg(rp
, "INVALID COMMAND WORD");
642 cmd
=skip_whitespace(cmd
, &end
);
646 if(!q_break
) goto end_qu
;
647 if(end
) goto incompl
;
648 if((si
= find_stock(cmd
)) == -1) goto inv_stock
;
655 case JUMP
: numberonly
= 1;
659 if(end
) goto incompl
;
662 if(end
&& !numberonly
) goto missing_stock
;
665 cmd
= skip_whitespace(cmd
, &end
);
666 if(end
&& !numberonly
) goto missing_stock
;
668 if(numberonly
) goto incompl
;
672 if((si
= find_stock(cmd
)) == -1) goto inv_stock
;
674 *trans_price
= stock_array
[si
].price
* *units
;
676 /* special case code for stuff where the dispatcher function doesnt validate */
678 case CASH
: if(*units
> cur_player
->bonds
) goto insuff_bonds
; break;
683 return TxWriteMsg(rp
, "UNHANDLED COMMAND GIVEN");
685 return TxWriteMsg(rp
, "INCOMPLETE COMMAND GIVEN");
687 return TxWriteMsg(rp
, "NO STOCK NAME GIVEN");
689 return TxWriteMsg(rp
, "INVALID STOCK NAME GIVEN");
691 return TxWriteMsg(rp
, "DATA AVAILABLE AT END OF QUARTER ONLY");
693 return TxWriteMsg(rp
, "INSUFFICIENT AMOUNT OF BONDS STOCKED");
700 static double sqr(double x
) {
704 static void TxWrite(struct RastPort
*rp
, const char *ch
) {
705 Text(rp
, ch
, strlen(ch
));
709 /* expecting a scrollbuf of 41 chars */
710 static void scroll(char* scrollbuf
, char u
, int reset
, int y
, int bgpen
) {
711 if(reset
) memset(scrollbuf
, ' ', sizeof scrollbuf
-1);
713 memmove(scrollbuf
, scrollbuf
+1, 41-1);
715 unsigned sx
= rp
->custom
.x
, sy
= rp
->custom
.y
;
717 RectFill(rp
, 0, y
, 320, y
+23);
721 TxWrite(rp
, scrollbuf
);
728 static void scrollne(char u
) {
729 static char scrollbuf
[40+1];
730 scroll(scrollbuf
, u
, cur_news_line
== -1, 32, 3);
733 static void scrollit(char u
) {
734 static char scrollbuf
[40+1];
736 scroll(scrollbuf
, u
, !initdone
, 32-24, 2);
740 static void load_tick_element(TICK_ITEM
* t
, int stockno
) {
741 int l
= snprintf(t
->item
, sizeof(t
->item
), "%s-%d ", stock_array
[stockno
].name
, stock_array
[stockno
].price
);
742 //memset(t->item+l, ' ', sizeof(t->item)-l);
743 //t->item[sizeof(t->item)-1]=0;
746 static long long timeval2utime(struct timeval
*t
) {
747 return (t
->tv_sec
* 1000LL * 1000LL) + t
->tv_usec
;
750 static long long getutime64(void) {
753 return timeval2utime(&t
);
756 static int getmicros() {
757 // ULONG Seconds, Micros;
758 // CurrentTime(&Seconds,&Micros);
759 // return((int) (Micros % 100) + 1);
760 return getutime64() % 100 + 1;
764 static int gethundredths() {
765 // ULONG Seconds, Micros;
766 // CurrentTime(&Seconds,&Micros);
767 // return((int)Micros/10000);
768 return (getutime64()%1000000)/10000;
773 return ((float) getmicros() / 101.0);
777 return (float) rand() / RAND_MAX
;
781 static float pi2
= 6.28;
782 static float myrandom(float stdev
) {
784 holder
= (sqrt(-2.0 * log(frand())) * (cos(pi2
* frand()))) * stdev
;
788 static float get_float(FILE * infile
) {
792 while(((c
= getc(infile
)) == ' ') || (c
== '\015') || (c
== '\012')) ;
795 while(((c
= getc(infile
)) != ' ') && (c
!= '\015') && (c
!= '\012'))
798 return ((float) atof(innum
));
801 static int get_int(FILE * infile
) {
805 while(((c
= getc(infile
)) == ' ') || (c
== '\015') || (c
== '\012')) ;
808 while(((c
= getc(infile
)) != ' ') && (c
!= '\015') && (c
!= '\012'))
811 return (atoi(innum
));
814 static float normal(float value
) {
828 holder
= ((value
- ((float) i
)) * ndis
[i
+ 1]) - ((value
- ((float) (i
+ 1))) * ndis
[i
]);
830 holder
= 1.0 - holder
;
832 DPRINTF("value is %f i is %d\n",value
,i
);
833 DPRINTF("normal returns %f\n",holder
);
838 float variance(int stockno
) {
839 float tvx1
, tvx2
, tvx3
, tvx4
;
840 tvx1
= vx1
+ factor1
;
841 tvx2
= vx2
+ factor2
;
842 tvx3
= vx3
+ factor3
;
843 tvx4
= vx4
+ factor4
;
844 DPRINTF("ran %f q_int %f\n",myrandom(2.0 * q_int_rate
),q_int_rate
);
845 DPRINTF("4 tvx1 %f tvx2 %f tvx3 %f tvx4 %f\n",tvx1
,tvx2
,tvx3
,tvx4
);
846 DPRINTF("st %d b1 %f sqr %f sq* %f\n",stockno
,stock_array
[stockno
].b1
,sqr(stock_array
[stockno
].b1
),
847 (sqr(stock_array
[stockno
].b1
) * tvx1
));
848 DPRINTF("st %d b2 %f sqr %f sq* %f\n",stockno
,stock_array
[stockno
].b2
,sqr(stock_array
[stockno
].b2
),
849 (sqr(stock_array
[stockno
].b2
) * tvx2
));
850 DPRINTF("st %d b3 %f sqr %f sq* %f\n",stockno
,stock_array
[stockno
].b3
,sqr(stock_array
[stockno
].b3
),
851 (sqr(stock_array
[stockno
].b3
) * tvx3
));
852 DPRINTF("st %d e %f sqr %f sq* %f\n",stockno
,stock_array
[stockno
].e
,sqr(stock_array
[stockno
].e
),
853 (sqr(stock_array
[stockno
].e
) * tvx4
));
855 return (((sqr(stock_array
[stockno
].b1
) * tvx1
) +
856 (sqr(stock_array
[stockno
].b2
) * tvx2
) +
857 (sqr(stock_array
[stockno
].b3
) * tvx3
) + (sqr(stock_array
[stockno
].e
) * tvx4
)) * 10.0);
862 struct event myevent
;
863 e
= ezsdl_getevent(&myevent
);
864 if(e
!= EV_KEYDOWN
) return 0;
865 else return myevent
.which
;
868 static void end_year(void) {
873 scr_status
= RANKINGSUP
;
875 TxWrite(rp
, "Taxes Assessed");
877 TxWrite(rp
, "______________");
879 for(player
= 0; player
< no_of_players
; ++player
) {
880 play_ptr
= &players
[0] + player
;
881 for(counter
= 0; counter
< play_ptr
->auto_count
; ++counter
) {
882 if((play_ptr
->auto_ptr
[counter
]->option_type
== CALL
) ||
883 (play_ptr
->auto_ptr
[counter
]->option_type
== PUT
)) {
884 players
[player
].cash
+= (opt_value(player
+ 1, counter
) * .985);
885 players
[player
].other_earnings
+= ((opt_value(player
+ 1, counter
) * .985) -
886 players
[player
].auto_ptr
[counter
]->pur_price
);
887 del_auto(counter
, player
+ 1);
890 } /* end for counter */
893 play_ptr
->taxes
+= calc_taxes(player
);
895 cursor(11 + player
, 0);
896 TxWritef(rp
, "%20s $%-10.0f", play_ptr
->name
, play_ptr
->taxes
);
897 if(play_ptr
->taxes
< 0) {
898 cursor(11 + player
, 37);
900 } else if(play_ptr
->taxes
<= play_ptr
->cash
) {
901 play_ptr
->cash
-= play_ptr
->taxes
;
904 play_ptr
->taxes
-= play_ptr
->cash
;
907 play_ptr
->short_term
= play_ptr
->long_term
= play_ptr
->other_earnings
= 0;
908 } /* end for players */
915 TxWriteMsg(rp
, "END OF YEAR"); // changed from TxWrite
918 static void execute(int com_no
, int units
, int stock_no
, int price
, int auto_minus
, int auto_plus
, int player
) {
924 if(price
== NOT_FOUND
) {
925 if(players
[player
- 1].auto_count
< AUTOLIMIT
) {
926 add_auto_exec(auto_minus
, auto_plus
, AUTOBUY
, NONE
, units
, stock_no
, player
,
929 TxWriteMsg(rp
, "YOU ALREADY HAVE %d AUTO TRANSACTIONS", AUTOLIMIT
);
932 } else if(round(((float) units
) * ((float) price
) * 101.5) <= players
[player
- 1].cash
) {
933 if((players
[player
- 1].portfolio
[stock_no
].shares
!= 0) ||
934 (players
[player
- 1].stock_count
< STOCKLIMIT
)) {
935 /* add a record node for tax purposes */
937 add_purchase(player
, stock_no
, units
, price
);
939 /* if its a new stock, note that his portfolio has grown */
941 if(players
[player
- 1].portfolio
[stock_no
].shares
== 0)
942 ++players
[player
- 1].stock_count
;
944 /* charge the player */
946 players
[player
- 1].cash
-= round(((float) units
) * ((float) price
) * 101.5);
948 /* give him the stock */
950 players
[player
- 1].portfolio
[stock_no
].shares
+= units
;
955 } else { /* reached limit of holdings */
956 TxWriteMsg(rp
, "YOU ALREADY HAVE %d STOCKS", STOCKLIMIT
);
959 /* end if enough cash */
960 else { /* too little cash */
961 TxWriteMsg(rp
, "YOU HAVEN'T GOT ENOUGH CASH");
967 if(price
== NOT_FOUND
) {
968 if(players
[player
- 1].auto_count
< AUTOLIMIT
) {
969 add_auto_exec(auto_minus
, auto_plus
, AUTOSELL
, NONE
, units
, stock_no
, player
, NOT_FOUND
);
971 TxWriteMsg(rp
, "YOU ALREADY HAVE %d AUTO TRANSACTIONS", AUTOLIMIT
);
973 } else if((players
[player
- 1].portfolio
[stock_no
].shares
>= units
) && (units
> 0)) {
975 /* pay the player for the stock he sold, first deducting */
976 /* any margin debt owed on those shares. */
978 if(round((double) players
[player
- 1].portfolio
[stock_no
].margin_debt
) >=
979 round(((float) units
) * ((float) stock_array
[stock_no
].price
* 98.5)))
980 players
[player
- 1].portfolio
[stock_no
].margin_debt
-=
981 round(98.5 * ((float) units
) * ((float) stock_array
[stock_no
].price
));
983 players
[player
- 1].cash
+=
984 round(((float) units
) * ((float) stock_array
[stock_no
].price
) * 98.5) -
985 round((double) players
[player
- 1].portfolio
[stock_no
].margin_debt
);
986 players
[player
- 1].portfolio
[stock_no
].margin_debt
= 0;
989 if(round((double) players
[player
- 1].portfolio
[stock_no
].margin_debt
) < 1)
990 players
[player
- 1].portfolio
[stock_no
].margin_debt
= 0;
992 /* remove or update the tax record node */
994 del_purchase(player
, stock_no
, units
);
996 /* remove the shares from his portfolio */
998 players
[player
- 1].portfolio
[stock_no
].shares
-= units
;
1000 /* if he sold all his shares note his fewer holdings */
1002 if((players
[player
- 1].portfolio
[stock_no
].shares
== 0) &&
1003 (players
[player
- 1].portfolio
[stock_no
].margin_debt
== 0)) {
1004 players
[player
- 1].portfolio
[stock_no
].limit
= 0;
1005 --players
[player
- 1].stock_count
;
1009 upd_stock(stock_no
);
1010 } else { /* if he doesn't have that many shares */
1011 if(players
[player
- 1].portfolio
[stock_no
].shares
== 0)
1012 TxWriteMsg(rp
, "YOU DON'T OWN ANY!");
1014 TxWriteMsg(rp
, "YOU DON'T HAVE THAT MANY SHARES");
1018 if(round(((float) price
) * ((float) units
) * 1.015) <= players
[player
- 1].cash
) {
1019 if(players
[player
- 1].auto_count
< AUTOLIMIT
) {
1020 add_auto_exec(NONE
, NONE
, CALL
, stock_array
[stock_no
].price
, units
, stock_no
,
1022 players
[player
- 1].cash
-= round(((float) price
) * ((float) units
) * 1.015);
1027 TxWriteMsg(rp
, "YOU ALREADY HAVE %d AUTO TRANSACTIONS", AUTOLIMIT
);
1029 } else { /* if he hasn't got the money */
1030 TxWriteMsg(rp
, "YOU NEED SOME MORE CASH");
1034 if(round(((float) price
) * ((float) units
) * 1.015) <= players
[player
- 1].cash
) {
1035 if(players
[player
- 1].auto_count
< AUTOLIMIT
) {
1036 add_auto_exec(NONE
, NONE
, PUT
, stock_array
[stock_no
].price
, units
, stock_no
,
1038 players
[player
- 1].cash
-= round(((float) price
) * ((float) units
) * 1.015);
1043 TxWriteMsg(rp
, "YOU ALREADY HAVE %d AUTO TRANSACTIONS", AUTOLIMIT
);
1045 } else { /* if he hasn't got the money */
1046 TxWriteMsg(rp
, "YOU NEED SOME MORE CASH");
1051 if(round((((float) units
) * ((float) price
) * 103.0) / 2.0) <= players
[player
- 1].cash
) {
1052 if((players
[player
- 1].portfolio
[stock_no
].shares
!= 0) ||
1053 (players
[player
- 1].stock_count
< STOCKLIMIT
)) {
1055 /* update or add a tax record node */
1057 add_purchase(player
, stock_no
, units
, price
);
1059 /* if its a new stock, note that his portfolio has grown */
1061 if(players
[player
- 1].portfolio
[stock_no
].shares
== 0)
1062 ++players
[player
- 1].stock_count
;
1064 /* charge the player half the cost */
1066 players
[player
- 1].cash
-=
1067 round((((float) units
) * ((float) price
) * 103.0) / 2.0);
1069 /* put the other half on margin */
1071 players
[player
- 1].portfolio
[stock_no
].margin_debt
+=
1072 round((100.0 * ((float) units
) * ((float) price
)) / 2.0);
1074 /* give him the stock */
1076 players
[player
- 1].portfolio
[stock_no
].shares
+= ((int) units
);
1079 upd_stock(stock_no
);
1081 } else { /* reached limit of holdings */
1082 TxWriteMsg(rp
, "YOU ALREADY HAVE %d STOCKS", STOCKLIMIT
);
1086 /* end if enough cash */
1087 else { /* too little cash */
1088 TxWriteMsg(rp
, "YOU HAVEN'T GOT ENOUGH CASH");
1094 del_auto(units
- 1, player
);
1110 cur_player
->cash
+= ((float) units
) * 1000.0;
1111 cur_player
->bonds
-= units
;
1116 graph(stock_no
, year
);
1117 if(newsline
[cur_news_line
] != '\n')
1122 ptr
= cur_player
->auto_ptr
[units
- 1];
1123 if((ptr
->option_type
== CALL
) || (ptr
->option_type
== PUT
)) {
1124 price
= (int) round(.985 * ((float) price
));
1125 cur_player
->cash
+= (((float) price
) * ((float) ptr
->units
));
1126 cur_player
->other_earnings
+= ((((float) price
) - ((float) ptr
->pur_price
)) *
1127 ((float) ptr
->units
));
1128 del_auto(units
- 1, player
);
1131 TxWriteMsg(rp
, "You Can't Exercise a Limit Order");
1136 cur_player
->portfolio
[stock_no
].limit
= units
;
1137 for(counter
= 0; counter
< screen_count
; ++counter
)
1138 if((scr_status
== STOCKSUP
) && (scr_ptr
[counter
]->stock_no
== stock_no
)) {
1139 cursor(12 + counter
, 36);
1141 TxWritef(rp
, "%3d", units
);
1154 if((scr_status
== STOCKSUP
) || (scr_status
== AUTOSUP
))
1158 static void shutdown() {
1161 TxWrite(rp
, "Hit any key to continue");
1162 while(kbhit() == 0) ezsdl_sleep(20);
1166 static void quit(void) {
1171 for(tplayer
= 0; tplayer
< no_of_players
; ++tplayer
) {
1172 play_ptr
= &players
[0] + tplayer
;
1173 for(counter
= 0; counter
< NO_OF_STOCKS
; ++counter
) {
1174 if(play_ptr
->portfolio
[counter
].shares
> 0)
1175 execute(SELL
, play_ptr
->portfolio
[counter
].shares
, counter
, stock_array
[counter
].price
,
1176 NONE
, NONE
, tplayer
+ 1);
1178 for(counter
= 0; counter
< play_ptr
->auto_count
; ++counter
) {
1179 if((play_ptr
->auto_ptr
[counter
]->option_type
== CALL
) ||
1180 (play_ptr
->auto_ptr
[counter
]->option_type
== PUT
)) {
1181 play_ptr
->cash
+= opt_value(tplayer
+ 1, counter
);
1182 del_auto(counter
, tplayer
+ 1);
1188 TxWrite(rp
, "All Holdings Liquidated");
1189 TxWrite(rp
, " That's It!");
1193 static void set_graph() {
1195 /* Set up graph initialization */
1201 for(i
= 0; i
< 5; ++i
) {
1202 Move(rp
, 124 + (i
* 32), 176);
1203 Draw(rp
, 124 + (i
* 32), 183);
1216 TxWrite(rp
, "200-");
1218 TxWrite(rp
, "150-");
1220 TxWrite(rp
, "100-");
1230 /***************************************************/
1231 /* Draws a line up from the bottom of the graph */
1232 /* starting at horizontal position, POSITION, and */
1233 /* continuing NUMBER of times in the COLOR. */
1235 /* line_draw(position,number,color) */
1239 /***************************************************/
1242 static void line_draw(int position
, int number
, int color
) {
1243 if((number
> 0) && (number
<= 200)) {
1245 RectFill(rp
, 112 + (position
* 8), 175 - number
, 119 + (position
* 8), 175);
1266 mov dl, byte ptr [bx]
1275 lbp14: mov byte ptr [bx],dl
1287 static void graph(int stockno
, int year
) {
1298 for(x
= 0; x
< 20; ++x
) {
1300 if(history
[stockno
].splits
[x
]) {
1305 line_draw(x
+ 1, (int) round((((float) history
[stockno
].price
[x
]) * 0.8) + .49), color
);
1307 if(history
[MMMS
].price
[x
] != 0) {
1309 (round((((double) 21.51) - (((double) history
[MMMS
].price
[x
])) / ((double) 10.0)))),
1314 if(tcolor
!= NOT_FOUND
) {
1328 TxWritef(rp
, "%2d", year
- 1900);
1330 TxWritef(rp
, "%2d", year
);
1335 TxWrite(rp
, stock_array
[stockno
].name
);
1337 TxWrite(rp
, "Stock");
1339 TxWrite(rp
, "Splits");
1340 scr_status
= GRAPHUP
;
1346 static void margin() {
1349 static char owes
[15];
1359 for(player
= 0; player
< no_of_players
; ++player
) {
1360 ptr
= &players
[0] + player
;
1362 for(counter
= 0; counter
< NO_OF_STOCKS
; ++counter
) {
1363 if((round((double) ptr
->portfolio
[counter
].margin_debt
) >
1364 (dif
= (round((((float) ptr
->portfolio
[counter
].shares
) * 100.0 *
1365 ((float) stock_array
[counter
].price
)) / 2.0))))) {
1366 dif
= round((double) ptr
->portfolio
[counter
].margin_debt
) - dif
;
1367 if(ptr
->cash
>= dif
) {
1369 ptr
->portfolio
[counter
].margin_debt
-= dif
;
1372 ptr
->portfolio
[counter
].margin_debt
-= ptr
->cash
;
1374 timer1
.status
= OFF
;
1380 if(round((double) ptr
->portfolio
[counter
].margin_debt
) < 1.0) {
1381 ptr
->portfolio
[counter
].margin_debt
= 0;
1382 if(ptr
->portfolio
[counter
].shares
== 0)
1385 if(cur_player
== ptr
) {
1393 if(ptr
->cash
< ptr
->taxes
) {
1395 ptr
->taxes
-= ptr
->cash
;
1400 owes
[player
+ 4] = 1;
1402 ptr
->cash
-= ptr
->taxes
;
1406 if(cur_player
== ptr
) {
1407 calc_netw(player
+ 1);
1413 if(found
|| passby
) {
1415 message
= TRUE
; // can probably be removed
1416 if(passby
&& !found
) {
1417 TxWriteMsg(rp
, "MARGIN CALL ISSUED");
1420 if(found
== OPTIONS
) {
1422 scr_status
= RANKINGSUP
;
1423 for(player
= 0; player
< no_of_players
; ++player
) {
1427 TxWriteMsg(rp
, "Player %d Must Settle Margin Debts", player
+ 1);
1432 scr_status
= RANKINGSUP
;
1433 for(player
= 0; player
< no_of_players
; ++player
) {
1434 if(owes
[4 + player
]) {
1437 TxWriteMsg(rp
, "Player %d Must Settle Tax Debts", player
+ 1);
1442 for(player
= 0; player
< no_of_players
; ++player
) {
1443 ptr
= &players
[0] + player
;
1444 /* FIXME: the original calc_netw function was missing a return statement, so this assignment is probably a bug */
1445 y
= calc_netw(player
+ 1);
1447 y
-= (((float) ptr
->bonds
) * 1000.0);
1448 for(x
= 0; x
< players
[player
].auto_count
; ++x
) {
1449 if((players
[player
].auto_ptr
[x
]->option_type
== CALL
) ||
1450 (players
[player
].auto_ptr
[x
]->option_type
== PUT
))
1458 ptr
->auto_count
= 0;
1459 ptr
->stock_count
= 0;
1461 for(x
= 0; x
< NO_OF_STOCKS
; ++x
) {
1462 ptr
->portfolio
[x
].shares
= 0;
1463 ptr
->portfolio
[x
].margin_debt
= 0;
1467 TxWriteMsg(rp
, "%s IS BANKRUPT", ptr
->name
);
1469 } /* end going through players */
1479 static void shift_it(char *str
) {
1481 for(i
= 0; i
< 16; ++i
)
1482 str
[i
] = str
[i
+ 4];
1485 static void end_quarter() {
1489 timer1
.status
= OFF
;
1490 timer2
.status
= OFF
;
1491 timer3
.status
= OFF
;
1492 in_progress
= FALSE
;
1494 for(player
= 0; player
< no_of_players
; ++player
) {
1495 earnings
= round((double) ((((float) players
[player
].bonds
) * BONDVALUE
) * bond_rate
));
1496 players
[player
].cash
+= earnings
;
1497 players
[player
].other_earnings
+= earnings
;
1498 players
[player
].net_worth
+=
1499 round((double) ((((float) players
[player
].bonds
) * BONDVALUE
) * bond_rate
));
1501 for(x
= 0; x
< NO_OF_STOCKS
; ++x
)
1502 history
[x
].price
[15 + quarter
] = ((int) stock_array
[x
].price
);
1504 for(x
= 0; x
< NO_OF_STOCKS
; ++x
) {
1505 for(y
= 0; y
< 16; ++y
)
1506 history
[x
].price
[y
] = history
[x
].price
[y
+ 4];
1507 for(y
= 16; y
< 20; ++y
)
1508 history
[x
].price
[y
] = 0;
1509 shift_it(history
[x
].splits
);
1511 bond_rate
= (q_int_rate
* .85);
1521 TxWriteMsg(rp
, "END OF QUARTER");
1522 factor1
= sqr(0.2 * q_int_rate
);
1523 factor2
= sqr(0.02 * q_int_rate
);
1524 factor3
= sqr(0.04 * q_int_rate
);
1525 factor4
= sqr(0.3 * q_int_rate
);
1528 static void getsave() {
1531 int stock
, shares
, price
;
1532 int num
, junk
, tyear
, player
, counter
, tweek
;
1534 saved
= fopen("save", "r");
1537 TxWrite(rp
, "NO SAVED GAME FOUND");
1542 no_of_players
= get_int(saved
);
1543 year
= get_int(saved
);
1544 quarter
= (int) get_int(saved
);
1545 week
= (int) get_int(saved
);
1547 emphasis
= (char) get_int(saved
);
1548 prime_rate
= get_float(saved
);
1549 q_int_rate
= get_float(saved
);
1550 wk_int_rate
= get_float(saved
);
1551 bond_rate
= get_float(saved
);
1553 vx1
= get_float(saved
);
1554 vx2
= get_float(saved
);
1555 vx3
= get_float(saved
);
1556 vx4
= get_float(saved
);
1558 for(player
= 0; player
< no_of_players
; ++player
) {
1559 players
[player
].name_length
= (int) get_int(saved
);
1560 fgets(players
[player
].name
, 21, saved
);
1561 players
[player
].name
[players
[player
].name_length
] = '\0';
1562 players
[player
].cash
= get_float(saved
);
1563 players
[player
].net_worth
= get_float(saved
);
1564 players
[player
].taxes
= get_float(saved
);
1565 players
[player
].short_term
= get_float(saved
);
1566 players
[player
].long_term
= get_float(saved
);
1567 players
[player
].other_earnings
= get_float(saved
);
1568 players
[player
].bonds
= (int) get_int(saved
);
1569 players
[player
].stock_count
= (int) get_int(saved
);
1570 players
[player
].auto_count
= (int) get_int(saved
);
1572 for(counter
= 0; counter
< players
[player
].stock_count
; ++counter
) {
1573 stock
= (int) get_int(saved
);
1575 players
[player
].portfolio
[stock
].shares
= (int) get_int(saved
);
1576 players
[player
].portfolio
[stock
].margin_debt
= get_float(saved
);
1577 num
= get_int(saved
);
1580 for(junk
= 0; junk
< num
; ++junk
) {
1581 year
= get_int(saved
);
1582 week
= (int) get_int(saved
);
1583 shares
= (int) get_int(saved
);
1584 price
= (int) get_int(saved
);
1585 add_purchase(player
+ 1, stock
, shares
, price
);
1590 for(counter
= 0; counter
< players
[player
].auto_count
; ++counter
) {
1591 aptr
= players
[player
].auto_ptr
[counter
];
1592 aptr
->minus_price
= (int) get_int(saved
);
1593 aptr
->plus_price
= (int) get_int(saved
);
1594 aptr
->option_type
= (int) get_int(saved
);
1595 aptr
->option_price
= (int) get_int(saved
);
1596 aptr
->units
= (int) get_int(saved
);
1597 aptr
->stock_no
= (int) get_int(saved
);
1598 aptr
->cur_price
= (int) get_int(saved
);
1599 aptr
->pur_price
= get_int(saved
);
1602 for(counter
= 0; counter
< NO_OF_STOCKS
; ++counter
) {
1603 stock_array
[counter
].price
= (int) get_int(saved
);
1604 for(junk
= 0; junk
< 20; ++junk
)
1605 history
[counter
].price
[junk
] = (int) get_int(saved
);
1606 for(junk
= 0; junk
< 20; ++junk
)
1607 history
[counter
].splits
[junk
] = (int) get_int(saved
);
1613 load_tick_element(&ticker
[0], 0);
1614 load_tick_element(&ticker
[0] + 1, 1);
1615 load_tick_element(&ticker
[0] + 2, 2);
1619 static void headers2() {
1622 int junk1_counter
, junk2_counter
, junk3_counter
;
1630 TxWrite(rp
, "How Many Will Be Playing?");
1634 if(isdigit(no_of_players
))
1635 no_of_players
-= DIFFERENCE
;
1639 if((no_of_players
<= 0) || (no_of_players
> 4))
1641 for(junk1_counter
= 0; junk1_counter
< no_of_players
; ++junk1_counter
) {
1645 TxWritef(rp
, "Enter Player %d's Name", junk1_counter
+ 1);
1647 TxWrite(rp
, "(Maximum Of 20 Characters)");
1651 while(junk3_counter
< 20) {
1657 if(isupper(c
) || islower(c
) || (c
== ' ') || (c
== '.') || (c
== ',')) {
1659 if(junk3_counter
== 20) {
1663 players
[junk1_counter
].name
[junk3_counter
] = c
;
1664 TxWritef(rp
, "%c", c
);
1666 } else if(c
== (char) CR
) {
1667 players
[junk1_counter
].name
[++junk3_counter
] = '\0';
1669 } else if(c
== BACKSP
) {
1670 if(junk3_counter
>= 0) {
1672 cursor(14, 9 + junk3_counter
);
1674 cursor(14, 9 + junk3_counter
);
1683 while(players
[junk1_counter
].name
[junk2_counter
] != '\0')
1685 if(junk2_counter
> 20) {
1687 players
[junk1_counter
].name
[19] = '\0';
1689 players
[junk1_counter
].name_length
= junk2_counter
;
1693 while((money
!= 25) && (money
!= 100) && (money
!= 50)) {
1698 TxWrite(rp
, "How Much Money Would You Like?");
1700 TxWrite(rp
, "(In Thousands)");
1702 TxWrite(rp
, "Enter 25, 50, or 100");
1708 if((isdigit(c
)) && (junk2_counter
< 3)) {
1709 inmoney
[junk2_counter
++] = c
;
1710 inmoney
[junk2_counter
] = '\0';
1711 TxWritef(rp
, "%c", c
);
1712 } else if((c
== BACKSP
) && (junk2_counter
!= 0)) {
1713 inmoney
[junk2_counter
--] = '\0';
1714 cursor(15, 20 + junk2_counter
);
1716 cursor(15, 20 + junk2_counter
);
1718 money
= atoi(inmoney
);
1722 for(junk1_counter
= 0; junk1_counter
< no_of_players
; ++junk1_counter
) {
1723 players
[junk1_counter
].cash
= money
* 1000.0;
1724 players
[junk1_counter
].net_worth
= players
[junk1_counter
].cash
;
1725 players
[junk1_counter
].stock_count
= 0;
1731 static void getyear(int year
) {
1733 int i
, x
, counter
, found
;
1746 datfile
[counter
++] = i
+ DIFFERENCE
;
1748 datfile
[counter
++] = '.';
1749 datfile
[counter
++] = 'd';
1750 datfile
[counter
++] = 'a';
1751 datfile
[counter
++] = 't';
1752 datfile
[counter
++] = '\0';
1755 in
= fopen(datfile
, "r");
1759 high_prime
= get_float(in
);
1760 low_prime
= get_float(in
);
1764 for(i
= 0; i
< (2 * x
); ++i
) {
1765 while(getc(in
) != '\n') ;
1771 for(i
= 0; i
< x
; ++i
) {
1772 fgets(yrly_mssgs
.item
[i
].string
, 82, in
);
1773 yrly_mssgs
.item
[i
].intr
= get_float(in
);
1774 yrly_mssgs
.item
[i
].gnp
= get_float(in
);
1775 yrly_mssgs
.item
[i
].pol
= get_float(in
);
1776 yrly_mssgs
.item
[i
].var
= get_float(in
);
1778 yrly_mssgs
.item
[i
].used
= FALSE
;
1779 DPRINTF("i is %d\n",i
);
1780 DPRINTF("message %s \n",yrly_mssgs
.item
[i
].string
);
1784 vx1
= vx2
= vx3
= vx4
= 0;
1785 for(i
= 0; i
< y_mssg_count
; ++i
) {
1786 vx1
+= sqr(yrly_mssgs
.item
[i
].intr
);
1787 vx2
+= sqr(yrly_mssgs
.item
[i
].gnp
);
1788 vx3
+= sqr(yrly_mssgs
.item
[i
].pol
);
1789 vx4
+= sqr(yrly_mssgs
.item
[i
].var
- 1.0);
1792 for(i
= 0; i
< x
; ++i
) {
1794 while(getc(in
) != '\n') ;
1795 vx1
+= sqr(get_float(in
));
1796 vx2
+= sqr(get_float(in
));
1797 vx3
+= sqr(get_float(in
));
1798 vx4
+= sqr(get_float(in
) - 1.0);
1802 vx1
/= (NO_STD_MESSAGES
+ x
);
1803 vx2
/= (NO_STD_MESSAGES
+ x
);
1804 vx3
/= (NO_STD_MESSAGES
+ x
);
1805 vx4
/= (NO_STD_MESSAGES
+ x
);
1809 DPRINTF("final messcount is %d\n",y_mssg_count
);
1814 /***************************************************/
1815 /************ begin main body of event() *********/
1816 /***************************************************/
1817 static float x4
, E
, R
;
1818 static float gamma1
= 1.2;
1819 static float gamma2
= .24;
1820 static float gamma3
= .24;
1822 static void event(int stockno
, float news
) {
1826 if(stockno
!= MMMS
) {
1830 x4
= ((((float) gethundredths()) - 50.0) / 5000.0) * news
* stock_array
[stockno
].e
;
1833 /* calculated expected rate of return using method 2 as outlined */
1836 E
= ((gamma1
* stock_array
[stockno
].b1
) +
1837 (gamma2
* stock_array
[stockno
].b2
) + (gamma3
* stock_array
[stockno
].b3
)) * the_interest
;
1842 /* generate percent change in stock price */
1845 R
= (((stock_array
[stockno
].b1
* x1
) +
1846 (stock_array
[stockno
].b2
* x2
) +
1847 (stock_array
[stockno
].b3
* x3
) + (stock_array
[stockno
].e
* x4
) + E
) * 1.15) + 1.0;
1851 /* check value of R to prevent negative stock prices */
1857 /* calculate new stock price */
1860 stock_array
[stockno
].price
= (int) round((stock_array
[stockno
].price
* R
));
1862 if(stock_array
[stockno
].price
>= SPLITPRICE
) {
1863 history
[stockno
].splits
[quarter
+ 15] = 1;
1864 stock_array
[stockno
].price
/= 2;
1866 TxWriteMsg(rp
, "%s STOCK SPLITS 2 FOR 1", stock_array
[stockno
].name
);
1868 for(y
= 0; y
< no_of_players
; ++y
) {
1869 newshares
= (int) players
[y
].portfolio
[stockno
].shares
;
1871 if(((int) players
[y
].portfolio
[stockno
].shares
) >= 5000) {
1872 players
[y
].portfolio
[stockno
].shares
*= 2;
1873 players
[y
].cash
+= (((float) players
[y
].portfolio
[stockno
].shares
) - 9999.0) *
1874 ((float) stock_array
[stockno
].price
);
1875 players
[y
].other_earnings
+=
1876 (((float) players
[y
].portfolio
[stockno
].shares
) -
1877 9999.0) * ((float) stock_array
[stockno
].price
);
1878 players
[y
].portfolio
[stockno
].shares
= (int) 9999;
1880 players
[y
].portfolio
[stockno
].shares
*= 2;
1882 newshares
= players
[y
].portfolio
[stockno
].shares
- newshares
;
1884 if(((int) players
[y
].portfolio
[MMMS
].shares
) > 0) {
1885 players
[y
].cash
+= ((float) players
[y
].portfolio
[MMMS
].shares
) * 333.0;
1886 players
[y
].other_earnings
+=
1887 ((float) players
[y
].portfolio
[MMMS
].shares
) * 333.0;
1891 /*** adjust purchase record for splits *****/
1894 temp
= players
[y
].portfolio
[stockno
].purchases
;
1897 while(temp
->next
!= NULL
)
1901 while(temp
!= NULL
) {
1902 if(((int) temp
->shares
) < newshares
) {
1903 newshares
-= (int) temp
->shares
;
1906 temp
->shares
+= (int) newshares
;
1910 temp
= temp
->previous
;
1916 /*** show splits on screen ***/
1922 stock_array
[MMMS
].price
= 0;
1925 for(i
= 0; i
< NO_OF_STOCKS
; ++i
) {
1926 x
+= stock_array
[i
].price
;
1929 x
-= stock_array
[GOLD
].price
;
1930 x
-= stock_array
[REALESTATE
].price
;
1931 stock_array
[MMMS
].price
= x
/ (NO_OF_STOCKS
- 3);
1934 } /* end procedure event() */
1937 static void stall(int x
) {
1942 staller
= y
= gethundredths();
1952 while(((z
= gethundredths()) < staller
) || (flag
))
1961 static void save() {
1962 int player
, stock
, temp
, count
;
1967 saveto
= fopen("save", "w");
1968 if(saveto
== NULL
) {
1970 TxWriteMsg(rp
, "FAILED ATTEMPT TO SAVE");
1972 fprintf(saveto
, " %d %d %d %d ", no_of_players
, year
, quarter
, week
);
1974 fprintf(saveto
, " %d ", (int) emphasis
);
1975 fprintf(saveto
, "%6.4f %6.4f %6.4f %6.4f\n", prime_rate
, q_int_rate
, wk_int_rate
, bond_rate
);
1976 fprintf(saveto
, "%8.6f %8.6f %8.6f %8.6f\n", vx1
, vx2
, vx3
, vx4
);
1977 for(player
= 0; player
< no_of_players
; ++player
) {
1978 fprintf(saveto
, " %d %-20s\n", players
[player
].name_length
, players
[player
].name
);
1979 fprintf(saveto
, "%f %f %f\n", players
[player
].cash
, players
[player
].net_worth
,
1980 players
[player
].taxes
);
1981 fprintf(saveto
, "%f %f %f\n", players
[player
].short_term
, players
[player
].long_term
,
1982 players
[player
].other_earnings
);
1984 fprintf(saveto
, "%d %d %d\n", players
[player
].bonds
, players
[player
].stock_count
,
1985 players
[player
].auto_count
);
1987 for(stock
= 0; stock
< NO_OF_STOCKS
; ++stock
) {
1988 if(players
[player
].portfolio
[stock
].shares
> 0) {
1990 fprintf(saveto
, "%d %d %f\n", stock
,
1991 players
[player
].portfolio
[stock
].shares
,
1992 players
[player
].portfolio
[stock
].margin_debt
);
1994 ptr
= players
[player
].portfolio
[stock
].purchases
;
1995 while(ptr
->next
!= NULL
) {
1999 fprintf(saveto
, "%d\n", count
);
2000 ptr
= players
[player
].portfolio
[stock
].purchases
;
2001 while(ptr
!= NULL
) {
2002 fprintf(saveto
, "%d %d %d %d\n", ptr
->year
, ptr
->week
, ptr
->shares
,
2010 for(count
= 0; count
< players
[player
].auto_count
; ++count
) {
2011 aptr
= players
[player
].auto_ptr
[count
];
2012 fprintf(saveto
, " %d %d %d ", aptr
->minus_price
, aptr
->plus_price
, aptr
->option_type
);
2013 fprintf(saveto
, "%d %d %d %d %d\n", aptr
->option_price
, aptr
->units
, aptr
->stock_no
,
2014 aptr
->cur_price
, aptr
->pur_price
);
2018 for(stock
= 0; stock
< NO_OF_STOCKS
; ++stock
) {
2019 fprintf(saveto
, "%d\n", stock_array
[stock
].price
);
2020 for(count
= 0; count
< 20; ++count
)
2021 fprintf(saveto
, "%d\n", history
[stock
].price
[count
]);
2022 for(count
= 0; count
< 20; ++count
)
2023 fprintf(saveto
, "%d\n", history
[stock
].splits
[count
]);
2025 temp
= fclose(saveto
);
2029 TxWriteMsg(rp
, "FAILED ATTEMPT TO SAVE");
2032 TxWriteMsg(rp
, "GAME OVER");
2039 /********************************************/
2040 /*** begin main body of procedure OPTION ****/
2041 /********************************************/
2042 /* unused - maybe was called from one of the missing functions */
2043 static float option(int com_no
, int stockno
, int ex_price
) {
2044 float d1
, d2
, vari
, factor1
, factor2
, holder
;
2047 vari
= variance(stockno
);
2049 DPRINTF("stockno %d com_no %d\n",stockno
,com_no
);
2050 DPRINTF("variance is %f\n",vari
);
2052 t
= (53.0 - ((float) week
)) / 13.0;
2053 DPRINTF("\n t is %d\nlog is %f\n",t
,log10(1.0));
2055 factor1
= log10((float) stock_array
[stockno
].price
/ (float) ex_price
);
2056 factor2
= (sqrt(vari
) * sqrt((double) t
));
2057 DPRINTF("factor 1 %f factor 2 %f\n",factor1
,factor2
);
2058 DPRINTF("sqrt vari %f sqrt t %f\n",sqrt(vari
),sqrt((double) t
));
2060 d1
= (factor1
+ ((q_int_rate
+ (vari
/ 2.0)) * t
)) / factor2
;
2061 d2
= (factor1
+ ((q_int_rate
- (vari
/ 2.0)) * t
)) / factor2
;
2062 DPRINTF("d1 is %f d2 is %f\n",d1
,d2
);
2063 DPRINTF("vari / 2 * t %f\n",(vari
/2.0) * t
);
2067 100.0 * ((stock_array
[stockno
].price
* normal(d1
)) -
2068 ((ex_price
/ exp((double) q_int_rate
* t
)) * normal(d2
)));
2071 100.0 * (((ex_price
/ exp((double) q_int_rate
* t
)) * normal(-d2
)) -
2072 (stock_array
[stockno
].price
* normal(-d1
)));
2074 DPRINTF("price calculated %f\n",holder
);
2075 DPRINTF("stock %s price %d ow %f\n",stock_array
[stockno
].name
,stock_array
[stockno
].price
,exp(q_int_rate
* t
));
2077 if(holder
< ((53.0 - ((float) week
)) * 4.0))
2078 holder
= (53.0 - ((float) week
)) * 4.0;
2079 if((holder
< ((stock_array
[stockno
].price
- ex_price
) * 100)) && (com_no
== CALL
))
2080 holder
= ((stock_array
[stockno
].price
- ex_price
) * 100.0);
2081 if((holder
< ((ex_price
- stock_array
[stockno
].price
) * 100)) && (com_no
== PUT
))
2082 holder
= ((ex_price
- stock_array
[stockno
].price
) * 100.0);
2084 DPRINTF("price %f\n",holder
);
2086 return (round(holder
));
2090 static void bonds(int units
) {
2091 if(units
+ ((int) players
[player
- 1].bonds
) > 99) {
2093 TxWriteMsg(rp
, "Maximum of 99 bonds can be held");
2094 } else if((((float) units
) * 1000.0) <= players
[player
- 1].cash
) {
2095 players
[player
- 1].cash
-= (((float) units
) * 1000.0);
2097 players
[player
- 1].bonds
+= ((int) units
);
2098 if(scr_status
!= RANKINGSUP
)
2102 TxWriteMsg(rp
, "INSUFFICIENT FUNDS");
2106 static void init() {
2109 /* initialize first quarter history */
2111 for(x
= 0; x
< NO_OF_STOCKS
; ++x
)
2112 history
[x
].price
[15] = 100;
2114 /* link the ticker elements together */
2116 for(i
= 0; i
< TICK_SIZE
; ++i
) {
2117 cur_tick
= &ticker
[0] + 1;
2118 if(i
!= TICK_SIZE
- 1)
2119 ticker
[i
].next
= &ticker
[0] + i
+ 1;
2121 ticker
[i
].next
= &ticker
[0];
2123 ticker
[i
].previous
= &ticker
[0] + i
- 1;
2125 ticker
[i
].previous
= &ticker
[0] + TICK_SIZE
- 1;
2127 load_tick_element(&ticker
[0] + i
, i
);
2129 } /* for loop setting up ticker */
2131 /* set up auto execute array and pointers */
2133 for(i
= 0; i
< MAXPLAYERS
; ++i
)
2134 for(x
= 0; x
< AUTOLIMIT
; ++x
)
2135 players
[i
].auto_ptr
[x
] = &players
[i
].auto_array
[0] + x
;
2137 /* set up screen array pointers */
2139 for(i
= 0; i
< STOCKLIMIT
; ++i
) {
2140 scr_ptr
[i
] = &screen
[0] + i
;
2144 /* initialize timers, timer1 in use, timer2 not in use */
2146 timer1
.status
= OFF
;
2147 timer2
.status
= OFF
;
2148 timer3
.status
= OFF
;
2149 timer1
.hour_changed
= FALSE
;
2150 timer2
.hour_changed
= FALSE
;
2151 timer3
.hour_changed
= FALSE
;
2155 } /* procedure initialize */
2157 static void getstd(char *infile
) {
2159 FILE *in
= fopen(infile
, "r");
2160 for(i
= 0; i
< 30; ++i
) {
2161 fgets(std_mssgs
.item
[i
].string
, 75, in
);
2162 std_mssgs
.item
[i
].intr
= get_float(in
);
2163 std_mssgs
.item
[i
].gnp
= get_float(in
);
2164 std_mssgs
.item
[i
].pol
= get_float(in
);
2165 std_mssgs
.item
[i
].var
= get_float(in
);
2171 /* a procedure to write the credits etc. on the screen. It pauses */
2172 /* then clears the screen */
2174 static int headers1(void) {
2182 TxWrite(rp
, "The Financial Time Machine");
2184 TxWrite(rp
, "(C) 1985 by Lehner Communications, Inc.");
2186 TxWrite(rp
, "programmed by NMc");
2188 TxWrite(rp
, "special thanks to Ed Friedman");
2191 while((yorn
!= (int) 'y') && (yorn
!= (int) 'Y') && (yorn
!= (int) 'n') && (yorn
!= (int) 'N')) {
2195 TxWrite(rp
, "Continue A Previous Game?");
2197 TxWrite(rp
, "(Type Y or N)");
2201 if((yorn
== (int) 'Y') || (yorn
== (int) 'y')) {
2203 } else if((yorn
== (int) 'N') || (yorn
== (int) 'n')) {
2209 TxWrite(rp
, "Enter Historical Mode or Forecast Mode?");
2211 TxWrite(rp
, "(Type H or F)");
2212 while((forh
!= (int) 'F') && (forh
!= (int) 'f') && (forh
!= (int) 'H') && (forh
!= (int) 'h')) {
2217 if((forh
== (int) 'F') || (forh
== (int) 'f')) {
2223 TxWrite(rp
, "Forecast Mode Emphasis On:");
2225 TxWrite(rp
, "1) GNP Factors");
2227 TxWrite(rp
, "2) Political Factors");
2229 TxWrite(rp
, "3) Interest Rate Factors");
2231 TxWrite(rp
, "Type 1, 2, or 3");
2232 while((emphasis
< '1') || (emphasis
> '3')) {
2251 while((temp_year
< 1930) || (temp_year
> 1980)) {
2255 TxWrite(rp
, "Enter The Game Year ");
2257 TxWrite(rp
, "(1930 to 1980)");
2263 if((isdigit(c
)) && (stall
< 4)) {
2264 file_name
[stall
++] = c
;
2265 TxWritef(rp
, "%c", c
);
2267 if((c
== BACKSP
) && (stall
!= 0)) {
2269 cursor(14, 18 + stall
);
2271 cursor(14, 18 + stall
);
2273 if((c
== CR
) && (stall
== 4))
2277 file_name
[5] = '\0';
2278 temp_year
= atoi(file_name
);
2291 static void set_top_screen(void) {
2295 TxWrite(rp
, "PRIME");
2301 RectFill(rp
, 0, 8, 320, 31);
2304 RectFill(rp
, 0, 32, 320, 55);
2310 static void set1_bottom_screen() {
2312 TxWrite(rp
, "HOLDINGS");
2314 TxWrite(rp
, "PAGE 1");
2315 cursor(8, (39 - cur_player
->name_length
)/2);
2316 TxWrite(rp
, cur_player
->name
);
2318 TxWrite(rp
, " S LOTS VALUE CP MARGIN LIMIT");
2320 TxWrite(rp
, "COH $");
2322 TxWrite(rp
, "NETW $");
2330 /* Draw appropriate rectangles */
2374 /* unused - maybe was called from one of the missing funcs */
2375 static void set2_bottom_screen() {
2379 TxWrite(rp
, "HOLDINGS");
2381 TxWrite(rp
, "PAGE 2");
2382 cursor(8, (39 - cur_player
->name_length
)/2);
2383 TxWrite(rp
, cur_player
->name
);
2385 TxWrite(rp
, " S LOTS VALUE OPTION CP BUY SELL");
2387 TxWrite(rp
, "COH $");
2389 TxWrite(rp
, "NETW $");
2397 /************************************************************************/
2398 /********** begin assembler setup of screen characteristics *************/
2399 /************************************************************************/
2402 /* Draw appropriate rectangles */
2448 /************************************************************************/
2449 /*********** end assembler setup of screen characteristics **************/
2450 /************************************************************************/
2454 static void upd_com_line(int com_no
, int units
, int stock_no
, int price
, int autobuy
, int autosell
, char *com_array
,
2455 int *com_char_count
) {
2456 int divisor
, variation
;
2458 int found_first
; /* flag for finding non-zero int */
2462 while((commands
[com_no
][i
- 1] != '\0') && (commands
[com_no
][i
- 1] != ' ')) {
2463 com_array
[i
] = commands
[com_no
][i
- 1];
2466 if((com_no
== QUIT
) || (com_no
== SAVE
)) {
2473 /* put in the number of units, in characters */
2474 if(com_no
!= GRAPH
) {
2476 found_first
= FALSE
;
2478 com_array
[++i
] = '0';
2480 while(divisor
>= 1) {
2481 if((!found_first
) && ((units
/ divisor
) >= 1))
2484 com_array
[++i
] = (int) (units
/ divisor
) + DIFFERENCE
;
2485 units
= units
- (((int) units
/ divisor
) * divisor
);
2487 divisor
= divisor
/ 10;
2491 if((com_no
== DELETE
) || (com_no
== BONDS
) || (com_no
== CASH
) || (com_no
== JUMP
)) {
2492 if(com_no
== JUMP
) {
2493 com_array
[++i
] = ' ';
2494 com_array
[++i
] = 'W';
2495 com_array
[++i
] = 'E';
2496 com_array
[++i
] = 'E';
2497 com_array
[++i
] = 'K';
2498 com_array
[++i
] = 'S';
2500 *com_char_count
= i
;
2503 com_array
[++i
] = ' ';
2506 /* put in the stock name */
2508 if(com_no
!= EXERCISE
) {
2509 for(counter
= 0; stock_array
[stock_no
].name
[counter
] != '\0'; ++counter
)
2510 com_array
[++i
] = stock_array
[stock_no
].name
[counter
];
2513 if((com_no
== GRAPH
) || (com_no
== LIMIT
))
2516 /* put in the word AT */
2518 com_array
[++i
] = ' ';
2519 com_array
[++i
] = 'A';
2520 com_array
[++i
] = 'T';
2521 com_array
[++i
] = ' ';
2523 /* put in the price */
2530 switch (variation
) {
2532 if(price
!= NOT_FOUND
) {
2537 if(autobuy
!= NONE
) {
2538 com_array
[++i
] = '-';
2543 if(autosell
!= NONE
) {
2544 com_array
[++i
] = '+';
2550 if(pr
!= NOT_FOUND
) {
2552 found_first
= FALSE
;
2553 while(divisor
>= 1) {
2554 if((!found_first
) && ((pr
/ divisor
) >= 1))
2557 com_array
[++i
] = (int) (pr
/ divisor
) + DIFFERENCE
;
2558 pr
= pr
- (((int) pr
/ divisor
) * divisor
);
2560 divisor
= divisor
/ 10;
2563 com_array
[++i
] = ' ';
2573 *com_char_count
= i
;
2575 for(counter
= 1; counter
<= i
; counter
++) {
2576 TxWritef(rp
, "%c", com_array
[counter
]);
2578 } /* end procedure up_com_line() */
2581 static void add_auto_exec(int auto_minus
, int auto_plus
, int option
, int opt_price
, int units
, int stockno
, int player
,
2585 count
= players
[player
- 1].auto_count
;
2587 players
[player
- 1].auto_ptr
[count
]->minus_price
= auto_minus
;
2588 players
[player
- 1].auto_ptr
[count
]->plus_price
= auto_plus
;
2589 players
[player
- 1].auto_ptr
[count
]->option_type
= option
;
2590 players
[player
- 1].auto_ptr
[count
]->option_price
= opt_price
;
2591 players
[player
- 1].auto_ptr
[count
]->units
= units
;
2592 players
[player
- 1].auto_ptr
[count
]->stock_no
= stockno
;
2593 players
[player
- 1].auto_ptr
[count
]->cur_price
= stock_array
[stockno
].price
;
2594 players
[player
- 1].auto_ptr
[count
]->pur_price
= pur_price
;
2596 ++players
[player
- 1].auto_count
;
2598 if((cur_player
== &players
[0] + player
- 1) && (scr_status
== AUTOSUP
))
2603 /************************************************************/
2604 /* Rewrites the entire set of auto execs for the cur_player */
2605 /************************************************************/
2607 static void auto_display() {
2610 for(counter
= 0; counter
< cur_player
->auto_count
; ++counter
)
2611 write_auto(counter
);
2616 /************************************************************/
2617 /* Writes out a single auto exec of the current player */
2618 /************************************************************/
2620 static void write_auto(int position
) {
2621 int stockno
, cposition
;
2623 stockno
= cur_player
->auto_ptr
[position
]->stock_no
;
2624 cposition
= position
+ 12;
2625 cursor(cposition
, 1);
2626 TxWritef(rp
, "%3s", stock_array
[stockno
].name
);
2627 cursor(cposition
, 5);
2628 TxWritef(rp
, "%4d", cur_player
->auto_ptr
[position
]->units
);
2630 switch ((int) cur_player
->auto_ptr
[position
]->option_type
) {
2632 cursor(cposition
, 20);
2634 cursor(cposition
, 23);
2635 TxWritef(rp
, "%3d", cur_player
->auto_ptr
[position
]->option_price
);
2636 cursor(cposition
, 10);
2637 TxWritef(rp
, "%9.0f", opt_value(player
, position
));
2640 cursor(cposition
, 20);
2642 cursor(cposition
, 23);
2643 TxWritef(rp
, "%3d", cur_player
->auto_ptr
[position
]->option_price
);
2644 cursor(cposition
, 10);
2645 TxWritef(rp
, "%9.0f", opt_value(player
, position
));
2649 cursor(cposition
, 10);
2650 TxWrite(rp
, "LIMIT ORD");
2654 cursor(cposition
, 27);
2655 TxWritef(rp
, "%3d", cur_player
->auto_ptr
[position
]->cur_price
);
2657 cursor(cposition
, 31);
2658 if(cur_player
->auto_ptr
[position
]->option_type
== AUTOBUY
) {
2659 if(cur_player
->auto_ptr
[position
]->minus_price
!= NONE
) {
2660 TxWritef(rp
, "%3d", cur_player
->auto_ptr
[position
]->minus_price
);
2661 } else if(cur_player
->auto_ptr
[position
]->plus_price
!= NONE
) {
2662 TxWritef(rp
, "%3d", cur_player
->auto_ptr
[position
]->plus_price
);
2667 TxWritef(rp
, "%3s", " - ");
2670 cursor(cposition
, 36);
2671 if(cur_player
->auto_ptr
[position
]->option_type
== AUTOSELL
) {
2672 if(cur_player
->auto_ptr
[position
]->minus_price
!= NONE
) {
2673 TxWritef(rp
, "%3d", cur_player
->auto_ptr
[position
]->minus_price
);
2674 } else if(cur_player
->auto_ptr
[position
]->plus_price
!= NONE
) {
2675 TxWritef(rp
, "%3d", cur_player
->auto_ptr
[position
]->plus_price
);
2678 TxWritef(rp
, "%3s", " - ");
2682 static void clear_auto(int position
) {
2684 cursor(position
, 1);
2686 cursor(position
, 5);
2688 cursor(position
, 10);
2690 cursor(position
, 20);
2692 cursor(position
, 27);
2694 cursor(position
, 31);
2696 cursor(position
, 35);
2698 cursor(24, com_char_count
);
2702 /************************************************************/
2703 /* Updates the current price of a stock in the cur_players */
2704 /* auto exec list and on the screen. */
2705 /************************************************************/
2707 static void upd_autos(int stockno
) {
2711 if(scr_status
!= RANKINGSUP
) {
2712 for(counter
= 0; counter
< cur_player
->auto_count
; ++counter
) {
2713 if((cur_player
->auto_ptr
[counter
]->stock_no
== stockno
) &&
2714 (cur_player
->auto_ptr
[counter
]->cur_price
!= stock_array
[stockno
].price
)) {
2716 cur_player
->auto_ptr
[counter
]->cur_price
= stock_array
[stockno
].price
;
2717 if(scr_status
== AUTOSUP
) {
2718 cursor(12 + counter
, 27);
2719 TxWritef(rp
, "%3d", stock_array
[stockno
].price
);
2720 if((cur_player
->auto_ptr
[counter
]->option_type
!= AUTOBUY
) &&
2721 (cur_player
->auto_ptr
[counter
]->option_type
!= AUTOSELL
)) {
2722 cursor(12 + counter
, 10);
2723 TxWritef(rp
, "%9.0f", opt_value(player
, counter
));
2735 /** Calculates the value of the player's (1 - 4) option in auto ptr ****/
2738 static float opt_value(int player
, int position
) {
2743 ptr
= &players
[0] + player
- 1;
2744 if(ptr
== cur_player
)
2745 stock_price
= ptr
->auto_ptr
[position
]->cur_price
;
2747 stock_price
= stock_array
[ptr
->auto_ptr
[position
]->stock_no
].price
;
2749 DPRINTF("stock price is %d\n",stock_price
);
2751 if(ptr
->auto_ptr
[position
]->option_type
== CALL
)
2752 difference
= (float) (((int) stock_price
) - ((int) ptr
->auto_ptr
[position
]->option_price
));
2754 difference
= (float) (((int) ptr
->auto_ptr
[position
]->option_price
) - ((int) stock_price
));
2756 DPRINTF("difference is %f\n",difference
);
2758 difference
*= (100.0 * ((float) ptr
->auto_ptr
[position
]->units
));
2759 DPRINTF("difference is now %f\n",difference
);
2762 return (difference
);
2767 /****************************************************************************/
2768 /* This deletes the specified auto exec from the specified player. It */
2769 /* updates the screen if appropriate. */
2770 /****************************************************************************/
2772 static void del_auto(int position
, int player
) {
2776 tmp_ptr
= players
[player
- 1].auto_ptr
[position
];
2777 for(counter
= position
; counter
< AUTOLIMIT
- 1; ++counter
) {
2778 players
[player
- 1].auto_ptr
[counter
] = players
[player
- 1].auto_ptr
[counter
+ 1];
2780 players
[player
- 1].auto_ptr
[AUTOLIMIT
- 1] = tmp_ptr
;
2781 --players
[player
- 1].auto_count
;
2782 if((cur_player
== &players
[0] + player
- 1) && (scr_status
== AUTOSUP
)) {
2783 clear_auto(cur_player
->auto_count
);
2789 static void chk_autos(int stockno
) {
2790 int count
, player
, tunits
;
2793 for(player
= 1; player
<= no_of_players
; ++player
) {
2794 ptr
= &players
[0] + player
- 1;
2795 for(count
= 0; count
< ptr
->auto_count
; ++count
) {
2796 tunits
= (int) ptr
->auto_ptr
[count
]->units
;
2797 if((((int) ptr
->auto_ptr
[count
]->stock_no
) == stockno
) &&
2798 (((int) ptr
->auto_ptr
[count
]->option_type
) == AUTOBUY
)) {
2799 if((((int) ptr
->auto_ptr
[count
]->minus_price
) >= stock_array
[stockno
].price
) &&
2800 (((int) ptr
->auto_ptr
[count
]->minus_price
) > 0) &&
2802 round(((float) ptr
->auto_ptr
[count
]->units
) * ((float) stock_array
[stockno
].price
) *
2803 101.5)) && (((int) ptr
->stock_count
) < STOCKLIMIT
)) {
2804 del_auto(count
, player
);
2806 execute(BUY
, tunits
, stockno
, stock_array
[stockno
].price
, NONE
, NONE
, player
);
2807 } else if((((int) ptr
->auto_ptr
[count
]->plus_price
) <= stock_array
[stockno
].price
) &&
2808 (((int) ptr
->auto_ptr
[count
]->plus_price
) > 0) &&
2809 (ptr
->cash
>= round(((float) ptr
->auto_ptr
[count
]->units
) *
2810 ((float) stock_array
[stockno
].price
) * 101.5)) &&
2811 (((int) ptr
->stock_count
) < STOCKLIMIT
))
2813 del_auto(count
, player
);
2815 execute(BUY
, tunits
, stockno
, stock_array
[stockno
].price
, NONE
, NONE
, player
);
2818 /* end if doing an auto_minus */
2819 else if((((int) ptr
->auto_ptr
[count
]->stock_no
) == stockno
) &&
2820 (((int) ptr
->auto_ptr
[count
]->option_type
) == AUTOSELL
)) {
2821 if((((int) ptr
->auto_ptr
[count
]->minus_price
) > 0) &&
2822 (((int) ptr
->auto_ptr
[count
]->minus_price
) >= stock_array
[stockno
].price
)) {
2823 del_auto(count
, player
);
2825 if(tunits
> ((int) ptr
->portfolio
[stockno
].shares
))
2826 tunits
= ((int) ptr
->portfolio
[stockno
].shares
);
2828 execute(SELL
, tunits
, stockno
, stock_array
[stockno
].price
, NONE
, NONE
,
2830 } else if((((int) ptr
->auto_ptr
[count
]->plus_price
) > 0)
2831 && (((int) ptr
->auto_ptr
[count
]->plus_price
) <= stock_array
[stockno
].price
)) {
2832 del_auto(count
, player
);
2834 if(tunits
> ((int) ptr
->portfolio
[stockno
].shares
))
2835 tunits
= ((int) ptr
->portfolio
[stockno
].shares
);
2837 execute(SELL
, tunits
, stockno
, stock_array
[stockno
].price
, NONE
, NONE
,
2842 /** end if doing an AUTOSELL **/
2844 for(count
= 0; count
< NO_OF_STOCKS
; ++count
) {
2845 if((((int) ptr
->portfolio
[count
].limit
) >= stock_array
[count
].price
) &&
2846 (((int) ptr
->portfolio
[count
].shares
) > 0))
2847 execute(SELL
, ((int) ptr
->portfolio
[count
].shares
), count
, stock_array
[stockno
].price
,
2848 NONE
, NONE
, player
);
2854 static void upd_coh() {
2855 if((scr_status
!= RANKINGSUP
) && (scr_status
!= GRAPHUP
)) {
2857 TxWritef(rp
, "%-12.0f", cur_player
->cash
);
2862 static void upd_netw() {
2863 if((scr_status
!= RANKINGSUP
) && (scr_status
!= GRAPHUP
)) {
2865 TxWritef(rp
, "%-12.0f", cur_player
->net_worth
);
2870 static void upd_bonds() {
2871 if(scr_status
!= RANKINGSUP
) {
2873 TxWritef(rp
, "%2d", cur_player
->bonds
);
2878 static const char* getquartername(int q
) {
2879 assert(q
< 5 && q
> 0);
2880 static const char quarters
[4][4] = {"1ST", "2ND", "3RD", "4TH"};
2881 return quarters
[q
-1];
2884 static void upd_quarter() {
2885 int q
= quarter
% 4;
2889 RectFill(rp
, 0,0,FONT_W
*3,FONT_H
);
2891 TxWrite(rp
,getquartername(q
));
2892 TxWrite(rp
, " QUARTER");
2893 cursor(24, com_char_count
);
2896 static void upd_year() {
2899 TxWritef(rp
, "YEAR %d", year
);
2902 TxWritef(rp
, "%4d", year
);
2904 cursor(24, com_char_count
);
2907 static void upd_prime() {
2910 RectFill(rp
,SCREENW
-5*FONT_W
,0,SCREENW
,FONT_H
);
2912 x
= prime_rate
* 100;
2914 TxWritef(rp
, "%5.2f%%", x
);
2915 cursor(24, com_char_count
);
2918 static void write_stock(int line_inc
, int element
) {
2921 stockno
= scr_ptr
[element
]->stock_no
;
2922 cursor(12 + line_inc
, 1);
2923 TxWritef(rp
, "%3s", stock_array
[stockno
].name
);
2924 cursor(12 + line_inc
, 5);
2925 TxWritef(rp
, "%4d", scr_ptr
[element
]->units
);
2926 cursor(12 + line_inc
, 10);
2927 TxWritef(rp
, "%9.0f", ((float) cur_player
->portfolio
[stockno
].shares
) * (stock_array
[stockno
].price
* 100.0));
2928 cursor(12 + line_inc
, 20);
2929 TxWritef(rp
, "%3d", scr_ptr
[element
]->price
);
2930 cursor(12 + line_inc
, 24);
2931 TxWritef(rp
, "%9.0f", round((double) cur_player
->portfolio
[stockno
].margin_debt
));
2932 cursor(12 + line_inc
, 36);
2933 if(cur_player
->portfolio
[stockno
].limit
> 0) {
2934 TxWritef(rp
, "%3d", cur_player
->portfolio
[stockno
].limit
);
2936 TxWritef(rp
, "%3s", " ");
2940 static void clear_stock(int line_inc
) {
2942 cursor(line_inc
, 1);
2943 TxWritef(rp
, "%3s", " ");
2944 cursor(line_inc
, 5);
2945 TxWritef(rp
, "%4s", " ");
2946 cursor(line_inc
, 10);
2947 TxWritef(rp
, "%9s", " ");
2948 cursor(line_inc
, 20);
2949 TxWritef(rp
, "%3s", " ");
2950 cursor(line_inc
, 24);
2951 TxWritef(rp
, "%9s", " ");
2952 cursor(line_inc
, 34);
2953 TxWritef(rp
, "%5s", " ");
2957 static void load_screen() {
2961 for(counter
= 0; counter
< NO_OF_STOCKS
; ++counter
) {
2962 if((cur_player
->portfolio
[counter
].shares
> 0) || (cur_player
->portfolio
[counter
].margin_debt
> 0)) {
2963 scr_ptr
[screen_count
]->stock_no
= ((int) counter
);
2964 scr_ptr
[screen_count
]->price
= ((int) stock_array
[counter
].price
);
2965 scr_ptr
[screen_count
]->margin_debt
= cur_player
->portfolio
[counter
].margin_debt
;
2966 scr_ptr
[screen_count
]->units
= cur_player
->portfolio
[counter
].shares
;
2970 for(counter
= 0; counter
< cur_player
->auto_count
; ++counter
) {
2971 cur_player
->auto_ptr
[counter
]->cur_price
=
2972 ((int) stock_array
[cur_player
->auto_ptr
[counter
]->stock_no
].price
);
2977 /* This procedure loops through all the current players holdings and auto */
2978 /* execs and updates the entire screen of data. */
2980 static void screen_upd(void) {
2982 for(counter
= 0; counter
< screen_count
; ++counter
) {
2983 write_stock(counter
, counter
);
2987 static double calc_netw(int player
) {
2989 double total
, difference
;
2992 if((cur_player
== &players
[0] + player
- 1) && (scr_status
== STOCKSUP
))
2997 for(counter
= 0; counter
< cur_player
->stock_count
; ++counter
) {
2998 total
+= (100.0 * ((float) scr_ptr
[counter
]->units
) * ((float) scr_ptr
[counter
]->price
))
2999 - round((double) scr_ptr
[counter
]->margin_debt
);
3002 for(counter
= 0; counter
< NO_OF_STOCKS
; ++counter
) {
3003 total
+= (100.0 * ((float) players
[player
- 1].portfolio
[counter
].shares
) *
3004 ((float) stock_array
[counter
].price
)) -
3005 players
[player
- 1].portfolio
[counter
].margin_debt
;
3008 for(counter
= 0; counter
< players
[player
- 1].auto_count
; ++counter
) {
3009 if((players
[player
- 1].auto_ptr
[counter
]->option_type
== PUT
) ||
3010 (players
[player
- 1].auto_ptr
[counter
]->option_type
== CALL
))
3012 difference
= opt_value(player
, counter
);
3015 /* if it is an auto transaction instead of an option */
3018 total
+= difference
;
3021 total
+= players
[player
- 1].cash
;
3022 total
+= ((float) players
[player
- 1].bonds
) * 1000.0;
3024 players
[player
- 1].net_worth
= total
;
3028 static void upd_stock(int stockno
) {
3035 if(scr_status
== STOCKSUP
) {
3036 while((scr_ptr
[tally
]->stock_no
!= stockno
) && (tally
< screen_count
)) ++tally
;
3038 /* if the stock is a new acquisition */
3040 if((tally
== screen_count
) && (cur_player
->portfolio
[stockno
].shares
!= 0)) {
3041 scr_ptr
[screen_count
]->stock_no
= stockno
;
3042 scr_ptr
[screen_count
]->units
= cur_player
->portfolio
[stockno
].shares
;
3043 scr_ptr
[screen_count
]->price
= stock_array
[stockno
].price
;
3044 scr_ptr
[screen_count
]->margin_debt
= cur_player
->portfolio
[stockno
].margin_debt
;
3046 write_stock(tally
, screen_count
);
3051 /* if player has sold all shares of the stock */
3053 if((cur_player
->portfolio
[stockno
].shares
== 0) &&
3054 (cur_player
->portfolio
[stockno
].margin_debt
== 0) && (tally
< screen_count
)) {
3057 tmp_ptr
= scr_ptr
[tally
];
3058 for(counter
= tally
; counter
< STOCKLIMIT
- 1; ++counter
) {
3059 scr_ptr
[counter
] = scr_ptr
[counter
+ 1];
3061 scr_ptr
[STOCKLIMIT
- 1] = tmp_ptr
;
3063 for(counter
= tally
; counter
< screen_count
; ++counter
) {
3064 write_stock(counter
, counter
);
3066 clear_stock(screen_count
);
3071 /* if a change in the amount or value of a stock already held occured */
3073 if((cur_player
->portfolio
[stockno
].shares
> 0) || (cur_player
->portfolio
[stockno
].margin_debt
> 0)) {
3074 /* update the players netw according to the current prices */
3076 if(scr_ptr
[tally
]->price
!= stock_array
[stockno
].price
) {
3077 cur_player
->net_worth
+=
3078 (float) (((int) stock_array
[stockno
].price
-
3079 (int) scr_ptr
[tally
]->price
) * 100.0 * ((int) scr_ptr
[tally
]->units
));
3081 scr_ptr
[tally
]->price
= stock_array
[stockno
].price
;
3082 cursor(12 + tally
, 10);
3083 garbage
= (float) (scr_ptr
[tally
]->price
) * (float) (scr_ptr
[tally
]->units
) * 100.0;
3084 TxWritef(rp
, "%9.0f", garbage
);
3085 cursor(12 + tally
, 20);
3086 TxWritef(rp
, "%3d", scr_ptr
[tally
]->price
);
3087 cursor(24, com_char_count
);
3090 if(scr_ptr
[tally
]->units
!= cur_player
->portfolio
[stockno
].shares
) {
3091 scr_ptr
[tally
]->units
= cur_player
->portfolio
[stockno
].shares
;
3092 scr_ptr
[tally
]->margin_debt
= cur_player
->portfolio
[stockno
].margin_debt
;
3093 write_stock(tally
, tally
);
3094 cursor(24, com_char_count
);
3097 if(scr_ptr
[tally
]->margin_debt
!= cur_player
->portfolio
[stockno
].margin_debt
) {
3098 scr_ptr
[tally
]->margin_debt
= cur_player
->portfolio
[stockno
].margin_debt
;
3099 cursor(12 + tally
, 24);
3100 TxWritef(rp
, "%9.0f", round((float) scr_ptr
[tally
]->margin_debt
));
3101 cursor(24, com_char_count
);
3104 if((cur_player
->portfolio
[stockno
].shares
== 0) && (!stop
))
3107 /* end: update a current holding */
3109 } /* end: if rankings aren't up */
3115 int junk_counter
; /* a throwaway counter variable */
3116 int hit
; /* which PLAYER function key was hit */
3118 cur_player
= &players
[0]; /* set current player as player 1 */
3120 ezsdl_init(SU(SCREENW
), SU(SCREENH
));
3122 struct RastPort foo
= {0};
3125 SetRGB4(rp
,0,0,0,0);
3126 SetRGB4(rp
,1,15,15,15);
3127 SetRGB4(rp
,2,15,0,0);
3128 SetRGB4(rp
,3,15,15,0);
3129 SetRGB4(rp
,4,0,15,0);
3130 SetRGB4(rp
,5,0,0,15);
3135 /* puts us in 40x25 color text mode */
3139 /* build the ticker ring and set up the player data, initialize timers */
3143 for(junk_counter
= 0; junk_counter
< NO_OF_STOCKS
; ++junk_counter
) {
3144 players
[0].portfolio
[junk_counter
].purchases
= NULL
;
3145 players
[1].portfolio
[junk_counter
].purchases
= NULL
;
3146 players
[2].portfolio
[junk_counter
].purchases
= NULL
;
3147 players
[3].portfolio
[junk_counter
].purchases
= NULL
;
3150 /* header messages sent then screen cleared */
3158 if(emphasis
== '1') {
3162 if(emphasis
== '2') {
3173 getyear(year
); /** no overlay as of 11/22/85 **/
3175 prime_rate
= (high_prime
+ low_prime
) / 2.0;
3177 /* puts in the news and stock ticker lines, quarter, prime rate, etc. */
3181 /* sets up the player data section, player name, coh, netw, etc. */
3183 set1_bottom_screen();
3186 while((year
!= 1985) && (year
!= 6)) {
3190 if(((ic
= kbhit()) != 0) || ((q_break
== TRUE
) && (jump_weeks
> 0) && (make_call
== FALSE
))) {
3198 if((q_break
== TRUE
) && (jump_weeks
> 0) && (make_call
== FALSE
)) {
3204 if(((scr_status
== RANKINGSUP
) || (scr_status
== GRAPHUP
)) && ((c
< -80) || (c
> -71))) {
3206 if(scr_status
== GRAPHUP
) {
3211 scr_status
= STOCKSUP
;
3213 set1_bottom_screen();
3222 if((c
>= -80) && (c
<= -71)) {
3224 if(scr_status
== GRAPHUP
) {
3225 scr_status
= RANKINGSUP
;
3233 if(timer2
.status
== OFF
)
3234 tmp_player
= 1; /* F1 */
3238 if(timer2
.status
== OFF
)
3239 tmp_player
= 2; /* F1 */
3243 if(timer2
.status
== OFF
)
3244 tmp_player
= 3; /* F3 */
3248 if(timer2
.status
== OFF
)
3249 tmp_player
= 4; /* F4 */
3254 scr_status
= RANKINGSUP
; /* F7 */
3260 scr_status
= RANKINGSUP
; /* F8 */
3268 for(stock
= 0; stock
< (NO_OF_STOCKS
- 1); stock
+= 3) {
3269 cursor(10 + (int) (stock
/ 3), 0);
3270 TxWritef(rp
, " %3s - %3d %3s - %3d %3s - %3d",
3271 stock_array
[alpha
[stock
]].name
,
3272 stock_array
[alpha
[stock
]].price
,
3273 stock_array
[alpha
[stock
+ 1]].name
,
3274 stock_array
[alpha
[stock
+ 1]].price
,
3275 stock_array
[alpha
[stock
+ 2]].name
,
3276 stock_array
[alpha
[stock
+ 2]].price
);
3280 tempstr
[0] = stock_array
[MMMS
].name
[0];
3281 tempstr
[1] = stock_array
[MMMS
].name
[1];
3282 tempstr
[2] = stock_array
[MMMS
].name
[2];
3283 tempstr
[3] = stock_array
[MMMS
].name
[3];
3285 TxWritef(rp
, "%3s - %3d", stock_array
[MMMS
].name
, stock_array
[MMMS
].price
);
3287 scr_status
= RANKINGSUP
; /* F9 */
3295 /* toggle: stop or restart game */
3297 if(timer1
.status
== OFF
) {
3300 /** no overlay as of 11/22/85 **/
3311 if(((hit
!= NOT_FOUND
) && (timer2
.status
== OFF
)) || (hit
== player
)) {
3312 if(((com_char_count
== 0) ||
3313 (player
== hit
) || (timer1
.status
== OFF
)) && (hit
== player
)) {
3317 if(((com_char_count
== 0) ||
3318 (player
== hit
) || (timer1
.status
== OFF
)) && (hit
!= player
)) {
3319 timer2
.status
= OFF
;
3320 change_player(tmp_player
);
3325 timer2
.count
= time_count
+ CHANGEOVERTIME
;
3327 /* if the timer is about to run over the hour we set a flag and then set */
3328 /* the timer beyond the hour change */
3330 if(timer2
.count
>= 3599) {
3331 timer2
.count
-= 3599;
3332 timer2
.hour_changed
= TRUE
;
3340 if(com_char_count
!= 0) {
3342 cursor(24, com_char_count
);
3344 cursor(24, com_char_count
);
3350 (com_array
, &com_char_count
, &com_no
, &units
, &stock_no
, &trans_price
, &autobuy
,
3351 &autosell
) == TRUE
) {
3353 upd_com_line(com_no
, units
, stock_no
, trans_price
, autobuy
, autosell
, com_array
,
3360 com_array
[1+com_char_count
] = 0;
3361 if(com_char_count
== 0) {
3363 timer2
.hour_changed
= FALSE
;
3366 (com_array
, &com_char_count
, &com_no
, &units
, &stock_no
, &trans_price
, &autobuy
,
3367 &autosell
) == TRUE
) {
3369 timer2
.count
= 0; /* timer over */
3370 timer2
.hour_changed
= FALSE
;
3372 execute(com_no
, units
, stock_no
, trans_price
, autobuy
, autosell
, player
);
3380 for(x
= 1; x
<= com_char_count
; ++x
) {
3387 if(c
== CLICK_CHANGE
) {
3388 if(click_on
== TRUE
)
3395 if(com_char_count
== 29) { /* buffer is full */
3401 com_array
[com_char_count
] = c
;
3402 TxWritef(rp
, "%c", c
);
3405 if((isupper(c
)) || (c
== ' ') || (c
== '+') || (c
== '-') || (c
== '*')) {
3407 com_array
[com_char_count
] = c
;
3408 TxWritef(rp
, "%c", c
);
3414 com_array
[com_char_count
] = c
;
3415 TxWritef(rp
, "%c", c
);
3423 /* end if kbhit() */
3424 /********** BEGIN SCREEN SCROLLING STUFF ****************/
3426 if(timer1
.status
== ON
) {
3427 if(newsline
[cur_news_line
] == '\n')
3429 if((half_way
== -2) && (in_progress
== TRUE
)) {
3430 half_way
= load_stock
+ 6;
3431 if(half_way
> (NO_OF_STOCKS
- 1))
3432 half_way
-= NO_OF_STOCKS
;
3444 if(cur_news_line
== -1)
3447 newsch
= newsline
[cur_news_line
++];
3454 if(cur_tick
->item
[tick_position
] == '\0') {
3457 if(time_count
== 3600)
3459 cur_tick
= cur_tick
->next
;
3460 if(in_progress
== TRUE
) {
3461 event(load_stock
, var
);
3462 if(half_way
== load_stock
) {
3473 load_tick_element(cur_tick
->previous
, load_stock
);
3474 chk_autos(load_stock
);
3475 upd_stock(load_stock
);
3476 upd_autos(load_stock
);
3477 cursor(24, com_char_count
);
3478 if(load_stock
!= NO_OF_STOCKS
- 1)
3488 scrollit(cur_tick
->item
[tick_position
]);
3490 if(click_on
== TRUE
)
3494 /************ END SCREEN SCROLLING STUFF ****************/
3500 timer1
.hour_changed
= FALSE
;
3501 timer2
.hour_changed
= FALSE
;
3502 timer3
.hour_changed
= FALSE
;
3505 if((timer3
.status
== OFF
) &&
3506 (!stop
) && (!in_progress
) && ((cur_news_line
== -1) || (newsline
[cur_news_line
] == '\n'))) {
3507 timer3
.count
= time
+ 8 + ((int) round((double) frand() * 3.0));
3508 if(timer3
.count
>= 3599) {
3509 timer3
.count
-= 3599;
3510 timer3
.hour_changed
= TRUE
;
3514 } else if((timer3
.status
== ON
) && (time
> timer3
.count
) && (!in_progress
) && (!timer3
.hour_changed
)) {
3520 k
= ((float) y_mssg_count
- 0.00001);
3523 DPRINTF("%f %f %f %f %d %d\n",j
,k
,l
,m
,messno
,y_mssg_count
);
3525 if(yrly_mssgs
.item
[messno
].used
== FALSE
) {
3527 for(g
= 0; g
< 82; ++g
)
3528 newsline
[g
] = yrly_mssgs
.item
[messno
].string
[g
];
3530 yrly_mssgs
.item
[messno
].used
= TRUE
;
3536 messno
= (int) (frand() * 29.9999);
3539 for(g
= 0; g
< 82; ++g
)
3540 newsline
[g
] = std_mssgs
.item
[messno
].string
[g
];
3546 if(mess_type
== STD
) {
3547 gnp
= std_mssgs
.item
[messno
].gnp
;
3548 pol
= std_mssgs
.item
[messno
].pol
;
3549 intr
= std_mssgs
.item
[messno
].intr
;
3550 var
= std_mssgs
.item
[messno
].var
;
3553 gnp
= yrly_mssgs
.item
[messno
].gnp
;
3554 pol
= yrly_mssgs
.item
[messno
].pol
;
3555 intr
= yrly_mssgs
.item
[messno
].intr
;
3556 var
= yrly_mssgs
.item
[messno
].var
;
3559 instd1
= .2 * q_int_rate
;
3560 instd2
= .02 * q_int_rate
;
3561 instd3
= .04 * q_int_rate
;
3562 instd4
= .3 * q_int_rate
;
3564 x1
= myrandom(instd1
) + gnp
;
3565 x2
= myrandom(instd2
) + pol
;
3566 x3
= myrandom(instd4
) + intr
;
3568 prime_rate
-= intr
/ 2.0;
3569 if(prime_rate
> high_prime
)
3570 prime_rate
= high_prime
;
3571 else if(prime_rate
< low_prime
)
3572 prime_rate
= low_prime
;
3573 q_int_rate
= pow(prime_rate
+ 1.0, 0.25) - 1.0;
3576 the_interest
= ((float) weeks
) * q_int_rate
/ 13.0;
3578 weeks
= ((int) week
) - ((int) event_week
);
3580 weeks
= 52 - ((int) event_week
) + ((int) week
);
3581 event_week
= (int) week
;
3583 loop_to
= load_stock
+ 2;
3584 if(loop_to
> (NO_OF_STOCKS
- 1))
3585 loop_to
-= NO_OF_STOCKS
;
3587 } else if((in_progress
) && (load_stock
== loop_to
)) {
3589 if(in_progress
== TRUE
) {
3590 event(loop_to
- 1, var
);
3592 loop_to
= NO_OF_STOCKS
- 1;
3598 timer3
.status
= OFF
;
3601 if(timer2
.status
== ON
) {
3602 /* if time for changing players has run out then change 'em */
3604 if((time
> timer2
.count
) && (!timer2
.hour_changed
)) {
3605 com_char_count
= 0; /* delete stuff in progress */
3607 change_player(tmp_player
);
3608 timer2
.status
= OFF
;
3612 /* see if it's time to start a new week */
3614 if(timer1
.status
== ON
) {
3617 if((time
> timer1
.count
) && (!timer1
.hour_changed
)) {
3622 for(x
= 0; x
< no_of_players
; ++x
) {
3623 for(y
= 0; y
< NO_OF_STOCKS
; ++y
) {
3624 players
[x
].portfolio
[y
].margin_debt
*= (1.0 + wk_int_rate
);
3628 if(make_call
== TRUE
)
3630 /** no overlay as of 11/22/85 **/
3631 wk_int_rate
= (q_int_rate
/ 13.0) * 1.15;
3632 if(((int) week
) % 13 == 1) {
3634 /** no overlay as of 11/22/85 **/
3636 /** no overlay as of 11/22/85 **/
3637 if(((int) week
) == 53)
3639 /** no overlay as of 11/22/85 **/
3640 if(((((int) quarter
) == 3) || (((int) quarter
) == 1))
3641 && ((year
!= 1985) && (year
!= 6)))
3643 /** no overlay as of 11/22/85 **/
3644 } else if(stop
== TRUE
) {
3645 timer1
.status
= OFF
;
3646 timer2
.status
= OFF
;
3647 timer3
.status
= OFF
;
3649 cursor(24, com_char_count
);
3650 timer1
.count
= time_count
+ WEEKLENGTH
;
3651 if(timer1
.count
>= 3599) {
3652 timer1
.count
-= 3599;
3653 timer1
.hour_changed
= TRUE
;
3657 } else if((timer1
.status
== OFF
) && (!q_break
) && (!stop
)) {
3659 if((timer1
.count
= (time_count
+ WEEKLENGTH
)) > 3599) {
3660 timer1
.count
-= 3599;
3661 timer1
.hour_changed
= TRUE
;
3664 } /* while year != 1985 nor 6 */