 


Task

Implement the Fifteen Puzzle Game.



The   15-puzzle   is also known as:

   Fifteen Puzzle
   Gem Puzzle
   Boss Puzzle
   Game of Fifteen
   Mystic Square
   14-15 Puzzle
   and some others.


Related Tasks

   15 Puzzle Solver
   16 Puzzle Game


tiles=[1:15,0];
solution=[tiles(1:4);...
          tiles(5:8);...
          tiles(9:12);...
          tiles(13:16)];
solution=string(solution);
solution(16)=" ";
 
init_pos=grand(1,"prm",tiles);
puzzle=[init_pos(1:4);...
        init_pos(5:8);...
        init_pos(9:12);...
        init_pos(13:16)];
puzzle=string(puzzle);
 
blank_pos=[];
for i=1:4
    for j=1:4
        if puzzle(i,j)=="0" then
            blank_pos=[i,j];
        end
    end
end
 
clear i j
 
puzzle(blank_pos(1),blank_pos(2))=" ";
 
n_moves=0;
solved=%F;
while ~solved
    disp(puzzle); mprintf("\n");
 
    neighbours=[0 -1;...
               -1  0;...
                0 +1;...
               +1  0];
    neighbours(:,1)=neighbours(:,1)+blank_pos(1);
    neighbours(:,2)=neighbours(:,2)+blank_pos(2);
    neighbours=[neighbours zeros(4,1)]
 
    i=0;
    for i=1:4
        if ~(neighbours(i,1)<1 | neighbours(i,1)>4 |...
           neighbours(i,2)<1 | neighbours(i,2)>4) then
           neighbours(i,3)=evstr(puzzle(neighbours(i,1),neighbours(i,2)));
       end
    end
 
    valid_move=%F;
    while ~valid_move
        move_tile=[];    
        move_tile=input("Enter tile you want to move (0 to exit):");
        if sum(move_tile==neighbours(:,3)) & move_tile~=0 then
            valid_move=%T;
            n_moves=n_moves+1;
        elseif move_tile==0 then
            disp("Exit");
            abort
        else
            disp(puzzle);
            disp("Invalid input");
        end
    end
 
    neighb_i=find(neighbours(:,3)'==move_tile);
    puzzle(neighbours(neighb_i,1),neighbours(neighb_i,2))=" ";
    puzzle(blank_pos(1),blank_pos(2))=string(move_tile);
    blank_pos=neighbours(neighb_i,1:2);
 
    if sum(puzzle==solution)==16 then
        solved=%T;
        disp(puzzle);
        mprintf("\n"+...
                "   _____       _               _ _ \n"+...
                "  / ____|     | |             | | |\n"+...
                " | (___   ___ | |_   _____  __| | |\n"+...
                "  \\___ \\ / _ \\| \\ \\ / / _ \\/ _` | |\n"+...
                "  ____) | (_) | |\\ V /  __/ (_| |_|\n"+...
                " |_____/ \\___/|_| \\_/ \\___|\\__,_(_)\n")
    end
end
 
disp("Solved in "+string(n_moves)+" moves.");