Annotation of sbbs/sbbs2/sbj/sbj.c, revision 1.1.1.1

1.1       root        1: /* SBJ.C */
                      2: 
                      3: /* Developed 1990-1997 by Rob Swindell; PO Box 501, Yorba Linda, CA 92885 */
                      4: 
                      5: /************************/
                      6: /* Synchronet Blackjack */
                      7: /************************/
                      8: 
                      9: /*******************************************************/
                     10: /* Multiuser Blackjack game for Synchronet BBS systems */
                     11: /*******************************************************/
                     12: 
                     13: /****************************************************************************/
                     14: /* This source code is completely Public Domain and can be modified and        */
                     15: /* distributed freely (as long as changes are documented).                                     */
                     16: /* It is meant as an example to programmers of how to use the XSDK                     */
                     17: /****************************************************************************/
                     18: 
                     19: /***********/
                     20: /* History */
                     21: /****************************************************************************\
                     22: 
                     23:                Many bugs. Especially multiplayer.
                     24: v1.0
                     25:                Many bugs fixed. Timing problems still exist.
                     26: v1.01
                     27:                Fixed yet more bugs. No more timing problems. Appears bullet-proof.
                     28: v1.02
                     29:                Fixed dealer card up always showing card symbol (even when symbols off).
                     30:                Added ctrl-e answer detection and user notification.
                     31:                Fixed three 7's bug.
                     32:                Raised maximum number of decks to 100 for large multinode systems.
                     33:                Fixed /<CR> bug.
                     34:                Fixed multiple split bug.
                     35:                Fixed non-symbols being sent to other nodes bug.
                     36:                Changed this node's hands to say "You" instead of the user name.
                     37: v1.03
                     38:                Changed the warning and timeout times
                     39: v1.04
                     40:                Fixed symbols being displayed on dealer's hand even when disabled.
                     41:                Made different inactivity warning and timeout values for the main
                     42:                menu and when in play.
                     43: v1.05
                     44:                Fixed invalid (usually negative) card bug. THELP random() doc error.
                     45:                Card now actually contains all the cards minus one.
                     46:                Fixed multinode play join and hang bug.
                     47: v1.06
                     48:                If player gets blackjack and dealer gets 21, player wins. Used to push.
                     49: v1.07
                     50:                Fixed split, then double bug.
                     51: v1.08
                     52:                Replaced bioskey(1) calls with inkey() and used XSDK v2.0 with node
                     53:                intercommunication with users on BBS or in other external programs.
                     54: v2.00
                     55:                Fixed problem with loosing first character of chat lines
                     56:                Added DESQview awareness
                     57: v2.01
                     58:                Replaced all calls to delay() with fdelay()
                     59: v2.02
                     60:                Listing users now displays what external program they're running.
                     61:                Fixed problem with max bet being too small when users have over
                     62:                65mb of credit.
                     63: v2.02
                     64:                XSDK (and consequently SBJ) now supports shrinking Synchronet to run
                     65:                (available in v1b r1).
                     66:                SBBSNODE environment variable will be used for the current node's dir
                     67:                if the node dir is not specified on the command line.
                     68: v2.03
                     69:                XSDK and SBJ now support the new message services of Synchronet
                     70:                (added in v1b r2) for more full-proof internode messaging.
                     71: v2.10
                     72:                New XSDK that supports new file retrieval node status display.
                     73: v2.11
                     74:                Changed getnodemsg to eliminate tiny void where messages could fall.
                     75: 
                     76: 
                     77: \****************************************************************************/
                     78: 
                     79: #include <stdio.h>
                     80: #include <stdlib.h>
                     81: #include <ctype.h>
                     82: 
                     83: #include "xsdk.h"
                     84: 
                     85: #define MAX_DECKS      100
                     86: #define MAX_CARDS      10              /* maximum number of cards per hand */
                     87: #define MAX_HANDS      4               /* maximum number of hands per player */
                     88: 
                     89: #define DEBUG 0
                     90: 
                     91: #define J 11   /* jack */
                     92: #define Q 12   /* queen */
                     93: #define K 13   /* king */
                     94: #define A 14   /* ace */
                     95: 
                     96: #define H 0            /* heart */
                     97: #define D 1    /* diamond */
                     98: #define C 2            /* club */
                     99: #define S 3            /* spade */
                    100:                                                                        /* bits used in misc variable */
                    101: #define INPLAY         (1<<0)                  /* hand in play */
                    102: 
                    103: enum {                                                         /* values for status bytes */
                    104:         BET                                                    /* betting */
                    105:        ,WAIT                                                   /* waiting for turn */
                    106:        ,PLAY                                                   /* playing his hand */
                    107:        ,SYNC_P                                                 /* In sync area - player */
                    108:        ,SYNC_D                                                 /* In sync area - dealer */
                    109:        };
                    110: 
                    111: typedef struct { char value, suit; } card_t;
                    112: 
                    113: card_t newdeck[52]={
                    114:         2,H, 2,D, 2,C, 2,S,
                    115:         3,H, 3,D, 3,C, 3,S,
                    116:         4,H, 4,D, 4,C, 4,S,
                    117:         5,H, 5,D, 5,C, 5,S,
                    118:         6,H, 6,D, 6,C, 6,S,
                    119:         7,H, 7,D, 7,C, 7,S,
                    120:         8,H, 8,D, 8,C, 8,S,
                    121:         9,H, 9,D, 9,C, 9,S,
                    122:        10,H,10,D,10,C,10,S,
                    123:         J,H, J,D, J,C, J,S,
                    124:         Q,H, Q,D, Q,C, Q,S,
                    125:         K,H, K,D, K,C, K,S,
                    126:         A,H, A,D, A,C, A,S };
                    127: 
                    128: uchar  misc;
                    129: uchar  curplayer;
                    130: uchar  total_decks,sys_decks;
                    131: uchar  total_nodes;
                    132: int    cur_card;
                    133: uchar  dc;
                    134: card_t dealer[MAX_CARDS];
                    135: int    gamedab;                                         /* file handle for data file */
                    136: card_t card[MAX_DECKS*52];
                    137: card_t player[MAX_HANDS][MAX_CARDS];
                    138: char   hands,pc[MAX_HANDS];
                    139: uchar  total_players;
                    140: uchar  symbols=1;
                    141: char   autoplay=0;
                    142: int    logit=0,tutor=0;
                    143: uint   node[MAX_NODES];   /* the usernumber in each node */
                    144: char   status[MAX_NODES];
                    145: ulong  credits;
                    146: uint   bet[MAX_HANDS],ibet,min_bet,max_bet;
                    147: char   tmp[81];
                    148: char   *UserSays="\1n\1m\1h%s \1n\1msays \"\1c\1h%s\1n\1m\"\r\n";
                    149: char   *UserWhispers="\1n\1m\1h%s \1n\1mwhispers \"\1c\1h%s\1n\1m\"\r\n";
                    150: char   *ShoeStatus="\r\n\1_\1w\1hShoe: %u/%u\r\n";
                    151: 
                    152: #ifndef SBJCLEAN
                    153: 
                    154: void play(void);
                    155: char *cardstr(card_t card);
                    156: char hand(card_t card[MAX_CARDS], char count);
                    157: char soft(card_t card[MAX_CARDS], char count);
                    158: char pair(card_t card[MAX_CARDS], char count);
                    159: void getgamedat(char lockit);
                    160: void putgamedat(void);
                    161: void getcarddat(void);
                    162: void putcarddat(void);
                    163: void shuffle(void);
                    164: void waitturn(void);
                    165: void nextplayer(void);
                    166: char lastplayer(void);
                    167: char firstplayer(void);
                    168: void getnodemsg(void);
                    169: void putnodemsg(char *msg,char nodenumber);
                    170: void putallnodemsg(char *msg);
                    171: void syncplayer(void);
                    172: void syncdealer(void);
                    173: void moduserdat(void);
                    174: char *hit(void);
                    175: char *stand(void);
                    176: char *doubit(void);
                    177: char *split(void);
                    178: void open_gamedab(void);
                    179: void create_gamedab(void);
                    180: char *activity(char status_type);
                    181: void chat(void);
                    182: void listplayers(void);
                    183: char *joined(void);
                    184: char *left(void);
                    185: void strip_symbols(char *str);
                    186: void debug(void);
                    187: 
                    188: /****************************************************************************/
                    189: /* Entry point                                                                                                                         */
                    190: /****************************************************************************/
                    191: int main(int argc, char **argv)
                    192: {
                    193:        char str[81],ch,*p;
                    194:        int i,file;
                    195:        FILE *stream;
                    196: 
                    197: node_dir[0]=0;
                    198: for(i=1;i<argc;i++)
                    199:        if(!stricmp(argv[i],"/L"))
                    200:                logit=1;
                    201:        else if(!stricmp(argv[i],"/T"))
                    202:                tutor=2;
                    203:        else if(!stricmp(argv[i],"/S"))
                    204:                tutor=1;
                    205:        else strcpy(node_dir,argv[i]);
                    206: 
                    207: p=getenv("SBBSNODE");
                    208: if(!node_dir[0] && p)
                    209:        strcpy(node_dir,p);
                    210: 
                    211: if(!node_dir[0]) {       /* node directory not specified */
                    212:        bputs("usage: sbj <node directory> [/options]\r\n");
                    213:        bputs("\r\noptions: L = log wins/losses for each day\r\n");
                    214:        getch();
                    215:        return(1); }
                    216: 
                    217: if(node_dir[strlen(node_dir)-1]!='\\')  /* make sure node_dir ends in '\' */
                    218:        strcat(node_dir,"\\");
                    219: 
                    220: initdata();                                                            /* read XTRN.DAT and more */
                    221: credits=user_cdt;
                    222: total_nodes=sys_nodes;
                    223: 
                    224: remove("DEBUG.LOG");
                    225: 
                    226: if((file=nopen("SBJ.CFG",O_RDONLY))==-1) {  /* open config file */
                    227:        bputs("Error opening SBJ.CFG\r\n");
                    228:        pause();
                    229:        return(1); }
                    230: if((stream=fdopen(file,"rb"))==NULL) {      /* convert to stream */
                    231:        bputs("Error converting SBJ.CFG handle to stream\r\n");
                    232:        pause();
                    233:        return(1); }
                    234: fgets(str,81,stream);                                          /* number of decks in shoe */
                    235: total_decks=sys_decks=atoi(str);
                    236: fgets(str,81,stream);                                          /* min bet (in k) */
                    237: min_bet=atoi(str);
                    238: fgets(str,81,stream);                                          /* max bet (in k) */
                    239: max_bet=atoi(str);
                    240: fgets(str,81,stream);                                          /* default bet (in k) */
                    241: ibet=atoi(str);
                    242: fclose(stream);
                    243: if(!total_decks || total_decks>MAX_DECKS) {
                    244:        bputs("Invalid number of decks in SBJ.CFG\r\n");
                    245:        pause();
                    246:        return(1); }
                    247: if(!max_bet) {
                    248:        bputs("Invalid max bet in SBJ.CFG\r\n");
                    249:        pause();
                    250:        return(1); }
                    251: if(min_bet>max_bet) {
                    252:        bputs("Invalid min bet in SBJ.CFG\r\n");
                    253:        pause();
                    254:     return(1); }
                    255: if(ibet>max_bet || ibet<min_bet) {
                    256:        bputs("Invalid default bet in SBJ.CFG\r\n");
                    257:        pause();
                    258:     return(1); }
                    259: 
                    260: if(!fexist("CARD.DAB")) {
                    261:        cur_card=0;
                    262:        dc=0;
                    263:        memset(dealer,0,sizeof(dealer));
                    264:        memset(card,0,sizeof(card));
                    265:        putcarddat(); }
                    266: else {
                    267:        getcarddat();
                    268:        if(total_decks!=sys_decks) {
                    269:                remove("CARD.DAB");
                    270:                total_decks=sys_decks;
                    271:                putcarddat(); } }
                    272: 
                    273: if(!fexist("GAME.DAB"))         /* File's not there */
                    274:        create_gamedab();
                    275: 
                    276: open_gamedab();
                    277: 
                    278: getgamedat(0);
                    279: if(total_nodes!=sys_nodes) {  /* total nodes changed */
                    280:        close(gamedab);
                    281:        total_nodes=sys_nodes;
                    282:        create_gamedab();
                    283:        open_gamedab(); }
                    284: 
                    285: randomize();
                    286: 
                    287: while(_bios_keybrd(1))  /* clear input buffer */
                    288:        _bios_keybrd(0);
                    289: putchar(5); /* ctrl-e */
                    290: mswait(500);
                    291: if(_bios_keybrd(1)) {
                    292:        while(_bios_keybrd(1))
                    293:                _bios_keybrd(0);
                    294:        bputs("\r\n\1r\1h\1i*** ATTENTION ***\1n\1h\r\n");
                    295:        bputs("\r\nSynchronet Blackjack uses Ctrl-E (ENQ) for the 'club' card "
                    296:                "symbol.");
                    297:        bputs("\r\nYour terminal responded to this control character with an "
                    298:                "answerback string.");
                    299:        bputs("\r\nYou will need to disable all Ctrl-E (ENQ) answerback "
                    300:                "strings (Including \r\nCompuserve Quick B transfers) if you wish to "
                    301:                "toggle card symbols on.\r\n\r\n");
                    302:        symbols=0;
                    303:        pause(); }
                    304: 
                    305: cls();
                    306: bputs("\1n \1h\1cSynchronet\r\n");
                    307: bputs("\1n\0011\1k Blackjack! \r\n");
                    308: bputs("\1n\1r\1h   v2.33\r\n");
                    309: bprintf("\1n\1r(XSDK v%s)\r\n",xsdk_ver);
                    310: 
                    311: getgamedat(1);
                    312: node[node_num-1]=0;
                    313: putgamedat();
                    314: 
                    315: sec_warn=120;  /* Override default inactivity timeout values */
                    316: sec_timeout=180;
                    317: 
                    318: while(1) {
                    319:        aborted=0;
                    320:        mnemonics("\r\n~Instructions\r\n");
                    321:        mnemonics("~Join Game\r\n");
                    322:        mnemonics("~List Players\r\n");
                    323:        mnemonics("~Rules of the Game\r\n");
                    324:        mnemonics("~Toggle Card Symbols\r\n");
                    325:        sprintf(str,"~Quit to %s\r\n",sys_name);
                    326:        mnemonics(str);
                    327:        nodesync();
                    328:        bprintf("\1_\r\n\1y\1hWhich: \1n");
                    329:        switch(getkeys("IJLRTQ|!",0)) {
                    330:                #if DEBUG
                    331:                case '!':
                    332:                        if(!com_port)
                    333:                                autoplay=1;
                    334:                        break;
                    335:                case '|':
                    336:                        debug();
                    337:                        break;
                    338:                #endif
                    339:                case 'I':
                    340:                        printfile("SBJ.MSG");
                    341:                        break;
                    342:                case 'L':
                    343:                        listplayers();
                    344:                        bprintf(ShoeStatus,cur_card,total_decks*52);
                    345:                        break;
                    346:                case 'R':
                    347:                        bprintf("\1n\1c\r\nMinimum bet: \1h%uk",min_bet);
                    348:                        bprintf("\1n\1c\r\nMaximum bet: \1h%uk\r\n",max_bet);
                    349:                        bprintf("\1w\1h\r\nCard decks in shoe: \1h%u\r\n",sys_decks);
                    350:                        break;
                    351:                case 'T':
                    352:                        symbols=!symbols;
                    353:                        bprintf("\1_\1w\r\nCard symbols now: %s\r\n",symbols ? "ON":"OFF");
                    354:                        break;
                    355:                case 'Q':
                    356:                        exit(0);
                    357:                case 'J':
                    358:                        sec_warn=60;    /* Override default inactivity timeout values */
                    359:                        sec_timeout=90;
                    360:                        play();
                    361:                        sec_warn=120;
                    362:                        sec_timeout=180;
                    363:                        break; } }
                    364: }
                    365: 
                    366: #if DEBUG
                    367: void debug()
                    368: {
                    369:        int i;
                    370: 
                    371: if(user_level<90)
                    372:        return;
                    373: getgamedat(0);
                    374: getcarddat();
                    375: 
                    376: bprintf("\r\nDeck (%d) Current: %d\r\n\r\n",total_decks,cur_card);
                    377: for(i=0;i<total_decks*52;i++) {
                    378:        if(!(i%11))
                    379:                bputs("\r\n");
                    380:        bprintf("%3d:%-11s",i,cardstr(card[i])); }
                    381: 
                    382: pause();
                    383: bprintf("\1n\r\nDealer (%d)\r\n\r\n",dc);
                    384: for(i=0;i<dc;i++)
                    385:        bprintf("%s ",cardstr(dealer[i]));
                    386: bprintf("\1n\r\nNodes (%d) Current: %d\r\n\r\n"
                    387:        ,total_nodes,curplayer);
                    388: for(i=0;i<total_nodes;i++)
                    389:        bprintf("%d: node=%d status=%d %s\r\n",i+1,node[i]
                    390:                ,status[i],activity(status[i]));
                    391: }
                    392: 
                    393: void debugline(char *line)
                    394: {
                    395:        char str[256];
                    396:        int file;
                    397:        time_t now;
                    398:        struct dosdate_t date;
                    399:        struct dostime_t curtime;
                    400: 
                    401: #if 1
                    402: now=time(NULL);
                    403: unixtodos(now,&date,&curtime);
                    404: if((file=nopen("DEBUG.LOG",O_WRONLY|O_APPEND|O_CREAT))==-1)
                    405:        return;
                    406: sprintf(str,"%d %02u:%02u:%02u %s\r\n"
                    407:        ,node_num,curtime.ti_hour,curtime.ti_min,curtime.ti_sec,line);
                    408: write(file,str,strlen(str));
                    409: close(file);
                    410: #endif
                    411: }
                    412: 
                    413: #endif
                    414: 
                    415: void suggest(char action)
                    416: {
                    417: bputs("Dealer suggests you ");
                    418: switch(action) {
                    419:        case 'H':
                    420:                bputs("hit");
                    421:                break;
                    422:        case 'S':
                    423:                bputs("stand");
                    424:                break;
                    425:        case 'D':
                    426:                bputs("double");
                    427:                break;
                    428:        case 'P':
                    429:                bputs("split");
                    430:                break; }
                    431: bputs("\r\n");
                    432: }
                    433: 
                    434: void wrong(char action)
                    435: {
                    436: sound(100);
                    437: mswait(500);
                    438: nosound();
                    439: bputs("Dealer says you should have ");
                    440: switch(action) {
                    441:        case 'H':
                    442:                bputs("hit");
                    443:                break;
                    444:        case 'S':
                    445:                bputs("stood");
                    446:                break;
                    447:        case 'D':
                    448:                bputs("doubled");
                    449:                break;
                    450:        case 'P':
                    451:                bputs("split");
                    452:                break; }
                    453: bputs("\r\n");
                    454: }
                    455: 
                    456: /****************************************************************************/
                    457: /* This function is the actual game playing loop.                                                      */
                    458: /****************************************************************************/
                    459: void play()
                    460: {
                    461:        char str[256],str2[256],log[81],done,doub,dh,split_card,suggestion
                    462:                ,*YouWereDealt="\1n\1k\0015 You \1n\1m were dealt: %s\r\n"
                    463:                ,*UserWasDealt="\1n\1m\1h%s\1n\1m was dealt: %s\r\n"
                    464:                ,*YourHand="\1n\1k\0015 You \1n\1m                     (%2d) %s"
                    465:                ,*UserHand="\1n\1m\1h%-25s \1n\1m(%2d) %s"
                    466:                ,*DealerHand="\1n\1hDealer                    \1n\1m(%2d) "
                    467:                ,*Bust="\1n\1r\1hBust\1n\r\n"
                    468:                ,*Natural="\1g\1h\1iNatural "
                    469:                ,*Three7s="\1r\1h\1iThree 7's "
                    470:                ,*Blackjack="\1n\0011\1k Blackjack! \1n\r\n"
                    471:                ,*TwentyOne="\1n\0012\1k Twenty-one \1n\r\n";
                    472:        int h,i,j,file;
                    473:        uint max;
                    474:        long val;
                    475:        time_t start,now;
                    476:        struct dosdate_t date;
                    477: 
                    478: sprintf(str,"MESSAGE.%d",node_num);         /* remove message if waiting */
                    479: if(fexist(str))
                    480:     remove(str);
                    481: 
                    482: getgamedat(0);
                    483: if(node[node_num-1]) {
                    484:        getgamedat(1);
                    485:        node[node_num-1]=0;
                    486:        putgamedat();
                    487:        getgamedat(0); }
                    488: 
                    489: if(total_players && misc&INPLAY) {
                    490:        bputs("\r\n\1hWaiting for end of hand (^A to abort)...\1n");
                    491:        start=now=time(NULL);
                    492:        getgamedat(0);
                    493:        while(total_players && misc&INPLAY) {
                    494:                if((i=inkey(0))!=0) {    /* if key was hit */
                    495:                        if(i==1) {               /* if ctrl-a */
                    496:                                bputs("\r\n");
                    497:                                return; } }  /* return */
                    498:                mswait(100);
                    499:                getgamedat(0);
                    500:                now=time(NULL);
                    501:                if(now-start>300) { /* only wait up to 5 minutes */
                    502:                        bputs("\r\ntimeout\r\n");
                    503:                        return; } }
                    504:        bputs("\r\n"); }
                    505: 
                    506: getgamedat(1);
                    507: node[node_num-1]=user_number;
                    508: putgamedat();
                    509: 
                    510: if(!total_players)
                    511:     shuffle();
                    512: else
                    513:        listplayers();
                    514: 
                    515: sprintf(str,"\1n\1m\1h%s \1n\1m%s\r\n",user_name,joined());
                    516: putallnodemsg(str);
                    517: 
                    518: while(1) {
                    519:        aborted=0;
                    520:        #if DEBUG
                    521:        debugline("top of loop");
                    522:        #endif
                    523:        if(autoplay)
                    524:                lncntr=0;
                    525:        bprintf(ShoeStatus,cur_card,total_decks*52);
                    526:        if(cur_card>(total_decks*52)-(total_players*10)-10 && lastplayer())
                    527:                shuffle();
                    528:        getgamedat(1);
                    529:        misc&=~INPLAY;
                    530:        status[node_num-1]=BET;
                    531:        node[node_num-1]=user_number;
                    532:        putgamedat();
                    533: 
                    534:        bprintf("\r\n\1n\1cYou have \1h%s\1n\1ck credits\r\n"
                    535:                ,ultoac(credits/1024L,str));
                    536:        if(credits<min_bet/1024) {
                    537:                bprintf("\1n\1cMinimum bet: \1h%uk\r\n",min_bet);
                    538:                bputs("\1n\1r\1hCome back when you have more credits.\r\n");
                    539:         break; }
                    540:        if(credits/1024L>(ulong)max_bet)
                    541:                max=max_bet;
                    542:        else
                    543:                max=credits/1024L;
                    544:        sprintf(str,"\r\nBet amount (in kilobytes) or ~Quit [%u]: "
                    545:                ,ibet<credits/1024L ? ibet : credits/1024L);
                    546:        chat();
                    547:        mnemonics(str);
                    548:        if(autoplay && _bios_keybrd(1))
                    549:                autoplay=0;
                    550:        if(autoplay)
                    551:                i=ibet;
                    552:        else
                    553:                i=getnum(max);
                    554:        if(i==-1)       /* if user hit ^C or 'Q' */
                    555:                break;
                    556:        bputs("\r\n");
                    557:        if(i)           /* if user entered a value */
                    558:                bet[0]=i;
                    559:        else            /* if user hit enter */
                    560:                bet[0]=ibet<credits/1024L ? ibet : credits/1024L;
                    561:        if(bet[0]<min_bet) {
                    562:                bprintf("\1n\1cMinimum bet: \1h%uk\r\n",min_bet);
                    563:                bputs("\1n\1r\1hCome back when you're ready to bet more.\r\n");
                    564:                break; }
                    565:        ibet=bet[0];
                    566:        getgamedat(0);  /* to get all new arrivals */
                    567:        sprintf(str,"\1m\1h%s\1n\1m bet \1n\1h%u\1n\1mk\r\n",user_name,bet[0]);
                    568:        putallnodemsg(str);
                    569: 
                    570:        pc[0]=2;                                                /* init player's 1st hand to 2 cards */
                    571:        for(i=1;i<MAX_HANDS;i++)                /* init player's other hands to 0 cards */
                    572:                pc[i]=0;
                    573:        hands=1;                                                /* init total player's hands to 1 */
                    574: 
                    575:        getgamedat(1);                                  /* first come first serve to be the */
                    576:        for(i=0;i<total_nodes;i++)              /* dealer in control of sync */
                    577:                if(node[i] && status[i]==SYNC_D)
                    578:                        break;
                    579:        if(i==total_nodes) {
                    580:                #if DEBUG
                    581:                debugline("syncdealer");
                    582:                #endif
                    583:                syncdealer();  }                        /* all players meet here */
                    584:        else {                                                  /* first player is current after here */
                    585:                #if DEBUG
                    586:                debugline("syncplayer");
                    587:                #endif
                    588:                syncplayer(); }                         /* game is closed (INPLAY) at this point */
                    589: 
                    590:        #if DEBUG
                    591:        debugline("waitturn 1");
                    592:        #endif
                    593:     waitturn();
                    594:        getnodemsg();
                    595:                                                                                /* Initial deal card #1 */
                    596:        getcarddat();
                    597:        player[0][0]=card[cur_card++];
                    598:        putcarddat();
                    599:        sprintf(str,YouWereDealt,cardstr(card[cur_card-1]));
                    600:        if(!symbols)
                    601:                strip_symbols(str);
                    602:     bputs(str);
                    603:        sprintf(str,UserWasDealt,user_name,cardstr(card[cur_card-1]));
                    604:     putallnodemsg(str);
                    605:        
                    606:        if(lastplayer()) {
                    607:                getcarddat();
                    608:                dealer[0]=card[cur_card++];
                    609:                dc=1;
                    610:                putcarddat(); }
                    611:        nextplayer();
                    612:        #if DEBUG
                    613:        debugline("waitturn 2");
                    614:        #endif
                    615:        waitturn();
                    616:        getnodemsg();
                    617: 
                    618:        getcarddat();                                      /* Initial deal card #2 */
                    619:        player[0][1]=card[cur_card++];
                    620:        putcarddat();
                    621:        sprintf(str,YouWereDealt,cardstr(card[cur_card-1]));
                    622:        if(!symbols)
                    623:                strip_symbols(str);
                    624:        bputs(str);
                    625:        sprintf(str,UserWasDealt,user_name,cardstr(card[cur_card-1]));
                    626:     putallnodemsg(str);
                    627:        
                    628:        if(lastplayer()) {
                    629:                getcarddat();
                    630:                dealer[1]=card[cur_card++];
                    631:                dc=2;
                    632:                putcarddat(); }
                    633:        nextplayer();
                    634:        #if DEBUG
                    635:        debugline("waitturn 3");
                    636:        #endif
                    637:        waitturn();
                    638:        getnodemsg();
                    639:        getcarddat();
                    640: 
                    641:        for(i=0;i<hands;i++) {
                    642:                if(autoplay)
                    643:                        lncntr=0;
                    644:                done=doub=0;
                    645:                while(!done && pc[i]<MAX_CARDS && cur_card<total_decks*52) {
                    646:                        h=hand(player[i],pc[i]);
                    647:                        str[0]=0;
                    648:                        for(j=0;j<pc[i];j++) {
                    649:                                strcat(str,cardstr(player[i][j]));
                    650:                                strcat(str," "); }
                    651:                        j=bstrlen(str);
                    652:                        while(j++<19)
                    653:                                strcat(str," ");
                    654:                        if(h>21) {
                    655:                                strcat(str,Bust);
                    656:                                sprintf(str2,YourHand,h,str);
                    657:                                if(!symbols)
                    658:                                        strip_symbols(str2);
                    659:                                bputs(str2);
                    660:                                sprintf(str2,UserHand,user_name,h,str);
                    661:                                putallnodemsg(str2);
                    662:                                break; }
                    663:                        if(h==21) {
                    664:                                if(pc[i]==2) {  /* blackjack */
                    665:                                        if(player[i][0].suit==player[i][1].suit)
                    666:                                                strcat(str,Natural);
                    667:                                        strcat(str,Blackjack); }
                    668:                                else {
                    669:                                        if(player[i][0].value==7
                    670:                                                && player[i][1].value==7
                    671:                                                && player[i][2].value==7)
                    672:                                                strcat(str,Three7s);
                    673:                                        strcat(str,TwentyOne); }
                    674:                                sprintf(str2,YourHand,h,str);
                    675:                                if(!symbols)
                    676:                                        strip_symbols(str2);
                    677:                                bputs(str2);
                    678:                                sprintf(str2,UserHand,user_name,h,str);
                    679:                 putallnodemsg(str2);
                    680:                                // fdelay(500);
                    681:                                break; }
                    682:                        strcat(str,"\r\n");
                    683:                        sprintf(str2,YourHand,h,str);
                    684:                        if(!symbols)
                    685:                                strip_symbols(str2);
                    686:                        bputs(str2);
                    687:                        sprintf(str2,UserHand,user_name,h,str);
                    688:                        putallnodemsg(str2);
                    689:                        if(doub)
                    690:                                break;
                    691:                        sprintf(str,"\1n\1hDealer\1n\1m card up: %s\r\n"
                    692:                                ,cardstr(dealer[1]));
                    693:                        if(!symbols)
                    694:                                strip_symbols(str);
                    695:                        bputs(str);
                    696: 
                    697:                        if(tutor) {
                    698:                                if(pc[i]==2)
                    699:                                        split_card=pair(player[i],pc[i]);
                    700:                                else
                    701:                                        split_card=0;
                    702:                 if(split_card==A
                    703:                                        || (split_card==9 && (dealer[1].value<7
                    704:                                                || (dealer[1].value>7 && dealer[1].value<10)))
                    705:                     || split_card==8
                    706:                                        || (split_card==7 && dealer[1].value<9)
                    707:                                        || (split_card==6 && dealer[1].value<7)
                    708:                                        || (split_card==4 && dealer[1].value==5)
                    709:                                        || (split_card && split_card<4 && dealer[1].value<8))
                    710:                                        suggestion='P';
                    711:                 else if(soft(player[i],pc[i])) {
                    712:                     if(h>18)
                    713:                                                suggestion='S';
                    714:                                        else if(pc[i]==2
                    715:                                                && ((h==18
                    716:                                                        && dealer[1].value>3 && dealer[1].value<7)
                    717:                         || (h==17
                    718:                                                        && dealer[1].value>2 && dealer[1].value<7)
                    719:                         || (h>13
                    720:                                                        && dealer[1].value>3 && dealer[1].value<7)
                    721:                         || (h==12
                    722:                                                        && dealer[1].value>4 && dealer[1].value<7)))
                    723:                                                suggestion='D';
                    724:                     else
                    725:                                                suggestion='H'; }
                    726:                 else { /* hard */
                    727:                                        if(h>16 || (h>13 && dealer[1].value<7)
                    728:                                                || (h==12 && dealer[1].value>3 && dealer[1].value<7))
                    729:                                                suggestion='S';
                    730:                                        else if(pc[i]==2
                    731:                                                && (h==11 || (h==10 && dealer[1].value<10)
                    732:                                                || (h==9 && dealer[1].value<7)))
                    733:                                                suggestion='D';
                    734:                     else
                    735:                                                suggestion='H'; } }
                    736: 
                    737:                        if(tutor==1)
                    738:                                suggest(suggestion);
                    739:                        strcpy(str,"\r\n~Hit");
                    740:                        strcpy(tmp,"H\r");
                    741:                        if(bet[i]+ibet<=credits/1024L && pc[i]==2) {
                    742:                                strcat(str,", ~Double");
                    743:                                strcat(tmp,"D"); }
                    744:                        if(bet[i]+ibet<=credits/1024L && pc[i]==2 && hands<MAX_HANDS
                    745:                                && player[i][0].value==player[i][1].value) {
                    746:                                strcat(str,", ~Split");
                    747:                                strcat(tmp,"S"); }
                    748:                        strcat(str,", or [Stand]: ");
                    749:                        chat();
                    750:                        mnemonics(str);
                    751:                        if(autoplay && _bios_keybrd(1))
                    752:                                autoplay=0;
                    753: 
                    754: 
                    755:                        if(autoplay) {
                    756:                                lncntr=0;
                    757:                                bputs("\r\n");
                    758:                                strcpy(str,stand());
                    759:                                bputs(str);
                    760:                                putallnodemsg(str);
                    761:                                done=1; }
                    762:                        else
                    763:                        switch(getkeys(tmp,0)) {
                    764:                                case 'H':     /* hit */
                    765:                                        if(tutor==2 && suggestion!='H')
                    766:                                                wrong(suggestion);
                    767:                                        strcpy(str,hit());
                    768:                                        bputs(str);
                    769:                                        putallnodemsg(str);
                    770:                                        getcarddat();
                    771:                                        player[i][pc[i]++]=card[cur_card++];
                    772:                                        putcarddat();
                    773:                                        break;
                    774:                                case 'D':   /* double down */
                    775:                                        if(tutor==2 && suggestion!='D')
                    776:                         wrong(suggestion);
                    777:                                        strcpy(str,doubit());
                    778:                                        bputs(str);
                    779:                                        putallnodemsg(str);
                    780:                                        getcarddat();
                    781:                                        player[i][pc[i]++]=card[cur_card++];
                    782:                                        putcarddat();
                    783:                                        doub=1;
                    784:                                        bet[i]+=ibet;
                    785:                                        break;
                    786:                                case 'S':   /* split */
                    787:                                        if(tutor==2 && suggestion!='P')
                    788:                         wrong(suggestion);
                    789:                                        strcpy(str,split());
                    790:                                        bputs(str);
                    791:                                        putallnodemsg(str);
                    792:                                        player[hands][0]=player[i][1];
                    793:                                        getcarddat();
                    794:                                        player[i][1]=card[cur_card++];
                    795:                                        player[hands][1]=card[cur_card++];
                    796:                                        putcarddat();
                    797:                                        pc[hands]=2;
                    798:                                        bet[hands]=ibet;
                    799:                                        hands++;
                    800:                                        break;
                    801:                                case CR:
                    802:                                        if(tutor==2 && suggestion!='S')
                    803:                         wrong(suggestion);
                    804:                                        strcpy(str,stand());
                    805:                                        bputs(str);
                    806:                                        putallnodemsg(str);
                    807:                                        done=1;
                    808:                                        break; } } }
                    809: 
                    810:        if(lastplayer()) {      /* last player plays the dealer's hand */
                    811:                getcarddat();
                    812:                while(hand(dealer,dc)<17 && dc<MAX_CARDS && cur_card<total_decks*52)
                    813:                        dealer[dc++]=card[cur_card++];
                    814:                putcarddat(); }
                    815: 
                    816:        nextplayer();
                    817:        #if DEBUG
                    818:        debugline("waitturn 4");
                    819:        #endif
                    820:        waitturn();
                    821:        getnodemsg();
                    822: 
                    823:        if(firstplayer()==node_num) {
                    824:                strcpy(str,"\1n\0014\1h Final \1n\r\n");
                    825:                bputs(str);
                    826:                putallnodemsg(str); }
                    827:        getcarddat();
                    828:        dh=hand(dealer,dc);                                     /* display dealer's hand */
                    829:        sprintf(str,DealerHand,dh);
                    830:        for(i=0;i<dc;i++) {
                    831:                strcat(str,cardstr(dealer[i]));
                    832:                strcat(str," "); }
                    833:        i=bstrlen(str);
                    834:        while(i++<50)                           /* was 50 */
                    835:                strcat(str," ");
                    836:        if(dh>21) {
                    837:                strcat(str,Bust);
                    838:                if(!symbols)
                    839:                        strip_symbols(str);
                    840:                bputs(str); }
                    841:        else if(dh==21) {
                    842:                if(dc==2) {     /* blackjack */
                    843:                        if(dealer[0].suit==dealer[1].suit)
                    844:                                strcat(str,Natural);
                    845:                        strcat(str,Blackjack); }
                    846:                else {                  /* twenty-one */
                    847:                        if(dc==3 && dealer[0].value==7 && dealer[1].value==7
                    848:                                && dealer[2].value==7)
                    849:                                strcat(str,Three7s);
                    850:                        strcat(str,TwentyOne); }
                    851:                if(!symbols)
                    852:             strip_symbols(str);
                    853:                bputs(str); }
                    854:        else {
                    855:                if(!symbols)
                    856:             strip_symbols(str);
                    857:                bprintf("%s\r\n",str); }
                    858: 
                    859:        for(i=0;i<hands;i++) {                                          /* display player's hand(s) */
                    860:                h=hand(player[i],pc[i]);
                    861:                str[0]=0;
                    862:                for(j=0;j<pc[i];j++) {
                    863:                        strcat(str,cardstr(player[i][j]));
                    864:                        strcat(str," "); }
                    865:                j=bstrlen(str);
                    866:                while(j++<19)
                    867:                        strcat(str," ");
                    868:                if(logit) {
                    869:                        _dos_getdate(&date);
                    870:                        sprintf(log,"%02d%02d%02d.LOG"                  /* log winnings */
                    871:                                ,date.month,date.day,date.year-1900);
                    872:                        if((file=nopen(log,O_RDONLY))!=-1) {
                    873:                                read(file,tmp,filelength(file));
                    874:                                tmp[filelength(file)]=0;
                    875:                                val=atol(tmp);
                    876:                                close(file); }
                    877:                        else
                    878:                                val=0L;
                    879:                        if((file=nopen(log,O_WRONLY|O_CREAT|O_TRUNC))==-1) {
                    880:                                bprintf("error opening %s\r\n",log);
                    881:                                return; } }
                    882:                if(h<22 && (h>dh || dh>21       /* player won */
                    883:                        || (h==21 && pc[i]==2 && dh==21 && dh>2))) {    /* blackjack */
                    884:                        j=bet[i];                                                                 /* and dealer got 21 */
                    885:                        if(h==21 &&     /* natural blackjack or three 7's */
                    886:                                ((player[i][0].value==7 && player[i][1].value==7
                    887:                                && player[i][2].value==7)
                    888:                                || (pc[i]==2 && player[i][0].suit==player[i][1].suit)))
                    889:                                j*=2;
                    890:                        else if(h==21 && pc[i]==2)      /* regular blackjack */
                    891:                                j*=1.5; /* blackjack pays 1� to 1 */
                    892:                        sprintf(tmp,"\1n\1h\1m\1iWon!\1n\1h %u\1n\1mk",j);
                    893:                        strcat(str,tmp);
                    894:                        credits+=j*1024L;
                    895:                        val-=j*1024L;
                    896:                        moduserdat(); }
                    897:                else if(h<22 && h==dh)
                    898:                        strcat(str,"\1n\1hPush");
                    899:                else {
                    900:                        strcat(str,"\1nLost");
                    901:                        credits-=bet[i]*1024L;
                    902:                        val+=bet[i]*1024L;
                    903:                        moduserdat(); }
                    904:                if(logit) {
                    905:                        sprintf(tmp,"%ld",val);
                    906:                        write(file,tmp,strlen(tmp));
                    907:                        close(file); }                                  /* close winning log */
                    908:                strcat(str,"\1n\r\n");
                    909:                sprintf(str2,YourHand,h,str);
                    910:                if(!symbols)
                    911:                        strip_symbols(str2);
                    912:                bputs(str2);
                    913:                sprintf(str2,UserHand,user_name,h,str);
                    914:                putallnodemsg(str2); }
                    915: 
                    916:        nextplayer();
                    917:        if(!lastplayer()) {
                    918:                #if DEBUG
                    919:                debugline("lastplayer waitturn");
                    920:                #endif
                    921:                waitturn();
                    922:                nextplayer(); }
                    923:        #if DEBUG
                    924:        debugline("end of loop");
                    925:        #endif
                    926:        getnodemsg(); }
                    927: 
                    928: getgamedat(1);
                    929: node[node_num-1]=0;
                    930: putgamedat();
                    931: sprintf(str,"\1n\1m\1h%s \1n\1m%s\r\n",user_name,left());
                    932: putallnodemsg(str);
                    933: }
                    934: 
                    935: /****************************************************************************/
                    936: /* This function returns a static string that describes the status byte        */
                    937: /****************************************************************************/
                    938: char *activity(char status_type)
                    939: {
                    940:        static char str[50];
                    941: 
                    942: switch(status_type) {
                    943:        case BET:
                    944:                strcpy(str,"betting");
                    945:                break;
                    946:        case WAIT:
                    947:                strcpy(str,"waiting for turn");
                    948:                break;
                    949:        case PLAY:
                    950:                strcpy(str,"playing");
                    951:                break;
                    952:        case SYNC_P:
                    953:                strcpy(str,"synchronizing");
                    954:                break;
                    955:        case SYNC_D:
                    956:                strcpy(str,"synchronizing (dealer)");
                    957:         break;
                    958:        default:
                    959:                strcat(str,"UNKNOWN");
                    960:                break; }
                    961: return(str);
                    962: }
                    963: 
                    964: /****************************************************************************/
                    965: /* This function returns the string that represents a playing card.            */
                    966: /****************************************************************************/
                    967: char *cardstr(card_t card)
                    968: {
                    969:        static char str[20];
                    970:        char tmp[20];
                    971: 
                    972: strcpy(str,"\1n\0017"); /* card color - background always white */
                    973: if(card.suit==H || card.suit==D)
                    974:        strcat(str,"\1r");  /* hearts and diamonds - foreground red */
                    975: else
                    976:        strcat(str,"\1k");  /* spades and clubs - foreground black */
                    977: if(card.value>10)      /* face card */
                    978:        switch(card.value) {
                    979:                case J:
                    980:                        strcat(str,"J");
                    981:                        break;
                    982:                case Q:
                    983:                        strcat(str,"Q");
                    984:                        break;
                    985:                case K:
                    986:                        strcat(str,"K");
                    987:                        break;
                    988:                case A:
                    989:                        strcat(str,"A");
                    990:                        break; }
                    991: else {
                    992:        sprintf(tmp,"%d",card.value);
                    993:        strcat(str,tmp); }
                    994: switch(card.suit) {  /* suit */
                    995:        case H:
                    996:                strcat(str,"\3");
                    997:                break;
                    998:        case D:
                    999:                strcat(str,"\4");
                   1000:                break;
                   1001:        case C:
                   1002:                strcat(str,"\5");
                   1003:                break;
                   1004:        case S:
                   1005:                strcat(str,"\6");
                   1006:                break; }
                   1007: strcat(str,"\1n");
                   1008: return(str);
                   1009: }
                   1010: 
                   1011: 
                   1012: /****************************************************************************/
                   1013: /* This function returns the best value of a given hand.                                       */
                   1014: /****************************************************************************/
                   1015: char hand(card_t card[MAX_CARDS],char count)
                   1016: {
                   1017:        char c,total=0,ace=0;
                   1018: 
                   1019: for(c=0;c<count;c++) {
                   1020:        if(card[c].value==A) {          /* Ace */
                   1021:                if(total+11>21)
                   1022:                        total++;
                   1023:                else {
                   1024:                        ace++;
                   1025:                        total+=11; } }
                   1026:        else if(card[c].value>=J)       /* Jack, Queen, King */
                   1027:                total+=10;
                   1028:        else                                            /* Number cards */
                   1029:                total+=card[c].value; }
                   1030: while(total>21 && ace) { /* ace is low if bust */
                   1031:        total-=10;
                   1032:        ace--; }
                   1033: return(total);
                   1034: }
                   1035: 
                   1036: /****************************************************************************/
                   1037: /* This function returns number of soft aces in a given hand                           */
                   1038: /****************************************************************************/
                   1039: char soft(card_t card[MAX_CARDS],char count)
                   1040: {
                   1041:        char c,total=0,ace=0;
                   1042: 
                   1043: for(c=0;c<count;c++) {
                   1044:        if(card[c].value==A) {          /* Ace */
                   1045:                if(total+11>21)
                   1046:                        total++;
                   1047:                else {
                   1048:                        ace++;
                   1049:                        total+=11; } }
                   1050:        else if(card[c].value>=J)       /* Jack, Queen, King */
                   1051:                total+=10;
                   1052:        else                                            /* Number cards */
                   1053:                total+=card[c].value; }
                   1054: while(total>21 && ace) { /* ace is low if bust */
                   1055:        total-=10;
                   1056:        ace--; }
                   1057: return(ace);
                   1058: }
                   1059: 
                   1060: /****************************************************************************/
                   1061: /* This function returns card that is paired in the hand                                       */
                   1062: /****************************************************************************/
                   1063: char pair(card_t card[MAX_CARDS],char count)
                   1064: {
                   1065:        char c,d;
                   1066: 
                   1067: for(c=0;c<count;c++)
                   1068:        for(d=c+1;d<count;d++)
                   1069:                if(card[c].value==card[d].value)           /* Ace */
                   1070:                        return(card[c].value);
                   1071: return(0);
                   1072: }
                   1073: 
                   1074: 
                   1075: /****************************************************************************/
                   1076: /* This function shuffles the deck.                                                                            */
                   1077: /****************************************************************************/
                   1078: void shuffle()
                   1079: {
                   1080:        char str[81];
                   1081:        uint i,j;
                   1082:        card_t shufdeck[52*MAX_DECKS];
                   1083: 
                   1084: 
                   1085: getcarddat();
                   1086: 
                   1087: sprintf(str,"\1_\1w\1h\r\nShuffling %d Deck Shoe...",total_decks);
                   1088: bputs(str);
                   1089: strcat(str,"\r\n");     /* add crlf for other nodes */
                   1090: putallnodemsg(str);
                   1091: 
                   1092: for(i=0;i<total_decks;i++)
                   1093:        memcpy(shufdeck+(i*52),newdeck,sizeof(newdeck));          /* fresh decks */
                   1094: 
                   1095: i=0;
                   1096: while(i<(total_decks*52)-1) {
                   1097:        j=random((total_decks*52)-1);
                   1098:        if(!shufdeck[j].value)  /* card already used */
                   1099:                continue;
                   1100:        card[i]=shufdeck[j];
                   1101:        shufdeck[j].value=0;    /* mark card as used */
                   1102:        i++; }
                   1103: 
                   1104: cur_card=0;
                   1105: for(i=0;i<MAX_HANDS;i++)
                   1106:        pc[i]=0;
                   1107: hands=0;
                   1108: dc=0;
                   1109: putcarddat();
                   1110: bputs("\r\n");
                   1111: }
                   1112: 
                   1113: /****************************************************************************/
                   1114: /* This function reads and displays a message waiting for this node, if        */
                   1115: /* there is one.                                                                                                                       */
                   1116: /****************************************************************************/
                   1117: void getnodemsg()
                   1118: {
                   1119:        char str[81], *buf;
                   1120:        int file;
                   1121:        ulong length;
                   1122: 
                   1123: nodesync();
                   1124: sprintf(str,"MESSAGE.%d",node_num);
                   1125: if(flength(str)<1L)                                    /* v1.02 fix */
                   1126:        return;
                   1127: if((file=nopen(str,O_RDWR))==-1) {
                   1128:        bprintf("Couldn't open %s\r\n",str);
                   1129:        return; }
                   1130: length=filelength(file);
                   1131: if((buf=malloc(length+1L))==NULL) {
                   1132:        close(file);
                   1133:        bprintf("\7\r\ngetnodemsg: Error allocating %lu bytes of memory for %\r\n"
                   1134:                ,length+1L,str);
                   1135:        return; }
                   1136: buf[read(file,buf,length)]=0;
                   1137: chsize(file,0);
                   1138: close(file);
                   1139: if(!symbols)
                   1140:        strip_symbols(buf);
                   1141: bputs(buf);
                   1142: free(buf);
                   1143: }
                   1144: 
                   1145: /****************************************************************************/
                   1146: /* This function creates a message for a certain node.                                         */
                   1147: /****************************************************************************/
                   1148: void putnodemsg(char *msg, char nodenumber)
                   1149: {
                   1150:        char str[81];
                   1151:        int file;
                   1152: 
                   1153: sprintf(str,"MESSAGE.%d",nodenumber);
                   1154: if((file=nopen(str,O_WRONLY|O_CREAT|O_APPEND))==-1) {
                   1155:        bprintf("\r\n\7putnodemsg: error opening/creating %s\r\n",str);
                   1156:        return; }
                   1157: write(file,msg,strlen(msg));
                   1158: close(file);
                   1159: }
                   1160: 
                   1161: /****************************************************************************/
                   1162: /* This function creates a message for all nodes in the game.                          */
                   1163: /****************************************************************************/
                   1164: void putallnodemsg(char *msg)
                   1165: {
                   1166:        int i;
                   1167: 
                   1168: for(i=0;i<total_nodes;i++)
                   1169:        if(node[i] && i+1!=node_num)
                   1170:                putnodemsg(msg,i+1);
                   1171: }
                   1172: 
                   1173: /****************************************************************************/
                   1174: /* This function waits until it is the current player.                                         */
                   1175: /****************************************************************************/
                   1176: void waitturn()
                   1177: {
                   1178:        time_t start,now;
                   1179: 
                   1180: start=now=time(NULL);
                   1181: getgamedat(1);
                   1182: status[node_num-1]=WAIT;
                   1183: putgamedat();
                   1184: while(curplayer!=node_num) {
                   1185:        chat();
                   1186:        mswait(100);
                   1187:        getgamedat(0);
                   1188:        if(curplayer && !node[curplayer-1] /*  || status[curplayer-1]==BET */ )
                   1189:                nextplayer();           /* current player is not playing? */
                   1190: 
                   1191:        if(!node[node_num-1]) { /* current node not in game? */
                   1192:                getgamedat(1);
                   1193:                node[node_num-1]=user_number;   /* fix it */
                   1194:                putgamedat(); }
                   1195: 
                   1196:        now=time(NULL);
                   1197:        if(now-start>300) { /* only wait upto 5 minutes */
                   1198:                bputs("\r\nwaitturn: timeout\r\n");
                   1199:                break; } }
                   1200: getgamedat(1);
                   1201: status[node_num-1]=PLAY;
                   1202: putgamedat();
                   1203: }
                   1204: 
                   1205: /****************************************************************************/
                   1206: /* This is the function that is called to see if the user has hit a key,       */
                   1207: /* and if so, read in a line of chars and send them to the other nodes.        */
                   1208: /****************************************************************************/
                   1209: void chat()
                   1210: {
                   1211:        char str1[150],str2[256],ch;
                   1212:        int i;
                   1213: 
                   1214: aborted=0;
                   1215: if((ch=inkey(0))!=0 || wordwrap[0]) {
                   1216:        if(ch=='/') {
                   1217:                bputs("\1n\1y\1hCommand: \1n");
                   1218:                ch=getkeys("?LS|%\r",0);
                   1219:                switch(ch) {
                   1220:                        case CR:
                   1221:                                return;
                   1222:                        #if DEBUG
                   1223:                        case '|':
                   1224:                                debug();
                   1225:                                return;
                   1226:                        #endif
                   1227:                        case '%':
                   1228:                                if(!com_port)   /* only if local */
                   1229:                                        exit(0);
                   1230:                                break;
                   1231:                        case '?':
                   1232:                                mnemonics("\r\n~List Players");
                   1233:                                mnemonics("\r\n~Send Private Message to Player");
                   1234:                                bputs("\r\n");
                   1235:                                return;
                   1236:                        case 'L':
                   1237:                                listplayers();
                   1238:                                bprintf(ShoeStatus,cur_card,total_decks*52);
                   1239:                                return;
                   1240:                        case 'S':
                   1241:                                listplayers();
                   1242:                                bputs("\1n\r\n\1y\1hWhich node: \1n");
                   1243:                                i=getnum(sys_nodes);
                   1244:                                getgamedat(0);
                   1245:                                if(i>0 && i!=node_num && node[i-1]) {
                   1246:                                        bputs("\r\n\1n\1y\1hMessage: ");
                   1247:                                        if(getstr(str1,50,K_LINE)) {
                   1248:                                                sprintf(str2,UserWhispers,user_name
                   1249:                                                        ,str1);
                   1250:                                                putnodemsg(str2,i); } }
                   1251:                                else
                   1252:                                        bputs("\1n\r\n\1r\1hInvalid node.\1n\r\n");
                   1253:                                return; } }
                   1254:        ungetkey(ch);
                   1255:        if(!getstr(str1,50,K_CHAT|K_WRAP))
                   1256:                return;
                   1257:        sprintf(str2,UserSays,user_name,str1);
                   1258:        putallnodemsg(str2); }
                   1259: getnodemsg();
                   1260: }
                   1261: 
                   1262: /****************************************************************************/
                   1263: /* This function returns 1 if the current node is the highest (or last)        */
                   1264: /* node in the game, or 0 if there is another node with a higher number        */
                   1265: /* in the game. Used to determine if this node is to perform the dealer   */
                   1266: /* function                                                                                                                      */
                   1267: /****************************************************************************/
                   1268: char lastplayer()
                   1269: {
                   1270:        int i;
                   1271: 
                   1272: getgamedat(0);
                   1273: if(total_players==1 && node[node_num-1])       /* if only player, definetly */
                   1274:        return(1);                                                              /* the last */
                   1275: 
                   1276: for(i=node_num;i<total_nodes;i++)                        /* look for a higher number */
                   1277:        if(node[i])
                   1278:                break;
                   1279: if(i<total_nodes)                                                        /* if one found, return 0 */
                   1280:        return(0);
                   1281: return(1);                                                                     /* else return 1 */
                   1282: }
                   1283: 
                   1284: /****************************************************************************/
                   1285: /* Returns the node number of the lower player in the game                                     */
                   1286: /****************************************************************************/
                   1287: char firstplayer()
                   1288: {
                   1289:        int i;
                   1290: 
                   1291: for(i=0;i<total_nodes;i++)
                   1292:        if(node[i])
                   1293:                break;
                   1294: if(i==total_nodes)
                   1295:        return(0);
                   1296: return(i+1);
                   1297: }
                   1298: 
                   1299: /****************************************************************************/
                   1300: /* This function is only run on the highest node number in the game. It        */
                   1301: /* waits until all other nodes are waiting in their sync routines, and then */
                   1302: /* releases them by changing the status byte from SYNC_P to PLAY                       */
                   1303: /* it is assumed that getgamedat(1) is called immediately prior.                       */
                   1304: /****************************************************************************/
                   1305: void syncdealer()
                   1306: {
                   1307:        char *Dealing="\1n\1hDealing...\r\n\1n";
                   1308:        int i;
                   1309:        time_t start,now;
                   1310: 
                   1311: status[node_num-1]=SYNC_D;
                   1312: putgamedat();
                   1313: start=now=time(NULL);
                   1314: // fdelay(1000);                                /* wait for stragglers to join game v1.02 */
                   1315: getgamedat(0);
                   1316: while(total_players) {
                   1317:        for(i=0;i<total_nodes;i++)
                   1318:                if(i!=node_num-1 && node[i] && status[i]!=SYNC_P)
                   1319:                        break;
                   1320:        if(i==total_nodes)                /* all player nodes are waiting */
                   1321:                break;
                   1322:        chat();
                   1323:        mswait(100);
                   1324:        getgamedat(0);
                   1325:        if(!node[node_num-1]) { /* current node not in game? */
                   1326:                getgamedat(1);
                   1327:                node[node_num-1]=user_number;   /* fix it */
                   1328:                putgamedat(); }
                   1329:        now=time(NULL);
                   1330:        if(now-start>300) { /* only wait upto 5 minutes */
                   1331:                bputs("\r\nsyncdealer: timeout\r\n");
                   1332:         break; } }
                   1333: 
                   1334: getgamedat(1);
                   1335: misc|=INPLAY;
                   1336: curplayer=firstplayer();
                   1337: putgamedat();
                   1338: 
                   1339: getnodemsg();
                   1340: bputs(Dealing);
                   1341: putallnodemsg(Dealing);
                   1342: 
                   1343: getgamedat(1);
                   1344: for(i=0;i<total_nodes;i++)               /* release player nodes */
                   1345:        if(node[i])
                   1346:                status[i]=PLAY;
                   1347: putgamedat();
                   1348: }
                   1349: 
                   1350: 
                   1351: /****************************************************************************/
                   1352: /* This function halts this node until the dealer releases it by changing      */
                   1353: /* the status byte from SYNC_P to PLAY                                                                         */
                   1354: /* it is assumed that getgamedat(1) is called immediately prior.                       */
                   1355: /****************************************************************************/
                   1356: void syncplayer()
                   1357: {
                   1358:        time_t start,now;
                   1359: 
                   1360: status[node_num-1]=SYNC_P;
                   1361: putgamedat();
                   1362: start=now=time(NULL);
                   1363: while(node[node_num-1] && status[node_num-1]==SYNC_P) {
                   1364:        chat();
                   1365:        mswait(100);
                   1366:        getgamedat(0);
                   1367:        if(!node[node_num-1]) { /* current node not in game? */
                   1368:                getgamedat(1);
                   1369:                node[node_num-1]=user_number;   /* fix it */
                   1370:                putgamedat(); }
                   1371:        now=time(NULL);
                   1372:        if(now-start>300) { /* only wait upto 5 minutes */
                   1373:                bputs("\r\nsyncplayer: timeout\r\n");
                   1374:         break; } }
                   1375: }
                   1376: 
                   1377: /****************************************************************************/
                   1378: /* Updates the MODUSER.DAT file that SBBS reads to ajust the user's credits */
                   1379: /* This function is called whenever the user's credits are adjust so that   */
                   1380: /* the file will be current in any event.                                                                      */
                   1381: /****************************************************************************/
                   1382: void moduserdat()
                   1383: {
                   1384:        char str[128];
                   1385:        FILE *stream;
                   1386: 
                   1387: sprintf(str,"%sMODUSER.DAT",node_dir);
                   1388: if((stream=fopen(str,"wt"))==NULL) {
                   1389:        bprintf("Error opening %s for write\r\n",str);
                   1390:        return; }
                   1391: fprintf(stream,"%ld",credits-user_cdt);
                   1392: fclose(stream);
                   1393: 
                   1394: }
                   1395: 
                   1396: /****************************************************************************/
                   1397: /* This function reads the entire shoe of cards and the dealer's hand from  */
                   1398: /* the card database file (CARD.DAB)                                                                           */
                   1399: /****************************************************************************/
                   1400: void getcarddat()
                   1401: {
                   1402:        int file;
                   1403: 
                   1404: if((file=nopen("CARD.DAB",O_RDONLY))==-1) {
                   1405:        bputs("getcarddat: Error opening CARD.DAB\r\n");
                   1406:        return; }
                   1407: read(file,&dc,1);
                   1408: read(file,dealer,sizeof(dealer));
                   1409: read(file,&total_decks,1);
                   1410: read(file,&cur_card,2);
                   1411: read(file,card,total_decks*52*sizeof(card_t));
                   1412: close(file);
                   1413: }
                   1414: 
                   1415: /****************************************************************************/
                   1416: /* This function writes the entire shoe of cards and the dealer's hand to   */
                   1417: /* the card database file (CARD.DAB)                                                                           */
                   1418: /****************************************************************************/
                   1419: void putcarddat()
                   1420: {
                   1421:        int file;
                   1422: 
                   1423: if((file=nopen("CARD.DAB",O_WRONLY|O_CREAT))==-1) {
                   1424:        bputs("putcarddat: Error opening CARD.DAB\r\n");
                   1425:        return; }
                   1426: write(file,&dc,1);
                   1427: write(file,dealer,sizeof(dealer));
                   1428: write(file,&total_decks,1);
                   1429: write(file,&cur_card,2);
                   1430: write(file,card,total_decks*52*sizeof(card_t));
                   1431: close(file);
                   1432: }
                   1433: 
                   1434: /****************************************************************************/
                   1435: /* This function creates random ways to say "hit"                           */
                   1436: /****************************************************************************/
                   1437: char *hit()
                   1438: {
                   1439:        static char str[81];
                   1440: 
                   1441: strcpy(str,"\1n\1r\1h");
                   1442: switch(rand()%10) {
                   1443:        case 1:
                   1444:                strcat(str,"Hit it.");
                   1445:                break;
                   1446:        case 2:
                   1447:                strcat(str,"Hit me, Baby!");
                   1448:                break;
                   1449:        case 3:
                   1450:                strcat(str,"Give me an ace.");
                   1451:                break;
                   1452:        case 4:
                   1453:                strcat(str,"One more.");
                   1454:                break;
                   1455:        case 5:
                   1456:                strcat(str,"Just one more.");
                   1457:                break;
                   1458:        case 6:
                   1459:                strcat(str,"Give me a baby card.");
                   1460:                break;
                   1461:        case 7:
                   1462:                strcat(str,"Hit it, Dude.");
                   1463:                break;
                   1464:        case 8:
                   1465:                strcat(str,"Hit.");
                   1466:                break;
                   1467:        case 9:
                   1468:                strcat(str,"Um... Hit.");
                   1469:                break;
                   1470:        case 10:
                   1471:                strcat(str,"Thank you Sir, may I have another.");
                   1472:                break;
                   1473:        default:
                   1474:                strcat(str,"Face card, please.");
                   1475:                break; }
                   1476: strcat(str,"\1n\r\n");
                   1477: return(str);
                   1478: }
                   1479: 
                   1480: /****************************************************************************/
                   1481: /* This function creates random ways to say "double"                        */
                   1482: /****************************************************************************/
                   1483: char *doubit()
                   1484: {
                   1485:        static char str[81];
                   1486: 
                   1487: strcpy(str,"\1n\1b\1h");
                   1488: switch(rand()%10) {
                   1489:        case 1:
                   1490:                strcat(str,"Double.");
                   1491:                break;
                   1492:        case 2:
                   1493:                strcat(str,"Double Down, Man.");
                   1494:                break;
                   1495:        case 3:
                   1496:                strcat(str,"Double it, Dude.");
                   1497:                break;
                   1498:        case 4:
                   1499:                strcat(str,"One more card for double the dough.");
                   1500:                break;
                   1501:        case 5:
                   1502:                strcat(str,"Double me.");
                   1503:                break;
                   1504:        case 6:
                   1505:                strcat(str,"Oh yeah... Double!");
                   1506:                break;
                   1507:        case 7:
                   1508:                strcat(str,"I shouldn't do it, but... Double!");
                   1509:                break;
                   1510:        case 8:
                   1511:                strcat(str,"Double my bet and give me one more card.");
                   1512:                break;
                   1513:        case 9:
                   1514:                strcat(str,"Um... Double.");
                   1515:                break;
                   1516:        case 10:
                   1517:                strcat(str,"Thank you Sir, may I Double?");
                   1518:                break;
                   1519:        default:
                   1520:                strcat(str,"Double - face card, please.");
                   1521:                break; }
                   1522: strcat(str,"\1n\r\n");
                   1523: return(str);
                   1524: }
                   1525: 
                   1526: /****************************************************************************/
                   1527: /* This function creates random ways to say "stand"                         */
                   1528: /****************************************************************************/
                   1529: char *stand()
                   1530: {
                   1531:        static char str[81];
                   1532: 
                   1533: strcpy(str,"\1n\1c\1h");
                   1534: switch(rand()%10) {
                   1535:        case 1:
                   1536:                strcat(str,"Stand.");
                   1537:                break;
                   1538:        case 2:
                   1539:                strcat(str,"Stay.");
                   1540:                break;
                   1541:        case 3:
                   1542:                strcat(str,"No more.");
                   1543:                break;
                   1544:        case 4:
                   1545:                strcat(str,"Just right.");
                   1546:                break;
                   1547:        case 5:
                   1548:                strcat(str,"I should hit, but I'm not gonna.");
                   1549:                break;
                   1550:        case 6:
                   1551:                strcat(str,"Whoa!");
                   1552:                break;
                   1553:        case 7:
                   1554:                strcat(str,"Hold it.");
                   1555:                break;
                   1556:        case 8:
                   1557:                strcat(str,"No way, Jose!");
                   1558:                break;
                   1559:        case 9:
                   1560:                strcat(str,"Um... Stand.");
                   1561:                break;
                   1562:        case 10:
                   1563:                strcat(str,"Thanks, but no thanks.");
                   1564:                break;
                   1565:        default:
                   1566:                strcat(str,"No card, no bust.");
                   1567:                break; }
                   1568: strcat(str,"\1n\r\n");
                   1569: return(str);
                   1570: }
                   1571: 
                   1572: /****************************************************************************/
                   1573: /* This function creates random ways to say "split"                         */
                   1574: /****************************************************************************/
                   1575: char *split()
                   1576: {
                   1577:        static char str[81];
                   1578: 
                   1579: strcpy(str,"\1n\1y\1h");
                   1580: switch(rand()%10) {
                   1581:        case 1:
                   1582:                strcat(str,"Split.");
                   1583:                break;
                   1584:        case 2:
                   1585:                strcat(str,"Split 'em.");
                   1586:                break;
                   1587:        case 3:
                   1588:                strcat(str,"Split it.");
                   1589:                break;
                   1590:        case 4:
                   1591:                strcat(str,"Split, please.");
                   1592:                break;
                   1593:        case 5:
                   1594:                strcat(str,"I should hit, but I'm gonna split instead.");
                   1595:                break;
                   1596:        case 6:
                   1597:                strcat(str,"Whoa! Split them puppies...");
                   1598:                break;
                   1599:        case 7:
                   1600:                strcat(str,"Split 'em, Dude.");
                   1601:                break;
                   1602:        case 8:
                   1603:                strcat(str,"Double the cards, for double the money.");
                   1604:                break;
                   1605:        case 9:
                   1606:                strcat(str,"Um... Split.");
                   1607:                break;
                   1608:        case 10:
                   1609:                strcat(str,"Thank you Sir, I think I'll split 'em.");
                   1610:                break;
                   1611:        default:
                   1612:                strcat(str,"Banana Split.");
                   1613:                break; }
                   1614: strcat(str,"\1n\r\n");
                   1615: return(str);
                   1616: }
                   1617: 
                   1618: /****************************************************************************/
                   1619: /* This function creates random ways to say "joined"                        */
                   1620: /****************************************************************************/
                   1621: char *joined()
                   1622: {
                   1623:        static char str[81];
                   1624: 
                   1625: switch(rand()%10) {
                   1626:        case 1:
                   1627:                strcpy(str,"joined.");
                   1628:                break;
                   1629:        case 2:
                   1630:                strcpy(str,"sat down to play.");
                   1631:                break;
                   1632:        case 3:
                   1633:                strcpy(str,"plopped on the chair next to you.");
                   1634:                break;
                   1635:        case 4:
                   1636:                strcpy(str,"belched loudly to announce his entrance.");
                   1637:                break;
                   1638:        case 5:
                   1639:                strcpy(str,"dropped in.");
                   1640:                break;
                   1641:        case 6:
                   1642:                strcpy(str,"joined our game.");
                   1643:                break;
                   1644:        case 7:
                   1645:                strcpy(str,"fell on his face entering the casino!");
                   1646:                break;
                   1647:        case 8:
                   1648:                strcpy(str,"slams a roll of credits on the table.");
                   1649:                break;
                   1650:        case 9:
                   1651:                strcpy(str,"rolled in to join the game.");
                   1652:                break;
                   1653:        case 10:
                   1654:                strcpy(str,"smiles widely as he takes your wife's seat.");
                   1655:                break;
                   1656:        default:
                   1657:                strcpy(str,"spills a drink on your pants while sitting down.");
                   1658:                break; }
                   1659: return(str);
                   1660: }
                   1661: 
                   1662: /****************************************************************************/
                   1663: /* This function creates random ways to say "left"                          */
                   1664: /****************************************************************************/
                   1665: char *left()
                   1666: {
                   1667:        static char str[81];
                   1668: 
                   1669: switch(rand()%10) {
                   1670:        case 1:
                   1671:                strcpy(str,"left abruptly.");
                   1672:                break;
                   1673:        case 2:
                   1674:                strcpy(str,"sneaked away.");
                   1675:                break;
                   1676:        case 3:
                   1677:                strcpy(str,"took the credits and ran.");
                   1678:                break;
                   1679:        case 4:
                   1680:                strcpy(str,"fell out of the chair.");
                   1681:                break;
                   1682:        case 5:
                   1683:                strcpy(str,"left the game.");
                   1684:                break;
                   1685:        case 6:
                   1686:                strcpy(str,"slipped out the door.");
                   1687:                break;
                   1688:        case 7:
                   1689:                strcpy(str,"giggled as he left the table.");
                   1690:                break;
                   1691:        case 8:
                   1692:                strcpy(str,"left clenching empty pockets.");
                   1693:                break;
                   1694:        case 9:
                   1695:                strcpy(str,"went to the pawn shop to hawk a watch.");
                   1696:                break;
                   1697:        case 10:
                   1698:                strcpy(str,"bailed out the back door.");
                   1699:                break;
                   1700:        default:
                   1701:                strcpy(str,"made like a train and left.");
                   1702:                break; }
                   1703: return(str);
                   1704: }
                   1705: 
                   1706: /****************************************************************************/
                   1707: /* This function creates the file "GAME.DAB" in the current directory.      */
                   1708: /****************************************************************************/
                   1709: void create_gamedab()
                   1710: {
                   1711: 
                   1712: if((gamedab=sopen("GAME.DAB"
                   1713:        ,O_WRONLY|O_CREAT|O_BINARY,SH_DENYNO,S_IWRITE|S_IREAD))==-1) {
                   1714:        bputs("Error creating GAME.DAB\r\n");
                   1715:        pause();
                   1716:        exit(1); }
                   1717: misc=0;
                   1718: curplayer=0;
                   1719: memset(node,0,sizeof(node));
                   1720: memset(status,0,sizeof(status));
                   1721: write(gamedab,&misc,1);
                   1722: write(gamedab,&curplayer,1);
                   1723: write(gamedab,&total_nodes,1);
                   1724: write(gamedab,node,total_nodes*2);
                   1725: write(gamedab,status,total_nodes);
                   1726: close(gamedab);
                   1727: }
                   1728: 
                   1729: /****************************************************************************/
                   1730: /* This function opens the file "GAME.DAB" in the current directory and     */
                   1731: /* leaves it open with deny none access. This file uses record locking         */
                   1732: /* for shared access.                                                                                                          */
                   1733: /****************************************************************************/
                   1734: void open_gamedab()
                   1735: {
                   1736: if((gamedab=sopen("GAME.DAB",O_RDWR|O_BINARY,SH_DENYNO))==-1) {
                   1737:     bputs("Error opening GAME.DAB\r\n");                /* open deny none */
                   1738:     pause();
                   1739:        exit(1); }
                   1740: }
                   1741: 
                   1742: /****************************************************************************/
                   1743: /* Lists the players currently in the game and the status of the shoe.         */
                   1744: /****************************************************************************/
                   1745: void listplayers()
                   1746: {
                   1747:        int i;
                   1748: 
                   1749: getgamedat(0);
                   1750: bputs("\r\n");
                   1751: if(!total_players) {
                   1752:        bputs("\1_\1w\1hNo game in progress\r\n");
                   1753:        return; }
                   1754: for(i=0;i<total_nodes;i++)
                   1755:        if(node[i])
                   1756:                bprintf("\1-\1mNode %2d: \1h%s \1n\1m%s\r\n"
                   1757:                        ,i+1,username(node[i]),activity(status[i]));
                   1758: getcarddat();
                   1759: /***
                   1760: bprintf("\r\nCurrent player=Node %d user #%d\r\n",curplayer,node[curplayer-1]);
                   1761: ***/
                   1762: }
                   1763: 
                   1764: /****************************************************************************/
                   1765: /* This function replaces the card symbols in 'str' with letters to         */
                   1766: /* represent the different suits.                                                                                      */
                   1767: /****************************************************************************/
                   1768: void strip_symbols(char *str)
                   1769: {
                   1770:        int i,j;
                   1771: 
                   1772: j=strlen(str);
                   1773: for(i=0;i<j;i++)
                   1774:        if(str[i]>=3 && str[i]<=6)
                   1775:                switch(str[i]) {
                   1776:                        case 3:
                   1777:                                str[i]='H';
                   1778:                                break;
                   1779:                        case 4:
                   1780:                                str[i]='D';
                   1781:                                break;
                   1782:                        case 5:
                   1783:                                str[i]='C';
                   1784:                                break;
                   1785:                        case 6:
                   1786:                                str[i]='S';
                   1787:                                break; }
                   1788: }
                   1789: 
                   1790: #endif /* end of function not needed for SBJCLEAN.C */
                   1791: 
                   1792: /****************************************************************************/
                   1793: /* Reads information from GAME.DAB file. If 'lockit' is 1, the file is      */
                   1794: /* and putgamedat must be called to unlock it. If your updating the info       */
                   1795: /* in GAME.DAB, you must first call getgamedat(1), then putgamedat().          */
                   1796: /****************************************************************************/
                   1797: void getgamedat(char lockit)
                   1798: {
                   1799:     int i=0;
                   1800: 
                   1801: /* retry 100 times taking at least 3 seconds */
                   1802: while(lock(gamedab,0L,filelength(gamedab))==-1 && i++<100)
                   1803:        mswait(30);  /* lock the whole thing */
                   1804: if(i>=100) {
                   1805: //       printf("gamedab=%d %04X:%p %04X\r\n",gamedab,_psp,&gamedab,_DS);
                   1806:        printf("\7getgamedat: error locking GAME.DAB\r\n"); }
                   1807: 
                   1808: lseek(gamedab,0L,SEEK_SET);
                   1809: read(gamedab,&misc,1);
                   1810: read(gamedab,&curplayer,1);
                   1811: read(gamedab,&total_nodes,1);
                   1812: read(gamedab,node,total_nodes*2);         /* user number playing for each node */
                   1813: read(gamedab,status,total_nodes);         /* the status of the player */
                   1814: total_players=0;
                   1815: for(i=0;i<total_nodes;i++)
                   1816:     if(node[i])
                   1817:         total_players++;
                   1818: if(!lockit)
                   1819:        unlock(gamedab,0L,filelength(gamedab));
                   1820: }
                   1821: 
                   1822: /****************************************************************************/
                   1823: /* Writes information to GAME.DAB file. getgamedat(1) MUST be called before  */
                   1824: /* this function is called.                                                 */
                   1825: /****************************************************************************/
                   1826: void putgamedat()
                   1827: {
                   1828: 
                   1829: lseek(gamedab,0L,SEEK_SET);
                   1830: write(gamedab,&misc,1);
                   1831: write(gamedab,&curplayer,1);
                   1832: write(gamedab,&total_nodes,1);
                   1833: write(gamedab,node,total_nodes*2);
                   1834: write(gamedab,status,total_nodes);
                   1835: unlock(gamedab,0L,filelength(gamedab));
                   1836: }
                   1837: 
                   1838: /***************************************************************/
                   1839: /* This function makes the next active node the current player */
                   1840: /***************************************************************/
                   1841: void nextplayer()
                   1842: {
                   1843:     int i;
                   1844: 
                   1845: getgamedat(1);                      /* get current info and lock */
                   1846: 
                   1847: if((!curplayer                                         /* if no current player */
                   1848:     || total_players==1)            /* or only one player in game */
                   1849:     && node[node_num-1]) {          /* and this node is in the game */
                   1850:        curplayer=node_num;                     /* make this node current player */
                   1851:     putgamedat();                   /* write data and unlock */
                   1852:     return; }                       /* and return */
                   1853: 
                   1854: for(i=curplayer;i<total_nodes;i++)     /* search for the next highest node */
                   1855:     if(node[i])                     /* that is active */
                   1856:         break;
                   1857: if(i>=total_nodes) {                           /* if no higher active nodes, */
                   1858:        for(i=0;i<curplayer-1;i++)              /* start at bottom and go up  */
                   1859:         if(node[i])
                   1860:             break;
                   1861:        if(i==curplayer-1)                              /* if no active nodes found */
                   1862:                curplayer=0;                            /* make current player 0 */
                   1863:     else
                   1864:                curplayer=i+1; }
                   1865: else
                   1866:        curplayer=i+1;                                  /* else active node current player */
                   1867: 
                   1868: putgamedat();                       /* write info and unlock */
                   1869: }
                   1870: 
                   1871: /* End of SBJ.C */

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.