Finish 2012-04-11 12:00:00 UTC

... missed the worm

by Fel

Status: Passed
Results: 114032 (cyc: 9, node: 9802)
CPU Time: 82.525
Score: 11663.2
Submitted at: 2012-04-07 00:07:37 UTC
Scored at: 2012-04-07 00:20:49 UTC

Current Rank: 949th (Highest: 16th )
Based on: ... missed the worm (diff)
Basis for: Warm Shine 3 (diff)

Comments
Please login or create a profile.
Code
function [board, orientation] = solver(tiles, boardSize)

orientation = ones(size(tiles,1), 1);
ntiles      = size(tiles,1);
nElem       = boardSize(1)*boardSize(2);
board       = zeros(boardSize);
cs          = [1 2 3 4; 2 3 4 1; 3 4 1 2; 4 1 2 3];
played      = discardUnplayed(ntiles-nElem, tiles);

if (ntiles-nElem<0)
    height=min([ceil(sqrt(ntiles)) boardSize(1)]);
    if (ntiles/boardSize(2))>height
        height=ceil(ntiles/boardSize(2));
    end
else
    ntiles=nElem;
    height=boardSize(1);
end

for k=1:ntiles
    [y,x]=ind2sub([height,boardSize(2)],k);
    board(y,x)=-1;
end
last = [y,x];

for i=8:-1:1
    b(:,:,i) = board;
    o(:,i) = orientation;
end

list = played;
[b(:,:,1),o(:,1),list] = place([1 height],1:last(2),b(:,:,1),played,list,o(:,1),ntiles,boardSize, cs);
[b(:,:,1),o(:,1),list] = place(height:-1:1,[last(2) 1],b(:,:,1),played,list,o(:,1),ntiles,boardSize, cs);
newList(:,:,1) = list;

list = played;
[b(:,:,5),o(:,5),list] = place(height:-1:1,last(2),b(:,:,5),played,list,o(:,5),ntiles,boardSize, cs);
[b(:,:,5),o(:,5),list] = place(height,1:last(2),b(:,:,5),played,list,o(:,5),ntiles,boardSize, cs);
[b(:,:,5),o(:,5),list] = place(1:height,1,b(:,:,5),played,list,o(:,5),ntiles,boardSize, cs);
[b(:,:,5),o(:,5),list] = place(1,1:last(2),b(:,:,5),played,list,o(:,5),ntiles,boardSize, cs);
newList(:,:,2) = list;

for i=[4 0]
    [b(:,:,i+2),o(:,i+2),list] = place(2:height-1,2:boardSize(2)-1,b(:,:,i+1),played,newList(:,:,i/4+1),o(:,i+1),ntiles,boardSize, cs);
    [b(:,:,i+3),o(:,i+3),list] = place(height-1:-1:2,2:boardSize(2)-1,b(:,:,i+1),played,newList(:,:,i/4+1),o(:,i+1),ntiles,boardSize, cs);
    [b(:,:,i+4),o(:,i+4),list] = place(2:height-1,boardSize(2)-1:-1:2,b(:,:,i+1),played,newList(:,:,i/4+1),o(:,i+1),ntiles,boardSize, cs);
    [b(:,:,i+1),o(:,i+1),list] = place(height-1:-1:2,boardSize(2)-1:-1:2,b(:,:,i+1),played,newList(:,:,i/4+1),o(:,i+1),ntiles,boardSize, cs);
end

S = 8;

if prod(boardSize) < 1000
[b(:,:,9 ), o(:,9 )] = picky(tiles, boardSize);
[b(:,:,10), o(:,10)] = calibrating_pure(tiles, boardSize);
[b(:,:,11), o(:,11)] = werner(tiles, boardSize);
S = S + 3;
end

overall  = zeros(S,1);
for i=1:S
    overall(i) = overallScore(b(:,:,i),o(:,i),tiles, cs);
end
[~,mo] = min(overall);
board = b(:,:,mo);
orientation = o(:,mo);

%disp(['  Mejor SOLUCION SOLVER_' num2str(mo) ])

end

function [score] = overallScore(board, orientation, tiles, cs)
    
    boardSize=size(board);
    tile = zeros(boardSize(1)*4,boardSize(2));
    tmp = tiles.';
    for y = 1:boardSize(1)
        for x = 1:boardSize(2)
            if board(y,x)
                %tile((y-1)*4+1:y*4,x)=tiles(board(y,x),cs(orientation(board(y,x)),:))';
                tile((y-1)*4+1:y*4,x)=tmp(cs(orientation(board(y,x)),:),board(y,x));
            end
        end
    end
    internal    = sum(sum(abs(tile(5:4:end,1:end)-tile(3:4:end-4,1:end))))+sum(sum(abs(tile(2:4:end,1:end-1)-tile(4:4:end,2:end))));
    external    = sum(tile(4:4:end,1))+sum(tile(2:4:end,end))+sum(tile(end-1,1:end))+sum(tile(1,1:end));
    out_tiles   = 1:size(tiles,1);
    in_tiles    = board(board>0);
    out_tiles(in_tiles) = [];
    notplayed   = sum(sum(tiles(out_tiles,:)));
    score       = internal + external + notplayed;
end

function [brd, ort, lst] = place(rowRange, colRange, board, tiles, list, orientation, ntiles, boardSize, cs)
    k = 1;
    brd = board;
    ort = orientation;
    lst = list;
    L   = size(lst,1);
    for y=rowRange
        for x=colRange
            if (brd(y,x)==-1)
                [n,e,s,w] = findBoundaries(brd, tiles, ort, y, x, boardSize, cs);
                [t, o] = findBestTile(lst, L, n, e, s, w, cs);
                ort(t) = o;
                brd(y,x)=t;
                lst(t,:)=inf(1,4);
                k = k + 1;
                if (k > ntiles)
                    return;
                end
            end
        end
    end
end

function tiles = discardUnplayed(numUnplayed, tiles)

if numUnplayed>0
    sums = sum(tiles,2);
    for i = 1:numUnplayed
        [~, m]=min(sums);
        tiles(m,:)=inf(1,4);
        sums(m)=inf;
    end
end
end

function [tile, orientation] = findBestTile(list, L, north, east, south, west, cs)

score = int32(zeros(L,4));

grid  = ones(L,1)*[north east south west];
for i=1:4
    score(:,i) = sum(int32(abs(list(:,cs(:,i))-grid)),2);    
