Archived

This topic is now archived and is closed to further replies.

DrewSmug

variable sharing problem

Recommended Posts

DrewSmug    122
right now i am working on a snake like game (using dos text). i have created the area where the snake and apple will reside i can create the spot the first apple will start off at and then i start a thread that will change the spot of the apple every 4 seconds. here is my problem: in the appleTimer() function just to test it after 1 second i display another apple which works fine but then after the next four seconds my exe. file shuts down and says there is an access violation, and then proceedes to point me to the line right after my tag that says ''clear old apple spot''. i''m wondering why it will let change the screenBuffer in the first half of my appleTimer function but not right there(in the second half). i don''t know if this will help but i can compile the program and run it, it just dies in the middle. and lastly i don''t know if this will help but i''m using microsoft visual c++ compiler, and want it to run in dos on my win2k machine. hope that was detailed enough, any and all help will be greatly appreciated, thanks. #include <ctime> #include <windows.h> #define GRID_WIDTH 16 #define GRID_HEIGHT 20 #define POS_X 30 #define POS_Y 2 void displayScreen(); void appleTimer(); CHAR_INFO screenBuffer[GRID_WIDTH * GRID_HEIGHT]; SMALL_RECT drawRect = {POS_X, POS_Y, POS_X + (GRID_WIDTH - 1), POS_Y + (GRID_HEIGHT - 1)}; COORD gridSize = {GRID_WIDTH , GRID_HEIGHT}; COORD zeroZero = {0, 0}; HANDLE OutputH; void main() { //initialize the screen to be blank for(int y = 0; y < gridSize.Y; y++) { for(int x = 0; x < gridSize.X; x++) { screenBuffer[x + y * GRID_WIDTH].Char.AsciiChar = '' ''; screenBuffer[x + y * GRID_WIDTH].Attributes = FOREGROUND_GREEN | (BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE); } } //initialize first apple position screenBuffer[12 + 4 * GRID_WIDTH].Char.AsciiChar = ''*''; screenBuffer[12 + 4 * GRID_WIDTH].Attributes = FOREGROUND_RED | (BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE); //start applePosition thread HANDLE threadHandle02; threadHandle02 = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) appleTimer, NULL, 0, NULL); //start displayScreen thread HANDLE threadHandle01; threadHandle01 = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) displayScreen, NULL, 0, NULL); Sleep(6000); } void displayScreen() { while(1) { OutputH = GetStdHandle(STD_OUTPUT_HANDLE); WriteConsoleOutput(OutputH, screenBuffer, gridSize, zeroZero, &drawRect); } } void appleTimer() { int x; int y; Sleep(1000); //playing with apple position screenBuffer[4 + 10 * GRID_WIDTH].Char.AsciiChar = ''*''; screenBuffer[4 + 10 * GRID_WIDTH].Attributes = FOREGROUND_RED | (BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE); clock_t time_start = clock(); while(true) { bool TimeElapse; clock_t time_now = clock(); if((time_now - time_start) > CLOCKS_PER_SEC * 4) TimeElapse = true; else TimeElapse = false; if(TimeElapse) { time_start = clock(); //clear old apple spot screenBuffer[x + y * GRID_WIDTH].Char.AsciiChar = '' ''; screenBuffer[x + y * GRID_WIDTH].Attributes = FOREGROUND_RED | (BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE); //new apple spot srand(GetTickCount()); y = rand()%16; x = rand()%16; screenBuffer[x + y * GRID_WIDTH].Char.AsciiChar = ''*''; screenBuffer[x + y * GRID_WIDTH].Attributes = FOREGROUND_RED | (BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE); } } }

Share this post


Link to post
Share on other sites
Palidine    1315
reposted in readable form


#include <ctime>
#include <windows.h>

#define GRID_WIDTH 16
#define GRID_HEIGHT 20
#define POS_X 30
#define POS_Y 2

void displayScreen();
void appleTimer();

