/* * 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 */ #include #include #include #include #include #include #include #include #include /* 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); }