TP5 - Correction
ppompeani_cars_mutex1.c
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
void clear_screen() { fprintf(stdout, "\e[1;1H\e[2J"); }
void refresh() { fflush(stdout); }
void move_cursor(unsigned int y, unsigned int x) {
fprintf(stdout, "\e[%d;%dH", y, x);
}
void print_n(char *s, unsigned int repeat) {
while (repeat > 0) {
fprintf(stdout, "%s", s);
repeat--;
}
}
const unsigned int ROAD_SIZE = 40;
pthread_mutex_t STDOUT_MUTEX;
void game_init() {
srand(time(NULL));
pthread_mutex_init(&STDOUT_MUTEX, NULL);
clear_screen();
move_cursor(1, 1);
print_n("-", ROAD_SIZE);
move_cursor(3, 1);
print_n("- ", ROAD_SIZE / 2);
move_cursor(5, 1);
print_n("-", ROAD_SIZE);
move_cursor(1, ROAD_SIZE + 1);
refresh();
}
void game_close() {
clear_screen();
refresh();
}
void *car_thread(void *param) {
int car = *((int *)param);
int car_color = rand() % 6;
int increment, x, y;
char logo;
if (car == 0) {
increment = -1;
x = ROAD_SIZE;
y = 2;
logo = '<';
} else {
increment = 1;
x = 1;
y = 4;
logo = '>';
}
for (int i = 1; i < ROAD_SIZE; i++) {
pthread_mutex_lock(&STDOUT_MUTEX);
{
// We reset old position
move_cursor(y, x);
fputc(' ', stdout);
// We move to new position
x += increment;
move_cursor(y, x);
fputc(logo, stdout);
move_cursor(1, ROAD_SIZE + 1);
refresh();
}
pthread_mutex_unlock(&STDOUT_MUTEX);
usleep(50000 + rand() % 10000);
}
pthread_mutex_lock(&STDOUT_MUTEX);
{
move_cursor(y, x);
fputc(' ', stdout);
move_cursor(1, ROAD_SIZE + 1);
refresh();
}
pthread_mutex_unlock(&STDOUT_MUTEX);
return NULL;
}
int main(int argc, char **argv) {
game_init();
pthread_t last;
char input;
int car_arg;
do {
input = fgetc(stdin);
switch (input) {
case 'j':
car_arg = 1;
pthread_create(&last, NULL, car_thread, &car_arg);
break;
case 'k':
car_arg = 0;
pthread_create(&last, NULL, car_thread, &car_arg);
break;
}
} while (input != 'q');
pthread_join(last, NULL);
game_close();
}
ppompeani_cars_mutex2.c
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <termios.h>
#include <unistd.h>
void clear_screen() { fprintf(stdout, "\e[1;1H\e[2J"); }
void refresh() { fflush(stdout); }
void move_cursor(unsigned int y, unsigned int x) {
fprintf(stdout, "\e[%d;%dH", y, x);
}
void print_n(char *s, unsigned int repeat) {
while (repeat > 0) {
fprintf(stdout, "%s", s);
repeat--;
}
}
// Amélioration Couleur
const unsigned int COLOR_RESET = 0, COLOR_RED = 1, COLOR_GREEN = 2,
COLOR_YELLOW = 3, COLOR_BLUE = 4, COLOR_PURPLE = 5,
COLOR_LIGHTBLUE = 6;
void color(int color) {
if (color == COLOR_RESET) {
fprintf(stdout, "\e[0m");
} else {
fprintf(stdout, "\e[3%cm", color + '0');
}
}
unsigned int ROAD_SIZE, BLOCK_SIZE, LEFT_LIMIT, RIGHT_LIMIT;
pthread_mutex_t ROAD_MUTEX;
// Amélioration Input
struct termios OLD_TERMINAL_PARAMS;
void game_init() {
BLOCK_SIZE = ROAD_SIZE / 10 + 2;
LEFT_LIMIT = ROAD_SIZE / 2 - BLOCK_SIZE;
RIGHT_LIMIT = ROAD_SIZE / 2 + BLOCK_SIZE;
pthread_mutex_init(&ROAD_MUTEX, NULL);
srand(time(NULL));
clear_screen();
// Première partie de la ligne 1
move_cursor(1, 1);
print_n("-", LEFT_LIMIT);
// Deuxième partie de la ligne 1
move_cursor(1, RIGHT_LIMIT);
print_n("-", LEFT_LIMIT + 1);
// Première partie de la ligne 2
move_cursor(3, 1);
print_n("- ", LEFT_LIMIT / 2 - 1);
// Deuxième partie de la ligne 2
move_cursor(3, LEFT_LIMIT + 2);
print_n("-", BLOCK_SIZE * 2 - 3);
// Troisième partie de la ligne 2
move_cursor(3, RIGHT_LIMIT + 2);
print_n("- ", LEFT_LIMIT / 2);
// Ligne 3
move_cursor(5, 1);
print_n("-", ROAD_SIZE);
move_cursor(1, LEFT_LIMIT);
fprintf(stdout, "\\");
move_cursor(1, RIGHT_LIMIT);
fprintf(stdout, "/");
move_cursor(2, LEFT_LIMIT + 1);
fprintf(stdout, "\\");
move_cursor(2, RIGHT_LIMIT - 1);
fprintf(stdout, "/");
// Amélioration Messages
move_cursor(7, 1);
fprintf(stdout, "Press j to spawn a car riding to the east");
move_cursor(8, 1);
fprintf(stdout, "Press k to spawn a car riding to the west");
move_cursor(9, 1);
fprintf(stdout, "Press q to quit");
move_cursor(1, ROAD_SIZE + 1);
// Amélioration Input
struct termios new_terminal_params;
// Store old params
tcgetattr(STDIN_FILENO, &OLD_TERMINAL_PARAMS);
// Copy params
new_terminal_params = OLD_TERMINAL_PARAMS;
// Change params
// Remove ICANON flag (wait for enter) and ECHO flag (print stdin)
new_terminal_params.c_lflag &= ~(ICANON | ECHO);
// Apply params
tcsetattr(STDIN_FILENO, TCSANOW, &new_terminal_params);
refresh();
}
void game_close() {
clear_screen();
// Amélioration Input
// Restore old params
tcsetattr(STDIN_FILENO, TCSANOW, &OLD_TERMINAL_PARAMS);
refresh();
}
// Amélioration Compteur
// Extra: une couleur différente à chaque fois que le compteur change
unsigned int CAR_COUNTER = 0;
void *counter_thread(void *param) {
int counter_color = 0;
int last_count = CAR_COUNTER;
while (1) {
if (CAR_COUNTER != last_count) {
counter_color = (counter_color + 1) % 6;
last_count = CAR_COUNTER;
move_cursor(3, ROAD_SIZE + 2);
color(counter_color);
fprintf(stdout, "%d", CAR_COUNTER);
}
sleep(1);
}
return NULL;
}
void *car_thread(void *param) {
int car = *((int *)param);
unsigned int car_color = rand() % 6;
unsigned int increment, x, y, base_sleep = 80000;
char logo;
if (car == 0) {
increment = -1;
x = ROAD_SIZE + 1;
y = 2;
logo = '<';
} else {
increment = 1;
x = 0;
y = 4;
logo = '>';
}
// Amélioration Compteur
CAR_COUNTER++;
for (int i = 1; i < ROAD_SIZE; i++) {
// We check if we can move
if ((x == LEFT_LIMIT - 1 && y == 4) || (x == RIGHT_LIMIT + 1 && y == 2)) {
move_cursor(11, 1);
fprintf(stdout, "locking!");
pthread_mutex_lock(&ROAD_MUTEX);
}
// We reset old position
move_cursor(y, x);
fputc(' ', stdout);
// We move to new position
if (car == 0) {
if (x == RIGHT_LIMIT || x == RIGHT_LIMIT + 1) {
y++;
base_sleep = 110000;
} else if (x == LEFT_LIMIT || x == LEFT_LIMIT + 1) {
y--;
base_sleep = 110000;
} else {
base_sleep = 80000;
}
}
x += increment;
move_cursor(y, x);
// Amélioration Couleur
color(car_color);
fputc(logo, stdout);
move_cursor(1, ROAD_SIZE + 1);
refresh();
// We release the lock if we're out of the critical part of the road
if ((x == RIGHT_LIMIT + 1 && y == 4) || (x == LEFT_LIMIT - 1 && y == 2)) {
move_cursor(11, 1);
fprintf(stdout, "unlocking!");
pthread_mutex_unlock(&ROAD_MUTEX);
}
usleep(base_sleep + rand() % 10000);
}
move_cursor(y, x);
fputc(' ', stdout);
move_cursor(1, ROAD_SIZE + 1);
refresh();
return NULL;
}
// Amélioration Messages
void *error_thread(void *param) {
color(0);
move_cursor(11, 1);
fprintf(stdout, "Unrecognised input.");
refresh();
sleep(2);
color(0);
move_cursor(11, 1);
fprintf(stdout, " ");
refresh();
return NULL;
}
int main(int argc, char **argv) {
{
char buf[10];
printf("Quel taille doit faire la route ? (défaut 40, min 20) → ");
fgets(buf, 10, stdin);
int size = atoi(buf);
if (size < 20) {
ROAD_SIZE = 40;
} else {
ROAD_SIZE = size;
}
}
game_init();
pthread_t last, unused_thread_id;
// Amélioration Compteur
pthread_create(&unused_thread_id, NULL, counter_thread, NULL);
char input;
int car_arg;
do {
input = fgetc(stdin);
switch (input) {
case 'j':
case 'k':
if (input == 'j') {
car_arg = 1;
} else {
car_arg = 0;
}
pthread_create(&last, NULL, car_thread, &car_arg);
color(0);
move_cursor(11, 1);
fprintf(stdout, " ");
refresh();
break;
case 'q':
// Amélioration Messages
color(0);
move_cursor(11, 1);
fprintf(stdout, "Quitting. ");
refresh();
break;
default:
// Amélioration Messages
pthread_create(&unused_thread_id, NULL, error_thread, NULL);
}
} while (input != 'q');
pthread_join(last, NULL);
game_close();
}
ppompeani_cars_sem.c
#include <pthread.h>
#include <semaphore.h>
#include <stdio.h>
#include <stdlib.h>
#include <termios.h>
#include <unistd.h>
void clear_screen() { fprintf(stdout, "\e[1;1H\e[2J"); }
void refresh() { fflush(stdout); }
void move_cursor(unsigned int y, unsigned int x) {
fprintf(stdout, "\e[%d;%dH", y, x);
}
void print_n(char *s, unsigned int repeat) {
while (repeat > 0) {
fprintf(stdout, "%s", s);
repeat--;
}
}
// Amélioration Couleur
const unsigned int COLOR_RESET = 0, COLOR_RED = 1, COLOR_GREEN = 2,
COLOR_YELLOW = 3, COLOR_BLUE = 4, COLOR_PURPLE = 5,
COLOR_LIGHTBLUE = 6;
void color(int color) {
if (color == COLOR_RESET) {
fprintf(stdout, "\e[0m");
} else {
fprintf(stdout, "\e[3%cm", color + '0');
}
}
unsigned int ROAD_SIZE, BLOCK_SIZE, LEFT_LIMIT, RIGHT_LIMIT;
sem_t SEMS[2];
// Amélioration Input
struct termios OLD_TERMINAL_PARAMS;
void game_init() {
BLOCK_SIZE = ROAD_SIZE / 10 + 2;
LEFT_LIMIT = ROAD_SIZE / 2 - BLOCK_SIZE;
RIGHT_LIMIT = ROAD_SIZE / 2 + BLOCK_SIZE;
sem_init(&SEMS[0], 0, BLOCK_SIZE / 2);
sem_init(&SEMS[1], 0, 0);
srand(time(NULL));
clear_screen();
// Première partie de la ligne 1
move_cursor(1, 1);
print_n("-", LEFT_LIMIT);
// Deuxième partie de la ligne 1
move_cursor(1, RIGHT_LIMIT);
print_n("-", LEFT_LIMIT + 1);
// Première partie de la ligne 2
move_cursor(3, 1);
print_n("- ", LEFT_LIMIT / 2 - 1);
// Deuxième partie de la ligne 2
move_cursor(3, LEFT_LIMIT + 2);
print_n("-", BLOCK_SIZE * 2 - 3);
// Troisième partie de la ligne 2
move_cursor(3, RIGHT_LIMIT + 2);
print_n("- ", LEFT_LIMIT / 2);
// Ligne 3
move_cursor(5, 1);
print_n("-", ROAD_SIZE);
move_cursor(1, LEFT_LIMIT);
fprintf(stdout, "\\");
move_cursor(1, RIGHT_LIMIT);
fprintf(stdout, "/");
move_cursor(2, LEFT_LIMIT + 1);
fprintf(stdout, "\\");
move_cursor(2, RIGHT_LIMIT - 1);
fprintf(stdout, "/");
// Amélioration Messages
move_cursor(7, 1);
fprintf(stdout, "Press j to spawn a car riding to the east");
move_cursor(8, 1);
fprintf(stdout, "Press k to spawn a car riding to the west");
move_cursor(9, 1);
fprintf(stdout, "Press q to quit");
move_cursor(1, ROAD_SIZE + 1);
// Amélioration Input
struct termios new_terminal_params;
// Store old params
tcgetattr(STDIN_FILENO, &OLD_TERMINAL_PARAMS);
// Copy params
new_terminal_params = OLD_TERMINAL_PARAMS;
// Change params
// Remove ICANON flag (wait for enter) and ECHO flag (print stdin)
new_terminal_params.c_lflag &= ~(ICANON | ECHO);
// Apply params
tcsetattr(STDIN_FILENO, TCSANOW, &new_terminal_params);
refresh();
}
void game_close() {
clear_screen();
// Amélioration Input
// Restore old params
tcsetattr(STDIN_FILENO, TCSANOW, &OLD_TERMINAL_PARAMS);
refresh();
}
// Amélioration Compteur
// Extra: une couleur différente à chaque fois que le compteur change
unsigned int CAR_COUNTER = 0;
void *counter_thread(void *param) {
int counter_color = 0;
int last_count = CAR_COUNTER;
while (1) {
if (CAR_COUNTER != last_count) {
counter_color = (counter_color + 1) % 6;
last_count = CAR_COUNTER;
move_cursor(3, ROAD_SIZE + 2);
color(counter_color);
fprintf(stdout, "%d", CAR_COUNTER);
}
sleep(1);
}
return NULL;
}
void *car_thread(void *param) {
int car = *((int *)param);
unsigned int car_color = rand() % 6;
unsigned int increment, x, y, base_sleep = 80000;
char logo;
if (car == 0) {
increment = -1;
x = ROAD_SIZE + 1;
y = 2;
logo = '<';
} else {
increment = 1;
x = 0;
y = 4;
logo = '>';
}
// Amélioration Compteur
CAR_COUNTER++;
for (int i = 1; i < ROAD_SIZE; i++) {
// We check if we can move
if ((x == LEFT_LIMIT - 1 && y == 4) || (x == RIGHT_LIMIT + 1 && y == 2)) {
move_cursor(11, 1);
fprintf(stdout, "locking!");
sem_wait(&SEMS[car]);
}
// We reset old position
move_cursor(y, x);
fputc(' ', stdout);
// We move to new position
if (car == 0) {
if (x == RIGHT_LIMIT || x == RIGHT_LIMIT + 1) {
y++;
base_sleep = 110000;
} else if (x == LEFT_LIMIT || x == LEFT_LIMIT + 1) {
y--;
base_sleep = 110000;
} else {
base_sleep = 80000;
}
}
x += increment;
move_cursor(y, x);
// Amélioration Couleur
color(car_color);
fputc(logo, stdout);
move_cursor(1, ROAD_SIZE + 1);
refresh();
// We release the lock if we're out of the critical part of the road
if ((x == RIGHT_LIMIT + 1 && y == 4) || (x == LEFT_LIMIT - 1 && y == 2)) {
move_cursor(11, 1);
fprintf(stdout, "unlocking!");
sem_post(&SEMS[car]);
}
usleep(base_sleep + rand() % 10000);
}
move_cursor(y, x);
fputc(' ', stdout);
move_cursor(1, ROAD_SIZE + 1);
refresh();
return NULL;
}
// Amélioration Messages
void *error_thread(void *param) {
color(0);
move_cursor(11, 1);
fprintf(stdout, "Unrecognised input.");
refresh();
sleep(2);
color(0);
move_cursor(11, 1);
fprintf(stdout, " ");
refresh();
return NULL;
}
void *switchLanes(void *param) {
int sem = 0;
while (1) {
sleep(2);
move_cursor(12, 1);
color(0);
fprintf(stdout, "Switching sem: %d", sem);
move_cursor(1, ROAD_SIZE + 1);
refresh();
for (int i = 0; i < BLOCK_SIZE / 2; i++) {
sem_wait(&SEMS[sem]);
}
for (int i = 0; i < BLOCK_SIZE / 2; i++) {
sem_post(&SEMS[1 - sem]);
}
sem = 1 - sem;
}
return NULL;
}
int main(int argc, char **argv) {
{
char buf[10];
printf("Quel taille doit faire la route ? (défaut 40, min 20) → ");
fgets(buf, 10, stdin);
int size = atoi(buf);
if (size < 20) {
ROAD_SIZE = 40;
} else {
ROAD_SIZE = size;
}
}
game_init();
pthread_t last, unused_thread_id;
// Amélioration Compteur
pthread_create(&unused_thread_id, NULL, counter_thread, NULL);
pthread_create(&unused_thread_id, NULL, switchLanes, NULL);
char input;
int car_arg;
do {
input = fgetc(stdin);
switch (input) {
case 'j':
case 'k':
if (input == 'j') {
car_arg = 1;
} else {
car_arg = 0;
}
pthread_create(&last, NULL, car_thread, &car_arg);
color(0);
move_cursor(11, 1);
fprintf(stdout, " ");
refresh();
break;
case 'q':
// Amélioration Messages
color(0);
move_cursor(11, 1);
fprintf(stdout, "Quitting. ");
refresh();
break;
default:
// Amélioration Messages
pthread_create(&unused_thread_id, NULL, error_thread, NULL);
}
} while (input != 'q');
pthread_join(last, NULL);
game_close();
}
ppompeani_cars_sem_bonus.c
#include <pthread.h>
#include <semaphore.h>
#include <stdio.h>
#include <stdlib.h>
#include <termios.h>
#include <unistd.h>
void clear_screen() { fprintf(stdout, "\e[1;1H\e[2J"); }
void refresh() { fflush(stdout); }
void move_cursor(unsigned int y, unsigned int x) {
fprintf(stdout, "\e[%d;%dH", y, x);
}
void print_n(char *s, unsigned int repeat) {
while (repeat > 0) {
fprintf(stdout, "%s", s);
repeat--;
}
}
// Amélioration Couleur
const unsigned int COLOR_RESET = 0, COLOR_RED = 1, COLOR_GREEN = 2,
COLOR_YELLOW = 3, COLOR_BLUE = 4, COLOR_PURPLE = 5,
COLOR_LIGHTBLUE = 6;
void color(int color) {
if (color == COLOR_RESET) {
fprintf(stdout, "\e[0m");
} else {
fprintf(stdout, "\e[3%cm", color + '0');
}
}
unsigned int ROAD_SIZE, BLOCK_SIZE, LEFT_LIMIT, RIGHT_LIMIT;
sem_t SEMS[2];
unsigned int nb_blocked_cars[2];
// Amélioration Input
struct termios OLD_TERMINAL_PARAMS;
void game_init() {
BLOCK_SIZE = ROAD_SIZE / 10 + 2;
LEFT_LIMIT = ROAD_SIZE / 2 - BLOCK_SIZE;
RIGHT_LIMIT = ROAD_SIZE / 2 + BLOCK_SIZE;
sem_init(&SEMS[0], 0, BLOCK_SIZE / 2);
sem_init(&SEMS[1], 0, 0);
srand(time(NULL));
clear_screen();
// Première partie de la ligne 1
move_cursor(1, 1);
print_n("-", LEFT_LIMIT);
// Deuxième partie de la ligne 1
move_cursor(1, RIGHT_LIMIT);
print_n("-", LEFT_LIMIT + 1);
// Première partie de la ligne 2
move_cursor(3, 1);
print_n("- ", LEFT_LIMIT / 2 - 1);
// Deuxième partie de la ligne 2
move_cursor(3, LEFT_LIMIT + 2);
print_n("-", BLOCK_SIZE * 2 - 3);
// Troisième partie de la ligne 2
move_cursor(3, RIGHT_LIMIT + 2);
print_n("- ", LEFT_LIMIT / 2);
// Ligne 3
move_cursor(5, 1);
print_n("-", ROAD_SIZE);
move_cursor(1, LEFT_LIMIT);
fprintf(stdout, "\\");
move_cursor(1, RIGHT_LIMIT);
fprintf(stdout, "/");
move_cursor(2, LEFT_LIMIT + 1);
fprintf(stdout, "\\");
move_cursor(2, RIGHT_LIMIT - 1);
fprintf(stdout, "/");
// Amélioration Messages
move_cursor(7, 1);
fprintf(stdout, "Press j to spawn a car riding to the east");
move_cursor(8, 1);
fprintf(stdout, "Press k to spawn a car riding to the west");
move_cursor(9, 1);
fprintf(stdout, "Press q to quit");
move_cursor(1, ROAD_SIZE + 1);
// Amélioration Input
struct termios new_terminal_params;
// Store old params
tcgetattr(STDIN_FILENO, &OLD_TERMINAL_PARAMS);
// Copy params
new_terminal_params = OLD_TERMINAL_PARAMS;
// Change params
// Remove ICANON flag (wait for enter) and ECHO flag (print stdin)
new_terminal_params.c_lflag &= ~(ICANON | ECHO);
// Apply params
tcsetattr(STDIN_FILENO, TCSANOW, &new_terminal_params);
refresh();
}
void game_close() {
clear_screen();
// Amélioration Input
// Restore old params
tcsetattr(STDIN_FILENO, TCSANOW, &OLD_TERMINAL_PARAMS);
refresh();
}
// Amélioration Compteur
// Extra: une couleur différente à chaque fois que le compteur change
unsigned int CAR_COUNTER = 0;
void *counter_thread(void *param) {
int counter_color = 0;
int last_count = CAR_COUNTER;
while (1) {
if (CAR_COUNTER != last_count) {
counter_color = (counter_color + 1) % 6;
last_count = CAR_COUNTER;
move_cursor(3, ROAD_SIZE + 2);
color(counter_color);
fprintf(stdout, "%d", CAR_COUNTER);
}
sleep(1);
}
return NULL;
}
void *car_thread(void *param) {
int car = *((int *)param);
unsigned int car_color = rand() % 6;
unsigned int increment, x, y, base_sleep = 80000;
char logo;
if (car == 0) {
increment = -1;
x = ROAD_SIZE + 1;
y = 2;
logo = '<';
} else {
increment = 1;
x = 0;
y = 4;
logo = '>';
}
// Amélioration Compteur
CAR_COUNTER++;
int has_acquired = 0;
for (int i = 1; i < ROAD_SIZE; i++) {
// We check if we can move
if (!has_acquired && ((x == LEFT_LIMIT - 1 - nb_blocked_cars[car] && y == 4) || (x == RIGHT_LIMIT + 1 + nb_blocked_cars[car] && y == 2))) {
move_cursor(11, 1);
fprintf(stdout, "locking!");
has_acquired = 1;
nb_blocked_cars[car]++;
sem_wait(&SEMS[car]);
nb_blocked_cars[car]--;
}
// We reset old position
move_cursor(y, x);
fputc(' ', stdout);
// We move to new position
if (car == 0) {
if (x == RIGHT_LIMIT || x == RIGHT_LIMIT + 1) {
y++;
base_sleep = 110000;
} else if (x == LEFT_LIMIT || x == LEFT_LIMIT + 1) {
y--;
base_sleep = 110000;
} else {
base_sleep = 80000;
}
}
x += increment;
move_cursor(y, x);
// Amélioration Couleur
color(car_color);
fputc(logo, stdout);
move_cursor(1, ROAD_SIZE + 1);
refresh();
// We release the lock if we're out of the critical part of the road
if ((x == RIGHT_LIMIT + 1 && y == 4) || (x == LEFT_LIMIT - 1 && y == 2)) {
move_cursor(11, 1);
fprintf(stdout, "unlocking!");
sem_post(&SEMS[car]);
}
usleep(base_sleep + rand() % 10000);
}
move_cursor(y, x);
fputc(' ', stdout);
move_cursor(1, ROAD_SIZE + 1);
refresh();
return NULL;
}
// Amélioration Messages
void *error_thread(void *param) {
color(0);
move_cursor(11, 1);
fprintf(stdout, "Unrecognised input.");
refresh();
sleep(2);
color(0);
move_cursor(11, 1);
fprintf(stdout, " ");
refresh();
return NULL;
}
void *switchLanes(void *param) {
int sem = 0;
while (1) {
sleep(2);
move_cursor(12, 1);
color(0);
fprintf(stdout, "Switching sem: %d", sem);
move_cursor(1, ROAD_SIZE + 1);
refresh();
for (int i = 0; i < BLOCK_SIZE / 2; i++) {
sem_wait(&SEMS[sem]);
}
for (int i = 0; i < BLOCK_SIZE / 2; i++) {
sem_post(&SEMS[1 - sem]);
usleep(140000);
}
sem = 1 - sem;
}
return NULL;
}
int main(int argc, char **argv) {
{
char buf[10];
printf("Quel taille doit faire la route ? (défaut 40, min 20) → ");
fgets(buf, 10, stdin);
int size = atoi(buf);
if (size < 20) {
ROAD_SIZE = 40;
} else {
ROAD_SIZE = size;
}
}
game_init();
pthread_t last, unused_thread_id;
// Amélioration Compteur
pthread_create(&unused_thread_id, NULL, counter_thread, NULL);
pthread_create(&unused_thread_id, NULL, switchLanes, NULL);
char input;
int car_arg;
do {
input = fgetc(stdin);
switch (input) {
case 'j':
case 'k':
if (input == 'j') {
car_arg = 1;
} else {
car_arg = 0;
}
pthread_create(&last, NULL, car_thread, &car_arg);
color(0);
move_cursor(11, 1);
fprintf(stdout, " ");
refresh();
break;
case 'q':
// Amélioration Messages
color(0);
move_cursor(11, 1);
fprintf(stdout, "Quitting. ");
refresh();
break;
default:
// Amélioration Messages
pthread_create(&unused_thread_id, NULL, error_thread, NULL);
}
} while (input != 'q');
pthread_join(last, NULL);
game_close();
}