I've been toying around with game ideas while trying to figure out threading; I've got a simple program and was hoping to get an idea on any problems that occur before I move on. Right now, it just moves the "enemies" about. Code: // compiled using Code::Blocks 10.05 // modified threading example // http://www.cs.rpi.edu/academics/courses/netprog/WindowsThreads.html // Win32 console app #include <windows.h> #include <stdio.h> #include <stdlib.h> #include <time.h> #define MAX_E 15 // number of "enemies" #define MAX_Y 20 // max rows #define MAX_X 79 // max cols HANDLE hcon; // global handle to console window int sentinel; // global loop control variable typedef struct { COORD old_c; COORD new_c; char shown; char blank; // structure for each "character" } test; typedef struct { test *enemies_list; // the thread function allows only one argument. To pass a boat load // of data, use a struct as a "container" of other data } enemy_array; DWORD WINAPI ThreadRoutine(LPVOID lpArg) { enemy_array t = *(enemy_array *)lpArg; // lpArg needs to be cast to the appropriate data type // in this case, it's (enemy_array *). To get to the data // we want, dereference *(cast_type *)lpArg for(; sentinel != 10; ) { // to exit out of the threading function, // set the sentinel value from within the main // !! not sure if this is correct !! int i = 0; time_t t1 = time(0), t2; do{ t2 = time(0); } while(t2 < t1 + 1); // crude timer function; wait for ~1 second while(i < MAX_E) { SetConsoleCursorPosition(hcon, t.enemies_list[i].old_c); putchar(t.enemies_list[i].blank); // update each of the "enemies" by placing a space where it // was; there is NO collision detection at this time switch(rand() % 4) { case 0 : if(t.enemies_list[i].new_c.Y - 1 > 0) // move up --t.enemies_list[i].new_c.Y; else if(t.enemies_list[i].new_c.Y == 0) t.enemies_list[i].new_c.Y = MAX_Y; break; case 1 : if(t.enemies_list[i].new_c.X - 1 > 0) // move left --t.enemies_list[i].new_c.X; else if(t.enemies_list[i].new_c.X == 0) t.enemies_list[i].new_c.X = MAX_X; break; case 2 : if(t.enemies_list[i].new_c.X + 1 < MAX_X) // move right ++t.enemies_list[i].new_c.X; else if(t.enemies_list[i].new_c.X == MAX_X) t.enemies_list[i].new_c.X = 0; break; case 3 : if(t.enemies_list[i].new_c.Y + 1 < MAX_Y) // move down ++t.enemies_list[i].new_c.Y; else if(t.enemies_list[i].new_c.Y == MAX_Y) t.enemies_list[i].new_c.Y = 0; break; } SetConsoleCursorPosition(hcon, t.enemies_list[i].new_c); putchar(t.enemies_list[i].shown); t.enemies_list[i].old_c.X = t.enemies_list[i].new_c.X; t.enemies_list[i].old_c.Y = t.enemies_list[i].new_c.Y; // update the new coordinates of each "enemy" ++i; } } return NULL; } int main() { int i; HANDLE hHandles; // handle to thread DWORD ThreadId; CONSOLE_CURSOR_INFO cci; // structure for cursor test player = { { 40, 10 }, { 40, 10 }, 'X', ' ' }; enemy_array ea; ea.enemies_list = malloc(sizeof(test) * MAX_E); // allocate some enemies if(ea.enemies_list) { int i=0; while(i < MAX_E) { ea.enemies_list[i].blank = ' '; ea.enemies_list[i].shown = "!@#$%^&*()_+"[rand() % 12]; ea.enemies_list[i].new_c.X = ea.enemies_list[i].old_c.X = rand() % 80; ea.enemies_list[i].new_c.Y = ea.enemies_list[i].old_c.Y = rand() % 20; // set their coordinates and assign them a "random" display character ++i; } } else { fprintf(stderr, "could not allocate space for enemies"); return 1; } sentinel = 0; // controls the threading function runtime cci.dwSize = 1; cci.bVisible = 0; // hide the cursor hcon = GetStdHandle(STD_OUTPUT_HANDLE); // get handle to console window SetConsoleCursorInfo(hcon, &cci); // prepare display hHandles = CreateThread(NULL, 0, ThreadRoutine, &ea, 0, &ThreadId); // try to create the thread if (hHandles == NULL) { fprintf(stderr,"Could not create Thread\n"); exit(0); } SetConsoleCursorPosition(hcon, player.new_c); putchar(player.shown); // set the initial placement of the player's character for(; getchar() != '\n';) { // main player loop } sentinel = 10; // clean up and prepare for program termination WaitForSingleObject(hHandles, INFINITE); cci.dwSize = 1; cci.bVisible = 1; SetConsoleCursorInfo(hcon, &cci); // restore cursor free(ea.enemies_list); return 0; } If anyone sees anything troublesome, please point it out.