home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 2 BBS
/
02-BBS.zip
/
OP2DEV.ZIP
/
TTT2.C
< prev
next >
Wrap
C/C++ Source or Header
|
1990-11-17
|
10KB
|
382 lines
/*
* 3D Tic Tac Toe.
*/
#include <stdio.h>
#include <stdarg.h>
#define INCL_DOS
#include <os2.h>
#include "bbsexpan.h"
#define EMPTY 0
#define PLAYER 1
#define BEAST 5
/*
* This is a table of all winning
* combinations.
* I stole it out of Kilobaud, April
* 78.
* You can look there to see how it
* is ordered.
*/
char w[] = {
0, 1, 2, 3,
4, 5, 6, 7,
8, 9, 10, 11,
12, 13, 14, 15,
0, 4, 8, 12,
1, 5, 9, 13,
2, 6, 10, 14,
3, 7, 11, 15,
0, 5, 10, 15,
3, 6, 9, 12,
16, 17, 18, 19,
20, 21, 22, 23,
24, 25, 26, 27,
28, 29, 30, 31,
16, 20, 24, 28,
17, 21, 25, 29,
18, 22, 26, 30,
19, 23, 27, 31,
16, 21, 26, 31,
19, 22, 25, 28,
32, 33, 34, 35,
36, 37, 38, 39,
40, 41, 42, 43,
44, 45, 46, 47,
32, 36, 40, 44,
33, 37, 41, 45,
34, 38, 42, 46,
35, 39, 43, 47,
32, 37, 42, 47,
35, 38, 41, 44,
48, 49, 50, 51,
52, 53, 54, 55,
56, 57, 58, 59,
60, 61, 62, 63,
48, 52, 56, 60,
49, 53, 57, 61,
50, 54, 58, 62,
51, 55, 59, 63,
48, 53, 58, 63,
51, 54, 57, 60,
0, 16, 32, 48,
1, 17, 33, 49,
2, 18, 34, 50,
3, 19, 35, 51,
4, 20, 36, 52,
5, 21, 37, 53,
6, 22, 38, 54,
7, 23, 39, 55,
8, 24, 40, 56,
9, 25, 41, 57,
10, 26, 42, 58,
11, 27, 43, 59,
13, 29, 45, 61,
12, 28, 44, 60,
14, 30, 46, 62,
15, 31, 47, 63,
0, 21, 42, 63,
4, 21, 38, 55,
8, 25, 42, 59,
12, 25, 38, 51,
1, 21, 41, 61,
13, 25, 37, 49,
2, 22, 42, 62,
14, 26, 38, 50,
3, 22, 41, 60,
7, 22, 37, 52,
11, 26, 41, 56,
15, 26, 37, 48,
0, 20, 40, 60,
0, 17, 34, 51,
3, 18, 33, 48,
3, 23, 43, 63,
12, 24, 36, 48,
12, 29, 46, 63,
15, 30, 45, 60,
15, 27, 39, 51
};
int rules(PORT_REC *);
int user(PORT_REC *);
int board(PORT_REC *);
int psq(int, PORT_REC *);
int beast(PORT_REC *);
int weight(int);
/*
* This is the board.
* Starts off all empty.
*/
char b[64];
char *top = " 0 1 2 3\n\r";
char *top2 = " 0 1 2 3 0 1 2 3 0 1 2 3 0 1 2 3\n\r";
char *sep = " ----------- ----------- ----------- -----------\n\r";
/*
* The mainline is just
* a driver.
*/
main(int argc, char *argv[])
{
int rc;
char buf[20];
rc = UseChildAppInit(argv[1],argv[0],&anchor,&unhand,&semhand,&usernum,&instance);
if( rc != 0 ) {
printf("\nCould not initialize application (%d)\n",rc);
return(1);
}
COLOR(BRMAGENTA);
SerWritef(unhand,"\n\r3-D Tic-Tac-Toe... an Omega Point exclusive presentation!\n\r\n\r");
while( LoggedIn() ) {
for(rc=0;rc<64;rc++)
b[rc] = EMPTY;
SerColorWrite("\n\rDo you want the rules? ",BRYELLOW,unhand);
COLOR(BRCYAN);
if( SerGetCmd(buf,2,unhand) < 0 )
continue;
if(buf[0]=='Y')
rules(unhand);
SerColorWrite("\n\rDo you want to go first? ",BRYELLOW,unhand);
COLOR(BRCYAN);
if( SerGetCmd(buf,2,unhand) < 0 ) break;
SerWritef(unhand,"\n\r");
if(buf[0]=='Y')
if( user(unhand) == -1 ) break;
SerWritef(unhand,"\n\r");
while( (USENUM==0 || SerConnected(unhand)) && UseTm(unhand) && V_USRON ) {
if( beast(unhand) == -1 ) break;
if( user(unhand) == -1 ) break;
}
COLOR(BRYELLOW);
SerWritef(unhand,"\n\rPlay again? ");
COLOR(BRCYAN);
if( SerGetCmd(buf,2,unhand) < 0 ) break;
if( buf[0]=='Y' ) continue;
break;
}
exit(1);
}
/*
* Print the rules of the
* game.
*/
rules(PORT_REC *unhand)
{
COLOR(BRWHITE);
SerWritef(unhand,"\n\rThree dimensional tic-tac-toe is played on a 4x4x4\n\r");
SerWritef(unhand,"board. To win you must get 4 in a row. Your moves\n\r");
SerWritef(unhand,"are specified as a 3 digit number; the first digit\n\r");
SerWritef(unhand,"is the level, the second the row and the third the\n\r");
SerWritef(unhand,"column. Levels and columns go from left to right\n\r");
SerWritef(unhand,"from 0 to 3. Rows go from top to bottom with 0 on\n\r");
SerWritef(unhand,"the top.\n\r\n\r");
}
/*
* Accept a user move.
* Exit if he wins.
*/
user(PORT_REC *unhand)
{
int i, j, t;
int rc;
char buf[20];
board(unhand);
while( (USENUM==0 || SerConnected(unhand)) && UseTm(unhand) && V_USRON ) {
COLOR(BRYELLOW);
SerWritef(unhand,"\n\rYour move (Q to quit)? ");
COLOR(BRCYAN);
rc = SerGetCmd(buf,4,unhand);
if( rc < 1 ) continue;
SerWritef(unhand,"\n\r");
if( buf[0] == 'Q' ) {
COLOR(BRWHITE);
SerWritef(unhand,"\n\rChicken.\n\r");
return(-1);
}
i = 16*(buf[0]-'0') + (buf[1]-'0') + 4*(buf[2]-'0');
if(i>=0 && i<=63 && b[i]==EMPTY)
break;
COLOR(BRRED);
SerWritef(unhand,"\n\rEh?\n\r");
}
if(i<0 || i>63) return(-1);
b[i] = PLAYER;
for(i=0; i<4*76; i+=4) {
t = 0;
for(j=0; j<4; ++j)
t += b[w[i+j]];
if(t == 4*PLAYER) {
COLOR(BRWHITE);
SerWritef(unhand,"\n\rYou win!\n\r");
return(-1);
}
}
}
/*
* Display the board.
* Not as easy as it sounds.
*/
board(PORT_REC *unhand)
{
register int i, j;
COLOR(WHITE);
SerWritef(unhand,"%s",top);
SerWritef(unhand,"%s\n\r",top2);
for(i=0; i<4; ++i) {
if(i != 0) {
COLOR(BLUE);
SerWritef(unhand,"%s",sep);
COLOR(WHITE);
SerWritef(unhand," %d ",i);
}
else {
COLOR(WHITE);
SerWritef(unhand," %d ",i);
}
for(j=0; j<64; j+=4) {
psq(i+j, unhand);
if(j==12 || j==28 || j==44)
SerWritef(unhand," ");
else if(j >= 60)
SerWritef(unhand,"\n\r");
else {
COLOR(BLUE);
SerWritef(unhand,"|");
}
}
}
}
/*
* Format and put out square
* `s' of the board.
*/
psq(int s,PORT_REC *unhand)
{
register int v;
v = b[s];
if(v == PLAYER) {
COLOR(BRGREEN);
SerWritef(unhand,"UU");
}
else if(v == BEAST) {
COLOR(BRMAGENTA);
SerWritef(unhand,"CC");
}
else
SerWritef(unhand," ");
}
/*
* Move for the machine.
* Just exit on machine wins
* and draws.
*/
beast(PORT_REC *unhand)
{
register int i, j, t;
int s, bs, bt, v[76];
for(i=0; i<4*76; i+=4) {
t = 0;
for(j=0; j<4; ++j)
t += b[w[i+j]];
v[i>>2] = t;
if(t == 3*BEAST)
break;
}
if(i < 4*76) {
for(j=0; j<4; ++j)
if(b[w[i+j]] == EMPTY) {
b[w[i+j]] = BEAST;
break;
}
board(unhand);
COLOR(BRWHITE);
SerWritef(unhand,"\n\rI win!!\n\r");
return(-1);
}
bt = 0;
for(s=0; s<64; ++s) {
if(b[s] != EMPTY)
continue;
t = 0;
for(i=0; i<4*76; i+=4) {
for(j=0; j<4; ++j)
if(w[i+j] == s)
break;
if(j != 4) {
if(v[i>>2] == 3*PLAYER) {
b[s] = BEAST;
return(1);
}
t += weight(v[i>>2]);
}
}
if(t > bt) {
bt = t;
bs = s;
}
}
if(bt != 0)
b[bs] = BEAST;
else {
for(s=0; s<64; ++s)
if(b[s] == EMPTY)
break;
if(s == 64) {
COLOR(BRWHITE);
SerWritef(unhand,"\n\rDraw.\n\r");
return(-1);
}
b[s] = BEAST;
}
return(1);
}
/*
* Given a total along a winning
* combination, return the weight
* value.
*/
weight(int at)
{
register int t;
t = at;
if(t == PLAYER)
return(1);
if(t == 2*PLAYER)
return(4);
if(t == BEAST)
return(1);
if(t == 2*BEAST)
return(2);
return(0);
}