Copy to Clipboard Test

Fifteen Sliding Puzzle Code

const int SFX_FIFTEEN_PUZZLE_MOVE = 16; //Sound to play when making move.
const int SFX_FIFTEEN_PUZZLE_SOLVED = 27;//Sound to play when puzzle is solved. 

const int FIFTEEN_PUZZLE_SHUFFLE_NUM_MOVES =180; //Number of moves when shuffling puzzle
const int FIFTEEN_PUZZLE_SHUFFLE_ASPEED =1; //Delay between shuffling moves, in frames.



//4*4 grid space, occupied by 15 numbered tiles and 1 empty space. Tiles in the same row or column of the open 
//position can be moved by sliding them horizontally or vertically, respectively. Stand on tile adjacent to empty space and press A.
//The goal of the puzzle is to arrange the tiles in numerical order.
//1. Set up 16 consecutive combos, 15 for number tiles, followed by empty space. You should end up with 4*4 block of combos depicting solved state of the puzzle.
//2. Build 4*4 block on the screen using Right click -> Draw Block-> 4*4
//3. Place FFC at top left corner of the grid
//D0 - 1-Disable secrets, like for inputing passwords.
ffc script FifteenPuzzle{
	void run(int secret){
		if (Screen->State[ST_SECRET]) Quit();
		this->EffectWidth*=4;
		this->EffectHeight*=4;
		int startpos = ComboAt(CenterX(this), CenterY(this));
		int startposx = ComboX(startpos);
		int startposy = ComboY(startpos);
		int boundx = ComboX(startpos)+63;
		int boundy = ComboY(startpos)+63;
		int pos[16] = {startpos, startpos+1, startpos+2, startpos+3, 
			startpos+16, startpos+17, startpos+18, startpos+19,
			startpos+32, startpos+33, startpos+34, startpos+35,
			startpos+48, startpos+49, startpos+50, startpos+51};
		int cmb[16];
		for (int i=0; i<16; i++){
			cmb[i] = Screen->ComboD[startpos]+i;
		}
		int movecmb = -1;
		int pushdir = -1;
		int movex = -1;
		int movey = -1;
		int movecounter = 0;
		int curpos=-1;
		//shuffle tiles
		int blankspace = pos[15];
		for (int i=1; i<=FIFTEEN_PUZZLE_SHUFFLE_NUM_MOVES;i++){
			int adjcmb = AdjacentCombo(blankspace, Rand(4));
			if ((ComboX(adjcmb))<startposx)	adjcmb=-1;
			if ((ComboY(adjcmb))<startposy) adjcmb=-1;
			if ((ComboX(adjcmb))>boundx) adjcmb=-1;
			if ((ComboY(adjcmb))>boundy) adjcmb=-1;
			if (adjcmb>=0){
				SwapCombos(blankspace, adjcmb);
				blankspace=adjcmb;
				Waitframes(FIFTEEN_PUZZLE_SHUFFLE_ASPEED);
			}
			else i--;
		}
		while(true){
			if (pushdir<0){
				if (RectCollision(ComboX(startpos), ComboY(startpos),ComboX(startpos+4)-1, ComboY(startpos+48)+15, CenterLinkX(), CenterLinkY(), (CenterLinkX()+1), (CenterLinkY())+1)){
					if (Link->PressEx1){
						curpos = ComboAt(CenterLinkX(), CenterLinkY());
						int blankpos = FindAdjacentBlankPos(curpos, cmb[15], startpos);
						if (blankpos>=0){
							Game->PlaySound(SFX_FIFTEEN_PUZZLE_MOVE);
							movex = ComboX(curpos);
							movey = ComboY(curpos);
							pushdir = blankpos;
							movecmb = Screen->ComboD[curpos];
							movecounter = 16;
							Screen->ComboD[curpos] = cmb[15];
						}				
					}
				}
			}
			else{
				NoAction();
				if (pushdir==DIR_UP)movey--;
				if (pushdir==DIR_DOWN)movey++;
				if (pushdir==DIR_LEFT)movex--;
				if (pushdir==DIR_RIGHT)movex++;
				Screen->FastCombo(1, movex, movey, movecmb, Screen->ComboC[curpos], OP_OPAQUE);
				movecounter--;
				if (movecounter==0){
					int adjcmb = AdjacentCombo(curpos, pushdir);
					pushdir=-1;
					Screen->ComboD[curpos] = cmb[15];
					Screen->ComboD[adjcmb] = movecmb;
					for (int i=0; i<16;i++){
						if (secret>0) break;
						if (Screen->ComboD[pos[i]]!=cmb[i]) break;
						else if (i==15){								
							Game->PlaySound(SFX_FIFTEEN_PUZZLE_SOLVED);
							Screen->TriggerSecrets();
							Screen->State[ST_SECRET]=true;
							Quit();
						}
					}
				}
			}
			Waitframe();
		}
	}
	
	void SwapCombos(int pos1, int pos2){
		int cmb1 = Screen->ComboD[pos1];
		int cmb2 = Screen->ComboD[pos2];
		int cset1 = Screen->ComboC[pos1];
		int cset2 = Screen->ComboC[pos2];
		Screen->ComboD[pos1] = cmb2;
		Screen->ComboD[pos2] = cmb1;
		Screen->ComboC[pos1] = cset2;
		Screen->ComboC[pos1] = cset1;
	}
	
	int FindAdjacentBlankPos(int curpos, int blankcmb, int startpos){
		int startposx = ComboX(startpos);
		int startposy = ComboY(startpos);
		int boundx = startposx+63;
		int boundy = startposx+63;
		int adjcmb[4];
		for (int i=0;i<4;i++){
			adjcmb[i]= AdjacentCombo(curpos, i);
			if ((ComboX(adjcmb[i]))<startposx) 	adjcmb[i]=-1;
			if ((ComboY(adjcmb[i]))<startposy) 	adjcmb[i]=-1;
			if ((ComboX(adjcmb[i]))>boundx) adjcmb[i]=-1;
			if ((ComboY(adjcmb[i]))>boundy) adjcmb[i]=-1;
			if (adjcmb[i]>=0){
				if ((Screen->ComboD[adjcmb[i]])==blankcmb) return i;
			}
		}
		return -1;
	}
}