Oh god! please end my suffering!

Started by
4 comments, last by KamilKZ 9 years, 11 months ago

I've tried to put AI into this code for so long it's breaking me emotionally. Please fix my void Game::play(SDL_Surface *screen) function. Please just show me anything. Help me make this program work!.

In the code X or the ai takes it turn whenever the mouse moves. I can click to create circles but an x mark will cover it as I move the cursor. The problem lies with in the Game.cpp file. I have a function called void Game::play(SDL_Surface *screen) that calls other void functions during a do while loop. Inside my check_victory function at the bottom it return 1 if nobody won the game which keeps the loop running because continuer=1.

Header file Game.h


#ifndef GAME_H_INCLUDED
#define GAME_H_INCLUDED

enum {EMPTY, CIRCLE, CROSS};
class Game
{
    public:
        Game();
        void play(SDL_Surface* screen);
        //Starts of your voids
		void get_computer_move(SDL_Surface* screen);
		void get_player_move(SDL_Surface* screen);
		void init_grid(SDL_Surface* screen);

		int check_victory(SDL_Surface* screen);
        ~Game();
		//0x004119d9

    private:
        SDL_Surface *board, *cmark, *xmark, *horizontale, *verticale, *diagonale1, *diagonale2;
        SDL_Event event;
        int grid[3][3], continuer, i, j, turn, end, nowinner, ai, ai2;
        SDL_Rect position, positionforme, positionwon, positionforai;
};


#endif // GAME_H_INCLUDED

Cpp file Game.cpp


#include <iostream>
#include <SDL.h>
#include <SDL_image.h>
#include <time.h>
#include "Game.h"


Game::Game()
{
    cmark= IMG_Load("cmark.jpg");
    xmark= IMG_Load("xmark.jpg");
    board= IMG_Load("board.jpg");
    horizontale=IMG_Load("horizontale.jpg");
    verticale=IMG_Load("verticale.jpg");
    diagonale1=IMG_Load("diagonale1.png");
    diagonale2=IMG_Load("diagonale2.png");
}


void Game::init_grid(SDL_Surface* screen)
{
	for(int i=0; i<3; i++)
    {
        for(j=0; j<3; j++)
        {
            grid[i][j]=EMPTY;
        }
    }
}
void Game::get_player_move(SDL_Surface* screen)
{	
	if (event.type == SDL_MOUSEBUTTONDOWN )
	{				
		if (grid[event.button.y/70][event.button.x/70] == EMPTY)
					
			positionforme.x=((event.button.x/70)*70)+15;
			positionforme.y=((event.button.y/70)*70)+15;
			//Afficher un rond, si cest au tour du rond
			grid[event.button.y/70][event.button.x/70]=CIRCLE;
			SDL_BlitSurface(cmark, NULL, screen, &positionforme);
			SDL_Flip(screen);
			
	}	
}

void Game::get_computer_move(SDL_Surface* screen)
{
	int ai = rand()% 211;
	int ai2 = rand()% 211;	
	positionforai.x = ((ai/70)*70)+15;
	positionforai.y = ((ai2/70)*70)+15;

		if (grid [ai/70][ai2/70] == EMPTY)
		{							
			grid[ai2/70][ai/70]=CROSS;
			SDL_BlitSurface(xmark, NULL, screen, &positionforai);
			SDL_Flip(screen);
	}
}



void Game::play(SDL_Surface *screen)
{
    int continuer=1, turn=0, end=0;
	
    position.x=0;
    position.y=0;
    SDL_FillRect(screen, NULL, SDL_MapRGB(screen->format, 255, 255, 255));
    SDL_BlitSurface(board, NULL, screen, &position);
    SDL_Flip(screen);


	
	while (continuer)
	{
		continuer = EMPTY;
		init_grid(screen);


		SDL_WaitEvent(&event);
		if (event.type == SDL_QUIT) break;
		
		do	
		{		
				
				
				get_player_move(screen);
				continuer= check_victory(screen);
				if (continuer== EMPTY)break;
				get_computer_move(screen);
				continuer =check_victory(screen);
				if (continuer== EMPTY)break;
				

				
			//continuer=check_victory(screen); 
			}while (continuer == EMPTY);	
		
		}
	 }		



		
	


