//#include <windows.h>   // use as needed for your system
#include <math.h>
#include <GL/gl.h>
#include <GL/glut.h>
#include <stdio.h>
#define GAMESIZE 3

//int field[GAMESIZE][GAMESIZE]={{0,1,2},{1,2,0},{2,0,1}};
int field[GAMESIZE][GAMESIZE];
int win=0;

//<<<<<<<<<<<<<<<<<<<<<<< myInit >>>>>>>>>>>>>>>>>>>>
 void myInit(void)
 {
    glClearColor(1.0,1.0,1.0,0.0);       // set white background color
    glColor3f(0.0f, 0.0f, 0.0f);          // set the drawing color 
 	glPointSize(4.0);
 	glLineWidth(4.0);
	glMatrixMode(GL_PROJECTION); 
	glLoadIdentity();
	gluOrtho2D(0.0, 640.0, 0.0, 480.0);
}
//<<<<<<<<<<<<<<<<<<<<<<<< myDisplay >>>>>>>>>>>>>>>>>
void myDisplay(void)
{
	glClear(GL_COLOR_BUFFER_BIT);     // clear the screen 
// draw the field
 	glLineWidth(4.0);
	glBegin(GL_LINES);
		glVertex2i(100, 200);
		glVertex2i(400, 200);
		glVertex2i(200, 100);
		glVertex2i(200, 400);
		glVertex2i(100, 300);
		glVertex2i(400, 300);
		glVertex2i(300, 100);
		glVertex2i(300, 400);
	glEnd();
 	glLineWidth(6.0);
//draw the state of the game	
	for (int x=0;x<GAMESIZE;x++)
		for (int y=0;y<GAMESIZE;y++){
		switch (field[x][y])
		{
		case 1: // the cross
			glBegin(GL_LINES);
			glVertex2i(120+x*100, 120+y*100);
			glVertex2i(180+x*100, 180+y*100);
			glVertex2i(180+x*100, 120+y*100);
			glVertex2i(120+x*100, 180+y*100);
			glEnd();	
			break;
		case 2: // the circle
			double angle =0;
			double angleInc = 2*M_PI/16;
			glBegin(GL_LINE_LOOP);
			glVertex2d(40*cos(angle) + 150+100*x,40*sin(angle)+150+100*y);
			for (int k=0;k<16;k++)
			{
			angle+=angleInc;
			glVertex2d(40*cos(angle) + 150+100*x,40*sin(angle)+150+100*y);
			}
			glEnd();	
		}
		}
//detect a winner
 	glLineWidth(8.0);
// x winner
	for (int x=0;x<GAMESIZE;x++){
		if ((field[x][0]+field[x][1]+field[x][2]>0) && (field[x][0]==field[x][1]) && (field[x][1]==field[x][2]))
		{
		// x-winner detected
		glBegin(GL_LINES);
		glVertex2i(150+x*100, 100);
		glVertex2i(150+x*100, 400);
		glEnd();
		win=1;
		}
	}
// y winner
	for (int y=0;y<GAMESIZE;y++){
		if ((field[0][y]+field[1][y]+field[2][y]>0) && (field[0][y]==field[1][y]) && (field[1][y]==field[2][y]))
		{
		// y-winner detected
		glBegin(GL_LINES);
		glVertex2i(100,150+y*100);
		glVertex2i(400,150+y*100);
		glEnd();
		win=1;
		}
	}
// diagonal winner 
		if ((field[0][0]+field[1][1]+field[2][2]>0) && (field[0][0]==field[1][1]) && (field[1][1]==field[2][2]))
		{
		glBegin(GL_LINES);
		glVertex2i(100,100);
		glVertex2i(400,400);
		glEnd();
		win=1;
		}

// diagonal winner 
		if ((field[0][2]+field[1][1]+field[2][0]>0) && (field[0][2]==field[1][1]) && (field[1][1]==field[2][0]))
		{
		glBegin(GL_LINES);
		glVertex2i(100,400);
		glVertex2i(400,100);
		glEnd();
		win=1;
		}
//draw everything
	glFlush();		                 // send all output to display 
}

void myMouse(int button, int state, int x, int y)
{
    static int who=1;
    if(button == GLUT_LEFT_BUTTON && state == GLUT_DOWN)
	 {

		int fx=(x-100)/100;
		int fy=((480-y)-100)/100;
//		printf("fx=%d,fy=%d,state=%d\n",fx,fy,who);
		
		if ((win==0) && (fx>=0) && (fx<=2) && (fy>=0) && (fy<=2) && (field[fx][fy]==0))
		{
//		printf("set field[%d,%d]=%d\n",fx,fy,who);
		field[fx][fy]=who;
		if (who==2) {who=1;} else {who=2;}
		}

	 }
	 else if(button == GLUT_RIGHT_BUTTON && state == GLUT_DOWN)
	{
	for (int x=0;x<GAMESIZE;x++)
		for (int y=0;y<GAMESIZE;y++){ field[x][y]=0;}
	win=0;
	}
	myDisplay();
}




//<<<<<<<<<<<<<<<<<<<<<<<< main >>>>>>>>>>>>>>>>>>>>>>
int main(int argc, char** argv)
{
	glutInit(&argc, argv);          // initialize the toolkit
	glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB); // set display mode
	glutInitWindowSize(640,480);     // set window size
	glutInitWindowPosition(100, 150); // set window position on screen
	glutCreateWindow("Tic Tac Toe"); // open the screen window
	glutMouseFunc(myMouse);     // register redraw function
	glutDisplayFunc(myDisplay);     // register redraw function
	myInit();                   
	glutMainLoop(); 		     // go into a perpetual loop
	return 0;
}


