# Tic Tac Toe - bleh, stuck.

This topic is 3087 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

Alright, I feel lame because I've had to ask two question within the last two days, but oh well, here goes. Just got started in SDL and I'm doing my first game (tic tac toe). Now, I wanted to make it so as that when the player is hovering the mouse over a square, a box white rectangle highlights it. I was experimenting with a few things on the first square, and it seems like this should work, but it doesn't. Any tips? main.cpp
#include "sdl.h"
#include "sdl_ttf.h"
#include "sdl_image.h"
#include "game.h"

int main(int argc, char* argv[])
{
Game game;
game.Execute();
return 0;
}


graphics.h
#ifndef GRAPHICS_H
#define GRAPHICS_H
#include "sdl.h"
#include "sdl_ttf.h"
#include "sdl_image.h"

class Screen
{
private:
SDL_Surface *MainScreen;
public:
Screen();
SDL_Surface* GetScreen();
void Flip();
void InitScreen();
void Draw(SDL_Surface* src, int x, int y);
};

class Image
{
private:
SDL_Surface *OriginalImage;
SDL_Surface *OptimizedImage;
Screen screen;
public:
Image();
};

#endif


graphics.cpp
#include "graphics.h"

//screen functions

Screen::Screen()
{
MainScreen = NULL;
}

void Screen::Flip()
{
SDL_Flip(MainScreen);
}

void Screen::InitScreen()
{
MainScreen = SDL_SetVideoMode(700,500,16, SDL_HWSURFACE | SDL_DOUBLEBUF);
}

SDL_Surface* Screen::GetScreen()
{
return MainScreen;
}

//image functions

Image::Image()
{
OptimizedImage = NULL;
OriginalImage = NULL;
}

void Screen::Draw(SDL_Surface* src, int x, int y)
{
SDL_Rect rect;

rect.x = x;
rect.y = y;

SDL_BlitSurface(src,NULL,MainScreen,&rect);
}

{
OptimizedImage = SDL_DisplayFormat(OriginalImage);
SDL_FreeSurface(OriginalImage);
return OptimizedImage;
}


game.h
#ifndef GAME_H
#define GAME_H
#include "sdl.h"
#include "sdl_ttf.h"
#include "sdl_image.h"
#include "graphics.h"

class Player
{
public:
Player();
void draw(Screen screen,char* file, int x, int y);
private:
Image images;
};

class Game
{
public:
Game();
void Execute();
void Start();
bool HandleEvent();
void CleanUp();
private:
SDL_Event Event;
Screen screen;
Player player;
int SquareOne[4];
int SquareTwo[4];
int SquareThree[4];
int SquareFour[4];
int SquareFive[4];
int SquareSix[4];
int SquareSeven[4];
int SquareEight[4];
int SquareNine[4];
bool running;
};

#endif


game_variables.cpp
#include "game.h"

Game::Game()
{
int SquareOne[4] = {5,217,5,147};
int SquareTwo[4] = {244,455,5,147};
int SquareThree[4] = {480,692,5,147};
int SquareFour[4] = {5,217,176,316};
int SquareFive[4] = {244,455,176,316};
int SquareSix[4] = {480,692,176,316};
int SquareSeven[4] = {5,217,350,491};
int SquareEight[4] = {244,455,350,491};
int SquareNine[4] = {480,692,350,491};

running = true;
}

game.cpp
#include "game.h"

//game functions
void Game::Start()
{
SDL_Init(SDL_INIT_EVERYTHING);
screen.InitScreen();
SDL_WM_SetCaption("Tic Tac Toe", NULL);
}

bool Game::HandleEvent()
{
int x = 0;
int y = 0;
if(SDL_PollEvent(&Event))
{
if(Event.type == SDL_QUIT)
{
running = false;
}
else if(Event.type == SDL_MOUSEMOTION)
{
x = Event.motion.x;
y = Event.motion.y;

if((x > SquareOne[0]) && (x < SquareOne[1]) && (y > SquareOne[2]) && (y < SquareOne[3]))
{
player.draw(screen,"selected.png",SquareOne[0],SquareOne[2]);
}
}
}
return true;
}

void Game::CleanUp()
{
}

Player::Player()
{
}

void Player::draw(Screen screen,char* file, int x, int y)
{
}


execute.cpp
#include "game.h"

void Game::Execute()
{
Start();
while(running)
{
player.draw(screen,"board.png",1,1);
HandleEvent();
screen.Flip();
}
CleanUp();
}



##### Share on other sites
I do not see anything obvious but:

Is the image loading and being passed into the draw function properly?

Is your image of a rect with alpha in the middle or is it of a square with a rect around it? If so how is your alpha blending setup?

