home *** CD-ROM | disk | FTP | other *** search
/ Power Hacker 2003 / Power_Hacker_2003.iso / E-zine / Magazines / b4b0 / b4b0-05 / nttt.c < prev    next >
Encoding:
C/C++ Source or Header  |  2002-05-27  |  15.6 KB  |  619 lines

  1. /* 
  2.  * nttt.c - TCP/IP TIC TAC TOE by r4lph
  3.  *          You guessed it. Tic tac toe, taken to the next level. Play your
  4.  *          friends, play your mom, even play so1o! Works on *BSD* and Linux
  5.  *          as far as I know. Mail r4lph@b4b0.org if it works on your non 
  6.  *          *BSD*\Linux system. If you don't like something in the code, 
  7.  *          for christs sake, don't tell me, just change it. Don't distribute
  8.  *          modified versions, blah blah blah. The connector will always be
  9.  *          X and the connected to will be O. 
  10.  * compile: cc -O2 -o nttt nttt.c
  11.  * Have fun.
  12.  * Oct. 18/1998
  13.  * r4lph <r4lph@b4b0.org>
  14. */
  15.  
  16. #include <stdio.h>
  17. #include <stdlib.h>
  18. #include <unistd.h>
  19. #include <string.h>
  20. #include <netdb.h>
  21. #include <signal.h>
  22. #include <sys/types.h>
  23. #include <sys/socket.h>
  24. #include <netinet/in.h>
  25.  
  26. /* defines */
  27. #define X 1
  28. #define O 0
  29. #define PORT 9876
  30.  
  31. /* color defines */
  32. #define END        ""
  33. #define RED        ""
  34. #define GREEN        ""
  35. #define BLUE        ""
  36. #define BOLDWHITE    ""
  37. #define BGRED        ""
  38.  
  39. /* function prototypes */
  40. int main(int argc, char *argv[]);     /* duh */
  41. unsigned long getip(char *hostname);  /* resolve hostname */
  42. void initiate(unsigned long ip);      /* initiate a connection */
  43. void wait_for_connection(void);       /* listen for a connection */
  44. void usage(char *name);               /* -h */
  45. void play_ttt(void);                  /* main ttt function */
  46. void draw(void);                      /* draw the grid on the screen */
  47. void x_input(void);                   /* input X value */
  48. void o_input(void);                   /* input O value */
  49. void x_plot(int x_coord);             /* update the grid */
  50. void o_plot(int o_coord);
  51. void sync_players(void);              /* synchronize players */
  52. int continue_ttt(void);               
  53. int check(char xoro);                 /* check for winner */
  54. void color_fix(int sig);                 /* signal handler */
  55. void reset_ttt(void);                 /* reset the ttt grid */
  56.  
  57. /* global socket descriptors BADBADBAD! */
  58. int sockfd, newsockfd, sfd;
  59.  
  60. /* two dimensional array for ttt grid */
  61. char ttt[3][3] = {{'1','2','3'},{'4','5','6'},{'7','8','9'}};
  62.  
  63. /* player info struct */
  64. struct players {
  65.    char remote[10]; /* usernames */
  66.    char local[10];
  67.    int x_or_o; /* are we X or O? */
  68. }player;
  69.  
  70. /* duh */
  71. int main(int argc, char *argv[])
  72. {
  73.    int arg;
  74.    int cont = 1;
  75.    
  76.    signal(SIGKILL, color_fix);
  77.    signal(SIGINT, color_fix);
  78.       
  79.    if(argc < 2)
  80.      usage(argv[0]);
  81.    
  82.    while((arg=getopt(argc, argv, "i:lh")) != EOF)
  83.      {
  84.     switch(arg)
  85.       {
  86.        case 'i':  /* initiate */
  87.            {
  88.           printf("%splayername>%s%s ",BOLDWHITE,END,RED);
  89.           scanf("%9s", player.local);
  90.           initiate(getip(optarg));
  91.           while(cont == 1)
  92.             {
  93.                reset_ttt();
  94.                sync_players();
  95.                play_ttt();
  96.                cont = continue_ttt();
  97.             }
  98.           close(sockfd);
  99.           printf("%s", END);
  100.           exit(0);
  101.            }
  102.        case 'l':  /* listen */
  103.            {
  104.           printf("%splayername>%s%s ",BOLDWHITE,END,RED);
  105.           scanf("%9s", player.local);
  106.           wait_for_connection();
  107.           while(cont == 1)
  108.             {
  109.                reset_ttt();
  110.                sync_players();
  111.                play_ttt();
  112.                cont = continue_ttt();
  113.             }
  114.           close(sockfd);
  115.           printf("%s", END);
  116.           exit(0);
  117.            }
  118.        case 'h':
  119.            {
  120.           usage(argv[0]);
  121.            }
  122.        default:
  123.            {
  124.           usage(argv[0]);
  125.            }
  126.       }
  127.      }   
  128.    return(0);
  129. }
  130.  
  131. unsigned long getip(char *hostname)
  132. {
  133.    struct hostent *he;
  134.    if((he=gethostbyname(hostname)) == NULL) /* get that smaq */
  135.      {
  136.     herror("gethostbyname");
  137.     printf("%s", END);
  138.     exit(1);
  139.      }
  140.    return(inet_addr(inet_ntoa(*((struct in_addr *)he->h_addr)))); /* yuck. */
  141. }
  142.  
  143. void usage(char *name)
  144. {
  145.    fprintf(stderr, "%s%sTCP/IP TIC TAC TOE by r4lph%s\n",BGRED,BLUE,END);
  146.    fprintf(stderr, "%susage: %s -l                 [ listen for a connection ]\n",BLUE, name);
  147.    fprintf(stderr, "       %s -i < remote host > [ initiate a connection ]\n", name);
  148.    fprintf(stderr, "       %s -h                 [ help ]%s\n", name, END);
  149.    exit(0);
  150. }
  151.  
  152. void draw(void)
  153. {
  154.    (void)system("clear");
  155.    printf("\n\n\n\n\n\n\n\n\n\n");
  156.    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]);
  157.    printf("\t\t\t   %s═══╬═════╬═══%s\n",RED,END);
  158.    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]);
  159.    printf("\t\t\t   %s═══╬═════╬═══%s\n", RED, END);
  160.    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]);
  161. }
  162.  
  163. int continue_ttt(void)
  164. {
  165.    char c;
  166.    printf("\n%s\t\t   Play another game? (y)es/(n)o:%s%s ",BOLDWHITE,END,RED);
  167.    scanf("%1s", &c); /* PLEEZE SEY YES !@# */
  168.    if(c == 'y' || c == 'Y')
  169.      return(1);
  170.    else
  171.      return(0);
  172. }
  173.  
  174. void reset_ttt(void)
  175. {
  176.    ttt[0][0] = '1'; /* OINK */
  177.    ttt[0][1] = '2';
  178.    ttt[0][2] = '3';
  179.    ttt[1][0] = '4';
  180.    ttt[1][1] = '5';
  181.    ttt[1][2] = '6';
  182.    ttt[2][0] = '7';
  183.    ttt[2][1] = '8';
  184.    ttt[2][2] = '9';
  185. }
  186.  
  187. void initiate(unsigned long ip)
  188. {
  189.    struct sockaddr_in remote;
  190.    
  191.    player.x_or_o = X;  /* we are X */
  192.    bzero(&remote, sizeof(struct sockaddr_in));
  193.    remote.sin_family = AF_INET;
  194.    remote.sin_port = htons(PORT);
  195.    remote.sin_addr.s_addr = ip;
  196.    
  197.    if((sfd=socket(AF_INET, SOCK_STREAM, 0)) == -1)
  198.      {
  199.     perror("socket");
  200.     printf("%s", END);
  201.     exit(1);
  202.      }
  203.    printf("%s%sWaiting for player...%s\n",END,BOLDWHITE,END);
  204.    if(connect(sfd, (struct sockaddr *)&remote, sizeof(struct sockaddr)) == -1)
  205.      {
  206.     perror("connect");
  207.     printf("%s", END);
  208.     close(sfd);
  209.     exit(1);
  210.      }
  211.    send(sfd, player.local, sizeof(player.local), 0);
  212.    recv(sfd, player.remote, sizeof(player.remote), 0);
  213.    printf("%s%sConnection established with%s%s %s [ %s ]%s\n",END,BOLDWHITE,END,RED,player.remote
  214.                                     ,inet_ntoa(remote.sin_addr.s_addr),END);
  215.    sleep(2);
  216. }
  217.  
  218. void wait_for_connection(void)
  219. {
  220.    struct sockaddr_in remote;
  221.    struct sockaddr_in local;
  222.    int addrlen;
  223.       
  224.    player.x_or_o = O;  /* we are O */
  225.    addrlen = sizeof(struct sockaddr_in);
  226.    
  227.    bzero(&remote, sizeof(struct sockaddr_in));
  228.    bzero(&local, sizeof(struct sockaddr_in));
  229.    local.sin_family = AF_INET;
  230.    local.sin_port = htons(PORT);
  231.    local.sin_addr.s_addr = INADDR_ANY;
  232.    
  233.    if((sockfd=socket(AF_INET, SOCK_STREAM, 0)) == -1)
  234.      {
  235.     perror("socket");
  236.     printf("%s", END);
  237.     exit(1);
  238.      }
  239.    if(bind(sockfd, (struct sockaddr *)&local, sizeof(struct sockaddr)) == -1)
  240.      {
  241.     perror("bind");
  242.     printf("%s", END);
  243.     close(sockfd);
  244.     exit(1);
  245.      }
  246.    if(listen(sockfd, 1) == -1)
  247.      {
  248.     perror("listen");
  249.     printf("%s", END);
  250.  
  251.     close(sockfd);
  252.     exit(1);
  253.      }
  254.    printf("%s%sWaiting for player...\n%s",END,BOLDWHITE,END);
  255.    if((newsockfd=accept(sockfd, (struct sockaddr *)&remote, &addrlen)) == -1)
  256.      {
  257.     perror("accept");
  258.     printf("%s", END);
  259.     close(sockfd);
  260.     exit(1);
  261.      }
  262.    sfd = newsockfd;
  263.    recv(sfd, player.remote, sizeof(player.remote), 0);
  264.    send(sfd, player.local, sizeof(player.local), 0);
  265.    printf("%s%sConnection established with %s%s%s [ %s ]%s\n",END,BOLDWHITE,END,RED, player.remote
  266.                                               , inet_ntoa(remote.sin_addr.s_addr), END);
  267.    sleep(2);
  268. }
  269.  
  270. void x_input(void)
  271. {
  272.    int coord;
  273.    if(player.x_or_o == O)
  274.      {
  275.     recv(sfd, &coord, sizeof(coord), 0);
  276.     x_plot(coord);
  277.     draw();
  278.     return;
  279.      }
  280.    printf("\n");
  281.    printf("\t\t\t    %s%sX>%s%s ",END,BOLDWHITE,END,RED);
  282.    scanf("%d", &coord);   /* d0nt LOSE !@#$ */
  283.    send(sfd, &coord, sizeof(coord), 0);
  284.    x_plot(coord);
  285.    draw();
  286.    return;
  287. }
  288.  
  289. void o_input(void)
  290. {
  291.    int coord;
  292.    if(player.x_or_o == X)
  293.      {
  294.     recv(sfd, &coord, sizeof(coord), 0);
  295.     o_plot(coord);
  296.     draw();
  297.     return;
  298.      }
  299.    printf("\n");
  300.    
  301.    printf("\t\t\t    %s%sO>%s%s ",END,BOLDWHITE,END,RED);
  302.    scanf("%d", &coord);
  303.    send(sfd, &coord, sizeof(coord), 0);
  304.    o_plot(coord);
  305.    draw();
  306.    return;
  307. }
  308.  
  309. void x_plot(int x_coord)
  310. {
  311.    switch(x_coord)
  312.      {
  313.       case 1:
  314.         if(ttt[0][0] == 'o' || ttt[0][0] == 'x')
  315.           {
  316.              printf("%s\t\t\tLocation %d is occupied%s",BOLDWHITE, x_coord, END);
  317.              x_input();
  318.           }
  319.         else
  320.           ttt[0][0] = 'x'; break;
  321.       case 2:
  322.         if(ttt[0][1] == 'o' || ttt[0][1] == 'x')
  323.           {
  324.              printf("%s\t\t\tLocation %d is occupied%s",BOLDWHITE, x_coord, END);
  325.              x_input();
  326.           }
  327.         else
  328.           ttt[0][1] = 'x'; break;
  329.       case 3:
  330.         if(ttt[0][2] == 'o' || ttt[0][2] == 'x')
  331.           {
  332.              printf("%s\t\t\tLocation %d is occupied%s",BOLDWHITE, x_coord, END);
  333.              x_input();
  334.           }
  335.         else
  336.           ttt[0][2] = 'x'; break;
  337.       case 4:
  338.         if(ttt[1][0] == 'o' || ttt[1][0] == 'x')
  339.           {
  340.              printf("%s\t\t\tLocation %d is occupied%s",BOLDWHITE, x_coord, END);
  341.              x_input();
  342.           }
  343.         else
  344.           ttt[1][0] = 'x'; break;
  345.       case 5:
  346.         if(ttt[1][1] == 'o' || ttt[1][1] == 'x')
  347.           {
  348.              printf("%s\t\t\tLocation %d is occupied%s",BOLDWHITE, x_coord, END);
  349.              x_input();
  350.           }
  351.         else
  352.           ttt[1][1] = 'x'; break;
  353.       case 6:
  354.         if(ttt[1][2] == 'o' || ttt[1][2] == 'x')
  355.           {
  356.              printf("%s\t\t\tLocation %d is occupied%s",BOLDWHITE, x_coord, END);
  357.              x_input();
  358.           }
  359.         else
  360.           ttt[1][2] = 'x'; break;
  361.       case 7:
  362.         if(ttt[2][0] == 'o' || ttt[2][0] == 'x')
  363.           {
  364.              printf("%s\t\t\tLocation %d is occupied%s",BOLDWHITE, x_coord, END);
  365.              x_input();
  366.           }
  367.         else
  368.           ttt[2][0] = 'x'; break;
  369.       case 8:
  370.         if(ttt[2][1] == 'o' || ttt[2][1] == 'x')
  371.           {
  372.              printf("%s\t\t\tLocation %d is occupied%s",BOLDWHITE, x_coord, END);
  373.              x_input();
  374.           }
  375.              else
  376.           ttt[2][1] = 'x'; break;
  377.       case 9:
  378.         if(ttt[2][2] == 'o' || ttt[2][2] == 'x')
  379.           {
  380.              printf("%s\t\t\tLocation %d is occupied%s",BOLDWHITE, x_coord, END);
  381.              x_input();
  382.           }
  383.         else
  384.           ttt[2][2] = 'x'; break;
  385.      }
  386. }
  387.  
  388. void o_plot(int o_coord)
  389. {
  390.    switch(o_coord)
  391.      {
  392.       case 1:
  393.         if(ttt[0][0] == 'o' || ttt[0][0] == 'x')
  394.           {
  395.              printf("%s\t\t\tLocation %d is occupied%s",BOLDWHITE, o_coord, END);
  396.              o_input();
  397.           }
  398.         else
  399.           ttt[0][0] = 'o'; break;
  400.       case 2:
  401.         if(ttt[0][1] == 'o' || ttt[0][1] == 'x')
  402.           {
  403.              printf("%s\t\t\tLocation %d is occupied%s",BOLDWHITE, o_coord, END);
  404.              o_input();
  405.           }
  406.         else
  407.           ttt[0][1] = 'o'; break;
  408.       case 3:
  409.         if(ttt[0][2] == 'o' || ttt[0][2] == 'x')
  410.           {
  411.              printf("%s\t\t\tLocation %d is occupied%s",BOLDWHITE, o_coord, END);
  412.              o_input();
  413.           }
  414.         else
  415.           ttt[0][2] = 'o'; break;
  416.       case 4:
  417.         if(ttt[1][0] == 'o' || ttt[1][0] == 'x')
  418.           {
  419.              printf("%s\t\t\tLocation %d is occupied%s",BOLDWHITE, o_coord, END);
  420.              o_input();
  421.           }
  422.         else
  423.           ttt[1][0] = 'o'; break;
  424.       case 5:
  425.         if(ttt[1][1] == 'o' || ttt[1][1] == 'x')
  426.           {
  427.              printf("%s\t\t\tLocation %d is occupied%s",BOLDWHITE, o_coord, END);
  428.              o_input();
  429.           }
  430.         else
  431.           ttt[1][1] = 'o'; break;
  432.       case 6:
  433.         if(ttt[1][2] == 'o' || ttt[1][2] == 'x')
  434.           {
  435.              printf("%s\t\t\tLocation %d is occupied%s",BOLDWHITE, o_coord, END);
  436.              o_input();
  437.           }
  438.         else
  439.           ttt[1][2] = 'o'; break;
  440.       case 7:
  441.         if(ttt[2][0] == 'o' || ttt[2][0] == 'x')
  442.           {
  443.              printf("%s\t\t\tLocation %d is occupied%s",BOLDWHITE, o_coord, END);
  444.              o_input();
  445.           }
  446.         else
  447.           ttt[2][0] = 'o'; break;
  448.       case 8:
  449.         if(ttt[2][1] == 'o' || ttt[2][1] == 'x')
  450.           {
  451.              printf("%s\t\t\tLocation %d is occupied%s",BOLDWHITE, o_coord, END);
  452.              o_input();
  453.           }
  454.         else
  455.           ttt[2][1] = 'o'; break;
  456.       case 9:
  457.         if(ttt[2][2] == 'o' || ttt[2][2] == 'x')
  458.           {
  459.              printf("%s\t\t\tLocation %d is occupied%s",BOLDWHITE, o_coord, END);
  460.              o_input();
  461.           }
  462.         else
  463.           ttt[2][2] = 'o'; break;
  464.      }
  465. }
  466.    
  467. void sync_players(void)
  468. {
  469. char buf[7];
  470.    
  471. if(player.x_or_o == X)
  472.   {
  473.      send(sfd, "sync", 5, 0);
  474.      recv(sfd, buf, sizeof(buf), 0);
  475.      if(strcmp("synced", buf) != 0)
  476.        {
  477.       fprintf(stderr, "%sCouldn't sync!%s\n", BOLDWHITE, END);
  478.       close(sfd);
  479.       exit(1);
  480.        }
  481.   }  
  482. if(player.x_or_o == O)
  483.   {
  484.      recv(sfd, buf, sizeof(buf), 0);
  485.      if(strcmp("sync", buf) != 0)
  486.        {
  487.       fprintf(stderr, "%sCouldn't sync!%s\n", BOLDWHITE, END);
  488.       close(sfd);
  489.       exit(1);
  490.        }
  491.      send(sfd, "synced", 7, 0);
  492.   }
  493. }
  494.  
  495. void play_ttt(void)
  496. {
  497. int c = 0;
  498.    
  499. draw();
  500. for(;;)
  501.   {  
  502.      x_input();
  503.      if(check('x'))
  504.        return;
  505.      c++; /* heh */
  506.      if(c==9)
  507.        { 
  508.       return;
  509.        }
  510.      o_input();
  511.      if(check('o'))
  512.        return;
  513.      c++; /* heh? */
  514.      if(c==9)
  515.        {
  516.       return;
  517.        }
  518.   }
  519. }
  520.  
  521. int check(char xoro)  /* sorta sounds like porno */
  522. {
  523.    int blah;
  524.    
  525.    if(xoro=='x')
  526.      blah = X;
  527.    if(xoro=='o')
  528.      blah = O;
  529.    
  530.    if(ttt[0][0]==xoro && ttt[0][1]==xoro && ttt[0][2]==xoro)
  531.      {
  532.     if(player.x_or_o==blah)
  533.       {
  534.          printf("\n%s\t\t\t   YOU WIN %s%s\n",GREEN, player.local, END);
  535.          return(1);  /* bewm */
  536.       }
  537.     printf("\n%s\t\t\t   YOU LOSE %s%s\n",GREEN, player.local, END);
  538.     return(1);
  539.      }
  540.    if(ttt[1][0]==xoro && ttt[1][1]==xoro && ttt[1][2]==xoro)
  541.      {
  542.         if(player.x_or_o==blah)
  543.           {
  544.              printf("\n%s\t\t\t   YOU WIN %s%s\n",GREEN, player.local, END);
  545.              return(1);
  546.           }
  547.         printf("\n%s\t\t\t   YOU LOSE %s%s\n",GREEN, player.local, END);
  548.         return(1);
  549.      }
  550.    if(ttt[2][0]==xoro && ttt[2][1]==xoro && ttt[2][2]==xoro)
  551.      {
  552.         if(player.x_or_o==blah)
  553.           {
  554.              printf("\n%s\t\t\t   YOU WIN %s%s\n",GREEN, player.local, END);
  555.              return(1);
  556.           }
  557.         printf("\n%s\t\t\t   YOU LOSE %s%s\n",GREEN, player.local, END);
  558.         return(1);
  559.      }
  560.    if(ttt[0][0]==xoro && ttt[1][0]==xoro && ttt[2][0]==xoro)
  561.      {
  562.         if(player.x_or_o==blah)
  563.           {
  564.              printf("\n%s\t\t\t   YOU WIN %s%s\n",GREEN, player.local, END);
  565.              return(1);
  566.           }
  567.         printf("\n%s\t\t\t   YOU LOSE %s%s\n",GREEN, player.local, END);
  568.         return(1);
  569.      }
  570.    if(ttt[0][1]==xoro && ttt[1][1]==xoro && ttt[2][1]==xoro)
  571.      {
  572.         if(player.x_or_o==blah)
  573.           {
  574.              printf("\n%s\t\t\t   YOU WIN %s%s\n",GREEN, player.local, END);
  575.              return(1);
  576.           }
  577.         printf("\n%s\t\t\t   YOU LOSE %s%s\n",GREEN, player.local, END);
  578.         return(1);
  579.      }
  580.    if(ttt[0][2]==xoro && ttt[1][2]==xoro && ttt[2][2]==xoro)
  581.      {
  582.         if(player.x_or_o==blah)
  583.           {
  584.              printf("\n%s\t\t\t   YOU WIN %s%s\n",GREEN, player.local, END);
  585.              return(1);
  586.           }
  587.         printf("\n%s\t\t\t   YOU LOSE %s%s\n",GREEN, player.local, END);
  588.         return(1);
  589.      }
  590.    if(ttt[0][0]==xoro && ttt[1][1]==xoro && ttt[2][2]==xoro)
  591.      {
  592.         if(player.x_or_o==blah)
  593.           {
  594.              printf("\n%s\t\t\t   YOU WIN %s%s\n",GREEN, player.local, END);
  595.              return(1);
  596.           }
  597.         printf("\n%s\t\t\t   YOU LOSE %s%s\n",GREEN, player.local, END);
  598.         return(1);
  599.      }
  600.    if(ttt[2][0]==xoro && ttt[1][1]==xoro && ttt[0][2]==xoro)
  601.      {
  602.         if(player.x_or_o==blah)
  603.           {
  604.              printf("\n%s\t\t\t   YOU WIN %s%s\n",GREEN, player.local, END);
  605.              return(1);
  606.           }
  607.         printf("\n%s\t\t\t   YOU LOSE %s%s\n",GREEN, player.local, END);
  608.         return(1);
  609.      }
  610.    return(0);
  611. }
  612.  
  613. void color_fix(int sig)
  614. {
  615.    printf("%s\n", END);
  616.    close(sfd);
  617.    exit(0);
  618. }
  619.