SDL2 медленный без задержки - PullRequest
0 голосов
/ 19 октября 2019

Я делаю программу, которая решает судоку в c, и отображает его с помощью SDL.

Проблема в том, что SDL_Delay() не работает, программа работает очень медленно, я думаю, что я забылосвободить поверхности или уничтожить текстуры или еще что-то, чтобы сохранить память, но я не могу точно определить это.

Вот весь код:

#include <stdio.h>
#include <stdlib.h>
#include <SDL2/SDL.h>
#include <SDL2/SDL_image.h>
#include <SDL2/SDL_ttf.h>
#include <string.h>
#include <stdbool.h>
#include <time.h>

const int window_width = 860;
const int window_height = 640;
int blank_board[9][9] = {

        {0,0,0,   0,0,0,   0,0,0},
        {0,0,0,   0,0,0,   0,0,0},
        {0,0,0,   0,0,0,   0,0,0},

        {0,0,0,   0,0,0,   0,0,0},
        {0,0,0,   0,0,0,   0,0,0},
        {0,0,0,   0,0,0,   0,0,0},

        {0,0,0,   0,0,0,   0,0,0},
        {0,0,0,   0,0,0,   0,0,0},
        {0,0,0,   0,0,0,   0,0,0}};



void square(SDL_Renderer *renderer, float x, float y, int width, int height, int colour1, int colour2, int colour3)
{
    SDL_SetRenderDrawColor(renderer, colour1, colour2, colour3, 255);
    SDL_Rect rect = {x, y, width, height};
    SDL_RenderFillRect(renderer, &rect);


}






void easy_message(SDL_Renderer *renderer, char message_string[50], bool use_int_messge, int message_int, int colour1, int colour2, int colour3, int text_size, int x, int y)
{
    char letter[420];
    if (use_int_messge == true)
        {
            sprintf(letter, "%s %d ", message_string, message_int);
        }
    else
    {
        sprintf(letter, "%s ", message_string);
    }

    SDL_Color colour = {colour1, colour2, colour3};

    TTF_Font * font = TTF_OpenFont("arial.ttf", text_size);

    SDL_Surface * surface = TTF_RenderText_Solid(font, letter, colour);

    SDL_Texture * texture = SDL_CreateTextureFromSurface(renderer, surface);

    int textW = 0;
    int textH = 0;

    SDL_QueryTexture(texture, NULL, NULL, &textW, &textH);
    SDL_Rect text_rect = {x, y, textW, textH};
    SDL_RenderCopy(renderer, texture, NULL, &text_rect);


    SDL_DestroyTexture(texture);
    SDL_FreeSurface(surface);
    TTF_CloseFont(font);


}

bool in_box(bool mouse_clicked, int mouse_posx, int mouse_posy, int box_x, int box_y, int box_width, int box_height)
{
    if(mouse_clicked == true)
    {
        if(mouse_posx >= box_x && mouse_posx <= box_x + box_width)
        {
            if(mouse_posy >= box_y && mouse_posy <= box_y + box_height)
                return true;
        }
    }
    return false;
}







void print_board(int *arr[9][9], SDL_Renderer *renderer)
{
    SDL_Surface * image = IMG_Load("board.png");
    if (!image)
    {
        printf("IMG_Load: %s\n", IMG_GetError());
    }
    int z,x, y, w, h;
    x = 50;
    y = 50;
    w = 150;
    h = 150;

    SDL_Texture * img_board = SDL_CreateTextureFromSurface(renderer, image);

    for (z=1; z < 12; ++z)
    {
        if(z/3 == 1)
        {
            SDL_Rect rect = {x - 350 + z*158, y, w, h};
            SDL_RenderCopy(renderer, img_board, NULL, &rect);
        }
        if(z/3 == 2)
        {
            SDL_Rect rect = {x - 824 + z*158, y + h + 10, w, h};
            SDL_RenderCopy(renderer, img_board, NULL, &rect);
        }
        if(z/3 == 3)
        {
            SDL_Rect rect = {x - 1298 + z*158, y + (h+10)*2, w, h};
            SDL_RenderCopy(renderer, img_board, NULL, &rect);
        }
    }


    /*int len_of_arr, len_of_ind, i, j;

    len_of_arr = (sizeof(*arr) / sizeof(*arr[0]));
    len_of_ind = (sizeof(arr[0]) / sizeof(*arr[0][0]));

    char letter[5];
    for (i=0; i < len_of_arr; ++i)
    {
        if(i%3 == 0 && i != 0)
        {
            printf("--------------------\n");
        }


        for (j=0; j < len_of_ind; ++j)
        {
            if(j%3 == 0)
            {
                printf("|");
            }






            if (j == 8)
            {
                printf("%d\n", arr[i][j]);
            }
            else
            {
                sprintf(letter, "%d", arr[i][j]);
                strcat(letter, " ");
                printf("%s", letter);
            }

        }

    }*/
    SDL_FreeSurface(image);
    SDL_DestroyTexture(img_board);

}





