3 * Author: Jan Vales (e0726236@student.tuwien.ac.at)
\r
5 * Purpose: Game-Server. Does basic game stuff: init, cheat-checking and AI.
\r
6 * Usage: ttt-server [-c]
\r
7 * Output: debuginfo only
\r
10 #include "globals.h"
\r
12 static int nSharedMemID = -1; /* ID for shared memory */
\r
13 static int semIDa = -1; /* semaphore 1 ID */
\r
14 static int semIDb = -1; /* semaphore 2 ID */
\r
15 static sharedmem_t *pSharedMem = (sharedmem_t *) -1; /* pointer on sharedmem_t */
\r
17 char *szCommand = "";
\r
18 static char ccf[3][3];
\r
19 void bailOut(); /* Forward declaration */
\r
21 /* cleanup on shutdown */
\r
23 if(pSharedMem!=(sharedmem_t *) -1) { /* shared mem attached? */
\r
24 if(shmdt((void *) pSharedMem)==-1) {
\r
25 pSharedMem = (sharedmem_t *) -1; /* shared mem not attached */
\r
26 bailOut("Can not detach semaphore");
\r
28 pSharedMem = (sharedmem_t *) -1; /* shared mem not attached */
\r
30 if(nSharedMemID!=-1) { /* shared mem already created ? */
\r
31 if(shmctl(nSharedMemID,IPC_RMID,(struct shmid_ds *) 0) == -1) {
\r
32 nSharedMemID = -1; /* shared mem not created */
\r
33 bailOut("Could not remove shared memory");
\r
35 nSharedMemID = -1; /* shared mem not created */
\r
39 if((semrm(semIDa))==-1){
\r
41 bailOut("Can not remove semaphore");
\r
46 if(semrm(semIDb)==-1){
\r
48 bailOut("Can not remove semaphore");
\r
54 /* prints error messages if an error has occoured */
\r
55 void bailOut(char *szMessage) {
\r
57 (void) fprintf(stderr,"%s: %s - %s\n", szCommand,szMessage,strerror(errno));
\r
59 (void) fprintf(stderr,"%s: %s\n", szCommand,szMessage);
\r
65 /* handles signals */
\r
66 void handler(int nSignal) {
\r
72 /* Game stuff starts here */
\r
84 pSharedMem->field[i][j]=0;
\r
89 int main(int argc, char **argv) {
\r
93 szCommand = argv[0];
\r
95 while( (c = getopt(argc, argv, "c")) != EOF ) {
\r
99 (void) fprintf(stdout,"Cheating erlaubt!\n");
\r
101 case '?': (void) fprintf(stderr,"USAGE: %s [-c]\n", szCommand); exit(EXIT_FAILURE); break;
\r
102 default: assert(0);
\r
106 /* INIT SEM + SHM*/
\r
107 if ((nSharedMemID = shmget(SHM_KEY,sizeof(sharedmem_t),PERM | IPC_CREAT | IPC_EXCL))==-1) {
\r
108 bailOut("Cannot create shared memory");
\r
110 if ((pSharedMem = (sharedmem_t *) shmat(nSharedMemID,(const void *) 0,0))==(sharedmem_t *) -1) {
\r
111 bailOut("Cannot attach shared memory");
\r
113 if ((semIDa=seminit(SEM_KEY_A, PERM, 1))==-1) {
\r
114 bailOut("Cannot allocate semaphoreA");
\r
116 if ((semIDb=seminit(SEM_KEY_B, PERM, 0))==-1) {
\r
117 bailOut("Cannot allocate semaphoreB");
\r
120 /* register handler */
\r
121 (void) signal(SIGINT, handler);
\r
122 (void) signal(SIGTERM, handler);
\r
123 (void) signal(SIGQUIT, handler);
\r
125 /* start game + reset cchk field */
\r
127 (void) fprintf(stdout,"Server bereit!\n");
\r
129 /* the game routine */
\r
131 if(P(semIDb)==-1)bailOut("Could not P semaphore");
\r
133 /* Cheack for cheating */
\r
137 if(pSharedMem->field[i][j] != ccf[i][j]){
\r
139 ccf[i][j] = pSharedMem->field[i][j];
\r
143 if(pSharedMem->status == -1){
\r
144 pSharedMem->status = 0;
\r
147 if((cnt > 1) & (ccheck == 1) & (pSharedMem->status != -1)){
\r
148 pSharedMem->status = -1;
\r
151 if(pSharedMem->status == -1)(void)fprintf(stderr,"clientcheat detectet!\n");
\r
154 /* check if Player is the winner */
\r
155 for(i=0;i<3;i++) { /* check horizentale - */
\r
156 if((pSharedMem->field[i][0] == 'X') & (pSharedMem->field[i][1] == 'X') & (pSharedMem->field[i][2] == 'X'))pSharedMem->status=2;
\r
157 if((pSharedMem->field[0][i] == 'X') & (pSharedMem->field[1][i] == 'X') & (pSharedMem->field[2][i] == 'X'))pSharedMem->status=2;
\r
159 if((pSharedMem->field[0][0] == 'X') & (pSharedMem->field[1][1] == 'X') & (pSharedMem->field[2][2] == 'X'))pSharedMem->status=2;
\r
160 if((pSharedMem->field[0][2] == 'X') & (pSharedMem->field[1][1] == 'X') & (pSharedMem->field[2][0] == 'X'))pSharedMem->status=2;
\r
163 /* only place my token, if client wanted to! */
\r
164 if(pSharedMem->status == 1){
\r
165 cnt = (rand() % 9)+1;
\r
166 (void)fprintf(stderr,"rand: %d, %d, %d\n", cnt, (cnt/3), (cnt%3));
\r
167 for(i = 0; i <= 10; i++) {
\r
168 if((i < 10) & (pSharedMem->field[(((cnt + i)%8)/3)][((cnt + i)%3)] == 0)){
\r
169 pSharedMem->field[(((cnt + i)%8)/3)][((cnt + i)%3)] = 'O';
\r
170 ccf[(((cnt + i)%8)/3)][((cnt + i)%3)] = 'O';
\r
175 pSharedMem->status = 0;
\r
177 (void)fprintf(stderr," draw!");
\r
178 pSharedMem->status = 4;
\r
181 /* print field on finish */
\r
182 for(i=0; i < 3; i++) {
\r
183 (void) fprintf(stdout,"%c, %c, %c\n", pSharedMem->field[i][0], pSharedMem->field[i][1],pSharedMem->field[i][2]);
\r
188 /* check if AI is the winner */
\r
189 for(i=0;i<3;i++) { /* check horizentale - */
\r
190 if((pSharedMem->field[i][0] == 'O') & (pSharedMem->field[i][1] == 'O') & (pSharedMem->field[i][2] == 'O'))pSharedMem->status=3;
\r
191 if((pSharedMem->field[0][i] == 'O') & (pSharedMem->field[1][i] == 'O') & (pSharedMem->field[2][i] == 'O'))pSharedMem->status=3;
\r
193 if((pSharedMem->field[0][0] == 'O') & (pSharedMem->field[1][1] == 'O') & (pSharedMem->field[2][2] == 'O'))pSharedMem->status=3;
\r
194 if((pSharedMem->field[0][2] == 'O') & (pSharedMem->field[1][1] == 'O') & (pSharedMem->field[2][0] == 'O'))pSharedMem->status=3;
\r
196 printf("status: %d\n", pSharedMem->status);
\r
197 if(V(semIDa))bailOut("Could not V semaphore");
\r
200 /* return 1337 for the guy who reached this impossible state! */
\r