I have a task in which I need to create a console game in the form of a road junction, it was created to study threads in the C language. My goal is to create a stream that would accept motion commands from the keyboard and at the same time the movement of imaginary typewriters on the screen should work. I read about threads, it seems like I understood the main point, but I can’t do simultaneous work, at startup either one part works or the other.
View of the program in the console (x - typewriter, @ - player), you must switch to the other side
# # # # # # # ##################
XXXX XX XX X XX XXXX XXXX XXXXX XX XX XX @ ################################################# ###################
int main(int argc, char** argv) { //Initialize game components srand(time(0)); screen = initscr(); if(screen == NULL) exit(-1); wresize(screen, SCREEN_HEIGHT, SCREEN_WIDTH ); old_cursor = curs_set(0); froggy.x = SCREEN_WIDTH / 2; froggy.y = SCREEN_HEIGHT - OUTER_BORDER - 1; initMotorway(); pthread_t thread; int status; status = pthread_create(&thread, NULL,catch_input(), NULL); if (status != 0) { printf("main error: can't create thread, status = %d\n", status); exit(10); } while(!quit && !error && !player_lost && !player_won) { moveFroggy(); moveCarsOnMotorway(); startCar((SCREEN_WIDTH - OUTER_BORDER)); drawScreen(); usleep(GAME_SPEED); } if(pthread_join(thread, NULL)) { printf("main error: can't join the thread"); exit(11); } ... If I place a call to a thread
status = pthread_create(&thread, NULL, moveFroggy(), NULL); before calling basic functions with graphics
while(!quit && !error && !player_lost && !player_won) { moveCarsOnMotorway(); startCar((SCREEN_WIDTH - OUTER_BORDER)); drawScreen(); usleep(GAME_SPEED); } Then when compiling, an empty window appears in the terminal and it seems to read commands, although I am not sure about that either, because the prints that I wrote in the MoveFroggy () function are not displayed, if you do the opposite, then moving machines are displayed but the method does not work commands from the keyboard.
Listing MoveFroggy ()
void moveFroggy(char buf) { pthread_mutex_lock(&my_mutex); if((first_frogy=false)){ froggy.y = SCREEN_HEIGHT - OUTER_BORDER; first_frogy = true; } if((checker = true)){ if((buf == 'a') && (froggy.x > OUTER_BORDER)){ froggy.x--; refresh(); } if(buf == 'd' && (froggy.x < (SCREEN_WIDTH - OUTER_BORDER))){ froggy.x++; refresh(); } if (buf == 'w' && (froggy.y >= (SCREEN_HEIGHT - NUM_LANES - OUTER_BORDER - GRASS_BORDER))) froggy.y--; if (buf == 's' && (froggy.y < (SCREEN_HEIGHT - OUTER_BORDER))) froggy.y++; if( buf == 'q'){ pthread_mutex_unlock(&my_mutex); exit(1); } if(froggy.y <= (SCREEN_HEIGHT - NUM_LANES - OUTER_BORDER - GRASS_BORDER)) player_won = 1; pthread_mutex_unlock(&my_mutex); } else{ pthread_mutex_unlock(&my_mutex); } } Thanks in advance for your help
UPDATE:
Declared global options and structures necessary for the program to work, wrote a mutex from below, will it capture all declared variables when calling and only the last ??
// Represents a specific screen positions by Cartesian coordinates typedef struct{ int x; int y; } Point; // Cars on the motorway are organized using a linked list // Every list element stores the car's coordinates and a pointer to the next car typedef struct Car { Point position; struct Car* next; } Car; // List of cars on motorway (pointer to first list element) Car* motorway; // Position of froggy on screen Point froggy; // Variables to represent current game state unsigned int error; unsigned int quit; unsigned int player_lost; unsigned int player_won; bool checker; bool first_frogy; // Other global variables WINDOW* screen; int old_cursor = 0; char new_input; pthread_mutex_t my_mutex; Made a separate function, according to the idea it should save input to a global variable, and the moveFroggy function will be called with all drawing functions from the main stream, and if there was a new input (checked by a bool variable), then change the state, if not, pass by
void* catch_input(){ char buf; while((buf = getchar())){ pthread_mutex_lock(&my_mutex); new_input = buf; checker = true; pthread_mutex_unlock(&my_mutex); } pthread_exit(NULL); } But still, only the stream catch_input works when compiling, but the main thread for some reason does not work and the drawing does not start, if you comment the catch_input flow, then the drawing works. What’s the problem?
getchar()processing in non-binary mode - Yaroslav