C++ SDL 扫雷器在击中炸弹时标记结束游戏

标签 c++ linux sdl-2

我的问题可能有一个简单的答案,但它难倒了我,因为尽管它对我来说看起来是正确的,但我似乎无法让它正常工作。正如标题中所读,当我使用右键单击放置旗帜时它有效,但是当我击中地雷时它会结束游戏而不是将旗帜放置在广场上并允许我继续游戏。 任何帮助,将不胜感激。 编辑:编辑了代码并为两个 bool 语句添加了大括号,但我遇到的主要问题是,当我右键单击我想放置一个标志的方 block 时,它是一个地雷,它充当如果地雷被击中,程序将继续运行并在 5 秒后退出。如果有人能帮助我解决当我右键单击放置旗帜时不会炸毁地雷的问题,我将不胜感激。 我的代码在下面,大部分都被注释了:

    /*Compile using:
* gcc MinesweeperGraphics.cpp `sdl-config --libs` -lstdc++ -o MinesweeperGraphics.bin 
* Supporting flags without ending program after it hits a bomb
*Win detection within program
*/
#include "SDL/SDL.h"
#include <string>
#include <iostream>
#include <cstdlib>
#include <time.h>

//The attributes of the screen
const int SCREEN_WIDTH = 270;
const int SCREEN_HEIGHT = 300;
const int SCREEN_BPP = 9;

//The surfaces that will be used
SDL_Surface *zero = NULL;
SDL_Surface *one = NULL;
SDL_Surface *two = NULL;
SDL_Surface *three = NULL;
SDL_Surface *four = NULL;
SDL_Surface *five = NULL;
SDL_Surface *six = NULL;
SDL_Surface *seven = NULL;
SDL_Surface *eight = NULL;
SDL_Surface *mine = NULL;
SDL_Surface *boom = NULL;
SDL_Surface *box = NULL;
SDL_Surface *flag = NULL;
SDL_Surface *background = NULL;
SDL_Surface *screen = NULL;
SDL_Event event;

