سلام!

کد بازی 4inaRow را می توانید در ادامه ی مطلب مشاهده کنید. هر گونه سوال یا پیشنهاد یا سوالی در رابطه با این کد داشتید، در قسمت نظرات آن را مطرح کنید.

File: block.h

#ifndef BLOCK_H
#define BLOCK_H

#include <iostream>
using namespace std;

class Block {
    
    private:

        int *_color;

    public:
        
        const static int empty = 0;

        Block( int = 0 );
        ~Block();
        Block( const Block& );
        void operator=( const Block& );

        int color() const;

        void setColor( int );

        bool operator==( const Block& );
};

#endif


File: block.cpp

#include "block.h"

Block::Block( int color ) {
    this->_color = new int;
    this->setColor( color ) ;
}

Block::~Block () {
    delete this->_color;
}

Block::Block( const Block &src ) {
    this->_color = new int;
    this->setColor( src.color() );
}

void Block::operator=( const Block &src ) {
    this->_color = new int;
    this->setColor( src.color() );
}

int Block::color () const {
    return *(this->_color);
}

void Block::setColor( int color ) {
    *(this->_color) = color;
}

bool Block::operator==( const Block& cmp ) {
    return ( this->color() == cmp.color() );
}

File: board.h

#ifndef BOARD_H
#define BOARD_H

#include "SDL/SDL.h"
#include "SDL/SDL_gfxPrimitives.h"
#include "SDL/SDL_ttf.h"

#include "block.h"

#include <iostream>
using namespace std;

class Board {
    
    private:

        Block **blocks;

        int _blockWidth, _blockHeight;
        int _turn;

        void setBlockWidth( int );
        void setBlockHeight( int ) ;
        void setTurn( int );

        void switchTurn();

        int blockWidth() const;
        int blockHeight() const;
        int turn() const;

        Block *operator[]( int ) const;

        void drawTable( SDL_Surface* );
        void drawBlock( SDL_Surface*, int, int );

        bool clicked( int );
        bool hasEmptyBlock( int );
        bool addPiece( int );
        int checkWinning();
        bool noEmptyBlock();

        const static int red = 1, blue = -1;

    public:

        const static int width = 7, height = 6;
        const static int draw = 2;
        
        Board( SDL_Surface*, int, int );
        ~Board();
        Board( const Board& );
        void operator=( const Board& );

        int run( SDL_Surface* );

        void showWinner( SDL_Surface* );

};

#endif

File: board.cpp

#include "board.h"

Board::Board ( SDL_Surface *screen, int width, int height ) {
    
    this->setTurn( 1 );
    
    this->setBlockWidth( screen->w / 7 );
    this->setBlockHeight( screen->h / 6 );

    blocks = new Block*[ height ];
    for ( int i = 0; i < height; i++ )
        blocks[i] = new Block[ width ];
}

Board::~Board () {
    for ( int i = 0; i < Board::height; i++ )
        delete[] blocks[i];
    delete[] blocks;
}

Board::Board( const Board &src ) {

    for ( int i = 0; i < Board::height; i++ )
        delete[] blocks[i];
    delete[] blocks;

    blocks = new Block*[ Board::height ];
    for ( int i = 0; i < Board::height; i++ ){
        blocks[i] = new Block[ Board::width ];
        for ( int j = 0; j < Board::width; j++ )
            blocks[i][j] = src[i][j];
    }
}

void Board::operator=( const Board &src ) {

    for ( int i = 0; i < Board::width; i++ )
        delete[] blocks[i];
    delete[] blocks;

    for ( int i = 0; i < Board::width; i++ )
        for ( int j = 0; j < Board::height; j++ )
            blocks[i][j].setColor( src[i][j].color() );
            
}

Block *Board::operator[]( int pos ) const {
    return blocks[pos];
}

