/*  This code lets you play Tic-Tac-Toe against yourself!
    If you wish you may have your friend play against you, 
    the bottom-line is that this version is NOT on the network
    and both players get to use the same DISPLAY..

    I hope you enjoy playing this game and please, please
    send your comments to

      Solai, e-mail: solaiapp@ucunix.san.uc.edu       

    Looking forward to hear some favourable comments 
    and the due modifications for a next version.
    Thanks.

            -solaii

   P.S : Developed solely using Xlib.

                    */  




#include <stdio.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>

Display *mydisplay;
Window mywindow;
GC mygc;
unsigned long myfore,myback;
XImage *myimage;
int myscreen;
int I,J,s[3][3],IS;
int IW,TN;
Font font;

main(argc,argv)
int argc;
char **argv;
{            
 
        XEvent myevent;
        KeySym mykey;
        XSizeHints myhint;
        char text[10];
        char *b[5];
        int done,done1;     
        int i,j,x,y;
        XColor color;

        printf("\nxtic (Tic-Tac-Toe) 1993\n");
        printf("developed by Solaiappan, O @ Comp.Sc/U.C\n");
	mydisplay = XOpenDisplay("");
	myscreen = DefaultScreen(mydisplay);

        b[0] = " PLAYER O WON ";
        b[1] = " PLAYER + WON "; 
        b[2] = " PLAY IS DRAW ";   
        b[3] = "PRESS ANY KEY TO EXIT";  
        b[4] = "PRESS BUTTON TO CONTINUE";
 
        /* Default Pixel Values */

        /* Default Program-Specified Window Position and Size */
	myhint.x=200;
	myhint.y=300;
	myhint.width=440;
	myhint.height=440;
	myhint.flags = PPosition | PSize;

        IS = 0;

        /* Window Creation */
	mywindow = XCreateSimpleWindow(mydisplay,DefaultRootWindow(mydisplay),
			myhint.x,myhint.y,myhint.width,myhint.height,5,
			myfore,myback);
	XSetStandardProperties(mydisplay,mywindow,"Tic-Tac-Toe","ttt",None,argv,
		argc,&myhint);

        /* GC Creation and Initialization */
	mygc = XCreateGC(mydisplay,mywindow,0,0);
        myback = WhitePixel(mydisplay,myscreen); 
        myfore = BlackPixel(mydisplay,myscreen);
        XSetForeground(mydisplay,mygc,myfore);  
        for(i=0;i<=2;++i) for(j=0;j<=2;++j) s[i][j] = -1;  
        XSetForeground(mydisplay,mygc,myback);      
        /* Input Event Selection */ 
	XSelectInput(mydisplay,mywindow, ButtonPressMask | ExposureMask |                            KeyPressMask);

        /* Window Mapping */
	XMapRaised(mydisplay,mywindow);
        font = XLoadFont(mydisplay,"10x20");
        XSetFont(mydisplay,mygc,font);

        /* Main Event-Reading Loop */
        done1 = 0;
        while(done1 == 0) 
        {  
	done = 0;
	while(done == 0)
	{
       
                /* Read the Next Event */
		XNextEvent(mydisplay, &myevent);
		switch(myevent.type)
		{
      
                        /* Repaint the Window on Expose Events */
			case Expose:  
                    	      do_set_up(); 
                              break; 
     
                        /* Process Mouse Button Presses */
			case ButtonPress:
                        x = myevent.xbutton.x;
                        y = myevent.xbutton.y;
                        I = -1;
                        J = -1;
                        if(x >= 20 && x <= 140) I = 0;
                        if(x >=160 && x <= 280) I = 1;
                        if(x >= 300 && x <= 420) I = 2;
                        if(y >= 20 && y <= 140) J = 0;
                        if(y >= 160 && y <= 280) J = 1;
                        if(y >= 300 && y <= 420) J = 2; 
                        if(I >= 0 && J >= 0 && s[I][J] == -1) symbol(); 
                        check();  
                        if(IW >= 0)   done = 1;
                        if(TN ==  9)   done = 1;  
                        break; 
                  case KeyPress : exit(1); 
                     }
                   }
                  XSetForeground(mydisplay,mygc,myfore);
                  XFillRectangle(mydisplay,mywindow,mygc,70,175,300,90); 
         	  XSetForeground(mydisplay,mygc,myback);  
                  XFillRectangle(mydisplay,mywindow,mygc,80,185,280,70);
                  XSetForeground(mydisplay,mygc,myfore);
                  XSetBackground(mydisplay,mygc,myback);
      if(TN == 9) XDrawImageString(mydisplay,mywindow,mygc,150,205,b[2],15);  
      if(IW >= 0) XDrawImageString(mydisplay,mywindow,mygc,140,208,b[IW],15); 
                  XDrawImageString(mydisplay,mywindow,mygc,100,228,b[4],24); 
                  XDrawImageString(mydisplay,mywindow,mygc,115,248,b[3],21);
                  XNextEvent(mydisplay,&myevent);
                  switch (myevent.type)
                  { case ButtonPress :
                     done = 0;
                  for(i=0;i<=2;++i) for(j=0;j<=2;++j) s[i][j] = -1;
                  do_set_up();
                   TN = 0; 
                    IS = 0;     
                     break;
                  case KeyPress :
                       done1 = 1;
                       break;
                       }  
       }   
}

