Sign in to follow this  

Oh god! please end my suffering!

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

If you intended to correct an error in the post then please contact us.

Recommended Posts

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);
}
Edited by LAURENT*

Share this post


Link to post
Share on other sites

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.

Share this post


Link to post
Share on other sites

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".

Share this post


Link to post
Share on other sites

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);	
		
    }
}	

Share this post


Link to post
Share on other sites
//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.  

Edited by LAURENT*

Share this post


Link to post
Share on other sites

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

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

Share this post


Link to post
Share on other sites

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

If you intended to correct an error in the post then please contact us.

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