end
[ms, t          ] = min(score);
[~ , orientation] = min(ms);
tile              = t(orientation);
end

function [north, east, south, west] = findBoundaries(board, tiles, orientation, row, col, boardSize, cs)
    north = boundary(board,tiles,orientation,row-1,col  ,3, boardSize, cs);
    south = boundary(board,tiles,orientation,row+1,col  ,1, boardSize, cs);
    west  = boundary(board,tiles,orientation,row  ,col-1,2, boardSize, cs);
    east  = boundary(board,tiles,orientation,row  ,col+1,4, boardSize, cs);
end

function value = boundary(board,tiles,orientation,row,col,id,boardSize,cs)
   
    if row<1 || col<1 || row>boardSize(1) || col>boardSize(2)
        value = 0;
    else
        if board(row,col) == -1
            value = nan;
        elseif board(row,col) == 0
            value = 0;            
        else
            tile  = tiles(board(row,col),cs(orientation(board(row,col)),:));
            value = tile(id);
        end
    end
end

function [board, orientation] = picky(tiles, boardSize)

nt = size(tiles,1);
board = zeros(boardSize);
nrow = boardSize(1);
ncol = boardSize(2);
nb = nrow*ncol;
orientation = ones(nt,1);

unused = true(1,nt);
rt{4} = circshift(tiles,[0 1]);
rt{3} = circshift(tiles,[0 2]);
rt{2} = circshift(tiles,[0 3]);
rt{1} = tiles;
goalN = nan(boardSize);
goalN(1,:) = 0;
goalS = nan(boardSize);
goalS(end,:) = 0;
goalE = nan(boardSize);
goalE(:,end) = 0;
goalW = nan(boardSize);
goalW(:,1) = 0;
tsum = sum(tiles,2);

% adjust goals

% greedily pick tiles
for i = 1:min(nb,nt)
    goal = [goalN(i),goalE(i),goalS(i),goalW(i)];
    for j = 4:-1:1
        hd = bsxfun(@minus,rt{j}(unused,:),goal);
        hd(isnan(hd)) = 0;
        hs{j} = sum(abs(hd),2);
    end;
    hsm = cat(2,hs{:});
    hsm(hsm~=min(hsm(:))) = inf;
    %hsm(hsm~=min(min(hsm))) = inf;
    hsm = bsxfun(@minus,hsm,tsum(unused));
    %[~,pick] = min(hsm(:));
    %[pick,ori] = ind2sub([nt-i+1,4],pick);
    [pick,ori] = find(hsm==min(min(hsm)),1,'first');
    pick = find(unused,pick);
    pick = pick(end);
    board(i) = pick;
    orientation(pick) = ori;
    unused(pick) = false;
    
    % update goals
    if (i+nrow <= nb)
        goalW(i+nrow) = rt{ori}(pick,2);
    end;
    if (mod(i,nrow) ~= 0)
        goalN(i+1) = rt{ori}(pick,3);
    end;
end;
end

function [board, orientation] = solver(tiles, boardSize)

orientation = ones(size(tiles,1), 1);
ntiles      = size(tiles,1);
nElem       = boardSize(1)*boardSize(2);
board       = zeros(boardSize);
cs          = [1 2 3 4; 2 3 4 1; 3 4 1 2; 4 1 2 3];
played      = discardUnplayed(ntiles-nElem, tiles);

if (ntiles-nElem<0)
    height=min([ceil(sqrt(ntiles)) boardSize(1)]);
    if (ntiles/boardSize(2))>height
        height=ceil(ntiles/boardSize(2));
    end
else
    ntiles=nElem;
    height=boardSize(1);
end

for k=1:ntiles
    [y,x]=ind2sub([height,boardSize(2)],k);
    board(y,x)=-1;
end
last = [y,x];

for i=8:-1:1
    b(:,:,i) = board;
    o(:,i) = orientation;
end

list = played;
[b(:,:,1),o(:,1),list] = place([1 height],1:last(2),b(:,:,1),played,list,o(:,1),ntiles,boardSize, cs);
[b(:,:,1),o(:,1),list] = place(height:-1:1,[last(2) 1],b(:,:,1),played,list,o(:,1),ntiles,boardSize, cs);
newList(:,:,1) = list;

list = played;
[b(:,:,5),o(:,5),list] = place(height:-1:1,last(2),b(:,:,5),played,list,o(:,5),ntiles,boardSize, cs);
[b(:,:,5),o(:,5),list] = place(height,1:last(2),b(:,:,5),played,list,o(:,5),ntiles,boardSize, cs);
[b(:,:,5),o(:,5),list] = place(1:height,1,b(:,:,5),played,list,o(:,5),ntiles,boardSize, cs);
[b(:,:,5),o(:,5),list] = place(1,1:last(2),b(:,:,5),played,list,o(:,5),ntiles,boardSize, cs);
newList(:,:,2) = list;

for i=[4 0]
    [b(:,:,i+2),o(:,i+2),list] = place(2:height-1,2:boardSize(2)-1,b(:,:,i+1),played,newList(:,:,i/4+1),o(:,i+1),ntiles,boardSize, cs);
    [b(:,:,i+3),o(:,i+3),list] = place(height-1:-1:2,2:boardSize(2)-1,b(:,:,i+1),played,newList(:,:,i/4+1),o(:,i+1),ntiles,boardSize, cs);
    [b(:,:,i+4),o(:,i+4),list] = place(2:height-1,boardSize(2)-1:-1:2,b(:,:,i+1),played,newList(:,:,i/4+1),o(:,i+1),ntiles,boardSize, cs);
    [b(:,:,i+1),o(:,i+1),list] = place(height-1:-1:2,boardSize(2)-1:-1:2,b(:,:,i+1),played,newList(:,:,i/4+1),o(:,i+1),ntiles,boardSize, cs);
end

[b(:,:,9 ), o(:,9 )] = picky(tiles, boardSize);
[b(:,:,10), o(:,10)] = calibrating_pure(tiles, boardSize);

overall  = zeros(10,1);
for i=1:10
    overall(i) = overallScore(b(:,:,i),o(:,i),tiles, cs);
end
[~,mo] = min(overall);
board = b(:,:,mo);
orientation = o(:,mo);

%disp(['  Mejor SOLUCION SOLVER_' num2str(mo) '. diff9 = ' num2str(num2str(overall(9) - overall(mo),'%d '))])

end