/* This function sets up game workspace. */  
do_set_up()
{
	int i,j;
        int x,y;

        XSetForeground(mydisplay,mygc,myfore);
        XFillRectangle(mydisplay,mywindow,mygc,0,0,480,480); 
        XSetForeground(mydisplay,mygc,myback);
        for(i=0;i<=2;++i) for(j=0;j<=2;++j) {
                            x = 20 +140*i;
                            y = 20 +140*j;
                            XFillRectangle(mydisplay,mywindow,mygc,x,y,120,120);
                                            }
           for(i=0;i<=2;++i) for(j=0;j<=2;++j)Symbol(i,j,s[i][j]);
}

/* This function draws symbols one after another. */
symbol()
{
     int x,y;

     XSetForeground(mydisplay,mygc,myfore);
     TN = TN + 1; 
     s[I][J] = IS;
                   x = 20 + 140*I;
                   y = 20 + 140*J;
     if(IS == 0) { x = x + 20;
                   y = y + 20; 
                   XFillArc(mydisplay,mywindow,mygc,x,y,80,80,0,360*64);
                   XSetForeground(mydisplay,mygc,myback);
                   x = x + 15;
                   y = y + 15;
                   XFillArc(mydisplay,mywindow,mygc,x,y,50,50,0,360*64);
                      }
     if(IS == 1) { x = x + 50;
                   y = y + 20;
                   XFillRectangle(mydisplay,mywindow,mygc,x,y,20,80);
                   x = x - 30;
                   y = y + 30;
                   XFillRectangle(mydisplay,mywindow,mygc,x,y,80,20);
                      }
     IS = IS + 1;
     IS = IS % 2;   
}

Symbol(II,JJ,V)
int II,JJ,V;

{
  int x,y;

  XSetForeground(mydisplay,mygc,myfore);

  x = 20 + 140*II;
  y = 20 + 140*JJ;

  if(V == 0) { x = x +20;
                y = y + 20;
                XFillArc(mydisplay,mywindow,mygc,x,y,80,80,0,360*64);
                XSetForeground(mydisplay,mygc,myback); 

                x = x + 15; 
                y = y + 15;
                XFillArc(mydisplay,mywindow,mygc,x,y,50,50,0,360*64);
                   }
   if (V == 1) { x = x + 50;
                 y = y + 20;
                 XFillRectangle(mydisplay,mywindow,mygc,x,y,20,80);
                 x = x - 30;
                 y = y + 30;
                 XFillRectangle(mydisplay,mywindow,mygc,x,y,80,20);
                 }

 }
check()
{
  int i,j,k;
  IW = -1;
  for(k=0;k<=1;++k) {    
      for(i=0;i<=2;++i){
            j = 0;
            while(j<=2) { if(k != s[i][j]) break;
                             j = j + 1; }  
                    j = j - 1;  
                  if(j == 2 && k == s[i][j])  IW = k;
              j = 0; 
            while(j<=2) {if(k != s[j][i]) break;
                             j = j + 1;  }  
                   j = j - 1;  
                  if(j == 2 && k == s[j][i])  IW = k;

                           }
          if(s[0][0] == k && s[1][1] == k && s[2][2] == k) IW = k; 
          if(s[0][2] == k && s[1][1] == k && s[2][0] == k) IW = k;  
                } 
}    
