#include #include #include #include #include #include #define MAX_PLAYERS 10 #define IPC_KEY 0x2007 #define SEM_PLAYERS MAX_PLAYERS // semáforo para entrar no jogo #define SEM_SERVER MAX_PLAYERS + 1 // semáforo do servidor #define UP(N) {struct sembuf up = {N, 1, 0}; semop(semid, &up, 1); } #define DOWN(N) {struct sembuf down = {N, -1, 0}; semop(semid, &down, 1); } typedef struct { char on; // se 1 jogador em jogo; se 0 não int n; // número da jogada corrente char who; // se 1 'move' diz respeito ao jogador; se 0 diz respeito ao servidor char move[4]; // última jogada do jogador ou última resposta do servidor } struct_player; struct_player *player; char key[MAX_PLAYERS][4]; int shmid, semid; void new_key(int player_id); void check_key(int player_id); void exit_signal(int sig); main() { int i; // apanhar o sinal SIGINT (enviado pelo terminal quando se usa CTRL-C) signal(SIGINT, exit_signal); // alocar e mapear um segmento de memória partilhada if ((shmid = shmget(IPC_KEY, sizeof(struct_player) * MAX_PLAYERS, IPC_CREAT | IPC_EXCL | S_IRUSR | S_IWUSR)) == -1) { printf("erro no shmget!\n"); exit(0); } if ((player = (struct_player *) shmat(shmid, NULL, 0)) == (void *) -1) { printf("erro no shmat!\n"); exit(0); } // alocar um conjunto de semáforos if ((semid = semget(IPC_KEY, MAX_PLAYERS + 2, IPC_CREAT | IPC_EXCL | S_IRUSR | S_IWUSR)) == -1) { printf("erro no semget!\n"); exit(0); } ... } void new_key(int player_id) { int i; for (i = 0; i < 4 ;i++) key[player_id][i] = 'A' + (((double) random()) / RAND_MAX) * 6; printf("Nova chave para o jogador %d: %.4s\n", player_id, key[player_id]); } void check_key(int player_id) { int p, b, i, j; p = 0; b = 0; for (i = 0; i < 4 ;i++) if (key[player_id][i] == player[player_id].move[i]) p++; for (j = 0; j < 4 ; j++) for (i = 0; i < 4 ; i++) if (key[player_id][j] == player[player_id].move[i]) { player[player_id].move[i] = 0; b++; break; } player[player_id].move[0] = '0' + p; player[player_id].move[1] = 'P'; player[player_id].move[2] = '0' + b - p; player[player_id].move[3] = 'B'; } void exit_signal(int sig) { // libertar e remover o segmento de memória partilhada shmdt(player); shmctl(shmid, IPC_RMID, NULL); // remover o conjunto de semáforos semctl(semid, 0, IPC_RMID); exit(0); }