function [score] = overallScore(board, orientation, tiles, cs)
    
    boardSize=size(board);
    tile = zeros(boardSize(1)*4,boardSize(2));
    tmp = tiles.';
    for y = 1:boardSize(1)
        for x = 1:boardSize(2)
            if board(y,x)
                %tile((y-1)*4+1:y*4,x)=tiles(board(y,x),cs(orientation(board(y,x)),:))';
                tile((y-1)*4+1:y*4,x)=tmp(cs(orientation(board(y,x)),:),board(y,x));
            end
        end
    end
    internal    = sum(sum(abs(tile(5:4:end,1:end)-tile(3:4:end-4,1:end))))+sum(sum(abs(tile(2:4:end,1:end-1)-tile(4:4:end,2:end))));
    external    = sum(tile(4:4:end,1))+sum(tile(2:4:end,end))+sum(tile(end-1,1:end))+sum(tile(1,1:end));
    out_tiles   = 1:size(tiles,1);
    in_tiles    = board(board>0);
    out_tiles(in_tiles) = [];
    notplayed   = sum(sum(tiles(out_tiles,:)));
    score       = internal + external + notplayed;
end

function [brd, ort, lst] = place(rowRange, colRange, board, tiles, list, orientation, ntiles, boardSize, cs)
    k = 1;
    brd = board;
    ort = orientation;
    lst = list;
    L   = size(lst,1);
    for y=rowRange
        for x=colRange
            if (brd(y,x)==-1)
                [n,e,s,w] = findBoundaries(brd, tiles, ort, y, x, boardSize, cs);
                [t, o] = findBestTile(lst, L, n, e, s, w, cs);
                ort(t) = o;
                brd(y,x)=t;
                lst(t,:)=inf(1,4);
                k = k + 1;
                if (k > ntiles)
                    return;
                end
            end
        end
    end
end

function tiles = discardUnplayed(numUnplayed, tiles)

if numUnplayed>0
    sums = sum(tiles,2);
    for i = 1:numUnplayed
        [~, m]=min(sums);
        tiles(m,:)=inf(1,4);
        sums(m)=inf;
    end
end
end

function [tile, orientation] = findBestTile(list, L, north, east, south, west, cs)

score = int32(zeros(L,4));

grid  = ones(L,1)*[north east south west];
for i=1:4
    score(:,i) = sum(int32(abs(list(:,cs(:,i))-grid)),2);    
end
[ms, t          ] = min(score);
[~ , orientation] = min(ms);
tile              = t(orientation);
end

function [north, east, south, west] = findBoundaries(board, tiles, orientation, row, col, boardSize, cs)
    north = boundary(board,tiles,orientation,row-1,col  ,3, boardSize, cs);
    south = boundary(board,tiles,orientation,row+1,col  ,1, boardSize, cs);
    west  = boundary(board,tiles,orientation,row  ,col-1,2, boardSize, cs);
    east  = boundary(board,tiles,orientation,row  ,col+1,4, boardSize, cs);
end

function value = boundary(board,tiles,orientation,row,col,id,boardSize,cs)
   
    if row<1 || col<1 || row>boardSize(1) || col>boardSize(2)
        value = 0;
    else
        if board(row,col) == -1
            value = nan;
        elseif board(row,col) == 0
            value = 0;            
        else
            tile  = tiles(board(row,col),cs(orientation(board(row,col)),:));
            value = tile(id);
        end
    end
end

function [board, orientation] = picky(tiles, boardSize)

nt = size(tiles,1);
board = zeros(boardSize);
nrow = boardSize(1);
ncol = boardSize(2);
nb = nrow*ncol;
orientation = ones(nt,1);

unused = true(1,nt);
rt{4} = circshift(tiles,[0 1]);
rt{3} = circshift(tiles,[0 2]);
rt{2} = circshift(tiles,[0 3]);
rt{1} = tiles;
goalN = nan(boardSize);
goalN(1,:) = 0;
goalS = nan(boardSize);
goalS(end,:) = 0;
goalE = nan(boardSize);
goalE(:,end) = 0;
goalW = nan(boardSize);
goalW(:,1) = 0;
tsum = sum(tiles,2);

% adjust goals

% greedily pick tiles
for i = 1:min(nb,nt)
    goal = [goalN(i),goalE(i),goalS(i),goalW(i)];
    for j = 4:-1:1
        hd = bsxfun(@minus,rt{j}(unused,:),goal);
        hd(isnan(hd)) = 0;
        hs{j} = sum(abs(hd),2);
    end;
    hsm = cat(2,hs{:});
    hsm(hsm~=min(hsm(:))) = inf;
    %hsm(hsm~=min(min(hsm))) = inf;
    hsm = bsxfun(@minus,hsm,tsum(unused));
    %[~,pick] = min(hsm(:));
    %[pick,ori] = ind2sub([nt-i+1,4],pick);
    [pick,ori] = find(hsm==min(min(hsm)),1,'first');
    pick = find(unused,pick);
    pick = pick(end);
    board(i) = pick;
    orientation(pick) = ori;
    unused(pick) = false;
    
    % update goals
    if (i+nrow <= nb)
        goalW(i+nrow) = rt{ori}(pick,2);
    end;
    if (mod(i,nrow) ~= 0)
        goalN(i+1) = rt{ori}(pick,3);
    end;
end;
end

function [board, orientation] = calibrating_pure(tiles, boardSize)

    ntiles = size(tiles, 1);
    nfields = prod(boardSize);
    
      
    methods = [1,2,4,5];
    methods = [methods + 20, methods + 30, methods + 10, methods];
    %     methods = [methods, 44];
    
    %     methods = [methods + 10, methods];
    %     if ntiles >= nfields * 0.8;
    %         methods = [methods + 30, methods + 20, methods + 10, methods];
    %     else
    %         methods = [methods + 20, methods + 10, methods];
    %     end
    
%         methods = 2;
        methods = 24;
    


    nmethods = numel(methods);
    
    scores = inf(nmethods, 1);
    results = cell(nmethods, 2);
    
    for i = 1:nmethods; 
        method = methods(i);
        
        [b,o,s] = mysolver(tiles, boardSize, method);
        if s < 100;
            % bail out
            board = b;
            orientation = o;
            return;
        end
          
        scores(i) = s;
        results{i, 1} = b;
        results{i, 2} = o; 
    end
     
    [bestscore, pick] = min(scores);
    
    board       = results{pick, 1};
    orientation = results{pick, 2};
    
end