int find_empty_row(int *arr[9][9])
{
    int len_of_arr, len_of_ind, i, j;

    len_of_arr = (sizeof(*arr) / sizeof(*arr[0]));
    len_of_ind = (sizeof(arr[0]) / sizeof(*arr[0][0]));

    for (i=0; i < len_of_arr; ++i)
    {
        for(j=0; j < len_of_ind; j++)
        {
            if(arr[i][j] == 0)
                return i;
        }
    }
    return -1;

}





int find_empty_col(int *arr[9][9])
{
    int len_of_arr, len_of_ind, i, j;

    len_of_arr = (sizeof(*arr) / sizeof(*arr[0]));
    len_of_ind = (sizeof(arr[0]) / sizeof(*arr[0][0]));

    for (i=0; i < len_of_arr; ++i)
    {
        for(j=0; j < len_of_ind; j++)
        {
            if(arr[i][j] == 0)
                return j;
        }
    }
    return -1;

}





bool valid(int *arr[9][9], int num, int pos1, int pos2)
{
    int len_of_arr, len_of_ind, i, j, box_x, box_y;

    len_of_arr = (sizeof(*arr) / sizeof(*arr[0]));
    len_of_ind = (sizeof(arr[0]) / sizeof(*arr[0][0]));

    for (i=0; i < len_of_ind; ++i)
    {
        if(arr[pos1][i] == num && pos2 != i)
        {
            return false;
        }
    }

    for (i=0; i < len_of_arr; ++i)
    {
        if(arr[i][pos2] == num && pos1 != i)
        {
            return false;
        }
    }

    box_x = pos2 / 3;
    box_y = pos1 / 3;

    for(i=(box_y*3); i < (box_y*3 + 3); ++i)
    {
        for (j=(box_x*3); j < (box_x*3 + 3); ++j)
            {
                if(arr[i][j] == num && i != pos1 && j != pos2)
                {
                    return false;
                }
            }
    }
    return true;
}







bool solve(int *arr[9][9])
{
    //func(9, 9, arr);
    int find1, find2, row, col;
    find1 = find_empty_row(arr);
    find2 = find_empty_col(arr);
    if(find1 == -1 && find2 == -1)
    {
        return true;
    }
    else
    {
        row = find1;
        col = find2;
    }
    for(int i=1; i < 10; ++i)
    {
        if(valid(arr, i, row, col))
        {
            arr[row][col] = i;
            if(solve(arr))
            {
                return true;
            }
            arr[row][col] = 0;
        }
    }
    return false;

}

void do_numbers_i(int i, int j, int y_add, SDL_Renderer *renderer, int *board[9][9], bool passed_in_board)
{
    if(passed_in_board == false)
    {
        if(i <= 2)
        {
            easy_message(renderer, "", true, board[j][i], 0, 0, 0, 28, 180 + i*53, 60 + y_add);
        }
        if (i <= 5 && i > 2)
        {
            easy_message(renderer, "", true, board[j][i], 0, 0, 0, 28, 180 + i*53, 60 + y_add);
        }

        if (i <= 8 && i > 5)
        {
            easy_message(renderer, "", true, board[j][i], 0, 0, 0, 28, 180 + i*53, 60 + y_add);
        }
    }
    else
    {
        if(i <= 2)
        {
            easy_message(renderer, "", true, board[j][i], 0, 0, 0, 28, 180 + i*53, 60 + y_add);
        }
        if (i <= 5 && i > 2)
        {
            easy_message(renderer, "", true, board[j][i], 0, 0, 0, 28, 180 + i*53, 60 + y_add);
        }

        if (i <= 8 && i > 5)
        {
            easy_message(renderer, "", true, board[j][i], 0, 0, 0, 28, 180 + i*53, 60 + y_add);
        }
    }


}