using namespace std;
////////////////////////////////////////////////////////////
SDL_Surface *load_image( string filename )
{
    SDL_Surface* loadedImage = NULL;        //Temporary storage for the image that's loaded
    SDL_Surface* optimizedImage = NULL;    //The optimized image that will be used
    loadedImage = SDL_LoadBMP( filename.c_str() );    //Load the image
    if( loadedImage != NULL )    //If nothing went wrong in loading the image
    {
        optimizedImage = SDL_DisplayFormat( loadedImage );        //Create an optimized image
        SDL_FreeSurface( loadedImage );        //Free the old image
    }
    return optimizedImage;    //Return the optimized image
}
////////////////////////////////////////////////////////////
void apply_surface( int x, int y, SDL_Surface* source, SDL_Surface* destination )
{
    SDL_Rect offset;    //Make a temporary rectangle to hold the offsets
    offset.x = x;    //Give the offsets to the rectangle
    offset.y = y;
    SDL_BlitSurface( source, NULL, destination, &offset );    //Blit the surface
}
////////////////////////////////////////////////////////////
int initializemines(int mines[11][11][2])
{
    int x,y,z;
    for (x=0;x<11;x++)
        for (y=0;y<11;y++)
            for (z=0;z<2;z++)
                mines[x][y][z]=12;
    for (x=1;x<10;x++)
        for (y=1;y<11;y++)
            for (z=0;z<2;z++)
                mines[x][y][z]=0;
    for (x=1;x<10;x++)
        for (y=1;y<11;y++)
            mines[x][y][0]=9*(int(rand()%8/7.0)); // 1/8 Chance of being a mine
    return 0;
}
////////////////////////////////////////////////////////////
int calculatemines(int mines[11][11][2])
{
    int x,y;
    for (x=1;x<10;x++)
        for (y=1;y<11;y++)
        {
            if (mines[x-1][y-1][0]==9)  // Upper Left
                mines[x][y][1]++;
            if (mines[x][y-1][0]==9)        // Upper
                mines[x][y][1]++;
            if (mines[x+1][y-1][0]==9)  // Upper Right
                mines[x][y][1]++;
            if (mines[x-1][y][0]==9)        // Left
                mines[x][y][1]++;
            if (mines[x-1][y+1][0]==9)  // Lower Left
                mines[x][y][1]++;
            if (mines[x+1][y][0]==9)        // Right
                mines[x][y][1]++;
            if (mines[x][y+1][0]==9)        // Lower
                mines[x][y][1]++;
            if (mines[x+1][y+1][0]==9)  // Lower Right
                mines[x][y][1]++;
            if (mines[x][y][0]==0) mines[x][y][0]=mines[x][y][1];
        }
    return 0;
}
////////////////////////////////////////////////////////////
int selectmines(int mines[11][11][2],int MouseX,int MouseY)
{
    cout<<MouseX<<","<<MouseY<<"\n";
    if (mines[MouseX][MouseY][0]==9)    //Hit a Mine
    {
        mines[MouseX][MouseY][0]=10;    //Boom
        for (int x=1; x<10;x++)
            for (int y=1; y<11;y++)
                if (mines[x][y][0]==9) mines[x][y][0]=11;  //Show other Mines
        return 1;
    }
    else
    {
        mines[MouseX][MouseY][1]=9;
        if (mines[MouseX][MouseY][0]==0)    //Shows Neighbors of Zeros
            for (int x=(MouseX-1); x<=(MouseX+1);x++)
                for (int y=(MouseY-1); y<=MouseY+1;y++)
                    if (mines[x][y][1]<9)   //If Neighbor <9
                        selectmines(mines,x,y); //Select Mines Again
    }
    return 0;
}
////////////////////////////////////////////////////////////
int printmines(int mines[11][11][2])
{
    int x,y,z,gx,gy;
    system("clear");
    cout<<"   ABCDEFGHIJKLMNOPQRSTUVWXYZ\n";
    for (z=0;z<1;z++)
    {
        for (y=1;y<11;y++)
        {
            cout<<y<<" ";
            if (y<10) cout<<" ";
            for (x=1;x<10;x++)
            {
        //      if (mines[x][y][0]==10) cout<<"☠";
        //      else if (mines[x][y][0]==11) cout<<"☢";
        //      else if (mines[x][y][1]<9) cout<<"⬜";
                cout<<mines[x][y][z];
                //////win conditions here I think
            }
            cout<<"\n";
        }
        cout<<"\n";
    }
    //Print Mines Graphically
    for (y=1;y<11;y++)
    {
        gy=(y-1)*30;
        for (x=1;x<10;x++)
        {
            gx=(x-1)*30;

            if (mines[x][y][0]==10) apply_surface( gx, gy, boom, screen );
            else if (mines[x][y][0]==11) apply_surface( gx, gy, mine, screen );
            else if (mines[x][y][1]<9) apply_surface( gx, gy, box, screen );
            else if (mines[x][y][0]==13) apply_surface( gx, gy, flag, screen );
            else switch (mines[x][y][0])
            {
                case 0:
                    apply_surface( gx, gy, zero, screen );
                break;
                case 1:
                    apply_surface( gx, gy, one, screen );
                break;
                case 2:
                    apply_surface( gx, gy, two, screen );
                break;
                case 3:
                    apply_surface( gx, gy, three, screen );
                break;
                case 4:
                    apply_surface( gx, gy, four, screen );
                break;
                case 5:
                    apply_surface( gx, gy, five, screen );
                break;
                case 6:
                    apply_surface( gx, gy, six, screen );
                break;
                case 7:
                    apply_surface( gx, gy, seven, screen );
                break;
                case 8:
                    apply_surface( gx, gy, eight, screen );
                break;
                case 9:
                    apply_surface( gx, gy, flag,screen);
                break;
            }
        }
    }
    if( SDL_Flip( screen ) == -1 ) return 1;
    return 0;
}
////////////////////////////////////////////////////////////
int main()
{
    if( SDL_Init( SDL_INIT_EVERYTHING ) == -1 )    //Initialize all SDL subsystems
        return 1;
    screen = SDL_SetVideoMode( SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_BPP, SDL_SWSURFACE );    //Set up the screen
    if( screen == NULL )    //If there was an error in setting up the screen
        return 1;
    SDL_WM_SetCaption( "Mine Sweeper", NULL );    //Set the window caption
    zero = load_image( "Zero.bmp" );    //Load the images
    one = load_image( "One.bmp" );
    two = load_image( "Two.bmp" );
    three = load_image( "Three.bmp" );
    four = load_image( "Four.bmp" );
    five = load_image( "Five.bmp" );
    six = load_image( "Six.bmp" );
    seven = load_image( "Seven.bmp" );
    eight = load_image( "Eight.bmp" );
    mine = load_image( "Mine.bmp" );
    boom = load_image( "Boom.bmp" );
    flag = load_image( "Flag.bmp" );
    box = load_image( "Box.bmp" );
    background = load_image( "Background.bmp" );
    char Letter;
    bool win=false;
    bool lose=false;
    bool done=false;
    int mines[11][11][2],MouseX=0,MouseY=0; // create mines array
    srand (time(NULL));     // initialize random seed
    initializemines(mines); // 
    calculatemines(mines);
    while (!done)
    {
        printmines(mines);
        while(SDL_PollEvent(&event))    //Did a Mouse Event Occur?
        {
            event.type == SDL_MOUSEBUTTONDOWN;  //Was a Mouse Button Pressed?
            switch (event.button.button)
            {
                case SDL_BUTTON_LEFT:   //If the Left Button was Pressed
                    MouseX=event.motion.x/30+1;
                    MouseY=event.motion.y/30+1;
                    if ((event.motion.x>0)&&(event.motion.y>0))
                        done=selectmines(mines,MouseX,MouseY);
                    break;
                case SDL_BUTTON_RIGHT:  //If the Right Button was Pressed
                    MouseX=event.motion.x/30+1;
                    MouseY=event.motion.y/30+1;
                    if ((event.motion.x>0)&&(event.motion.y>0)) //Trying to get right click to work without
                            done=selectmines(mines,MouseX,MouseY); //ending game after hitting a bomb
                            mines[MouseX][MouseY][0]=13;    //it currently lays the flag down but does not like bombs
                        if ((mines[MouseX][MouseY][0]==9)&&(mines[MouseX][MouseY][0]==10))
                        { //so it kills the program despite 
                        lose=false; //the bool statements
                        win=false;
                        mines[MouseX][MouseY][0]=13;
                        }
                        break;
            }
                for(int X=1;X<11;X++) //Checks to see if square hit was a bomb and if so it ends the program so it
                    for(int Y=1;Y<11;Y++) //won't randomly keep the program going until you decide to quit the program
                        if(mines[X][Y][0]==10) lose=true;
        }
        if(lose==true) done=true; //checks if done or not?
        if(win==true) done=true;
    }
    printmines(mines);
    SDL_Delay( 5000 );
    SDL_FreeSurface( zero );        //Free the surfaces
    SDL_FreeSurface( one );
    SDL_FreeSurface( two );
    SDL_FreeSurface( three );
    SDL_FreeSurface( four );
    SDL_FreeSurface( five );
    SDL_FreeSurface( six );
    SDL_FreeSurface( seven );
    SDL_FreeSurface( eight );
    SDL_FreeSurface( mine );
    SDL_FreeSurface( boom );
    SDL_FreeSurface( flag );
    SDL_FreeSurface( box );
    SDL_FreeSurface( background );
    SDL_Quit();    //Quit SDL
    return 0;
}