CHAR_INFO screenBuffer[GRID_WIDTH * GRID_HEIGHT];
SMALL_RECT drawRect = {POS_X, POS_Y, POS_X + (GRID_WIDTH - 1), POS_Y + (GRID_HEIGHT - 1)};
COORD gridSize = {GRID_WIDTH , GRID_HEIGHT};
COORD zeroZero = {0, 0};
HANDLE OutputH;

void main()
{
//initialize the screen to be blank

for(int y = 0; y < gridSize.Y; y++)
{
for(int x = 0; x < gridSize.X; x++)
{
screenBuffer[x + y * GRID_WIDTH].Char.AsciiChar = '' '';
screenBuffer[x + y * GRID_WIDTH].Attributes = FOREGROUND_GREEN | (BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE);
}
}

//initialize first apple position

screenBuffer[12 + 4 * GRID_WIDTH].Char.AsciiChar = ''*'';
screenBuffer[12 + 4 * GRID_WIDTH].Attributes = FOREGROUND_RED | (BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE);

//start applePosition thread

HANDLE threadHandle02;
threadHandle02 = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) appleTimer, NULL, 0, NULL);

//start displayScreen thread

HANDLE threadHandle01;
threadHandle01 = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) displayScreen, NULL, 0, NULL);




Sleep(6000);
}

void displayScreen()
{
while(1)
{
OutputH = GetStdHandle(STD_OUTPUT_HANDLE);
WriteConsoleOutput(OutputH, screenBuffer, gridSize, zeroZero, &drawRect);
}
}

void appleTimer()
{
int x;
int y;

Sleep(1000);
//playing with apple position

screenBuffer[4 + 10 * GRID_WIDTH].Char.AsciiChar = ''*'';
screenBuffer[4 + 10 * GRID_WIDTH].Attributes = FOREGROUND_RED | (BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE);

clock_t time_start = clock();
while(true) {
bool TimeElapse;
clock_t time_now = clock();
if((time_now - time_start) > CLOCKS_PER_SEC * 4)
TimeElapse = true;
else
TimeElapse = false;
if(TimeElapse) {
time_start = clock();
//clear old apple spot

screenBuffer[x + y * GRID_WIDTH].Char.AsciiChar = '' '';
screenBuffer[x + y * GRID_WIDTH].Attributes = FOREGROUND_RED | (BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE);
//new apple spot

srand(GetTickCount());
y = rand()%16;
x = rand()%16;
screenBuffer[x + y * GRID_WIDTH].Char.AsciiChar = ''*'';
screenBuffer[x + y * GRID_WIDTH].Attributes = FOREGROUND_RED | (BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE);
}
}
}

Share this post


Link to post
Share on other sites
Palidine    1315
i guess my first response is why, oh why, are you using threads? it''s not at all necessary for this game and it''s going to make debugging a nightmare. however, if you are using threads you haven''t put any protections on your screenBuffer array. both threads may be simultaneously accessing this array the way the code is currently written. that means that you might be trying to draw at the exact same time you are writing to the array. bad bad bad!

i can''t offhand see the actual problem in your program but an outside guess would be that you are attempting to write to the screenBuffer sometime during the WriteConsoleOutput(...) call and that function doesn''t like that you''re modifying it.

if you really want to stick with threads, look up "mutex" and "thread safe design" (or something like the latter).

-me

Share this post


Link to post
Share on other sites
Palidine    1315
quote:
Original post by DrewSmug
how do you post text in the scroll boxes



[ source ]
[ /source ]

without the spaces

and also, seriously reconsider using threads for this program. it''s not the right tool for the job. you really won''t gain anything by using them in this situation other than confusion. of course if you just want to learn thread, by all means play around with it.

-me

Share this post


Link to post
Share on other sites
DrewSmug    122
i''m not asking for any code or anything
but how would you go about programming it then
where or what would you recomend i look to
keeping in mind i had planned on having one more thread that checked to see if the arrow keys had been pushed to move the snake around the screen

Share this post


Link to post
Share on other sites