function [board, orientation, score] = mysolver(tiles, boardSize, pmethod)
    board = zeros(boardSize);
    orientation = ones(size(tiles,1), 1);
    boarde = board; 
    score = sum(tiles(:));
    
    nrows = boardSize(1);
    ncols = boardSize(2);
    
    start = floor(pmethod / 10);
    method = mod(pmethod, 10);
    
    ntiles = size(tiles, 1);
    
    %     [~, tilesperm] = sort(sum(tiles, 2), 'descend');
    %     tiles = tiles(tilesperm, :);
    
    % Kudos to Martin F. for quadrupling tiles
    tiles = [tiles; tiles(:,[2:4,1]); tiles(:,[3:4,1:2]); tiles(:,[4,1:3])];
    tilesvalues = sum(tiles, 2);
    tilestaken = false(4*ntiles, 1);
    
    % place initial tile 
    
    if start == 0;
        midrow = round(nrows./2);
        midcol = round(ncols./2);
        tileix = maxtile();
        
        placetile(tileix, midrow, midcol);
    elseif start == 1;
        % Again, Kudos to Martin F. for halving my score with this single loc.
        boarde(1,1) = 4;
    elseif start == 2;
        boarde(nrows,1) = 4;
        %         boarde(  1  ,  1  ) = 2;
        %         boarde(  1  ,ncols) = 2;
        %         boarde(nrows,  1  ) = 2;
        %         boarde(nrows,ncols) = 2;
    elseif start == 3;
        boarde(  1  ,  :  ) = 3e10;
        boarde(nrows,  :  ) = 3e10;
        boarde(  :  ,  1  ) = 3e10;
        boarde(  :  ,ncols) = 3e10;
        boarde(  1  ,  1  ) = 6e10;
        boarde(  1  ,ncols) = 6e10;
        boarde(nrows,  1  ) = 6e10;
        boarde(nrows,ncols) = 6e10;
%     elseif start == 4;
%         boarde(  1  ,  :  ) = 3e10;
%         boarde(nrows,  :  ) = 3e10;
%         boarde(  :  ,  1  ) = 3e10;
%         boarde(  :  ,ncols) = 3e10;
%         boarde(  1  ,  1  ) = 6e10;
%         boarde(  1  ,ncols) = 6e10;
%         boarde(nrows,  1  ) = 6e10;
%         boarde(nrows,ncols) = 6e10;
    end
     
    f = nextfield();
       
    while ~isempty(f) && ~all(tilestaken);
        nextrow = f(1);
        nextcol = f(2);
        
        tix = findbesttilefor(nextrow, nextcol);
        
        placetile(tix, nextrow, nextcol);
         
        f = nextfield();
    end
        
    function ret = findbesttilefor(r, c)
        if r > 1; 
            if board(r-1,c) > 0; nv = tiles(board(r-1,c), 3);
            else                 nv = nan;
            end
        else                     nv = 0;
        end
        if r < nrows;
            if board(r+1,c) > 0; sv = tiles(board(r+1,c), 1);
            else                 sv = nan;
            end
        else                     sv = 0;
        end
        if c > 1; 
            if board(r,c-1) > 0; wv = tiles(board(r,c-1), 2);
            else                 wv = nan;
            end
        else                     wv = 0;
        end 
        if c < ncols;
            if board(r,c+1) > 0; ev = tiles(board(r,c+1), 4);
            else                 ev = nan;
            end
        else                     ev = 0;
        end
          
        v = [nv, ev, sv, wv];
        
        tilecosts = bsxfun(@minus, tiles, v);
        tilecosts = abs(tilecosts); 
        tilecosts = mynansum(tilecosts, 2);
        tilecosts(tilestaken) = inf;
 
        [newerror, ret] = min(tilecosts - 1e-10*sum(tiles(:, isnan(v)), 2));
        newerror = ceil(newerror);
        
        score = score - sum(tiles(ret, ~isnan(v))) - mynansum(v, 2) + newerror;
    end
     
    function ret = maxtile()
        [~, ret] = max(tilesvalues(~tilestaken));
    end
    
    function ret = nextfield()
        [v, ix] = max(boarde(:));
        if v; ret = [mod(ix-1,nrows)+1, ceil(ix/nrows)];
%             fprintf(' %d %d\n', ret(1), ret(2)); 
        else  ret = []; 
        end
%         assert(isempty(ret) || (ret(1) > 0 && ret(1) <= nrows && ret(2) > 0 && ret(2) <= ncols));
    end
     
    function placetile(tileix, row, col)
        board(row, col) = tileix;
        boarde(row, col) = 0;
        
        switch method
            case 1; method1();
            case 2; method2a();method2b();method2c();
            case 3; method3();
            case 4; method4a();method4b();method4c();
            case 5; method5a();method5b();method5c();
        end
                
        poptile(tileix);
        
        function method1()
            % plain cross
            if row >   1   && ~board(row-1,col  ); boarde(row-1, col  ) = boarde(row-1, col  ) + 1; end;
            if row < nrows && ~board(row+1,col  ); boarde(row+1, col  ) = boarde(row+1, col  ) + 1; end;
            if col >   1   && ~board(row  ,col-1); boarde(row  , col-1) = boarde(row  , col-1) + 1; end;
            if col < ncols && ~board(row  ,col+1); boarde(row  , col+1) = boarde(row  , col+1) + 1; end;
