Tic-Tac-Toe C game error

Discuss the development of new homebrew software, tools and libraries.

Moderators: cheriff, TyRaNiD

Post Reply
drako
Posts: 2
Joined: Fri Sep 14, 2007 6:09 pm

Tic-Tac-Toe C game error

Post by drako »

Hi! Everybody

i'm wrote a simple tic-tac-toe game for the psp, using sdl, but i found that the positions of the "X" and the "O" did not correspond to the correct ones, i use a 2*2 matrix and indexes "j" and "i" to run the matrix and draw the symbols, sometimes i got the same symbol on two different positions (like for example [1][0] and [0][2]), even when the matrix has only one valor


This is my code
it's a little messy, (lots of commented code), but it still compile.

Code: Select all

#include <SDL/SDL.h>
#include <SDL/SDL_image.h>
#include <SDL/SDL_mixer.h>
#include <pspkernel.h>

#define PSP_BUTTON_UP              &#40;8&#41;
#define PSP_BUTTON_DOWN            &#40;6&#41;
#define PSP_BUTTON_LEFT            &#40;7&#41;
#define PSP_BUTTON_RIGHT           &#40;9&#41;
#define PSP_BUTTON_X               &#40;2&#41;

SDL_Surface *screen = NULL;
SDL_Joystick *joystick = NULL;

int done = 0;

int exit_callback&#40;int arg1, int arg2, void *common&#41;&#123;
  done = 1;
  return 0;
&#125;

int CallbackThread&#40;SceSize args, void *argp&#41; &#123;
	int cbid;
	cbid = sceKernelCreateCallback&#40;"Exit Callback", exit_callback, NULL&#41;;
	sceKernelRegisterExitCallback&#40;cbid&#41;;
	sceKernelSleepThreadCB&#40;&#41;;
	return 0;
&#125;

int SetupCallbacks&#40;void&#41; &#123;
	int thid = 0;
	thid = sceKernelCreateThread&#40;"update_thread", CallbackThread, 0x11,
	0xFA0, 0, 0&#41;;
	if&#40;thid >= 0&#41; &#123;
		sceKernelStartThread&#40;thid, 0, 0&#41;;
	&#125;
	return thid;
&#125;

int initSDL&#40;&#41;&#123;
	SDL_Init&#40;SDL_INIT_AUDIO | SDL_INIT_VIDEO | SDL_INIT_JOYSTICK&#41;;
        joystick = SDL_JoystickOpen&#40;0&#41;;
	screen = SDL_SetVideoMode&#40;480, 272, 24, SDL_HWSURFACE | SDL_HWPALETTE | SDL_DOUBLEBUF&#41;;

	if&#40;screen == NULL&#41;&#123;
		fprintf&#40;stderr, "No se pudo iniciar el mode de pantalla&#58; %s\n", SDL_GetError&#40;&#41;&#41;;
		return 0;
	&#125;

	if&#40;Mix_OpenAudio&#40;22050, MIX_DEFAULT_FORMAT,2,1024&#41;&#41;&#123;
		fprintf&#40;stderr,"Unable to open audio!\n"&#41;;
		return 0;
	&#125;
	return 1;
&#125;

SDL_Surface* loadImage&#40;char *filename&#41;&#123;
	SDL_Surface* loadedImage = NULL;
	SDL_Surface* optimizedImage = NULL;

	loadedImage = IMG_Load&#40;filename&#41;;
	if&#40;loadedImage != NULL&#41;&#123;
		optimizedImage = SDL_DisplayFormat&#40;loadedImage&#41;;
		SDL_FreeSurface&#40;loadedImage&#41;;
	&#125;else&#123;
		fprintf&#40;stderr, "No se encontro la imagen\n"&#41;;
		done = 1;
	&#125;
	return optimizedImage;
&#125;