void Board::drawBlock( SDL_Surface *screen, int x, int y ) {

    if ( blocks[y][x].color() == 1 )
        filledEllipseRGBA( screen, x * this->blockWidth() + this->blockWidth() / 2, y * this->blockHeight() + this->blockHeight() / 2, this->blockWidth() / 2 - this->blockWidth() / 30, this->blockHeight() / 2 - this->blockHeight() / 30, 255, 0, 0, 255 );

    else if ( blocks[y][x].color() == -1 )
        filledEllipseRGBA( screen, x * this->blockWidth() + this->blockWidth() / 2, y * this->blockHeight() + this->blockHeight() / 2, this->blockWidth() / 2 - this->blockWidth() / 30, this->blockHeight() / 2 - this->blockHeight() / 30, 0, 0, 255, 255 );
    
}

void Board::drawTable( SDL_Surface *screen ) {
    
    boxRGBA( screen, 0, 0, screen->w, screen->h, 0, 255, 255, 255 );

    for ( int i = 1; i < Board::width; i++ )
        lineRGBA( screen, i * this->blockWidth(), 0, i * this->blockWidth(), screen->h, 0, 0, 0, 255 );
    for ( int i = 1; i < Board::height; i++ )
        lineRGBA( screen, 0, i * this->blockHeight(), screen->w, i * this->blockHeight(), 0, 0, 0, 75 );

    for ( int i = 0; i < Board::width; i++ )
        for ( int j = 0; j < Board::height; j++ )
            drawBlock( screen, i, j );

}

bool Board::hasEmptyBlock( int x ) {
    for ( int i = 0; i < Board::height; i++ )
        if ( blocks[i][x].color() == Block::empty )
            return true;
    return false;
}

bool Board::addPiece( int x ) {
    for ( int i = Board::height - 1; i >= 0; i-- ){
        if ( blocks[i][x].color() == Block::empty ){
            blocks[i][x].setColor( this->turn() );
            this->switchTurn();
            return true;
        }
    }
}

bool Board::clicked( int x ) {
    if ( this->hasEmptyBlock( x ) )
        return ( this->addPiece( x ) );
}

bool Board::noEmptyBlock () {
    for ( int i = 0; i < Board::width; i++ )
        for ( int j = 0; j < Board::height; j++ )
            if ( blocks[j][i].color() == 0 )
                return false;
    return true;
}

int Board::checkWinning () {

    if ( this->noEmptyBlock() )
        return Board::draw;

    for ( int i = 0; i < Board::width; i++ )
        for ( int j = 0; j < Board::height - 3; j++ )
            if ( blocks[j][i] == blocks[j+1][i] && blocks[j][i] == blocks[j+2][i] && blocks[j][i] == blocks[j+3][i] && blocks[j][i].color() != 0 )
                return blocks[j][i].color();

    for ( int i = 0; i < Board::height; i++ )
        for ( int j = 0; j < Board::width - 3; j++ )
            if ( blocks[i][j] == blocks[i][j+1] && blocks[i][j] == blocks[i][j+2] && blocks[i][j] == blocks[i][j+3] && blocks[i][j].color() != 0 )
                return blocks[i][j].color();

    for ( int i = 0; i < Board::width - 3; i++ )
        for ( int j = 0; j < Board::height - 3; j++ )
            if ( blocks[j][i] == blocks[j+1][i+1] && blocks[j][i] == blocks[j+2][i+2] && blocks[j][i] == blocks[j+3][i+3] && blocks[j][i].color() != 0 )
                return blocks[j][i].color();
                
    for ( int i = 3; i < Board::width; i++ )
        for ( int j = 0; j < Board::height - 3; j++ )
            if ( blocks[j][i] == blocks[j+1][i-1] && blocks[j][i] == blocks[j+2][i-2] && blocks[j][i] == blocks[j+3][i-3] && blocks[j][i].color() != 0 )
                return blocks[j][i].color();

    return 0;

}