最佳答案

                    if ((mines[MouseX][MouseY][0]==9)&&(mines[MouseX][MouseY][0]==10)) //so it kills the program despite 
                    lose=false; //the bool statements
                    win=false;
                    break;

我猜您打算将条件 (if) 应用于 lose=false;win=false; 行, 但如所写,它仅控制第一条语句。像这样添加大括号:

                    if ((mines[MouseX][MouseY][0]==9)&&(mines[MouseX][MouseY][0]==10)) //so it kills the program despite 
                    {
                        lose=false; //the bool statements
                        win=false;
                    }
                    break;

关于C++ SDL 扫雷器在击中炸弹时标记结束游戏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36961190/

相关文章:

C++/SDL,一切都是白色的

c++ - 使用 c_types 将 python 数组传递给 c 函数

c++ - 为什么免费商店中对象的生命周期受范围限制?

c++ - 如何获得非常精确的耗时 C++

linux - 更改默认的PyCharm图标

linux - 在 shell 脚本中使用 mv 命令重命名文件的一部分

mingw - 无法使用 MinGW 和 SDL 进行链接 : undefined reference to WinMain@16

c++ - SDL2 为假全屏切换 SDL_WINDOW_RESIZABLE 状态

c++ - 哪个 C++ 标准头文件定义了 SIZE_MAX?

linux - 只提取 url 段而不是 shell 脚本中的以下正则表达式?