Gli eseguibili (Linux 32/64 bit e OS X) sono disponibili al seguente link. Le istruzioni vengono mostrate quando eseguite il programma.
Una possibile soluzione (commentata) della verifica è la seguente:
#include <stdlib.h> #include <stdio.h> #include <unistd.h> #include <fcntl.h> #include <string.h> #include <time.h> #define WR_PIPE "ticPipeIn" #define RD_PIPE "ticPipeOut" #define BUFSIZE 5 #define VICTORIES 100 #define SIZE 3 #define START "g" #define END '$' /* * La verifica richiede la realizzazione di un programma che vinca * 100 partite (non necessariamente consecutive) a tris contro il * computer. * * Una partita viene avviata scrivendo il carattere 'g' nella pipe * "ticPipeIn". Il programma riceve in "ticPipeOut" la posizione * occupata dalla pedina dell'avversario nel formato "R,C#", dove R * e C corrispondono al numero di riga e colonna. Riceve inoltre un * carattere di controllo per determinare lo stato della partita: * '$' indica che è terminata, '&' che non lo è. Nel secondo caso, * il programma scrive in "ticPipeIn" la mossa da fare, usando il * medesimo formato, e legge da "ticPipeOut" lo stato della partita * in seguito alla sua mossa. */ int main(int argc, char *argv[]) { int rp, wp, win, i, row, col; char board[SIZE][SIZE], buffer[BUFSIZE], status; /* Apri le pipe: termina il programma in caso di errore. */ wp = open(WR_PIPE, O_WRONLY); if (wp < 0) { perror("Errore apertura pipe in scrittura"); exit(EXIT_FAILURE); } rp = open(RD_PIPE, O_RDONLY); if (rp < 0) { perror("Errore apertura pipe in lettura"); exit(EXIT_FAILURE); } /* Imposta il seed per il generatore di numeri casuali. */ srand(time(NULL)); win = 0; while (win < VICTORIES) { /* Pulisci il campo ed inizia una nuova partita! */ memset(board, 0, SIZE * SIZE); write(wp, START, strlen(START)); do { /* Leggi la posizione dell'avversario e segnala come occupata. */ i = 0; while (read(rp, buffer + i, 1) && buffer[i] != '#') i++; buffer[i + 1] = '\0'; sscanf(buffer, "%d,%d#", &row, &col); board[row][col] = 1; /* Leggi lo stato della partita. Se è terminata, abbiamo una sconfitta o * un pareggio. Altrimenti facciamo la nostra mossa! */ read(rp, &status, 1); if (status != END) { /* La miglior strategia del mondo! Scegliamo in maniera casuale riga * e colonna finché non viene trovata una posizione libera. */ do { row = rand() % SIZE; col = rand() % SIZE; } while (board[row][col] != 0); /* Scrivi la posizione sulla pipe e segnala come occupata. */ snprintf(buffer, BUFSIZE, "%d,%d#", row, col); write(wp, buffer, strlen(buffer)); board[row][col] = 1; /* Leggi lo stato della partita. Incrementa il contatore in * caso di vittoria. */ read(rp, &status, 1); if (status == END) win++; } } while (status != END); } /* Ok, abbiamo vinto! Possiamo chiudere le pipe! */ close(wp); close(rp); return EXIT_SUCCESS; }