%             assert(all(boarde(:)<=4));
        end
        function method2a()
            % count neighboring stones + diagonal bonus
            if row >   1   && ~board(row-1,col  ); boarde(row-1, col  ) = boarde(row-1, col  ) + 1; end;
            if row < nrows && ~board(row+1,col  ); boarde(row+1, col  ) = boarde(row+1, col  ) + 1; end;
            if col >   1   && ~board(row  ,col-1); boarde(row  , col-1) = boarde(row  , col-1) + 1; end;
            if col < ncols && ~board(row  ,col+1); boarde(row  , col+1) = boarde(row  , col+1) + 1; end;
        end
        function method2b()
            if row >   1   && col >   1   && ~board(row-1,col-1); boarde(row-1, col-1) = boarde(row-1, col-1) + 0.1; end;
            if row >   1   && col < ncols && ~board(row-1,col+1); boarde(row-1, col+1) = boarde(row-1, col+1) + 0.1; end;
        end
        function method2c()
            if row < nrows && col >   1   && ~board(row+1,col-1); boarde(row+1, col-1) = boarde(row+1, col-1) + 0.1; end;
            if row < nrows && col < ncols && ~board(row+1,col+1); boarde(row+1, col+1) = boarde(row+1, col+1) + 0.1; end;
        end
        function method3()
            % pricy stones
            if row >   1   && ~board(row-1,col  ); boarde(row-1, col  ) = boarde(row-1, col  ) + tiles(tileix, 1); end;
            if row < nrows && ~board(row+1,col  ); boarde(row+1, col  ) = boarde(row+1, col  ) + tiles(tileix, 3); end;
            if col >   1   && ~board(row  ,col-1); boarde(row  , col-1) = boarde(row  , col-1) + tiles(tileix, 4); end;
            if col < ncols && ~board(row  ,col+1); boarde(row  , col+1) = boarde(row  , col+1) + tiles(tileix, 2); end;
        end
        function method4a()
            % pricy stones + diagonal bonus
            if row >   1   && ~board(row-1,col  ); boarde(row-1, col  ) = boarde(row-1, col  ) + tiles(tileix, 1); end;
            if row < nrows && ~board(row+1,col  ); boarde(row+1, col  ) = boarde(row+1, col  ) + tiles(tileix, 3); end;
            if col >   1   && ~board(row  ,col-1); boarde(row  , col-1) = boarde(row  , col-1) + tiles(tileix, 4); end;
            if col < ncols && ~board(row  ,col+1); boarde(row  , col+1) = boarde(row  , col+1) + tiles(tileix, 2); end;
        end
        function method4b()
            if row >   1   && col >   1   && ~board(row-1,col-1); boarde(row-1, col-1) = boarde(row-1, col-1) + 0.1; end;
            if row >   1   && col < ncols && ~board(row-1,col+1); boarde(row-1, col+1) = boarde(row-1, col+1) + 0.1; end;
        end
        function method4c()
            if row < nrows && col >   1   && ~board(row+1,col-1); boarde(row+1, col-1) = boarde(row+1, col-1) + 0.1; end;
            if row < nrows && col < ncols && ~board(row+1,col+1); boarde(row+1, col+1) = boarde(row+1, col+1) + 0.1; end;
        end
        function method5a()
            % pricy stones + diagonal bonus
            if row >   1   && ~board(row-1,col  ); boarde(row-1, col  ) = boarde(row-1, col  ) + tiles(tileix, 1); end;
            if row < nrows && ~board(row+1,col  ); boarde(row+1, col  ) = boarde(row+1, col  ) + tiles(tileix, 3); end;
            if col >   1   && ~board(row  ,col-1); boarde(row  , col-1) = boarde(row  , col-1) + tiles(tileix, 4); end;
            if col < ncols && ~board(row  ,col+1); boarde(row  , col+1) = boarde(row  , col+1) + tiles(tileix, 2); end;
        end
        function method5b()
            if row >   1   && col >   1   && ~board(row-1,col-1); boarde(row-1, col-1) = boarde(row-1, col-1) + 2; end;
            if row >   1   && col < ncols && ~board(row-1,col+1); boarde(row-1, col+1) = boarde(row-1, col+1) + 2; end;
        end
        function method5c()
            if row < nrows && col >   1   && ~board(row+1,col-1); boarde(row+1, col-1) = boarde(row+1, col-1) + 2; end;
            if row < nrows && col < ncols && ~board(row+1,col+1); boarde(row+1, col+1) = boarde(row+1, col+1) + 2; end;
        end
    end
    
    function poptile(pix)
        ix = mod(pix-1, ntiles)+1; 
        o = ceil(pix/ntiles);
        orientation(ix) = o; 
        tilestaken(ix+ntiles*(0:3), :) = true;
    end  
     
    boardzeros = board == 0;
    board = mod(board-1, ntiles)+1;
    board(boardzeros) = 0; 

end

function m = mynansum(m, d)
    m(isnan(m)) = 0;
    m = sum(m, d);
end

function [board, orientation, score] = werner(tiles, boardSize)

    nmethods = 2;
    results = cell(nmethods, 3);
    
    i=1;
    [results{i,1} results{i,2} results{i,3}] = solver12a(tiles, boardSize);if results{i,3}<1,board = results{i, 1}; orientation = results{i, 2}; score = results{i, 3};return,end
    i=2;
    [results{i,1} results{i,2} results{i,3}] = solver13a(tiles, boardSize);if results{i,3}<1,board = results{i, 1}; orientation = results{i, 2}; score = results{i, 3};return,end
    %i=3;
    %[results{i,1} results{i,2} results{i,3}] = solver14(tiles, boardSize);if results{i,3}<1,board = results{i, 1}; orientation = results{i, 2}; score = results{i, 3};return,end
    %i=4;
    %[results{i,1} results{i,2} results{i,3}] = solver16(tiles, boardSize);if results{i,3}<1,board = results{i, 1}; orientation = results{i, 2}; score = results{i, 3};return,end

    
    
    
    
%     [bestscore, pick] = min([results{:,3}]);
%     
%     i=5;
%     
%     [results{i,1} results{i,2} results{i,3}] = solver15_new(tiles, boardSize, results{pick,1}, results{pick,2});
%     
%     
%     %i=6;
%     
%     %[bestscore, pick] = min([results{:,3}]);
%     %[results{i,1} results{i,2} results{i,3}] = solver15a(tiles, boardSize, results{pick,1}, results{pick,2});
%     
%     
%        
     [~, pick] = min([results{:,3}]);
%     if pick==5,disp('YUHUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU'),end
%     if pick==6,disp('AHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH'),end
%     
%     pick = 5;
    
    board       = results{pick, 1};
    orientation = results{pick, 2};
    score = results{pick, 3};
end

