PDA

View Full Version : 15 Puzzle



Gleeok
12-05-2009, 02:39 AM
This forum is a little sluggish now-a-days so I thought I'd liven it up a bit with a little 15 puzzle I cooked up. :)

Video: http://www.youtube.com/watch?v=9Xe8DCWKXO4

EDIT: bug fixed.

Unfortunately there's one minor bug to fix before uploading a quest file. Plus I'd much like to draw some better graphics and scale them to fit in the screen better to boot. ( I gladly accept sprite donations! :p ..well it's only 15 tiles worth after all, if someone has an inkling for it.)


Since there's no quest file yet I guess I'll post the script as per the norm.




const int PIECE_TILE = 100;

int piece[16];
int selected;
int pm_dir;

ffc script Puzzle15
{
void run()
{
Init15();
while( true )
{
Waitframe();

doControls15();
KeepTime();

RenderBoard15();
if( IsComplete15() )
{
Init15();
}
}
}
}


void MoveSelected15( int dir )
{
if( dir == 0 )
if( selected - 4 < 0 ) selected += 12;
else selected -= 4;
if( dir == 1 )
if( selected + 4 > 15 ) selected -= 12;
else selected += 4;
if( dir == 2 )
if( selected % 4 == 0 ) selected += 3;
else selected -= 1;
if( dir == 3 )
if( selected == 15 || selected == 11 || selected == 7 || selected == 3) selected -= 3;
else selected += 1;
}

void doControls15()
{
if( !paused )
{
if( Link->getPressUp() ) MoveSelected15( 0 );
if( Link->getPressDown() ) MoveSelected15( 1 );
if( Link->getPressLeft() ) MoveSelected15( 2 );
if( Link->getPressRight() ) MoveSelected15( 3 );
if( Link->getPressA() ) MovePiece15();
}

if( Link->getPressStart() )
{
paused = !paused;
}

Link->InputStart = false;
Link->InputUp = false;
Link->InputDown = false;
Link->InputLeft = false;
Link->InputRight = false;

Link->X = 16;
Link->Y = 16;
}


void Init15()
{
InitClock();

piece[15] = 0;
for( int i = 0; i < 15; i++ )
piece[i] = i + 1;

selected = 0;
int loop = 0;
while( loop < 15000 )
{
loop = Randomize15( loop );
}
}


int Randomize15( int loop )
{
int r;
if( piece[0] == 0 ) r = 1 << ( Rand(2) * 2 );
else if( piece[3] == 0 ) r = 2 + ( Rand(2) * 5 );
else if( piece[12] == 0 ) r = 8 + ( Rand(2) * 5 );
else if( piece[15] == 0 ) r = 11 + ( Rand(2) * 3 );
else r = Rand(16);

int v = Move15( r, 1, 4 );
if ( v != -1 && IsInRow15( r, v ) )
{
Swap15( r, v );
}

return loop + 1;
}

void InitClock()
{
global_timer = 0;
seconds = 0;
minutes = 0;
}


int Move15( int i, int x, int y )
{
if( i - x >= 0 )
if( piece[ i - x ] == 0 )
{
pm_dir = 2;
return i - x;
}
if( i + x < 16 )
if( piece[ i + x ] == 0 )
{
pm_dir = 3;
return i + x;
}
if( i - y >= 0 )
if( piece[ i - y ] == 0 )
{
pm_dir = 0;
return i - y;
}
if( i + y < 16 )
if( piece[ i + y ] == 0 )
{
pm_dir = 1;
return i + y;
}
return -1;
}


int Swap15( int p1, int p2 )
{
int tmp = piece[ p1 ];
piece[ p1 ] = piece[ p2 ];
piece[ p2 ] = tmp;
}


bool IsInRow15( int source, int n )
{
if( source < 4 )
{
if( pm_dir > 1 ) return ( n < 4 );
else return ( ( n % 4 ) == source );
}
else if( source < 8 )
{
if( pm_dir > 1 ) return ( n > 3 && n < 8 );
else return ( ( n % 4 ) == ( source - 4 ) );
}
else if( source < 12 )
{
if( pm_dir > 1 ) return ( n > 7 && n < 12 );
else return ( ( n % 4 ) == ( source - 8 ) );
}
else
{
if( pm_dir > 1 ) return ( n > 11 );
else return ( ( n % 4 ) == ( source - 12 ) );
}
return false;
}


void MovePiece15()
{
int v = Move15( selected, 1, 4 );
if ( v != -1 && IsInRow15( selected, v ) )
{
Swap15( selected, v );
return;
}
// No good? Let's try and move up to a whole row then.
v = Move15( selected, 2, 8 );
if ( v != -1 && IsInRow15( selected, v ) )
{
if( pm_dir == 0 ) Swap15( selected - 4, v );
else if( pm_dir == 1 ) Swap15( selected + 4, v );
else if( pm_dir == 2 ) Swap15( selected - 1, v );
else if( pm_dir == 3 ) Swap15( selected + 1, v );
MovePiece15();
return;
}
v = Move15( selected, 3, 12 );
if ( v != -1 && IsInRow15( selected, v ) )
{
if( pm_dir == 0 ) Swap15( selected - 8, v );
else if( pm_dir == 1 ) Swap15( selected + 8, v );
else if( pm_dir == 2 ) Swap15( selected - 2, v );
else if( pm_dir == 3 ) Swap15( selected + 2, v );
MovePiece15();
return;
}
}


int PieceElement( int row, int column )
{
return ( row + ( column * 4 ) );
}


bool IsComplete15()
{
int complete = 0;
if( piece[15] == 0 )
{
for( int j; j < 15; j++ )
if( piece[j] == j + 1 )
complete++;
}
return ( complete == 15 );
}


int getY15( int i )
{
if( i < 4 ) return 0;
else if( i < 8 ) return 1;
else if( i < 12 ) return 2;
return 3;
}


void RenderBoard15()
{
int x_off = 64;
int y_off = 32;

// Draw the border
Screen->Rectangle( 5, x_off-1, y_off-1, x_off + 65, y_off + 65, 15, 1, 0, 0, 0, false, 128 );

for( int i = 0; i < 4; i++ )
for( int j = 0; j < 4; j++ )
Screen->DrawTile( 5, ( i * 16 ) + x_off, ( j * 16 ) + y_off,
PIECE_TILE + piece[ PieceElement( i, j ) ],
1, 1, 0, -1, -1, 0, 0, 0, 0, true, 128 );
// Draw the cursor
Screen->Rectangle( 6, x_off + (( selected % 4 ) * 16), y_off + ( getY15( selected ) * 16 ),
16 + x_off + (( selected % 4 ) * 16), 16 + y_off + ( getY15( selected ) * 16 ),
15, 1, 0, 0, 0, true, 64 );

// Draw the timer
int str[1] = ":";
if( minutes < 10 )
{
Screen->DrawInteger( 6, x_off, 8, 0, 10, 1, -1, -1, 0, 0, 128 );
Screen->DrawInteger( 6, x_off + 8 , 8, 0, 15, 1, -1, -1, minutes, 0, 128 );
}
else Screen->DrawInteger( 6, x_off, 8, 0, 15, 1, -1, -1, minutes, 0, 128 );
if( seconds < 10 )
{
Screen->DrawInteger( 6, x_off + 20, 8, 0, 10, 1, -1, -1, 0, 0, 128 );
Screen->DrawInteger( 6, x_off + 28, 8, 0, 15, 1, -1, -1, seconds, 0, 128 );
}
else Screen->DrawInteger( 6, x_off + 20, 8, 0, 15, 1, -1, -1, seconds, 0, 128 );
if( ( global_timer % 60 ) < 10 )
{
Screen->DrawInteger( 6, x_off + 40, 8, 0, 15, 1, -1, -1, 0, 0, 128 );
Screen->DrawInteger( 6, x_off + 48, 8, 0, 15, 1, -1, -1, global_timer * 1.6, 0, 128 );
}
else Screen->DrawInteger( 6, x_off + 40, 8, 0, 15, 1, -1, -1, global_timer * 1.6, 0, 128 );

Screen->DrawCharacter( 6, x_off + 14, 8, 0, 12, -1, -1, -1, str[0], 64 );
Screen->DrawCharacter( 6, x_off + 35, 8, 0, 12, -1, -1, -1, str[0], 64 );
}


void KeepTime()
{
if( paused ) return;

global_timer++;
if( global_timer >= 60 )
{
seconds++;
global_timer -= 60;
if( seconds >= 60 )
{
minutes++;
seconds -= 60;
}
}
}





edit: what's with the code tags!?

pkmnfrk
12-05-2009, 05:04 AM
Oh god 15 puzzle.

Haven't tried the script, but I hate you already D:<



;)

Gleeok
12-06-2009, 12:58 AM
Yep, although I don't think 15 puzzle gets many people exited. I pretty much got bored and wondered how long it would take to script it.

Uses:

- You could have it trigger if link is in water while holding select and presses the B button 20 times.
- Master using it and you can have this?
- As punishment for dying.


Anyway I edited the script. All the parts are there now and it works as it should.

Imzogelmo
12-06-2009, 11:45 AM
Tetris coming soon?!?!

Gleeok
12-07-2009, 10:22 AM
Nope. Tetris already came. :P

They're both in the same quest file, here:
http://armageddongames.net/showthread.php?44655-Tetriz

Lemon
01-19-2010, 04:12 AM
So, you could easily replace the numbers with an image right? This might be fun to try to implement into a quest for a side-quest for a heart piece or something.

Imzogelmo
01-19-2010, 08:11 PM
This is pure awesomeness. :)

Gleeok
01-21-2010, 09:38 AM
Who wants to try 512 puzzle next? XD