int Board::run( SDL_Surface *screen ) {    
    
    this->drawTable( screen );
    SDL_Flip( screen );

    SDL_Event event;

    while ( 1 ) {
        
        while ( SDL_PollEvent( &event ) ) {
            
            if ( event.type == SDL_QUIT )
                return 0;

            if ( event.type == SDL_KEYDOWN )
                if ( event.key.keysym.sym == SDLK_F4 )
                    if ( event.key.keysym.mod != 0 && ( event.key.keysym.mod & KMOD_ALT ) )
                        return 0;

            if ( event.type == SDL_MOUSEBUTTONDOWN && event.button.button == SDL_BUTTON_LEFT )
                if ( this->clicked( event.button.x / this->blockWidth() ) ){
                    this->drawTable( screen );
                    SDL_Flip( screen );

                    if ( this->checkWinning() )
                        return 1;

                }

            if ( event.type == SDL_VIDEORESIZE ){
                screen = SDL_SetVideoMode( event.resize.w, event.resize.h, 32, screen->flags );
                this->setBlockWidth( screen->w / Board::width );
                this->setBlockHeight( screen->h / Board::height );
                this->drawTable( screen );
                SDL_Flip( screen );
            }

        }

    }

}

void Board::showWinner( SDL_Surface *screen ) {
    
    TTF_Init();

    TTF_Font *font = TTF_OpenFont( "fonts/Arial.ttf", 52 );

    SDL_Color color{ 0, 0, 0 };

    string text;
    if ( this->checkWinning() == Board::red )
        text.append( "Red" );
    else if ( this->checkWinning() == Board::blue )
        text.append( "Blue" );
    if ( this->checkWinning() != Board::draw )
        text.append( " Won the Game!" );

    if ( this->checkWinning() == Board::draw )
        text.append( "Draw!" );

    SDL_Surface *message = TTF_RenderText_Solid( font, text.c_str(), color );

    SDL_Rect pos;    pos.x = ( screen->w - message->w ) / 2;    pos.y = ( screen->h - message->h ) / 2;
    SDL_BlitSurface( message, NULL, screen, &pos );

    TTF_CloseFont( font );
    TTF_Quit();

}

void Board::setBlockWidth( int blockWidth ) {
    this->_blockWidth = blockWidth;
}

void Board::setBlockHeight( int blockHeight ) {
    this->_blockHeight = blockHeight;
}

void Board::setTurn( int turn ) {
    this->_turn = turn;
}

void Board::switchTurn () {
    this->_turn *= -1;
}

int Board::blockWidth () const{
    return this->_blockWidth;
}

int Board::blockHeight () const {
    return this->_blockHeight;
}

int Board::turn () const {
    return this->_turn;
}

File: main.cpp

#include "SDL/SDL.h"

#include "board.h"

void closeProgram( Board *board ) {
    delete board;
    SDL_Quit();
    exit( 0 );
}

int main () {
    
    SDL_Init( SDL_INIT_EVERYTHING );

    const SDL_VideoInfo *videoInfo = SDL_GetVideoInfo();
    SDL_Surface *screen = SDL_SetVideoMode( videoInfo->current_w / 2, videoInfo->current_h / 2, 32, SDL_RESIZABLE );

    Board *board = new Board( screen, 7, 6 );

    if ( !board->run( screen ) )
        closeProgram( board );

    board->showWinner( screen );
    SDL_Flip( screen );
    
    SDL_Event event;

    while ( 1 ) {
        while ( SDL_PollEvent( &event ) ){
            if ( event.type == SDL_QUIT )
                closeProgram( board );
            
            if ( event.type == SDL_KEYDOWN ) {
                if ( event.key.keysym.sym == SDLK_F4 )
                    if ( event.key.keysym.mod != 0 && ( event.key.keysym.mod & KMOD_ALT ) )
                        closeProgram( board );
            }
        }
    }

    return 0;
}

File: makefile

run: all
    gdb -q 4inaRow
all: block.o board.o main.o
    g++ main.o board.o block.o -o 4inaRow -g -Wall -lSDL -lSDL_gfx -lSDL_ttf
block.o: block.h block.cpp
    g++ -c block.cpp
board.o: block.o board.h board.cpp
    g++ -c board.cpp
main.o: board.o main.cpp
    g++ -c main.cpp
clean:
    rm -rff *.o 4inaRow

کد های بالا را می توانید از لینک زیر دریافت کنید.

سورس بازی 4inaRow

موفق باشید!