void applySurface&#40;int x, int y, SDL_Surface *source, SDL_Surface *destination&#41;&#123;
	SDL_Rect offset;
	offset.x = x;
	offset.y = y;

	SDL_BlitSurface&#40;source, NULL, destination, &offset&#41;;
&#125;

int getRealxPos&#40;int x&#41;&#123;
	switch&#40;x&#41;&#123;
		case 0&#58;
			return 74;
		case 1&#58;
			return 189;
		case 2&#58;
			return 303;
	&#125;
	return 0;
&#125;

int getRealyPos&#40;int y&#41;&#123;
	switch&#40;y&#41;&#123;
		case 0&#58;
			return 16;
		case 1&#58;
			return 95;
		case 2&#58;
			return 175;
		&#125;
	return 0;

&#125;
/*
int initMatrix&#40;int gameMatrix&#91;2&#93;&#91;2&#93;&#41;&#123;
	int i = 0, j = 0;
	for&#40;i=0;i<2;i++&#41;
		for&#40;j=0;j<2;j++&#41;&#123;
			gameMatrix&#91;i&#93;&#91;j&#93; = 0;
		&#125;
	return 0;
&#125;

int drawMarks&#40;int gameMatrix&#91;2&#93;&#91;2&#93;,SDL_Surface *X, SDL_Surface* O, SDL_Surface* src_buffer&#41;&#123;
	int i = 0, j = 0;
	for&#40;i=0;i<2;i++&#41;
		for&#40;j=0;j<2;j++&#41;&#123;
			if&#40;gameMatrix&#91;i&#93;&#91;j&#93; == 1&#41;&#123;
				applySurface&#40;getRealxPos&#40;i&#41; + 19, getRealyPos&#40;j&#41; + 30,X,src_buffer&#41;;
			&#125;else if&#40;gameMatrix&#91;i&#93;&#91;j&#93; == 2&#41;&#123;
				applySurface&#40;getRealxPos&#40;i&#41; + 19, getRealyPos&#40;j&#41; + 30,O,src_buffer&#41;;
			&#125;
		&#125;	
	return 0;
&#125;
*/
int main&#40;int argc, char *argv&#91;&#93;&#41;&#123;
	SetupCallbacks&#40;&#41;;

	int xPos = 0;
	int yPos = 0;

	int i = 0, j = 0;

	int gameMatrix&#91;2&#93;&#91;2&#93;;


	for&#40;i=0;i<3;i++&#41;
		for&#40;j=0;j<3;j++&#41;&#123;
			gameMatrix&#91;i&#93;&#91;j&#93; = 0;
		&#125;

	int turn = 1;

	gameMatrix&#91;0&#93;&#91;2&#93; = 0;
	gameMatrix&#91;1&#93;&#91;0&#93; = 1;

	if&#40;!initSDL&#40;&#41;&#41;&#123;
		done = 1;
	&#125;

	SDL_Event event;

	SDL_Surface* background = loadImage&#40;"backgroundGato.png"&#41;;
	SDL_Surface* src_buffer = loadImage&#40;"backgroundGato.png"&#41;;

	SDL_Surface* marker = loadImage&#40;"frame.bmp"&#41;;
	SDL_Surface* X = loadImage&#40;"cruz.bmp"&#41;;
	SDL_Surface* O = loadImage&#40;"bola.bmp"&#41;;

	applySurface&#40;0,0,background,screen&#41;;

	do&#123;
		SDL_Delay&#40;100&#41;;
		applySurface&#40;0,0,background,src_buffer&#41;;
		applySurface&#40;getRealxPos&#40;xPos&#41;,getRealyPos&#40;yPos&#41;,marker,src_buffer&#41;;
		
			if&#40;SDL_JoystickGetButton&#40;joystick, PSP_BUTTON_RIGHT&#41;&#41;&#123;
				if&#40;xPos < 2&#41;&#123;
					++xPos;
				&#125;
			&#125;
			if&#40;SDL_JoystickGetButton&#40;joystick, PSP_BUTTON_LEFT&#41;&#41;&#123;
				if&#40;xPos > 0&#41;&#123;
					--xPos;
				&#125;
			&#125;
			if&#40;SDL_JoystickGetButton&#40;joystick, PSP_BUTTON_DOWN&#41;&#41;&#123;
				if&#40;yPos < 2&#41;&#123;
					++yPos;
				&#125;
			&#125;
			if&#40;SDL_JoystickGetButton&#40;joystick, PSP_BUTTON_UP&#41;&#41;&#123;
				if&#40;yPos > 0&#41;&#123;
					--yPos;
				&#125;
			&#125;
			
			while&#40;SDL_PollEvent &#40;&event&#41;&#41;&#123;
				if&#40;event.type == SDL_JOYBUTTONDOWN&#41;&#123;
					if&#40;event.jbutton.button == PSP_BUTTON_X&#41;&#123;
						if&#40;turn == 1&#41;&#123;
							gameMatrix&#91;xPos&#93;&#91;yPos&#93; = 1;
						&#125;else if&#40;turn == 2&#41;&#123;
							gameMatrix&#91;xPos&#93;&#91;yPos&#93; = 2;
						&#125;
						turn = &#40;turn==1&#41; ? 2&#58; 1;
					&#125;
				&#125;
			&#125;
			
		
		//for&#40;i=0;i<3;++i&#41;&#123;
			//for&#40;j=0;j<3;++j&#41;&#123;
		i =0;
		while&#40;i < 3&#41;&#123;
			j = 3;
			//while &#40;j < 3&#41;&#123;	
				if&#40;gameMatrix&#91;i&#93;&#91;j&#93; == 1&#41;&#123;
					applySurface&#40;getRealxPos&#40;i&#41; + 19, getRealyPos&#40;j&#41; + 30,X,src_buffer&#41;;
				&#125;else if&#40;gameMatrix&#91;i&#93;&#91;j&#93; == 2&#41;&#123;
					applySurface&#40;getRealxPos&#40;i&#41; + 19, getRealyPos&#40;j&#41; + 30,O,src_buffer&#41;;
				&#125;
				//j = j+1;
				//&#125;
			i = i+1;
			&#125;
				
			//&#125;
		//&#125;
		
		/*
		if &#40;gameMatrix&#91;0&#93;&#91;0&#93; == 1&#41;&#123;
		applySurface&#40;getRealxPos&#40;0&#41; + 19, getRealyPos&#40;0&#41; + 30,X,src_buffer&#41;;
		&#125;
		if &#40;gameMatrix&#91;0&#93;&#91;1&#93; == 1&#41;&#123;
		applySurface&#40;getRealxPos&#40;0&#41; + 19, getRealyPos&#40;1&#41; + 30,X,src_buffer&#41;;
		&#125;
		if &#40;gameMatrix&#91;0&#93;&#91;2&#93; == 1&#41;&#123;
		applySurface&#40;getRealxPos&#40;0&#41; + 19, getRealyPos&#40;2&#41; + 30,X,src_buffer&#41;;
		&#125;
		if &#40;gameMatrix&#91;1&#93;&#91;0&#93; == 1&#41;&#123;
		applySurface&#40;getRealxPos&#40;1&#41; + 19, getRealyPos&#40;0&#41; + 30,X,src_buffer&#41;;
		&#125;
		if &#40;gameMatrix&#91;1&#93;&#91;1&#93; == 1&#41;&#123;
		applySurface&#40;getRealxPos&#40;1&#41; + 19, getRealyPos&#40;1&#41; + 30,X,src_buffer&#41;;
		&#125;
		
		if &#40;gameMatrix&#91;1&#93;&#91;2&#93; == 1&#41;&#123;
		applySurface&#40;getRealxPos&#40;1&#41; + 19, getRealyPos&#40;2&#41; + 30,X,src_buffer&#41;;
		&#125;
		if &#40;gameMatrix&#91;2&#93;&#91;0&#93; == 1&#41;&#123;
		applySurface&#40;getRealxPos&#40;2&#41; + 19, getRealyPos&#40;0&#41; + 30,X,src_buffer&#41;;
		&#125;
		if &#40;gameMatrix&#91;2&#93;&#91;1&#93; == 1&#41;&#123;
		applySurface&#40;getRealxPos&#40;2&#41; + 19, getRealyPos&#40;1&#41; + 30,X,src_buffer&#41;;
		&#125;
		if &#40;gameMatrix&#91;2&#93;&#91;2&#93; == 1&#41;&#123;
		applySurface&#40;getRealxPos&#40;2&#41; + 19, getRealyPos&#40;2&#41; + 30,X,src_buffer&#41;;
		&#125;
		*/
	
		//drawMarks&#40;gameMatrix,X,O,src_buffer&#41;;
		applySurface&#40;0,0,src_buffer,screen&#41;;
		SDL_Flip&#40;screen&#41;;
	&#125;while&#40;!done&#41;;
	

	SDL_Quit&#40;&#41;;
	sceKernelExitGame&#40;&#41;;
	return 0;