function [board orientation score] = solver12a(tiles, boardSize)
       
    board = zeros(boardSize);
    orientation = ones(size(tiles,1), 1);
    score = sum(tiles(:));
    
    nrows = boardSize(1);
    ncols = boardSize(2);
    
    ntiles = size(tiles, 1);
    tiles = [tiles; tiles(:,[2:4,1]); tiles(:,[3:4,1:2]); tiles(:,[4,1:3])];
    tilestaken = false(4*ntiles, 1);

    boarde = board;
    boarde(1,1) = 4;
 
    f = nextfield();
       
    while ~isempty(f) && ~all(tilestaken);
        nextrow = f(1);
        nextcol = f(2);
        tix = findbesttilefor(nextrow, nextcol);
        placetile(tix, nextrow, nextcol);
        f = nextfield();
    end
        
    function ret = findbesttilefor(r, c)
        if r > 1; 
            if board(r-1,c) > 0; nv = tiles(board(r-1,c), 3);
            else                 nv = nan;
            end
        else                     nv = 0;
        end
        if r < nrows;
            if board(r+1,c) > 0; sv = tiles(board(r+1,c), 1);
            else                 sv = nan;
            end
        else                     sv = 0;
        end
        if c > 1;
            if board(r,c-1) > 0; wv = tiles(board(r,c-1), 2);
            else                 wv = nan;
            end
        else                     wv = 0;
        end 
        if c < ncols;
            if board(r,c+1) > 0; ev = tiles(board(r,c+1), 4);
            else                 ev = nan;
            end
        else                     ev = 0;
        end
        
        v = [nv, ev, sv, wv];
        mask = ~isnan(v);
        tilecosts = sum(abs(bsxfun(@minus, tiles(:,mask), v(mask))), 2);
        tilecosts(tilestaken) = inf;       
        [newerror, ret] = min(tilecosts-sum(tiles,2).*1e-6);
        score = score - sum(tiles(ret, ~isnan(v))) - mynansum(v,2) + newerror;
    end
    
    function ret = nextfield()
        [v, ix] = max(boarde(:));
        if v;ret = ixtorc(ix);else ret = [];end
    end
    
    function ret = ixtorc(ix)
        ret = [mod(ix-1,nrows)+1, ceil(ix/nrows)];
    end
    
    function placetile(tileix, row, col)
        board(row, col) = tileix;
        boarde(row, col) = 0;

        placetile1(tileix, row, col)
        placetile2(row, col)
        placetile3(row, col)
        
        poptile(tileix);
    end  
    
    function placetile1(tileix, row, col)
        if row >   1   && ~board(row-1,col  ); boarde(row-1, col  ) = boarde(row-1, col  ) + tiles(tileix, 1); end;
        if row < nrows && ~board(row+1,col  ); boarde(row+1, col  ) = boarde(row+1, col  ) + tiles(tileix, 3); end;
        if col >   1   && ~board(row  ,col-1); boarde(row  , col-1) = boarde(row  , col-1) + tiles(tileix, 4); end;
        if col < ncols && ~board(row  ,col+1); boarde(row  , col+1) = boarde(row  , col+1) + tiles(tileix, 2); end;
    end
    
    function placetile2(row, col)
        if row >   1   && col >   1   && ~board(row-1,col-1); boarde(row-1, col-1) = boarde(row-1, col-1) + 0.1; end;
        if row >   1   && col < ncols && ~board(row-1,col+1); boarde(row-1, col+1) = boarde(row-1, col+1) + 0.1; end;
    end
    
    function placetile3(row, col)
        if row < nrows && col >   1   && ~board(row+1,col-1); boarde(row+1, col-1) = boarde(row+1, col-1) + 0.1; end;
        if row < nrows && col < ncols && ~board(row+1,col+1); boarde(row+1, col+1) = boarde(row+1, col+1) + 0.1; end;
    end

    function poptile(pix)
        ix = mod(pix-1, ntiles)+1;
        o = ceil(pix/ntiles);
        orientation(ix) = o; 
        tilestaken(ix+ntiles*(0:3), :) = true;
    end 
    
    boardzeros = board == 0;
    board = mod(board-1, ntiles)+1;
    board(boardzeros) = 0;
    
end

