Where to call AI_response?

Started by
28 comments, last by Matt Apple 19 years ago
I'm having some troubles with Tic-Tac-Toe, that I have been unable to resolve. I have written the code for the player to place his piece; however, I am having issues with the computer's response. I have written a function for the computer's response, however I am not sure where to call it. Here's my code (cut down for efficiency): Implementation of the Grid class -

void Grid::blitFromInput()
{
	if(key[KEY_1_PAD])	blitToRect(0, 2, 'X');
	if(key[KEY_2_PAD])	blitToRect(1, 2, 'X');
	if(key[KEY_3_PAD])	blitToRect(2, 2, 'X');
	if(key[KEY_4_PAD])	blitToRect(0, 1, 'X');
	if(key[KEY_5_PAD])	blitToRect(1, 1, 'X');
	if(key[KEY_6_PAD])	blitToRect(2, 1, 'X');
	if(key[KEY_7_PAD])	blitToRect(0, 0, 'X');
	if(key[KEY_8_PAD])	blitToRect(1, 0, 'X');
	if(key[KEY_9_PAD])	blitToRect(2, 0, 'X');
}


void Grid::blitToRect(int x, int y, char turn)
{
	int temp_x = x;
	int temp_y = y;
	x *= static_cast<int>(scale_factor / 1.5) + 1;
	y *= static_cast<int>(scale_factor / 1.5) + 1;
	if(!(theGrid[temp_x][temp_y] == 'X' || theGrid[temp_x][temp_y] == 'O')) {
	if (turn == 'X') {
		draw_sprite(g->buffer,x_bitmap, x, y);
	} else {
		draw_sprite(g->buffer,o_bitmap, x, y);
	}
	theGrid[temp_x][temp_y] = turn;
}

	
}


bool Grid::AI_response()
{
	srand(time(0));	
	int x = rand()%3;
	int y = rand()%3;
	if(theGrid[x][y] == 0)
	{
		blitToRect(x, y, 'O');
		return true;
	}
	else
	{
		for(int i = 0; i < 3; i++)
			for(int j = 0; j < 3; j++)
			{
				if(theGrid[j] == 0) blitToRect(i, j, 'O');
				break;
			}
		return true;
	}
}

Main loop -

while ( !done )
    {
		g->update();
		g->render();
        if (key[ KEY_ESC ]) done = true;
		while(speed_counter > 0)
		{

			if(key[KEY_RIGHT])// If the user hits the right key, change the picture's X coordinate
			{
			   //my_pic_x ++;// Moving right so up the X coordinate by 1
			}
			else if(key[KEY_LEFT])// Ditto' - only for left key
			{
			   //my_pic_x --;// Moving left, so lower the X coordinate by 1
			}
			else if(key[KEY_UP])// If the user hits the up key, change the picture's Y coordinate
			{
			   //my_pic_y --;// Moving up, so lower the Y coordinate by 1
			}
			else if(key[KEY_DOWN])// Ditto' - only for down
			{
			   //my_pic_y ++;// Moving down, so up the Y coordinate by 1
			}
			grid->blitFromInput();
			speed_counter--;
		}//End timer test
    }

This is a logic problem, not a syntax or memory error. Thank you for your time.
Advertisement
Wow, that code is indented weird. *At least it seems that way to me*

It seems to me you'd do it right after the while(speed_counter > 0) loop has exited.
Originally I tried to put it right after the while like you said, but then it started making multiple moves in response to one of the player's moves.
The APs solution seems right. Are you sure that you are reinitializing speed_counter after calling AI_response?
If I do what the AP said, then the computer makes 4 moves before the player even makes 1.
I don't see where you're keeping track of whose turn it is. Perhaps your computer is taking 4 turns because the player's not fast enough to jump in for his turn? Did you just not post this logic?
You don't really need to keep track of whose turn it is.

You do need to call AI_response immediately after the "blitFromInput" IF the player actually made a move. So you need that function to communicate whether or not a move was actually entered (or, actually call AI_response itself, which is what I'd recommend). You don't need to return anything from AI_response, because the computer will always move when asked.

Also, you might want to do something to prevent the user from pressing multiple keys at once and getting all those boxes :) There is probably a good way to get rid of the repetition in that code, too. Are those constant values in a continuous range? If so, something like this should work:

for (int i = 0; i < 9; i++) {  if(key[KEY_1_PAD + i]) {    // i == 0 -> key 1 pressed    // i == 8 -> key 9 pressed    // So we do some div and mod arithmetic to get the right row/column...    blitToRect(i % 3, 2 - (i/3), 'X');    // then tell the AI response to kick in...    AI_response();    // and bail out, because we want to ignore multiple keypresses at once    return;  }}


Also, you'll probably want to check for illegal moves (i.e. on an already-occupied square). Just silently return for those; they'll probably happen a fair bit if the user holds down a key...

Also, I'm wondering why that division by 1.5 isn't incorporated into your (presumably constant) "scale_factor"...
Quote:Also, you'll probably want to check for illegal moves (i.e. on an already-occupied square). Just silently return for those; they'll probably happen a fair bit if the user holds down a key...

Doesn't my code already check for the illegal move? Is there a problem with the way that I do it?
Oh, you have it handled in blitToRect(), sorry.

... It might have been better to write the console version first to get the game logic worked out, and then fit graphical stuff into that framework :/
I have the graphical issues resolved, it is just the logical issues that I am having problems with. I don't have problems with the game graphics, just the game logic. So it wouldn't really matter whether I did text-based or graphical, because I would still have the same question.

This topic is closed to new replies.

Advertisement