void do_numbers_j(int i, int j, SDL_Renderer *renderer, int *board[9][9], bool passed_in_board)
{

    if(j==0)
    {
        do_numbers_i(i, j, 0, renderer, board, passed_in_board);
    }
    if(j==1)
    {
        do_numbers_i(i, j, 50, renderer, board, passed_in_board);
    }
    if(j==2)
    {
        do_numbers_i(i, j, 100, renderer, board, passed_in_board);
    }
    if(j==3)
    {
        do_numbers_i(i, j, 160, renderer, board, passed_in_board);
    }
    if(j==4)
    {
        do_numbers_i(i, j, 210, renderer, board, passed_in_board);
    }
    if(j==5)
    {
        do_numbers_i(i, j, 260, renderer, board, passed_in_board);
    }
    if(j==6)
    {
        do_numbers_i(i, j, 320, renderer, board, passed_in_board);
    }
    if(j==7)
    {
        do_numbers_i(i, j, 370, renderer, board, passed_in_board);
    }
    if(j==8)
    {
        do_numbers_i(i, j, 420, renderer, board, passed_in_board);
    }
    if(j==9)
    {
        do_numbers_i(i, j, 470, renderer, board, passed_in_board);
    }
}




void write_numbers_on_board(SDL_Renderer *renderer, int *board[9][9], bool passed_in_board)
{
    if (passed_in_board == true)
    {
        for (int i=0; i < 9; ++i)
        {

            for (int j=0; j < 9; ++j)
            {

                do_numbers_j(i, j, renderer, board, true);
            }

        }

    }
    else
    {
        for (int i=0; i < 9; ++i)
        {
            for (int j=0; j < 9; ++j)
            {

                do_numbers_j(i, j, renderer, board, false);
            }

        }

    }

}




void do_sudoku(int *board[9][9], SDL_Renderer *renderer, bool do_it)
{

    print_board(board, renderer);
    write_numbers_on_board(renderer, board, do_it);

    clock_t begin = clock();


    if (do_it == true)
    {
        solve(board);
    }
    //printf("_______________________\n\n");
    //print_board(board, renderer);

    clock_t end = clock();
    double time_spent = (double)(end - begin) / CLOCKS_PER_SEC;
    //printf("\n\nTime taken: %f\n\n", time_spent);

}









int main(int argc, char* argv[])
{
    int board[9][9] = {

        {0,8,0,   5,0,0,   0,0,0},
        {0,0,0,   0,3,0,   2,0,0},
        {0,0,9,   0,2,0,   7,0,0},

        {0,0,7,   0,0,0,   0,0,6},
        {0,4,0,   0,0,0,   0,5,0},
        {1,0,0,   2,0,0,   0,0,7},

        {0,0,8,   0,6,0,   0,0,3},
        {0,0,0,   3,0,1,   6,0,4},
        {0,0,1,   0,0,9,   0,0,0}};



    bool running = true;
    int mouse_x, mouse_y;
    SDL_Event event;

    SDL_Init(SDL_INIT_VIDEO);
    TTF_Init();

    SDL_Window * window = SDL_CreateWindow("SDL_ttf in SDL2", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, window_width, window_height, 0);
    SDL_Renderer * renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);
    bool solve = false;
    float x = 1;
    float y = 0;


    while (running)
    {
        while(SDL_PollEvent(&event))
        {
            if (event.type == SDL_QUIT)
            {
                running = false;
                break;
            }
            /*if (event.type == SDL_MOUSEMOTION)
            {
                SDL_GetGlobalMouseState(&mouse_x, &mouse_y);
            }*/
            if (event.type == SDL_KEYDOWN)
            {
                switch(event.key.keysym.sym)
                {
                    case SDLK_RETURN:
                    solve = true;
                    break;

                }

            }


        }
        SDL_GetGlobalMouseState(&mouse_x, &mouse_y);

        printf("\nMouse (%d, %d)", mouse_x, mouse_y);

        SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
        SDL_RenderClear(renderer);


        do_sudoku(board, renderer, solve);
        square(renderer, x, y, 50, 50, 255, 0, 0);
        SDL_RenderPresent(renderer);
        x = x+1;
        y = y+1;
        //SDL_Delay(20);
    }

    SDL_DestroyRenderer(renderer);
    SDL_DestroyWindow(window);

    SDL_Quit();
    TTF_Quit();


    return 0;
}

Я добавил квадрат, чтобы перемещаться пона экране, чтобы увидеть, насколько быстро он это делает, основываясь на скорости цикла, и без функции do_sudoku() он работает очень быстро, и это все, что мне удалось обнаружить.

...