How is your current z checking/state setup? (Sorry I am not familiar with SDL or its defaults, but these are all "my thing isnt rendering properly" type things to check.

Are you getting any results back from the Draw functions?

Some notes:

Passing images.LoadItem("Path.png") directly into the draw function is a bit messy. To me it reads that every time you go to draw something you are loading it, which is really ineffecient. It might be doing something smarter than that with a caching system behind the scenes in which case it is just misleading.

Your method of organizing the squares is hard to use. You may consider writing a rect class or using the SDL_Rect class and having an array of those. You can then loop through the array for your mouse checks instead of writing a case for each square and memorizing which position 0, 1, 2, and 3 are.

##### Share on other sites
The draw function is working properly. I can use it to draw the board, so no, that's not the issue.

##### Share on other sites
[Disclaimer: I haven't messed with SDL or C/C++ in forever.]
What isn't working about it? The selected.png isn't being drawn at all, or only when the mouse moves? If it is only being drawn when the mouse moves, I think the SDL_MouseMotion only occurs when the mouse moves(per this).

Anywho, you really shouldn't be needing to check this event at all, instead you might test the mouse's position each frame, etc.

[nitpicking]
Also, not to be offensive, but your code looks kinda horrid. :x In the future/now, might want to make a struct just for Square that has the x1,x2,y1,y2 vars in it, and have a board of Square squares[9], so you could have squares[1].x1 instead of SquareTwo[0]. Also, you may want to do away with the if/else structure you're having in HandleEvent if it gets any bigger, and throw in a switch/case. And why is HandleEvent a bool? o_O And you'd better make a function for handling the mouse position tests, instead of having 9 if/else tests.
[/nitpicking]

Hope you get it working! [grin]

##### Share on other sites
Quote:
 Original post by nerd_boy[Disclaimer: I haven't messed with SDL or C/C++ in forever.]What isn't working about it? The selected.png isn't being drawn at all, or only when the mouse moves? If it is only being drawn when the mouse moves, I think the SDL_MouseMotion only occurs when the mouse moves(per this).

Yes, selected.png isn't being drawn at all. And I'm only using the MouseMotion to get the mouse coordinates. I'm also not in the least bit surprised that my code looks horrid, but to to the fact that I'm in the learning stage, I'm more concerned with usability rather than cosmetics. However, if you have any particular critique a to how I could clean it up, I'd be happy to hear it along with any solution to my problem you may be able to come up with. Oh, and I made HandleEvent a bool because I had it returning a value, but I changed my code, so it's not necessary anymore. . . so, yeah, I should probably fix that, but again, more concerned with usability as a whole rather than the particulars.

##### Share on other sites
Have you tested as to whether or not that particular bit of code gets called at all? Both/Either immediately inside the SDL_MOUSEMOTION handling and/or the test for SquareOne?

##### Share on other sites
Yep, just tested it. I added the code so that, if the mouse coordinate conditions are met, the program will close, didn't work though. Should I be drawing the "selected.png" image to a different surface than I'm drawing the board to? could the board be covering "selected.png" up. That would suck, because it would ruin my image function, which only supports images being drawn to the screen, but is that a possibility, or should it show anyways?

##### Share on other sites
Nah, I don't see any reason why it shouldn't be drawing to the screen, throw the draw call outside of the test to see, though.

What do you mean, "it didn't work"? The code didn't quit? o_O If thats the case, sounds like the requirements aren't, for some reason, being met... Which would be weird.

##### Share on other sites
No, the program closed, so the requirements are being met, I was just saying that the "selected.png" image still wasn't posting. No thoughts on this?

EDIT: Ok, I figured it out, for some reason the variable for the coordinates aren't working. I plugged real numbers in and it worked. Any thoughts on a fix for this?

##### Share on other sites
Oof, completely missed that.

Inside of the game_variables.cpp where you have the contstructor for Game you are not initing the variables in your class, you are initing local variables in that function.

By doing:

int SquareOne[4] = {5,217,5,147};

You are declaring a local variable and initializing it. The one belonging to the class is never being initialized.

##### Share on other sites
I feel a bit daft now. :/

##### Share on other sites
But I thought the constructor was the way you initilized variables. If not in the constructor, then where? Just between the class brackets?

##### Share on other sites
You are correct, the constructor is the correct place.

I will give an example that is simpler, because honestly I haven't used c style arrays in this fashion in a while.

class ClassName{  ClassName::ClassName (void);  int m_nVariable;}ClassName::ClassName (void){  m_nVariable = 12; //Correct way to initialize your variable belonging to ClassName.  int m_nVariable = 12; //Incorrect way to initialize your variable belonging to ClassName.}

In the case of "int m_nVariable = 12;" you are actually initializing a variable on the stack that is "hiding" your classes variable. This is a feature of the language, but usually incurs a warning letting you know that this is happening (depending on your warning settings).

You can still reference your class variable if you have a local variable hiding it, but you need to use your this->m_nVariable to do it. In some cases variable hiding is done by deriving. Base class A has a variable and derived class B has an identical named variable, so to get to the one in class A you scope it A::variable.

In this case you can just get rid of the new variable declaration and init your class variables. You can replace your code with the following and it should work:

#include "game.h"Game::Game(){	SquareOne[0] = 5;	SquareOne[1] = 217;	SquareOne[2] = 5;	SquareOne[3] = 147;	SquareTwo[0] = 244;	SquareTwo[1] = 455;	SquareTwo[2] = 5;	SquareTwo[3] = 147;... etc	running = true;}

##### Share on other sites
Doh, I knew that, but I suppose that's what you get when you copy and paste :/