home *** CD-ROM | disk | FTP | other *** search
- /*
- * nttt.c - TCP/IP TIC TAC TOE by r4lph
- * You guessed it. Tic tac toe, taken to the next level. Play your
- * friends, play your mom, even play so1o! Works on *BSD* and Linux
- * as far as I know. Mail r4lph@b4b0.org if it works on your non
- * *BSD*\Linux system. If you don't like something in the code,
- * for christs sake, don't tell me, just change it. Don't distribute
- * modified versions, blah blah blah. The connector will always be
- * X and the connected to will be O.
- * compile: cc -O2 -o nttt nttt.c
- * Have fun.
- * Oct. 18/1998
- * r4lph <r4lph@b4b0.org>
- */
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <unistd.h>
- #include <string.h>
- #include <netdb.h>
- #include <signal.h>
- #include <sys/types.h>
- #include <sys/socket.h>
- #include <netinet/in.h>
-
- /* defines */
- #define X 1
- #define O 0
- #define PORT 9876
-
- /* color defines */
- #define END ""
- #define RED ""
- #define GREEN ""
- #define BLUE ""
- #define BOLDWHITE ""
- #define BGRED ""
-
- /* function prototypes */
- int main(int argc, char *argv[]); /* duh */
- unsigned long getip(char *hostname); /* resolve hostname */
- void initiate(unsigned long ip); /* initiate a connection */
- void wait_for_connection(void); /* listen for a connection */
- void usage(char *name); /* -h */
- void play_ttt(void); /* main ttt function */
- void draw(void); /* draw the grid on the screen */
- void x_input(void); /* input X value */
- void o_input(void); /* input O value */
- void x_plot(int x_coord); /* update the grid */
- void o_plot(int o_coord);
- void sync_players(void); /* synchronize players */
- int continue_ttt(void);
- int check(char xoro); /* check for winner */
- void color_fix(int sig); /* signal handler */
- void reset_ttt(void); /* reset the ttt grid */
-
- /* global socket descriptors BADBADBAD! */
- int sockfd, newsockfd, sfd;
-
- /* two dimensional array for ttt grid */
- char ttt[3][3] = {{'1','2','3'},{'4','5','6'},{'7','8','9'}};
-
- /* player info struct */
- struct players {
- char remote[10]; /* usernames */
- char local[10];
- int x_or_o; /* are we X or O? */
- }player;
-
- /* duh */
- int main(int argc, char *argv[])
- {
- int arg;
- int cont = 1;
-
- signal(SIGKILL, color_fix);
- signal(SIGINT, color_fix);
-
- if(argc < 2)
- usage(argv[0]);
-
- while((arg=getopt(argc, argv, "i:lh")) != EOF)
- {
- switch(arg)
- {
- case 'i': /* initiate */
- {
- printf("%splayername>%s%s ",BOLDWHITE,END,RED);
- scanf("%9s", player.local);
- initiate(getip(optarg));
- while(cont == 1)
- {
- reset_ttt();
- sync_players();
- play_ttt();
- cont = continue_ttt();
- }
- close(sockfd);
- printf("%s", END);
- exit(0);
- }
- case 'l': /* listen */
- {
- printf("%splayername>%s%s ",BOLDWHITE,END,RED);
- scanf("%9s", player.local);
- wait_for_connection();
- while(cont == 1)
- {
- reset_ttt();
- sync_players();
- play_ttt();
- cont = continue_ttt();
- }
- close(sockfd);
- printf("%s", END);
- exit(0);
- }
- case 'h':
- {
- usage(argv[0]);
- }
- default:
- {
- usage(argv[0]);
- }
- }
- }
- return(0);
- }
-
- unsigned long getip(char *hostname)
- {
- struct hostent *he;
- if((he=gethostbyname(hostname)) == NULL) /* get that smaq */
- {
- herror("gethostbyname");
- printf("%s", END);
- exit(1);
- }
- return(inet_addr(inet_ntoa(*((struct in_addr *)he->h_addr)))); /* yuck. */
- }
-
- void usage(char *name)
- {
- fprintf(stderr, "%s%sTCP/IP TIC TAC TOE by r4lph%s\n",BGRED,BLUE,END);
- fprintf(stderr, "%susage: %s -l [ listen for a connection ]\n",BLUE, name);
- fprintf(stderr, " %s -i < remote host > [ initiate a connection ]\n", name);
- fprintf(stderr, " %s -h [ help ]%s\n", name, END);
- exit(0);
- }
-
- void draw(void)
- {
- (void)system("clear");
- printf("\n\n\n\n\n\n\n\n\n\n");
- printf("\t\t\t %s%c%s ║ %s %c %s ║ %s%c\n",BLUE,ttt[0][0],RED,BLUE,ttt[0][1],RED,BLUE,ttt[0][2]);
- printf("\t\t\t %s═══╬═════╬═══%s\n",RED,END);
- printf("\t\t\t %s%c%s ║ %s %c %s ║ %s%c\n",BLUE,ttt[1][0],RED,BLUE,ttt[1][1],RED,BLUE,ttt[1][2]);
- printf("\t\t\t %s═══╬═════╬═══%s\n", RED, END);
- printf("\t\t\t %s%c%s ║ %s %c %s ║ %s%c\n",BLUE,ttt[2][0],RED,BLUE,ttt[2][1],RED,BLUE,ttt[2][2]);
- }
-
- int continue_ttt(void)
- {
- char c;
- printf("\n%s\t\t Play another game? (y)es/(n)o:%s%s ",BOLDWHITE,END,RED);
- scanf("%1s", &c); /* PLEEZE SEY YES !@# */
- if(c == 'y' || c == 'Y')
- return(1);
- else
- return(0);
- }
-
- void reset_ttt(void)
- {
- ttt[0][0] = '1'; /* OINK */
- ttt[0][1] = '2';
- ttt[0][2] = '3';
- ttt[1][0] = '4';
- ttt[1][1] = '5';
- ttt[1][2] = '6';
- ttt[2][0] = '7';
- ttt[2][1] = '8';
- ttt[2][2] = '9';
- }
-
- void initiate(unsigned long ip)
- {
- struct sockaddr_in remote;
-
- player.x_or_o = X; /* we are X */
- bzero(&remote, sizeof(struct sockaddr_in));
- remote.sin_family = AF_INET;
- remote.sin_port = htons(PORT);
- remote.sin_addr.s_addr = ip;
-
- if((sfd=socket(AF_INET, SOCK_STREAM, 0)) == -1)
- {
- perror("socket");
- printf("%s", END);
- exit(1);
- }
- printf("%s%sWaiting for player...%s\n",END,BOLDWHITE,END);
- if(connect(sfd, (struct sockaddr *)&remote, sizeof(struct sockaddr)) == -1)
- {
- perror("connect");
- printf("%s", END);
- close(sfd);
- exit(1);
- }
- send(sfd, player.local, sizeof(player.local), 0);
- recv(sfd, player.remote, sizeof(player.remote), 0);
- printf("%s%sConnection established with%s%s %s [ %s ]%s\n",END,BOLDWHITE,END,RED,player.remote
- ,inet_ntoa(remote.sin_addr.s_addr),END);
- sleep(2);
- }
-
- void wait_for_connection(void)
- {
- struct sockaddr_in remote;
- struct sockaddr_in local;
- int addrlen;
-
- player.x_or_o = O; /* we are O */
- addrlen = sizeof(struct sockaddr_in);
-
- bzero(&remote, sizeof(struct sockaddr_in));
- bzero(&local, sizeof(struct sockaddr_in));
- local.sin_family = AF_INET;
- local.sin_port = htons(PORT);
- local.sin_addr.s_addr = INADDR_ANY;
-
- if((sockfd=socket(AF_INET, SOCK_STREAM, 0)) == -1)
- {
- perror("socket");
- printf("%s", END);
- exit(1);
- }
- if(bind(sockfd, (struct sockaddr *)&local, sizeof(struct sockaddr)) == -1)
- {
- perror("bind");
- printf("%s", END);
- close(sockfd);
- exit(1);
- }
- if(listen(sockfd, 1) == -1)
- {
- perror("listen");
- printf("%s", END);
-
- close(sockfd);
- exit(1);
- }
- printf("%s%sWaiting for player...\n%s",END,BOLDWHITE,END);
- if((newsockfd=accept(sockfd, (struct sockaddr *)&remote, &addrlen)) == -1)
- {
- perror("accept");
- printf("%s", END);
- close(sockfd);
- exit(1);
- }
- sfd = newsockfd;
- recv(sfd, player.remote, sizeof(player.remote), 0);
- send(sfd, player.local, sizeof(player.local), 0);
- printf("%s%sConnection established with %s%s%s [ %s ]%s\n",END,BOLDWHITE,END,RED, player.remote
- , inet_ntoa(remote.sin_addr.s_addr), END);
- sleep(2);
- }
-
- void x_input(void)
- {
- int coord;
- if(player.x_or_o == O)
- {
- recv(sfd, &coord, sizeof(coord), 0);
- x_plot(coord);
- draw();
- return;
- }
- printf("\n");
- printf("\t\t\t %s%sX>%s%s ",END,BOLDWHITE,END,RED);
- scanf("%d", &coord); /* d0nt LOSE !@#$ */
- send(sfd, &coord, sizeof(coord), 0);
- x_plot(coord);
- draw();
- return;
- }
-
- void o_input(void)
- {
- int coord;
- if(player.x_or_o == X)
- {
- recv(sfd, &coord, sizeof(coord), 0);
- o_plot(coord);
- draw();
- return;
- }
- printf("\n");
-
- printf("\t\t\t %s%sO>%s%s ",END,BOLDWHITE,END,RED);
- scanf("%d", &coord);
- send(sfd, &coord, sizeof(coord), 0);
- o_plot(coord);
- draw();
- return;
- }
-
- void x_plot(int x_coord)
- {
- switch(x_coord)
- {
- case 1:
- if(ttt[0][0] == 'o' || ttt[0][0] == 'x')
- {
- printf("%s\t\t\tLocation %d is occupied%s",BOLDWHITE, x_coord, END);
- x_input();
- }
- else
- ttt[0][0] = 'x'; break;
- case 2:
- if(ttt[0][1] == 'o' || ttt[0][1] == 'x')
- {
- printf("%s\t\t\tLocation %d is occupied%s",BOLDWHITE, x_coord, END);
- x_input();
- }
- else
- ttt[0][1] = 'x'; break;
- case 3:
- if(ttt[0][2] == 'o' || ttt[0][2] == 'x')
- {
- printf("%s\t\t\tLocation %d is occupied%s",BOLDWHITE, x_coord, END);
- x_input();
- }
- else
- ttt[0][2] = 'x'; break;
- case 4:
- if(ttt[1][0] == 'o' || ttt[1][0] == 'x')
- {
- printf("%s\t\t\tLocation %d is occupied%s",BOLDWHITE, x_coord, END);
- x_input();
- }
- else
- ttt[1][0] = 'x'; break;
- case 5:
- if(ttt[1][1] == 'o' || ttt[1][1] == 'x')
- {
- printf("%s\t\t\tLocation %d is occupied%s",BOLDWHITE, x_coord, END);
- x_input();
- }
- else
- ttt[1][1] = 'x'; break;
- case 6:
- if(ttt[1][2] == 'o' || ttt[1][2] == 'x')
- {
- printf("%s\t\t\tLocation %d is occupied%s",BOLDWHITE, x_coord, END);
- x_input();
- }
- else
- ttt[1][2] = 'x'; break;
- case 7:
- if(ttt[2][0] == 'o' || ttt[2][0] == 'x')
- {
- printf("%s\t\t\tLocation %d is occupied%s",BOLDWHITE, x_coord, END);
- x_input();
- }
- else
- ttt[2][0] = 'x'; break;
- case 8:
- if(ttt[2][1] == 'o' || ttt[2][1] == 'x')
- {
- printf("%s\t\t\tLocation %d is occupied%s",BOLDWHITE, x_coord, END);
- x_input();
- }
- else
- ttt[2][1] = 'x'; break;
- case 9:
- if(ttt[2][2] == 'o' || ttt[2][2] == 'x')
- {
- printf("%s\t\t\tLocation %d is occupied%s",BOLDWHITE, x_coord, END);
- x_input();
- }
- else
- ttt[2][2] = 'x'; break;
- }
- }
-
- void o_plot(int o_coord)
- {
- switch(o_coord)
- {
- case 1:
- if(ttt[0][0] == 'o' || ttt[0][0] == 'x')
- {
- printf("%s\t\t\tLocation %d is occupied%s",BOLDWHITE, o_coord, END);
- o_input();
- }
- else
- ttt[0][0] = 'o'; break;
- case 2:
- if(ttt[0][1] == 'o' || ttt[0][1] == 'x')
- {
- printf("%s\t\t\tLocation %d is occupied%s",BOLDWHITE, o_coord, END);
- o_input();
- }
- else
- ttt[0][1] = 'o'; break;
- case 3:
- if(ttt[0][2] == 'o' || ttt[0][2] == 'x')
- {
- printf("%s\t\t\tLocation %d is occupied%s",BOLDWHITE, o_coord, END);
- o_input();
- }
- else
- ttt[0][2] = 'o'; break;
- case 4:
- if(ttt[1][0] == 'o' || ttt[1][0] == 'x')
- {
- printf("%s\t\t\tLocation %d is occupied%s",BOLDWHITE, o_coord, END);
- o_input();
- }
- else
- ttt[1][0] = 'o'; break;
- case 5:
- if(ttt[1][1] == 'o' || ttt[1][1] == 'x')
- {
- printf("%s\t\t\tLocation %d is occupied%s",BOLDWHITE, o_coord, END);
- o_input();
- }
- else
- ttt[1][1] = 'o'; break;
- case 6:
- if(ttt[1][2] == 'o' || ttt[1][2] == 'x')
- {
- printf("%s\t\t\tLocation %d is occupied%s",BOLDWHITE, o_coord, END);
- o_input();
- }
- else
- ttt[1][2] = 'o'; break;
- case 7:
- if(ttt[2][0] == 'o' || ttt[2][0] == 'x')
- {
- printf("%s\t\t\tLocation %d is occupied%s",BOLDWHITE, o_coord, END);
- o_input();
- }
- else
- ttt[2][0] = 'o'; break;
- case 8:
- if(ttt[2][1] == 'o' || ttt[2][1] == 'x')
- {
- printf("%s\t\t\tLocation %d is occupied%s",BOLDWHITE, o_coord, END);
- o_input();
- }
- else
- ttt[2][1] = 'o'; break;
- case 9:
- if(ttt[2][2] == 'o' || ttt[2][2] == 'x')
- {
- printf("%s\t\t\tLocation %d is occupied%s",BOLDWHITE, o_coord, END);
- o_input();
- }
- else
- ttt[2][2] = 'o'; break;
- }
- }
-
- void sync_players(void)
- {
- char buf[7];
-
- if(player.x_or_o == X)
- {
- send(sfd, "sync", 5, 0);
- recv(sfd, buf, sizeof(buf), 0);
- if(strcmp("synced", buf) != 0)
- {
- fprintf(stderr, "%sCouldn't sync!%s\n", BOLDWHITE, END);
- close(sfd);
- exit(1);
- }
- }
- if(player.x_or_o == O)
- {
- recv(sfd, buf, sizeof(buf), 0);
- if(strcmp("sync", buf) != 0)
- {
- fprintf(stderr, "%sCouldn't sync!%s\n", BOLDWHITE, END);
- close(sfd);
- exit(1);
- }
- send(sfd, "synced", 7, 0);
- }
- }
-
- void play_ttt(void)
- {
- int c = 0;
-
- draw();
- for(;;)
- {
- x_input();
- if(check('x'))
- return;
- c++; /* heh */
- if(c==9)
- {
- return;
- }
- o_input();
- if(check('o'))
- return;
- c++; /* heh? */
- if(c==9)
- {
- return;
- }
- }
- }
-
- int check(char xoro) /* sorta sounds like porno */
- {
- int blah;
-
- if(xoro=='x')
- blah = X;
- if(xoro=='o')
- blah = O;
-
- if(ttt[0][0]==xoro && ttt[0][1]==xoro && ttt[0][2]==xoro)
- {
- if(player.x_or_o==blah)
- {
- printf("\n%s\t\t\t YOU WIN %s%s\n",GREEN, player.local, END);
- return(1); /* bewm */
- }
- printf("\n%s\t\t\t YOU LOSE %s%s\n",GREEN, player.local, END);
- return(1);
- }
- if(ttt[1][0]==xoro && ttt[1][1]==xoro && ttt[1][2]==xoro)
- {
- if(player.x_or_o==blah)
- {
- printf("\n%s\t\t\t YOU WIN %s%s\n",GREEN, player.local, END);
- return(1);
- }
- printf("\n%s\t\t\t YOU LOSE %s%s\n",GREEN, player.local, END);
- return(1);
- }
- if(ttt[2][0]==xoro && ttt[2][1]==xoro && ttt[2][2]==xoro)
- {
- if(player.x_or_o==blah)
- {
- printf("\n%s\t\t\t YOU WIN %s%s\n",GREEN, player.local, END);
- return(1);
- }
- printf("\n%s\t\t\t YOU LOSE %s%s\n",GREEN, player.local, END);
- return(1);
- }
- if(ttt[0][0]==xoro && ttt[1][0]==xoro && ttt[2][0]==xoro)
- {
- if(player.x_or_o==blah)
- {
- printf("\n%s\t\t\t YOU WIN %s%s\n",GREEN, player.local, END);
- return(1);
- }
- printf("\n%s\t\t\t YOU LOSE %s%s\n",GREEN, player.local, END);
- return(1);
- }
- if(ttt[0][1]==xoro && ttt[1][1]==xoro && ttt[2][1]==xoro)
- {
- if(player.x_or_o==blah)
- {
- printf("\n%s\t\t\t YOU WIN %s%s\n",GREEN, player.local, END);
- return(1);
- }
- printf("\n%s\t\t\t YOU LOSE %s%s\n",GREEN, player.local, END);
- return(1);
- }
- if(ttt[0][2]==xoro && ttt[1][2]==xoro && ttt[2][2]==xoro)
- {
- if(player.x_or_o==blah)
- {
- printf("\n%s\t\t\t YOU WIN %s%s\n",GREEN, player.local, END);
- return(1);
- }
- printf("\n%s\t\t\t YOU LOSE %s%s\n",GREEN, player.local, END);
- return(1);
- }
- if(ttt[0][0]==xoro && ttt[1][1]==xoro && ttt[2][2]==xoro)
- {
- if(player.x_or_o==blah)
- {
- printf("\n%s\t\t\t YOU WIN %s%s\n",GREEN, player.local, END);
- return(1);
- }
- printf("\n%s\t\t\t YOU LOSE %s%s\n",GREEN, player.local, END);
- return(1);
- }
- if(ttt[2][0]==xoro && ttt[1][1]==xoro && ttt[0][2]==xoro)
- {
- if(player.x_or_o==blah)
- {
- printf("\n%s\t\t\t YOU WIN %s%s\n",GREEN, player.local, END);
- return(1);
- }
- printf("\n%s\t\t\t YOU LOSE %s%s\n",GREEN, player.local, END);
- return(1);
- }
- return(0);
- }
-
- void color_fix(int sig)
- {
- printf("%s\n", END);
- close(sfd);
- exit(0);
- }
-