Guest User

Untitled

a guest
Dec 15th, 2018
219
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
MatLab 7.55 KB | None | 0 0
  1. x = cell2mat(importdata('input.txt'));
  2.  
  3. E       = 200*(x=='E');   % Elves
  4. G       = 200*(x=='G');   % Goblins
  5. W       = x=='#';         % Walls
  6. nElves  = length(find(E));
  7.  
  8. attackPowerElves  = 3;
  9. [round,Enew,Gnew] = doBattle(E,G,W,attackPowerElves);
  10. disp((round-1)*(sum(sum(Enew))+sum(sum(Gnew)))) % Part 1
  11.  
  12. while 1
  13.     attackPowerElves = attackPowerElves + 1;
  14.     [round,Enew,Gnew] = doBattle(E,G,W,attackPowerElves);
  15.     if length(find(Enew))==nElves
  16.         disp((round-1)*(sum(sum(Enew))+sum(sum(Gnew)))) % part 2
  17.         break
  18.     end
  19. end
  20.  
  21. function d = distanceToTarget(r,c,Z)
  22. d       = zeros(size(Z,1),size(Z,2));
  23. d(r,c)  = 1;
  24. iter    = 0;
  25. while 1
  26.     iter = iter + 1;
  27.     dnew = d + iter*( ([zeros(1,size(d,2));d(1:end-1,:)]|...
  28.         [d(2:end,:);zeros(1,size(d,2))]|...
  29.         [d(:,2:end),zeros(size(d,1),1)]|...
  30.         [zeros(size(d,1),1),d(:,1:end-1)])...
  31.         & ~Z & ~d);
  32.     if isequal(d,dnew)
  33.         break
  34.     else
  35.         d = dnew;
  36.     end
  37. end
  38.  
  39. d(d==0)= 9999;
  40. d(r,c) = 0;
  41. end
  42.  
  43. function [round,E,G] = doBattle(E,G,W,attackPowerElves)
  44.  
  45. round = 0;
  46. battleFinished = false;
  47. while ~battleFinished
  48.     round = round + 1;
  49.     % Determine order for this round
  50.     [order_c,order_r] = find(G'|E');
  51.    
  52.     for unit = 1:length(order_c)
  53.         row = order_r(unit);
  54.         col = order_c(unit);
  55.         newRow = row;
  56.         newCol = col;
  57.        
  58.         if E(row,col)
  59.             % current unit is an Elf, target the Goblins
  60.             T = G;
  61.         elseif G(row,col)
  62.             % current unit is a Goblin, target the Elves
  63.             T = E;
  64.         else
  65.             % The unit that was here at the start of the round has died,
  66.             % skip this unit.
  67.             %disp('Dead units cannot take turns')
  68.             continue
  69.         end
  70.        
  71.         if ~any(T(:))
  72.             disp('No more targets found. Battle finished.')
  73.             battleFinished = true;
  74.             break
  75.         end
  76.        
  77.         % Determine squares that are in range:
  78.         z_occ = E | G | W;
  79.         z_occ(row,col) = false;
  80.        
  81.         inRange = ([zeros(1,size(T,2));T(1:end-1,:)]|...
  82.             [T(2:end,:);zeros(1,size(T,2))]|...
  83.             [T(:,2:end),zeros(size(T,1),1)]|...
  84.             [zeros(size(T,1),1),T(:,1:end-1)])...
  85.             & ~z_occ;
  86.        
  87.         if inRange(row,col)
  88.             % Unit already in range, no movement required.
  89.         else
  90.             if ~any(inRange(:))
  91.                 % Unit not in range and no places to go, end turn
  92.                 %disp('No squares in range, ending turn.')
  93.                 continue
  94.             else
  95.                 % move
  96.                
  97.                 % Determine distance to all squares that are in range:
  98.                 [idx_c,idx_r]   = find(inRange');
  99.                 minSteps        = inf;
  100.                 bestTarget_r    = 0;
  101.                 bestTarget_c    = 0;
  102.                 bestD           = 0;
  103.                 for i=1:length(idx_r)
  104.                     % exclude current unit position from obstacles send to
  105.                     % distance function
  106.                     z               = E|G|W;
  107.                     z(row,col)      = false; % exclude own location as obstacle
  108.                     d               = distanceToTarget(idx_r(i),idx_c(i),z);
  109.                    
  110.                     min_distance    = min([d(row-1,col),d(row+1,col),d(row,col-1),d(row,col+1)]);
  111.                    
  112.                     if min_distance<minSteps
  113.                         minSteps        = min_distance;
  114.                         bestTarget_r    = idx_r(i);
  115.                         bestTarget_c    = idx_c(i);
  116.                         bestD           = d;
  117.                     end
  118.                 end
  119.                 if minSteps == 9999
  120.                     %disp('No path found, ending turn.')
  121.                     continue
  122.                 end
  123.                
  124.                 % Take step towards [bestTarget_r,bestTarget_c]
  125.                
  126.                 if bestD(row-1,col)==minSteps
  127.                     if E(row,col)
  128.                         E(row-1,col) = E(row,col);
  129.                         E(row,col)   = 0;
  130.                         newRow       = row-1;
  131.                         newCol       = col;
  132.                     else
  133.                         G(row-1,col) = G(row,col);
  134.                         G(row,col)   = 0;
  135.                         newRow       = row-1;
  136.                         newCol       = col;
  137.                     end
  138.                 elseif bestD(row,col-1)==minSteps
  139.                     if E(row,col)
  140.                         E(row,col-1) = E(row,col);
  141.                         E(row,col)   = 0;
  142.                         newRow       = row;
  143.                         newCol       = col-1;
  144.                     else
  145.                         G(row,col-1) = G(row,col);
  146.                         G(row,col)   = 0;
  147.                         newRow       = row;
  148.                         newCol       = col-1;
  149.                     end
  150.                 elseif bestD(row,col+1)==minSteps
  151.                     if E(row,col)
  152.                         E(row,col+1) = E(row,col);
  153.                         E(row,col)   = 0;
  154.                         newRow       = row;
  155.                         newCol       = col+1;
  156.                     else
  157.                         G(row,col+1) = G(row,col);
  158.                         G(row,col)   = 0;
  159.                         newRow       = row;
  160.                         newCol       = col+1;
  161.                     end
  162.                 elseif bestD(row+1,col)==minSteps
  163.                     if E(row,col)
  164.                         E(row+1,col) = E(row,col);
  165.                         E(row,col)   = 0;
  166.                         newRow       = row+1;
  167.                         newCol       = col;
  168.                     else
  169.                         G(row+1,col) = G(row,col);
  170.                         G(row,col)   = 0;
  171.                         newRow       = row+1;
  172.                         newCol       = col;
  173.                     end
  174.                 else
  175.                     disp('something went wrong here...')
  176.                 end
  177.                
  178.             end
  179.         end
  180.         % Fight:
  181.         minHP = inf;
  182.         enemy_r = 0;
  183.         enemy_c = 0;
  184.         if T(newRow-1,newCol)
  185.             if T(newRow-1,newCol)<minHP
  186.                 minHP = T(newRow-1,newCol);
  187.                 enemy_r = newRow-1;
  188.                 enemy_c = newCol;
  189.             end
  190.         end
  191.         if T(newRow,newCol-1)
  192.             if T(newRow,newCol-1)<minHP
  193.                 minHP = T(newRow,newCol-1);
  194.                 enemy_r = newRow;
  195.                 enemy_c = newCol-1;
  196.             end
  197.         end
  198.         if T(newRow,newCol+1)
  199.             if T(newRow,newCol+1)<minHP
  200.                 minHP = T(newRow,newCol+1);
  201.                 enemy_r = newRow;
  202.                 enemy_c = newCol+1;
  203.             end
  204.         end
  205.         if T(newRow+1,newCol)
  206.             if T(newRow+1,newCol)<minHP
  207.                 minHP = T(newRow+1,newCol);
  208.                 enemy_r = newRow+1;
  209.                 enemy_c = newCol;
  210.             end
  211.         end
  212.        
  213.         if minHP==inf
  214.             % No targets, end turn.
  215.             continue
  216.         end
  217.        
  218.         if E(enemy_r,enemy_c)
  219.             E(enemy_r,enemy_c) = E(enemy_r,enemy_c) - 3;
  220.             if E(enemy_r,enemy_c)<1
  221.                 E(enemy_r,enemy_c) = 0;
  222.             end
  223.         else
  224.             G(enemy_r,enemy_c) = G(enemy_r,enemy_c) - attackPowerElves;
  225.             if G(enemy_r,enemy_c)<1
  226.                 G(enemy_r,enemy_c) = 0;
  227.             end
  228.         end
  229.     end
  230.     if battleFinished
  231.         break
  232.     end
  233. end
  234. end
Advertisement
Add Comment
Please, Sign In to add comment