&#125;

i tryed several things to try to find the solution, but none of them worked, when "gameMatrix [1][0] = 1" the valor of gameMatrix[0][2] also changes to 1 or it behaves as if it had that value

the code compiles without warnings, this is my makefile

Code: Select all

TARGET = gatox
PSPSDK = $&#40;shell psp-config --pspsdk-path&#41;
PSPBIN = $&#40;PSPSDK&#41;/../bin
OBJS = gatox.o

JOY = YES
CFLAGS = -Wall -Wno-long-long -O2 -G0 -DJOY_$&#40;JOY&#41;
CFLAGS += $&#40;shell $&#40;PSPBIN&#41;/sdl-config --cflags&#41;

#LIBS =  -lSDL_mixer -lvorbisidec -lSDL $&#40;shell $&#40;PSPBIN&#41;/sdl-config --libs&#41; 
LIBS = -lSDL_gfx -lSDL_image -lSDL_mixer -lSDL_ttf -lvorbisidec -lfreetype -lpng -ljpeg -lz -lm $&#40;shell $&#40;PSPBIN&#41;/sdl-config --libs&#41; 

EXTRA_TARGETS = EBOOT.PBP

include $&#40;PSPSDK&#41;/lib/build.mak


i would appreciate if someone could give me any pointers about how to solve this problem

