Sign in to follow this  
dolphins87

help with simple first game

Recommended Posts

I am creating my first game using SDL and I can get the X and O to display on a Tic-Tac-Toe board but I can't get them to be displayed based on whose turn it is. Its a player vs player game. I am using a bool value set to true if it's player ones turn it equals true if not its false and hence player two's turn. But it just randomly switches between the two pieces and I cannot figure out why but here's the code for that
if(player1 == true)
		{
			for(int i = 0; i < 9; ++i)
			{
				if((x > board_tiles[i].x) && (x < board_tiles[i].w) && (y > board_tiles[i].y) && (y < board_tiles[i].h))
				{
					apply_surface(board_tiles[i].x,board_tiles[i].y,pieceX,screen);
					player1 = false;
				}
			}

		}
		else if(player1 == false)
		{
			for(int i = 0; i < 9; ++i)
			{
				if((x > board_tiles[i].x) && (x < board_tiles[i].w) && (y > board_tiles[i].y) && (y < board_tiles[i].h))
				{
					apply_surface(board_tiles[i].x,board_tiles[i].y,pieceO,screen);
					player1 = true;
				}
			}
		}


I am using the for loop to decide in what square the user clicked the mouse so I search through them all and see if the user has clicked in them and x and y are the mouse offsets.

Share this post


Link to post
Share on other sites
I figured out what I was doing wrong and which it my program kept acting the way it did. It was beacuse of the mouse offsets. The values were staying the same through main() and when it re ran through the game loop it just changed the piece. But now I have a whole different problem. The players turn are not connistent. They are always different. It will go X,O,X,O,O,X,X or differently. It's just random. Here's my code if someone can take a look at it please. Thank you.


// headers
#include "SDL/SDL.h"
#include "SDL/SDL_image.h"
#include <string>

// constants for screen
const int SCREEN_WIDTH = 640;
const int SCREEN_HEIGHT = 480;
const int SCREEN_BPP = 32;

// the event structure
SDL_Event event;

// the tic-tac-toe board squares
SDL_Rect board_tiles[9];

// the surface
SDL_Surface *screen = NULL;
SDL_Surface *background = NULL;
SDL_Surface *pieceX = NULL;
SDL_Surface *pieceO = NULL;

// load the images into the surfaces
SDL_Surface *load_image(std::string filename)
{
SDL_Surface *loadedImage = NULL;
SDL_Surface *optimizedImage = NULL;

loadedImage = IMG_Load(filename.c_str());

if(loadedImage != NULL)
{
optimizedImage = SDL_DisplayFormat(loadedImage);

SDL_FreeSurface(loadedImage);

if(optimizedImage != NULL)
{
SDL_SetColorKey(optimizedImage,SDL_SRCCOLORKEY,SDL_MapRGB(optimizedImage->format,0,0xFF,0xFF));
}
}

return optimizedImage;
}

void apply_surface(int x, int y, SDL_Surface *source,SDL_Surface *destination,SDL_Rect *clip = NULL)
{
SDL_Rect offset;

offset.x = x;
offset.y = y;

SDL_BlitSurface(source,clip,destination,&offset);
}

bool init()
{
if(SDL_Init(SDL_INIT_EVERYTHING) == -1)
return false;

screen = SDL_SetVideoMode(SCREEN_WIDTH,SCREEN_HEIGHT,SCREEN_BPP,SDL_SWSURFACE);

if(screen == NULL)
return false;

SDL_WM_SetCaption("Tic-Tac-Toe 1.0",NULL);

return true;
}

bool load_files()
{
background = load_image("background.png");

pieceX = load_image("pieceX.png");

pieceO = load_image("pieceO.png");

if(background == NULL)
return false;

if(pieceX == NULL)
return false;

if(pieceO == NULL)
return false;

return true;
}

void clean_up()
{
SDL_FreeSurface(background);
SDL_FreeSurface(pieceX);
SDL_FreeSurface(pieceO);

SDL_Quit();
}

// initalizes all the square piece of the Tic-Tac-Toe board
void init_tiles()
{
// top left
board_tiles[0].x = 80;
board_tiles[0].y = 115;
board_tiles[0].w = 165;
board_tiles[0].h = 185;

// top middle
board_tiles[1].x = 180;
board_tiles[1].y = 115;
board_tiles[1].w = 345;
board_tiles[1].h = 185;

// top right
board_tiles[2].x = 350;
board_tiles[2].y = 115;
board_tiles[2].w = 440;
board_tiles[2].h = 185;

// middle left
board_tiles[3].x = 75;
board_tiles[3].y = 190;
board_tiles[3].w = 170;
board_tiles[3].h = 280;

// middle middle
board_tiles[4].x = 175;
board_tiles[4].y = 190;
board_tiles[4].w = 345;
board_tiles[4].h = 280;

// middle right
board_tiles[5].x = 350;
board_tiles[5].y = 190;
board_tiles[5].w = 440;
board_tiles[5].h = 280;

// bottom left
board_tiles[6].x = 75;
board_tiles[6].y = 285;
board_tiles[6].w = 165;
board_tiles[6].h = 340;

// bottom middle
board_tiles[7].x = 175;
board_tiles[7].y = 285;
board_tiles[7].w = 345;
board_tiles[7].h = 340;

// bottom right
board_tiles[8].x = 350;
board_tiles[8].y = 285;
board_tiles[8].w = 445;
board_tiles[8].h = 340;
}