function [board orientation score] = solver13a(tiles, boardSize)
    
    board = zeros(boardSize);
    orientation = ones(size(tiles,1), 1);
    score = sum(tiles(:));
    
    nrows = boardSize(1);
    ncols = boardSize(2);
    
    ntiles = size(tiles, 1);
    tiles = [tiles; tiles(:,[2:4,1]); tiles(:,[3:4,1:2]); tiles(:,[4,1:3])];
    tilestaken = false(4*ntiles, 1);

    boardSize_orig = boardSize;
    nrows_orig = boardSize_orig(1);
    ncols_orig = boardSize_orig(2);
    if ntiles<nrows*ncols
        rectangles=[repmat(1:nrows_orig,1,ncols_orig);repmat(1:ncols_orig,1,nrows_orig)];
        rectangles_area = prod(rectangles);
        rectangles_area(rectangles_area<ntiles)=inf;
        [~,b] = min(rectangles_area-ntiles+2*sum(rectangles));
        
        boardSize=rectangles(:,b)';
        board = zeros(boardSize);
        nrows = boardSize(1);
        ncols = boardSize(2);
    end
 
    boarde = board;
    try
    boarde(:,3) = 10.^6./8;
    boarde(:,ncols-2) = 10.^6./8;
    boarde(3,:) = 10.^6./8;
    boarde(nrows-2,:) = 10.^6./8;
    boarde(:,2) = 10.^6./4;
    boarde(:,ncols-1) = 10.^6./4;
    boarde(2,:) = 10.^6./4;
    boarde(nrows-1,:) = 10.^6./4;
    boarde(:,1) = 10.^6./2;
    boarde(:,ncols) = 10.^6./2;
    boarde(1,:) = 10.^6./2;
    boarde(nrows,:) = 10.^6./2;
    boarde(1,1) = 10.^6;
    boarde(1,ncols) = 10.^6;
    boarde(nrows,1) = 10.^6;
    boarde(nrows,ncols) = 10.^6;
    end
    if size(boarde,1)~=size(board,1) | size(boarde,2)~=size(board,2)
        boarde = zeros(size(board));
    end
    
    f = nextfield();
       
    while ~isempty(f) && ~all(tilestaken);
        nextrow = f(1);
        nextcol = f(2);
        tix = findbesttilefor(nextrow, nextcol);
        placetile(tix, nextrow, nextcol);
        f = nextfield();
    end
    
    
    
    if ntiles<nrows_orig*ncols_orig
        board_pimp=board;
        board = zeros(boardSize_orig);
        board(1:nrows,1:ncols)=board_pimp;
    end
    
    boardzeros = board == 0;
    board = mod(board-1, ntiles)+1;
    board(boardzeros) = 0;    
    
    function ret = findbesttilefor(r, c)
        if r > 1; 
            if board(r-1,c) > 0; nv = tiles(board(r-1,c), 3);
            else                 nv = nan;
            end
        else                     nv = 0;
        end
        if r < nrows;
            if board(r+1,c) > 0; sv = tiles(board(r+1,c), 1);
            else                 sv = nan;
            end
            
        else                     sv = 0;
        end
        if c > 1;
            if board(r,c-1) > 0; wv = tiles(board(r,c-1), 2);
            else                 wv = nan;
            end
        else                     wv = 0;
        end 
        if c < ncols;
            if board(r,c+1) > 0; ev = tiles(board(r,c+1), 4);
            else                 ev = nan;
            end
        else                     ev = 0;
        end
        v = [nv, ev, sv, wv];
        mask = ~isnan(v);
        tilecosts = sum(abs(bsxfun(@minus, tiles(:,mask), v(mask))), 2);
        tilecosts(tilestaken) = inf;       
        [newerror, ret] = min(tilecosts-sum(tiles,2).*1e-6);
        score = score - sum(tiles(ret, ~isnan(v))) - mynansum(v,2) + newerror;
    end
    
    function ret = nextfield()
        [v, ix] = max(boarde(:));
        if v;ret = ixtorc(ix);else ret = [];end
    end
    
    function ret = ixtorc(ix)
        ret = [mod(ix-1,nrows)+1, ceil(ix/nrows)];
    end
    
    function placetile(tileix, row, col)
        board(row, col) = tileix;
        boarde(row, col) = 0;

        placetile1(tileix, row, col)
        placetile2(row, col)
        placetile3(row, col)
        
        poptile(tileix);
    end  
    
    function placetile1(tileix, row, col)
        if row >   1   && ~board(row-1,col  ); boarde(row-1, col  ) = boarde(row-1, col  ) + tiles(tileix, 1); end;
        if row < nrows && ~board(row+1,col  ); boarde(row+1, col  ) = boarde(row+1, col  ) + tiles(tileix, 3); end;
        if col >   1   && ~board(row  ,col-1); boarde(row  , col-1) = boarde(row  , col-1) + tiles(tileix, 4); end;
        if col < ncols && ~board(row  ,col+1); boarde(row  , col+1) = boarde(row  , col+1) + tiles(tileix, 2); end;
    end
    
    function placetile2(row, col)
        if row >   1   && col >   1   && ~board(row-1,col-1); boarde(row-1, col-1) = boarde(row-1, col-1) + 2; end;
        if row >   1   && col < ncols && ~board(row-1,col+1); boarde(row-1, col+1) = boarde(row-1, col+1) + 2; end;
    end
    
    function placetile3(row, col)
        if row < nrows && col >   1   && ~board(row+1,col-1); boarde(row+1, col-1) = boarde(row+1, col-1) + 2; end;
        if row < nrows && col < ncols && ~board(row+1,col+1); boarde(row+1, col+1) = boarde(row+1, col+1) + 2; end;
    end

    
    function poptile(pix)
        ix = mod(pix-1, ntiles)+1;
        o = ceil(pix/ntiles);
        orientation(ix) = o; 
        tilestaken(ix+ntiles*(0:3), :) = true;
    end  
end

function [board orientation score] = solver14(tiles, boardSize)
       
    board = zeros(boardSize);
    orientation = ones(size(tiles,1), 1);
    score = sum(tiles(:));
    
    nrows = boardSize(1);
    ncols = boardSize(2);
    
    ntiles = size(tiles, 1);
    tiles = [tiles; tiles(:,[2:4,1]); tiles(:,[3:4,1:2]); tiles(:,[4,1:3])];
    tilestaken = false(4*ntiles, 1);

    boarde = board;
    boarde(ceil(nrows./2),ceil(ncols./2)) = 4;
 
    f = nextfield();
       
    while ~isempty(f) && ~all(tilestaken);
        nextrow = f(1);
        nextcol = f(2);
        tix = findbesttilefor(nextrow, nextcol);
        placetile(tix, nextrow, nextcol);
        f = nextfield();
    end
        
    function ret = findbesttilefor(r, c)
        if r > 1; 
            if board(r-1,c) > 0; nv = tiles(board(r-1,c), 3);
            else                 nv = nan;
            end
        else                     nv = 0;
        end
        if r < nrows;
            if board(r+1,c) > 0; sv = tiles(board(r+1,c), 1);
            else                 sv = nan;
            end
        else                     sv = 0;
        end
        if c > 1;
            if board(r,c-1) > 0; wv = tiles(board(r,c-1), 2);
            else                 wv = nan;
            end
        else                     wv = 0;
        end 
        if c < ncols;
            if board(r,c+1) > 0; ev = tiles(board(r,c+1), 4);
            else                 ev = nan;
            end
        else                     ev = 0;
        end
        v = [nv, ev, sv, wv];
        mask = ~isnan(v);
        tilecosts = sum(abs(bsxfun(@minus, tiles(:,mask), v(mask))), 2);
        tilecosts(tilestaken) = inf;       
        [newerror, ret] = min(tilecosts-sum(tiles,2).*1e-6);
        score = score - sum(tiles(ret, ~isnan(v))) - mynansum(v,2) + newerror;
    end
    
    function ret = nextfield()
        [v, ix] = max(boarde(:));
        if v;ret = ixtorc(ix);else ret = [];end
    end
    
    function ret = ixtorc(ix)
        ret = [mod(ix-1,nrows)+1, ceil(ix/nrows)];
    end
    
    function placetile(tileix, row, col)
        board(row, col) = tileix;
        boarde(row, col) = 0;

        placetile1(tileix, row, col)
        placetile2(row, col)
        placetile3(row, col)
        
        poptile(tileix);
    end  
    
    function placetile1(tileix, row, col)
        if row >   1   && ~board(row-1,col  ); boarde(row-1, col  ) = boarde(row-1, col  ) + tiles(tileix, 1); end;
        if row < nrows && ~board(row+1,col  ); boarde(row+1, col  ) = boarde(row+1, col  ) + tiles(tileix, 3); end;
        if col >   1   && ~board(row  ,col-1); boarde(row  , col-1) = boarde(row  , col-1) + tiles(tileix, 4); end;
        if col < ncols && ~board(row  ,col+1); boarde(row  , col+1) = boarde(row  , col+1) + tiles(tileix, 2); end;
    end
    
    function placetile2(row, col)
        if row >   1   && col >   1   && ~board(row-1,col-1); boarde(row-1, col-1) = boarde(row-1, col-1) + 0.1; end;
        if row >   1   && col < ncols && ~board(row-1,col+1); boarde(row-1, col+1) = boarde(row-1, col+1) + 0.1; end;
    end
    
    function placetile3(row, col)
        if row < nrows && col >   1   && ~board(row+1,col-1); boarde(row+1, col-1) = boarde(row+1, col-1) + 0.1; end;
        if row < nrows && col < ncols && ~board(row+1,col+1); boarde(row+1, col+1) = boarde(row+1, col+1) + 0.1; end;
    end

    function poptile(pix)
        ix = mod(pix-1, ntiles)+1;
        o = ceil(pix/ntiles);
        orientation(ix) = o; 
        tilestaken(ix+ntiles*(0:3), :) = true;
    end 
    
    boardzeros = board == 0;
    board = mod(board-1, ntiles)+1;
    board(boardzeros) = 0;
    
