Posted by Binary_Fire on Thu 22 May 20:27
report abuse | download | new post
- //X si 0 21/05/2008
- #include <cstdlib>
- #include <cstdio>
- #include <GL/glut.h>
- #include <GL/gl.h>
- #include <cstring>
- #include <ctime>
- typedef struct pozitie { int x,y,stare_castig; };
- #define PCP 2 //COMPUTER PLAYER
- #define HUP 1 //HUMAN PLAYER
- #define CFG_FILE "config.cfg"
- int mat[4][4];
- int step,flagStopPlay;
- int CurrWindowWidth,CurrWindowHeight;
- void printString(char*);
- void startGame();
- void initGame();
- void keyboardInput(unsigned char,int,int);
- void mouseInput(int,int,int,int);
- void drawMove(int,int,int);
- void renderArena();
- int see_winner(int);
- pozitie choosePC(int,int);
- void resizeScene(int,int);
- int see_winner(int mat[][4])
- {
- int i,j;
- //fixez o linie si ma uit sa vad daca e egala
- for ( i = 1; i < 4; ++i )
- if ( mat[i][1] == mat[i][2] && mat[i][2] == mat[i][3] && mat[i][1] != 0 )
- return mat[i][1];
- //fixez o coloana si ma uit sa vad daca e egala
- for ( i = 1; i < 4; ++i )
- if ( mat[1][i] == mat[2][i] && mat[2][i] == mat[3][i] && mat[1][i] != 0 )
- return mat[1][i];
- //ma uit pe diagonale
- if ( mat[1][1] == mat[2][2] && mat[2][2] == mat[3][3] && mat[1][1] != 0 )
- return mat[1][1];
- if ( mat[3][1] == mat[2][2] && mat[2][2] == mat[1][3] && mat[3][1] != 0 )
- return mat[3][1];
- //daca nu gasesc un castigator returnez 0
- return 0;
- }
- pozitie choosePC(int boardState[][4],int side,int start)
- {
- int i,j,castigator;
- int change_side[3] = { 0, 2, 1 };
- int castig[4][4];
- pozitie aux;
- int dim,pozx[10],pozy[10];
- int posMove;
- for ( i = 1; i <= 3; ++i )
- for ( j = 1; j <= 3; ++j )
- if ( boardState[i][j] == 0 )
- {
- boardState[i][j] = side; //am gasit o pozitie libera, o marchez cu jucatorul curent
- castigator = see_winner(boardState); //ma uit sa vad daca nu cumva castiga deja
- if ( castigator == side )
- {
- //atunci marchez pozitia ca fiind pierzatoare pentru adversar
- castig[i][j] = -1;
- }
- else
- {
- //daca nu a fost gasit castigator atunci analizez acest subarbore si ii retin starea de castig
- castig[i][j] = choosePC(boardState,change_side[side],0).stare_castig;
- }
- boardState[i][j] = 0;
- }
- else
- castig[i][j] = 5; //am pus o valoare mica diferita de -1,0,1 ca sa nu aiba asa valori urate in ea
- //caut pozitiile acum
- //daca am una pierzatoare pentru adversar va fi castigatoare pentru cel curent -> side
- dim = 0;
- for ( i = 1; i <= 3; ++i )
- for ( j = 1; j <= 3; ++j )
- if ( boardState[i][j] == 0 && castig[i][j] == -1 )
- {
- ++dim;
- pozx[dim] = i; pozy[dim] = j;
- }
- if ( dim > 0 )
- {
- //aleg random o pozitie
- posMove = rand()%dim + 1;
- aux.x = pozx[ posMove ];
- aux.y = pozy[ posMove ];
- aux.stare_castig = 1;
- return aux;
- }
- //daca nu am gasit atunci caut o pozitie de remiza
- dim = 0;
- for ( i = 1; i <= 3; ++i )
- for ( j = 1; j <= 3; ++j )
- if ( boardState[i][j] == 0 && castig[i][j] == 0 )
- {
- ++dim;
- pozx[dim] = i; pozy[dim] = j;
- }
- if ( dim > 0 )
- {
- //aleg random o pozitie
- posMove = rand()%dim + 1;
- aux.x = pozx[ posMove ];
- aux.y = pozy[ posMove ];
- aux.stare_castig = 0;
- return aux;
- }
- //altfel pot alege doar o pozitie castigatoare pentru adversar in concluzie pierd eu [side]
- for ( i = 1; i <= 3; ++i )
- for ( j = 1; j <= 3; ++j )
- if ( boardState[i][j] == 0 )
- {
- ++dim;
- pozx[dim] = i; pozy[dim] = j;
- }
- if ( dim > 0 )
- {
- //aleg random o pozitie
- posMove = rand()%dim + 1;
- aux.x = pozx[ posMove ];
- aux.y = pozy[ posMove ];
- aux.stare_castig = -1;
- return aux;
- }
- //daca nu am gasit nici o pozitie libera inseamna ca este remiza
- aux.x = aux.y = 0;
- aux.stare_castig = 0;
- return aux;
- }
- void resizeScene(int w,int h)
- {
- //folosesc functia "resizeScene" pentru a reinitializa fereastra in caz de
- //schimbare a marimii
- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
- CurrWindowWidth = w;
- CurrWindowHeight = h;
- glViewport(0, 0, w, h);
- glMatrixMode(GL_PROJECTION);
- //resetez totul
- glLoadIdentity();
- glOrtho(0.0, 10.0, 0.0, 10.0, -1.0, 1.0);
- renderArena();
- }
- void init()
- {
- glClearColor(0.0, 0.0, 0.0, 0.0);
- glColor3f(0.0,0.0,1.0);
- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
- //initializez tipul matricei folosite pentru vizualizare
- glMatrixMode(GL_PROJECTION);
- //initializez matricea
- glLoadIdentity();
- //initializez sistemul ortogonal
- glOrtho(0.0, 10.0, 0.0, 10.0, -1.0, 1.0);
- }
- void keyboardInput(unsigned char key, int x, int y)
- {
- if ( key == 27 ) //este ESCAPE, ies
- exit(0);
- if ( key == 'm' || key == 'M' ) //cu "m" schimb cine incepe jocul
- {
- char *dumi;
- int val;
- if ( freopen(CFG_FILE,"r",stdin) != NULL )
- {
- scanf("%s%d",dumi,&val);
- fclose(stdin);
- }
- if ( freopen(CFG_FILE,"w",stdout) != NULL )
- {
- printf("%s %d\n",dumi,val^1);
- fclose(stdout);
- }
- else
- printf("FISIERUL %s NU S-A PUTUT SCRIE\n",CFG_FILE);
- }
- //cu "y" reinitializez jocul
- if ( key == 'y' || key == 'Y' )
- init(), glutPostRedisplay(), startGame();
- }
- void printString(char *txt)
- {
- int i;
- glRasterPos2f(3.0,0.5);
- for ( i = 0; i < strlen(txt); ++i )
- {
- //fontul definit de GLUT este ciudat ... nu am gasit nicicum o modalitate de a-i schimba culoarea
- glColor3f(0.0,1.0,0.0);
- glutBitmapCharacter(GLUT_BITMAP_TIMES_ROMAN_24, txt[i]);
- }
- glutSwapBuffers();
- }
- void mouseInput(int button, int state, int x, int y)
- {
- int winnerc;
- pozitie tmp;
- if ( button == GLUT_LEFT_BUTTON && state == GLUT_DOWN && !flagStopPlay )
- {
- x = x / ( CurrWindowWidth / 5 );
- y = ( CurrWindowHeight - y ) / ( CurrWindowHeight / 5 );
- if ( mat[y][x] == 0 && x < 4 && y < 4 && x > 0 && y > 0 )
- {
- drawMove(x,y,1);
- mat[ y ][ x ] = 1; //trebuie inversate coordonatele !!!
- ++step;
- winnerc = see_winner(mat);
- if ( winnerc == 1 )
- {
- flagStopPlay = 1;
- printString("Ai castigat!");
- return ;
- }
- if ( step == 9 )
- {
- printString("Remiza");
- flagStopPlay = 1;
- return ;
- }
- tmp = choosePC(mat,2,1);
- drawMove(tmp.y,tmp.x,2); //se inverseaza coordonatele matricei in spatiul ortogonal
- mat[ tmp.x ][ tmp.y ] = 2;
- ++step;
- winnerc = see_winner(mat);
- if ( winnerc == 2 )
- {
- flagStopPlay = 1;
- printString("Ai pierdut!");
- return ;
- }
- if ( step == 9 )
- {
- printString("Remiza");
- flagStopPlay = 1;
- return ;
- }
- }
- }
- }
- void renderArena()
- {
- int i,j;
- glColor3f(0.0,1.0,0.0);
- //desenez tabla de joc pentru X si 0
- glBegin(GL_LINE_LOOP);
- glVertex2f(2.0,2.0);
- glVertex2f(2.0,8.0);
- glVertex2f(8.0,8.0);
- glVertex2f(8.0,2.0);
- glEnd();
- glBegin(GL_LINE_LOOP);
- glVertex2f(2.0,4.0);
- glVertex2f(8.0,4.0);
- glEnd();
- glBegin(GL_LINE_LOOP);
- glVertex2f(2.0,6.0);
- glVertex2f(8.0,6.0);
- glEnd();
- glBegin(GL_LINE_LOOP);
- glVertex2f(4.0,2.0);
- glVertex2f(4.0,8.0);
- glEnd();
- glBegin(GL_LINE_LOOP);
- glVertex2f(6.0,2.0);
- glVertex2f(6.0,8.0);
- glEnd();
- //gata
- glutSwapBuffers();
- //desenez si mutarile folosite, in caz ca in timpul jocului este nevoie de o redesenare a tablei de joc
- for ( i = 1; i < 4; ++i )
- for ( j = 1; j < 4; ++j )
- if ( mat[i][j] )
- drawMove(j,i,mat[i][j]);
- }
- //desenez mutarea
- void drawMove(int x,int y,int side)
- {
- int centerx,centery;
- //centrez coordonatele pozitiei mutarii din matricea jucatorilor in sistemul meu ortogonal
- centerx = x * 2 + 1;
- centery = y * 2 + 1;
- //computerul este la mutare, el este "0"
- if ( side == PCP )
- {
- //ii desenez mutarea
- glBegin(GL_LINE_LOOP);
- glColor3f(1.0,0.0,1.0);
- glVertex2f(centerx-0.5,centery+0.5);
- glVertex2f(centerx+0.5,centery+0.5);
- glVertex2f(centerx+0.5,centery-0.5);
- glVertex2f(centerx-0.5,centery-0.5);
- glEnd();
- }
- else
- //desenez mutarea jucatorului, "X"
- if ( side == HUP )
- {
- glBegin(GL_LINE_LOOP);
- glColor3f(1.0,1.0,0.0);
- glVertex2f(centerx-0.5,centery+0.5);
- glVertex2f(centerx+0.5,centery-0.5);
- glEnd();
- glBegin(GL_LINE_LOOP);
- glColor3f(1.0,1.0,0.0);
- glVertex2f(centerx-0.5,centery-0.5);
- glVertex2f(centerx+0.5,centery+0.5);
- glEnd();
- }
- glutSwapBuffers();
- }
- void initGame()
- {
- char dumi[10];
- int opt;
- pozitie tmp;
- step = 0;
- //initializez matricea jucatorilor, nimeni nu a plasat nimic
- memset(mat,0,sizeof(mat));
- srand(time(0));
- //ma uit in fisierul de configuratie
- if ( freopen(CFG_FILE,"r",stdin) != NULL )
- {
- scanf("%s%d",&dumi,&opt);
- fclose(stdin);
- }
- else
- {
- printf("FISIERUL DE CONFIGURATIE NU EXISTA\n");
- if ( freopen(CFG_FILE,"w",stdout) != NULL )
- {
- printf("%s %d\n",CFG_FILE,rand()%2);
- printf("FISIERUL A FOST CREAT");
- fclose(stdout);
- }
- else
- printf("FISIERUL NU A PUTUT FI CREAT\n");
- }
- //daca am ca parametru sa inceapa computerul prima data atunci il las sa isi faca el prima mutare
- if ( strcmp(dumi,"pcStart") == 0 && opt == 1 )
- {
- tmp = choosePC(mat,2,1);
- drawMove(tmp.y,tmp.x,2);
- mat[tmp.x][tmp.y] = 2;
- step = 1;
- }
- }
- void startGame()
- {
- initGame();
- flagStopPlay = 0;
- }
- int main(int argc,char** argv)
- {
- //initializez GLUT
- glutInit(&argc,argv);
- glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
- glutInitWindowSize(300,300);
- glutInitWindowPosition(350,350);
- //creez fereastra
- glutCreateWindow("X si 0");
- //initializez toate starile
- init();
- glutReshapeFunc(resizeScene);
- glutKeyboardFunc(keyboardInput);
- glutMouseFunc(mouseInput);
- glutDisplayFunc(renderArena);
- startGame();
- //incep main loop-ul, fara el nu se va afisa nimic
- glutMainLoop();
- return 0;
- }
Submit a correction or amendment below (click here to make a fresh posting)
After submitting an amendment, you'll be able to view the differences between the old and new posts easily.