int Game::check_victory(SDL_Surface* screen)
{
    int nowinner=0;
     //It verifies if there is a winner
        for(i=0; i<3; i++)
        {    //horizontal Win Line
            if((grid[i][0]==CROSS && grid[i][1]==CROSS && grid[i][2]==CROSS) || (grid[i][0]==CIRCLE && grid[i][1]==CIRCLE && grid[i][2]==CIRCLE))
            {
                positionwon.x=20;
                positionwon.y=i*70+34;
                SDL_BlitSurface(horizontale, NULL, screen, &positionwon);
                SDL_Flip(screen);
                end=1;
                return 0;
            }
            //Vertical Win Line
            if((grid[0][i]==CROSS && grid[1][i]==CROSS && grid[2][i]==CROSS) || (grid[0][i]==CIRCLE && grid[1][i]==CIRCLE && grid[2][i]==CIRCLE))
            {
                positionwon.x=i*70+34;
                positionwon.y=20;
                SDL_BlitSurface(verticale, NULL, screen, &positionwon);
                SDL_Flip(screen);
                end=1;
                return 0;
            }
        }
        //Diagonal Win Line
        if((grid[0][0]==CROSS && grid[1][1]==CROSS && grid[2][2]==CROSS) || (grid[0][0]==CIRCLE && grid[1][1]==CIRCLE && grid[2][2]==CIRCLE))
        {
            positionwon.x=20;
            positionwon.y=20;
            SDL_BlitSurface(diagonale1, NULL, screen, &positionwon);
            SDL_Flip(screen);
            end=1;
            return 0;
        }
        if((grid[0][2]==CROSS && grid[1][1]==CROSS && grid[2][0]==CROSS) || (grid[0][2]==CIRCLE && grid[1][1]==CIRCLE && grid[2][0]==CIRCLE))
        {
            positionwon.x=22;
            positionwon.y=20;
            SDL_BlitSurface(diagonale2, NULL, screen, &positionwon);
            SDL_Flip(screen);
            end=1; 
            return 0;
        }
        for(i=0; i<3; i++)
        {
            for(j=0; j<3; j++)
            {
                if(grid[i][j]!=EMPTY)
                {
                    nowinner++;
                }
            }
        }
        if(nowinner==9)
        {
            end=1;
            return 0;
        }
        return 1;
}

Game::~Game()
{
    SDL_FreeSurface(horizontale);
    SDL_FreeSurface(verticale);
    SDL_FreeSurface(diagonale1);
    SDL_FreeSurface(diagonale2);
    SDL_FreeSurface(xmark);
    SDL_FreeSurface(cmark);
}
Advertisement

Few people would just fire up your code and fix it. Firstly, what it is meant to do? I assume it's Tic Tac Toe? Secondly, what's wrong with it? Be as specific as possible.

Problem: You only draw once at the beginning of your loop, and then you go into an (almost) endless logic loop.

You need to draw your game _inside_ your main loop.


    //You are here, drawing only once.
    SDL_FillRect(screen, NULL, SDL_MapRGB(screen->format, 255, 255, 255));
    SDL_BlitSurface(board, NULL, screen, &position);
    SDL_Flip(screen);


	//Then you enter an (almost) infinite loop, never drawing again.
	while (continuer)
	{
		continuer = EMPTY;
		init_grid(screen);


		SDL_WaitEvent(&event);
		if (event.type == SDL_QUIT) break;
		
		do	
		{		
				
				
				get_player_move(screen);
				continuer= check_victory(screen);
				if (continuer== EMPTY)break;
				get_computer_move(screen);
				continuer =check_victory(screen);
				if (continuer== EMPTY)break;
				

				
			//continuer=check_victory(screen); 
			}while (continuer == EMPTY);	
		
		}
	 }

I'd definitely go through Lazyfoo's excellent SDL tutorials, if I were you.

All of the tutorials are significant, but you'll especially want to look at the additional articles: "Game Loops" and "State Machines".

In addition to what Servant of the Lord stated, it seems to me that on the player's turn you don't wait for the player's action.

I don't know about SDL and know very little C++, but with my knowledge I'd fix it this way:


void Game::play(SDL_Surface *screen)
{
    int continuer=1, turn=0, end=0;
	
    position.x=0;
    position.y=0;
    SDL_FillRect(screen, NULL, SDL_MapRGB(screen->format, 255, 255, 255));
    SDL_BlitSurface(board, NULL, screen, &position);
    SDL_Flip(screen);
	
    while (continuer)
    {
	continuer = EMPTY;
	init_grid(screen);
		
	do	
	{	
                // Wait for the player's action
	        SDL_WaitEvent(&event);
	        if (event.type == SDL_QUIT)
                {
                    // Exit from game
                    continuer = EMPTY;
                    break;
                }

		get_player_move(screen);
		continuer= check_victory(screen);
		if (continuer== EMPTY)  break;

                // Draw stuff

		get_computer_move(screen);
		continuer =check_victory(screen);
		if (continuer== EMPTY)  break;

                // Draw stuff
	}
        while (continuer == EMPTY);	
		
    }
}	

//You are here, drawing only once.
    SDL_FillRect(screen, NULL, SDL_MapRGB(screen->format, 255, 255, 255));
    SDL_BlitSurface(board, NULL, screen, &position);
    SDL_Flip(screen);

Nah SDL_Fillrect only make a fast fill of rectangle with the same colors. I think 255, 255, 255 is white. SDL_Blitsurface only display my jped image of the board.

1. Split up your draw calls from your game logic.

2. You're flipping buffers every time you draw something

This topic is closed to new replies.

Advertisement