end

function [board orientation score] = solver16(tiles, boardSize)
    
    board = zeros(boardSize);
    orientation = ones(size(tiles,1), 1);
    score = sum(tiles(:));
    
    nrows = boardSize(1);
    ncols = boardSize(2);
    
    ntiles = size(tiles, 1);
    tiles = [tiles; tiles(:,[2:4,1]); tiles(:,[3:4,1:2]); tiles(:,[4,1:3])];
    tilesvalues = sum(tiles, 2);
    tilestaken = false(4*ntiles, 1);

    boardSize_orig = boardSize;
    nrows_orig = boardSize_orig(1);
    ncols_orig = boardSize_orig(2);
    if ntiles<nrows*ncols
        rectangles=[repmat(1:nrows_orig,1,ncols_orig);repmat(1:ncols_orig,1,nrows_orig)];
        rectangles_area = prod(rectangles);
        rectangles_area(rectangles_area<ntiles)=inf;
        [~,b] = min(rectangles_area-ntiles+2*sum(rectangles));
        
        boardSize=rectangles(:,b)';
        board = zeros(boardSize);
        nrows = boardSize(1);
        ncols = boardSize(2);
    end
    
    
    boarde = board; % boardedgesoccupied
    boarde(:,1) = 10.^6./2;
    boarde(:,ncols) = 10.^6./2;
    boarde(1,:) = 10.^6./2;
    boarde(nrows,:) = 10.^6./2;
    boarde(1,1) = 10.^6;
    boarde(1,ncols) = 10.^6;
    boarde(nrows,1) = 10.^6;
    boarde(nrows,ncols) = 10.^6;
 
    boarde(ceil(nrows./2),ceil(ncols./2)) = 10.^7;
    
    f = nextfield();
       
    while ~isempty(f) && ~all(tilestaken);
        nextrow = f(1);
        nextcol = f(2);
        tix = findbesttilefor(nextrow, nextcol);
        placetile(tix, nextrow, nextcol);
        f = nextfield();
    end
    
    if ntiles<nrows_orig*ncols_orig
        board_pimp=board;
        board = zeros(boardSize_orig);
        board(1:nrows,1:ncols)=board_pimp;
    end
    
        
    function ret = findbesttilefor(r, c)
        if r > 1; 
            if board(r-1,c) > 0; nv = tiles(board(r-1,c), 3);
            else                 nv = nan;
            end
        else                     nv = 0;
        end
        if r < nrows;
            if board(r+1,c) > 0; sv = tiles(board(r+1,c), 1);
            else                 sv = nan;
            end
        else                     sv = 0;
        end
        if c > 1;
            if board(r,c-1) > 0; wv = tiles(board(r,c-1), 2);
            else                 wv = nan;
            end
        else                     wv = 0;
        end 
        if c < ncols;
            if board(r,c+1) > 0; ev = tiles(board(r,c+1), 4);
            else                 ev = nan;
            end
        else                     ev = 0;
        end
        v = [nv, ev, sv, wv];
        mask = ~isnan(v);
        tilecosts = sum(abs(bsxfun(@minus, tiles(:,mask), v(mask))), 2);
        tilecosts(tilestaken) = inf;       
        [newerror, ret] = min(tilecosts-sum(tiles,2).*1e-6);
        score = score - sum(tiles(ret, ~isnan(v))) - mynansum(v,2) + newerror;
    end
    
    function ret = nextfield()
        [v, ix] = max(boarde(:));
        if v;ret = ixtorc(ix);else ret = [];end
    end
    
    function ret = ixtorc(ix)
        ret = [mod(ix-1,nrows)+1, ceil(ix/nrows)];
    end
    
    function placetile(tileix, row, col)
        board(row, col) = tileix;
        boarde(row, col) = 0;

        placetile1(tileix, row, col)
        placetile2(row, col)
        placetile3(row, col)
        
        poptile(tileix);
    end
    
    function placetile1(tileix, row, col)
        if row >   1   && ~board(row-1,col  ); boarde(row-1, col  ) = boarde(row-1, col  ) + tiles(tileix, 1); end;
        if row < nrows && ~board(row+1,col  ); boarde(row+1, col  ) = boarde(row+1, col  ) + tiles(tileix, 3); end;
        if col >   1   && ~board(row  ,col-1); boarde(row  , col-1) = boarde(row  , col-1) + tiles(tileix, 4); end;
        if col < ncols && ~board(row  ,col+1); boarde(row  , col+1) = boarde(row  , col+1) + tiles(tileix, 2); end;
    end
    
    function placetile2(row, col)
        if row >   1   && col >   1   && ~board(row-1,col-1); boarde(row-1, col-1) = boarde(row-1, col-1) + 0.1; end;
        if row >   1   && col < ncols && ~board(row-1,col+1); boarde(row-1, col+1) = boarde(row-1, col+1) + 0.1; end;
    end
    
    function placetile3(row, col)
        if row < nrows && col >   1   && ~board(row+1,col-1); boarde(row+1, col-1) = boarde(row+1, col-1) + 0.1; end;
        if row < nrows && col < ncols && ~board(row+1,col+1); boarde(row+1, col+1) = boarde(row+1, col+1) + 0.1; end;
    end
    
    function poptile(pix)
        ix = mod(pix-1, ntiles)+1;
        o = ceil(pix/ntiles);
        orientation(ix) = o; 
        tilestaken(ix+ntiles*(0:3), :) = true;
    end 
    
    boardzeros = board == 0;
    board = mod(board-1, ntiles)+1;
    board(boardzeros) = 0;
    
end


function ret = mynansum(m, d)
    m(isnan(m)) = 0;
    ret = sum(m, d);
end