thxs for your time

Drako

PD: I apologize for my english, is noy my first languaje.
CpuWhiz
Posts: 42
Joined: Mon Jun 04, 2007 1:30 am

Post by CpuWhiz »

Short answer: int gameMatrix[3][3];

Long answer: When you allocate an array the numbers in the brackets is the total count, so for a 3x3 matrix you allocate it as [3][3] but use the numbers 0, 1, and 2 to access the elements. [1][0] and [0][2] are the same because you allocated a 2x2 instead of a 3x3. A index of [0][2] would be the 3rd item in that first row, but since there is only 2 items for that row it spills over into the next place in memory - the first item in the 2nd row, or the location of [1][0]. You mention a 2x2 in your opening paragraph but access elements like it's a 3x3 array. Likewise if you tried to access [2][2] you would be accessing past the allocated memory for the array and write to who knows what it memory. Doing that could and should give you a segmentation fault and a crash, but it might not. Fix the matrix to allocate a 3x3 as I showed above and this problem should go away.
drako
Posts: 2
Joined: Fri Sep 14, 2007 6:09 pm

Post by drako »

that was it!, and i was thinking that it was something more complicated jaja, thxs for your reply and the explanation, it was very clear. And i also think that errors like that should raise a segmentation fault

Drako
Post Reply