#include <vector>
#include <iostream>
#include <string>
#include <sstream>
using namespace std;
#include "SDL.h"
#include "SDL_ttf.h"
const short BLOCK_WIDTH = 100;
const short BLOCK_HEIGHT = 100;
const short BOARD_WIDTH = 4;
const short BOARD_HEIGHT = 4;
const short FONT_SIZE = 20;
void draw_board( vector<vector<int> > *board, SDL_Surface *screen )
{
TTF_Font *font = NULL;
SDL_Surface *number = NULL;
Uint32 color = SDL_MapRGB( screen->format, 0, 0, 125 );
SDL_Color textColor;
textColor.r = 0; textColor.g = 0; textColor.b = 0;
font = TTF_OpenFont("font.ttf", FONT_SIZE);
if( font == NULL )
return;
SDL_Rect dstrect;
dstrect.w = BLOCK_WIDTH;
dstrect.h = BLOCK_HEIGHT;
SDL_Rect fontrect;
SDL_FillRect( screen, NULL, SDL_MapRGB( screen->format, 0,0,0 ) );
int count = 1;
for( short i = 0; i < BOARD_WIDTH; i++ )
{
for( short j = 0; j < BOARD_HEIGHT; j++)
{
dstrect.y = i * BLOCK_WIDTH;
dstrect.x = j * BLOCK_HEIGHT;
fontrect.x = dstrect.x + ( dstrect.w / 2 );
fontrect.y = dstrect.y + ( dstrect.h / 2 );
if( number != NULL )
SDL_FreeSurface(number);
std::stringstream s;
s << (*board)[i][j];
number = TTF_RenderText_Solid( font, s.str().c_str() , textColor );
if( (*board)[i][j] != -1 ){
SDL_FillRect( screen, &dstrect, color );
SDL_BlitSurface( number, NULL, screen, &fontrect );
}
}
}
if( number != NULL )
SDL_FreeSurface(number);
SDL_Flip(screen);
return;
}
int round_to_nth(int num, int nth)
{
return num - num % nth;
}
void make_swap(int &n1, int &n2)
{
int t = n1;
n1 = n2;
n2 = t;
return;
}
// Return true if player clicked on a movable piece
bool click_event(int x, int y, vector<vector<int> > *board)
{
x = round_to_nth(x, BLOCK_WIDTH) / BLOCK_WIDTH;
y = round_to_nth(y, BLOCK_HEIGHT) / BLOCK_HEIGHT;
// Check Left
if( x > 0 )
{
if( (*board)[y][x-1] == -1 )
make_swap( (*board)[y][x], (*board)[y][x-1] );
}
// Check Right
if( x < BOARD_WIDTH - 1 )
{
if( (*board)[y][x+1] == -1 )
make_swap( (*board)[y][x], (*board)[y][x+1] );
}
// Check Above
if( y > 0 )
{
if( (*board)[y-1][x] == -1 )
make_swap( (*board)[y][x], (*board)[y-1][x] );
}
// Check Below
if( y < BOARD_HEIGHT - 1 )
{
if( (*board)[y+1][x] == -1 )
make_swap( (*board)[y][x], (*board)[y+1][x] );
}
return false;
}
int main( int argc, char **argv )
{
/**** SDL INITIALIZATION ****/
SDL_Surface *screen = NULL;
if( SDL_Init(SDL_INIT_EVERYTHING ) == -1 )
return 1;
if( TTF_Init() == -1 )
return 1;
screen = SDL_SetVideoMode( BLOCK_WIDTH * BOARD_WIDTH, BLOCK_HEIGHT * BOARD_HEIGHT,
32, SDL_SWSURFACE );
if( screen == NULL )
return 1;
SDL_WM_SetCaption("NPuzzle written in C++ and SDL", NULL);
/**** BOARD INITIALIZATION ****/
vector< vector<int> > board;
int count = 1;
for( short i = 0; i < BOARD_WIDTH; i++){
vector<int> t;
board.push_back(t);
for( short j = 0; j < BOARD_HEIGHT; j++){
board[i].push_back( count++ );
}
}
// -1 represents the empty square
board[BOARD_WIDTH-1][BOARD_HEIGHT-1] = -1;
/*** GAME LOGIC ***/
SDL_Event ev;
bool game = true;
while(game)
{
SDL_Delay(1);
while( SDL_PollEvent(&ev) )
{
if( ev.type == SDL_QUIT )
game = false;
if( ev.type == SDL_MOUSEBUTTONDOWN )
{
click_event( ev.button.x, ev.button.y, &board );
}
}
draw_board(&board,screen);
}
// Free resources and exit
SDL_FreeSurface(screen);
SDL_Quit();
return 0;
}