int main(int argc, char *args[])
{


// the mouse button offsets
int x = 0, y = 0;

bool quit = false;

bool player1 = true;

// initalize SDL
if(init() == false)
return 1;

// initalize and load all the files for us
if(load_files() == false)
return 1;

// load the Tic-Tac-Toe board
init_tiles();

apply_surface(0,0,background,screen);

while(quit == false)
{
while(SDL_PollEvent(&event))

{
if(event.type == SDL_MOUSEBUTTONDOWN)
{
if(event.button.button == SDL_BUTTON_LEFT)
{
x = event.button.x;
y = event.button.y;

}
}
else if(event.type == SDL_QUIT)
{
quit = true;
}

}

for(int i = 0; i < 9; ++i)
{
if(player1 == true)
{
if((x > board_tiles[i].x) && (x < board_tiles[i].w) && (y > board_tiles[i].y) && (y < board_tiles[i].h))
{
apply_surface(board_tiles[i].x,board_tiles[i].y,pieceX,screen);
}
}
else if(player1 == false)
{
if((x > board_tiles[i].x) && (x < board_tiles[i].w) && (y > board_tiles[i].y) && (y < board_tiles[i].h))
{
apply_surface(board_tiles[i].x,board_tiles[i].y,pieceO,screen);
}
}
}

if(player1 == true)
player1 = false;
else if(player1 == false)
player1 = true;

x = 0;
y = 0;

if(SDL_Flip(screen) == -1)
return 1;




}

clean_up();

return 0;
}



Share this post


Link to post
Share on other sites
It goes through the ( quit == false ) loop unhindered, changing player everytime it reaches the end.

It needs to change players only when the player has placed a piece.

As it is now there's 50% chance you are player 1 and 50% chance you are player 2 every time you click the mouse, hence the randomness.

I think that's it.

Share this post


Link to post
Share on other sites
Chris is right, but aside from that I noticed the code to put each player's piece is exactly the same except for what piece is being put down. What you could have done instead is to have an array of 2 elements, one containing a pointer to pieceX and the other containing a pointer to pieceO (and of course, you would no longer declare pieceX and pieceO as loose variables). Rather than using a boolean to determine who's turn it is, you would use a number that corresponds to the index of the array that contains that player's piece. As you make bigger and bigger projects, learning to avoid repetition will be one of the most useful skills you'll develop as a programmer.

You might go even further and make a class for each player. This class would have the player's name, a pointer to their current piece (what used to be pieceO or pieceX), and maybe even a number for how many games they've won. Instead of having an array with pointers to pieceX or pieceO, you would have pointers to Player objects. This way, you could put a text label on your game saying "It's your turn, Billy Bo Bob!".


Share this post


Link to post
Share on other sites
Thank you for all the information its all helping alot. Im gonna try to get the game working first them implemnting the classes after that and some more functionality. But I tried to figure out if the player won by trying to use the code in Dawson's book but I'm not sure what Im doing wrong. Im using an array of Surfaces and setting them all to NULL at first. Then when a player places a piece if with set the position in the array of surfaces to pieceX or pieceO and then I i'm trying to search through the board and see if the player has three in a row to see if they won and if they did then display a message. But its not displaying a message and not sure why. I know I'm having alot of problems but I'm also learning. Ive made some simple text based games but thats why I didnt want to try anything to difficult at first. Thanks

Share this post


Link to post
Share on other sites
Your basic program flow (if I understood everything correctly) looks something like this:


Loop
{
If Mouse Clicked -> Get Mouse position
Apply tile at mouse position
Change player
}


As others have pointed out, your biggest flaw is that all your functions are called every loop iteration. That is, the player changes regardless if he has clicked (i.e. finished his turn). Likewise, you do the tile-placement checks every for loop, even if a player did not place a tile, which is wasteful.

What you should do is re-organize your code so that there is a clear division between each player's turns, and that tile placement and turn changes are done only when the player actually makes a move. This can be done through a simple "state" system using a switch statement.

Here's some pseudo code to give you an idea of what I'm talking about:


variable STATE = player turn;

while(quit != true)
{
do standard stuff here that needs to be done every loop like:
- draw your tiles to screen
- check for non-state specific input (ex: Escape key -> set quit = true)

switch(STATE)
//============================================================
case player turn:
{
//============================================================
// Player input check
//============================================================
if(there is new input)
{
switch(input type)
{
case left mouse click:
{
if(empty tile)
{
set tile to player 1's tile
set STATE to turn done
}
else
{
do nothing, or display error ("This tile is already taken!") or something
}
}
}
}
break state switch statement;
}

//============================================================
case turn done:
{
if(any one player won)
set STATE to someone won;
else
{
change "current" player to the other player (player1 = !player1)
STATE = player turn;
}

break state switch statement;
}

//============================================================
case some one won:
{
dispaly victory screen or something like that;

break state switch statement;
}
}





You can then wrap each state code into it's own function to make your game loop look nicer and easier to understand.

Also, a hint - you can use the negation operator to "invert" bools. Instead of your if else if, just do player1 = !player1;

edit: here's a read on game states: http://gamedevgeek.com/tutorials/managing-game-states-in-c/

[Edited by - Koobazaur on January 2, 2008 1:58:42 AM]

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this