function game

% ---- This file constitutes the driver (tester) along with
% ---- the game simulation

% --------- Initialization Phase -------------------
% --- If file top10.txt does not exist, create it --

top10 = 'top10.txt';
if ~exist(top10)
   p(1).name = 'Jim Brown';
   p(1).score = 23;
   p(2).name = 'Sarah Finn';
   p(2).score = 27;
   p(3).name = 'Billy Club';
   p(3).score = 31;
   plen = length(p);
   fid = fopen(top10,'w');

   for ii = 1:plen
      fprintf(fid, '%s, %d\n', p(ii).name, p(ii).score);
   end

   fclose(fid);
end

% --- If file moves.txt does not exist, create it --

moves = 'moves.txt';
if ~exist('moves.txt')
   m(1) = "a,n";
   m(2) = "s,s";
   m(3) = "a,e";
   m(4) = "s,n";
   mlen = length(m);
   fid = fopen('moves.txt','w');

   for ii = 1:mlen
      fprintf(fid, '%s\n', m(ii));
   end

   fclose(fid);
end

% --- Initialize the maze and player namea ----------
maze = [0 1 0 0 0 0; 0 0 3 1 1 0; 0 1 0 0 0 1; 2 0 0 1 0 1];

playerName = 'Chuck Riedesel';

[newTop10, newMaze] = playGame(moves, top10, maze, playerName);

fprintf('new top 10 file: %s\n', newTop10)
fprintf('updated maze: \n')
disp(newMaze)
end

% ----------------------------------------------------------
% ---------- the game function itself ----------------------

function [newTop10, newMaze] = playGame(moves, top10, maze, playerName)

% --- Naming some constants is good practice -------

OPEN = 0;
WALL = 1;
PLAYER = 2;
GOAL = 3;

ROW = 1;
COL = 2;

newTop10 = top10;                        % Assume same file name
[rows, cols] = size(maze);
newMaze = repmat(WALL, rows+2, cols+2);  % Embed maze inside a "wall"
newMaze(2:end-1, 2:end-1) = maze;
pos = [rows+1, 2];
ii = 0;

% --- Bring in and process the moves until goal found or file ends

fid = fopen(moves);
while ~feof(fid) && newMaze(pos(ROW), pos(COL)) ~= GOAL 
   disp(newMaze(2:end-1, 2:end-1))
   ii = ii+1;
   st = fgetl(fid);
   type = st(1);                         % type is a: all or s: single
   dir = st(3);                          % dir is n, s, e, or w
   switch dir
      case 'n' 
         vec = [-1 0];
      case 's' 
         vec = [1 0];
      case 'e' 
         vec = [0 1];
      case 'w' 
         vec = [0 -1];
   end
   newPos = pos + vec;                   % newPos is the next step
   newMaze(pos(ROW), pos(COL)) = OPEN;   % clear current position
   switch type
      case 's'                           % single step, just an if
         if newMaze(newPos(ROW), newPos(COL)) ~= WALL 
            pos = newPos;
         end
      case 'a'                           % many step, need a while
         while newMaze(newPos(ROW), newPos(COL)) ~= WALL
            pos = newPos;
            newPos = pos + vec;
         end
   end
   if newMaze(pos(ROW), pos(COL)) == OPEN  % new player position
      newMaze(pos(ROW), pos(COL)) = PLAYER;
   end
end
fclose(fid);

% --- End of simulation loop, time for wrap up -------

if newMaze(pos(ROW), pos(COL)) == GOAL
   disp('goal!')
   updateTop10(newTop10, top10, playerName, ii)   
else
   disp('lose!')
end

newMaze = newMaze(2:end-1, 2:end-1);

end

% ------------------------------------------------------------
% ---------- function to update the top 10 list --------------

function updateTop10(newTop10, top10, playerName, score)

NAME = 1;
SCORE = 2;

% --- Bring in top 10 from file ----------------

fid = fopen(top10);
ii = 1;
tops(ii).name = 'Z';             % Fake line avoids overshooting
tops(ii).score = -1;
while ~feof(fid)
   ii = ii + 1;
   st = fgetl(fid);
   st = strsplit(st, ',');
   tops(ii).name = st{NAME};
   tops(ii).score = eval(st{SCORE});
end
ii = ii + 1;
tops(ii).name = 'Z';             % Fake line avoids overshooting
tops(ii).score = inf;
fclose(fid);

% --- Use insertion sort strategy to place new good score ---
while score < tops(ii).score
  tops(ii+1) = tops(ii);
  ii = ii - 1;
end
tops(ii+1).name = playerName;
tops(ii+1).score = score;

% --- Send updated top 10 back out to file -----------
fid = fopen(newTop10, 'w');
ii = 2;
while tops(ii).score < inf && ii < 12
   fprintf('%s  %d\n', tops(ii).name, tops(ii).score);
   fprintf(fid, '%s, %d\n', tops(ii).name, tops(ii).score);
   ii = ii+1;
end
fclose(fid);

end

