%ttt3.mf
mode_setup; if not known screen_topleft:
message "screen_topleft undefined, defaults to (-50,300)";
pair screen_topleft; screen_topleft:=(-50,300); fi;

%%A program should cope with inproper inputs, preconditions, etc.,
%%gracefully.  For example, as said above, I assume that {\tt
%%screen\_topleft} has been compiled into {\tt mf.base}. If not, I set
%%it to the value appropriate for the standard {\tt plain.mf} which is 
%%used to creat the base file.  The message is just meant to give the
%%user a clue, more information could well be given.
%%
%%Our first task is to draw the `\#' we're going to play on. 
%%First, let's change the origin's position:
%%currently it is {\tt -xpart screen\_topleft} over from the left edge
%%and {\tt screen\_rows - ypart screen\_topleft} pixels up from the
%%bottom edge. To move the origin close to the bottom left corner, we
%%can set:

currenttransform:=identity shifted (20+xpart
  screen_topleft, 20-screen_rows + ypart screen_topleft);
ttt:=min(screen_rows, screen_cols)-40;

%%\noindent Now, let's draw the `board' using a for loop. We'll worry
%%about generalizing later.

for i=1,2: draw (0,i*ttt/3)..(ttt,i*ttt/3);
draw (i*ttt/3,0)..(i*ttt/3,ttt); endfor;
%We will want to do some experimenting now so 
%first save the current picture:
picture tttboard; tttboard:=currentpicture;
path ttto,tttxa,tttxb;
ttto:=fullcircle scaled (.8*ttt/3) shifted (ttt/6,ttt/6);
draw ttto;

%%\noindent The predefined {\tt fullcircle} is a circle of diameter 1
%%centered at 
%%the origin. We shift it to the center of the bottom left square after 
%%scaling it to an appropriate size. 

tttxa:=(20,20)..(ttt/3-20,ttt/3-20);
tttxb:=(20,ttt/3-20)..(ttt/3-20,20);
draw tttxa shifted (ttt/3,ttt/3);
draw tttxb shifted (ttt/3,ttt/3);
sscreen(80pt#,40pt#,2pt#,1);

%%\font\tttthree=ttt3 scaled 1200 
%%\vglue .7in\line{\hfil\hfil\tttthree A\hfil}\vglue 24pt
%%Now we're ready to actually play the game. The users need to be able
%%to 1) start a new game, 2) make a move, and 3) undo a move. Let's have
%%the user enter two digits to determine this:

message "enter 00 to quit, 10 to start new game";
message "enter 11 to place mark at bottom left square";
message "enter -33 to erase mark just placed at top right square";

%%The erasing is there so the user won't get frustrated by careless
%%mistakes. The program will alternate the marks, starting with an
%%`X'.  I purposely use Cartesian coordinates for the position; some
%%people might prefer {\tt (row,column)} notation.

boolean tttmarkx; tttmarkx:=true; string s;
screenstrokes; currentpicture:=tttboard; showit;
forever: message "Move? "; s:=readstring;
 move:=round(scantokens s); exitif move=0;

%%We make a general loop in which we get input from the players and then
%%do the appropriate action. The {\tt numeric} is rounded to an integer;
%%more error checking could well be done here. Non-count loops are done
%%by using {\tt forever: $\ldots$exitif $<boolean>\;\ldots$
%%endfor;} loops.

 if (move=10) or (move=1): currentpicture:=tttboard; 
  showit; tttmarkx:=false;

%%Here we start handling the {\tt move} cases (included an
%%`undocumented' one). After each `move', we
%%will change the mark used so the {\tt tttmarkx:=false} is needed here
%%since we're not actually not making a move.

 elseif move > 0 :
  move:=move-11;

%%We adjust {\tt move} so that its digits give how much to shift the
%%mark (in units of {\tt ttt/3}). 

  if tttmarkx:
   draw tttxa shifted ((move div 10)*ttt/3,(move mod 10)*ttt/3);
   draw tttxb shifted ((move div 10)*ttt/3,(move mod 10)*ttt/3);
  else:
   draw ttto shifted ((move div 10)*ttt/3,(move mod 10)*ttt/3);
  fi; %end if tttmarks

%%Since I'm writing the program using Emacs, the redundancy above needs
%%little extra typing. It does, of course, waste CPU time so when we
%%rewrite this, we'll want to change this.

 else:
  move:=abs move;
  move:=move-11;

%%Recall that when we make a move the mark type flag is changed; thus,
%%here we want to erase the {\it previous\/} mark type so we say:

  if not tttmarkx:
   undraw tttxa shifted ((move div 10)*ttt/3,(move mod 10)*ttt/3);
   undraw tttxb shifted ((move div 10)*ttt/3,(move mod 10)*ttt/3);
  else:
   undraw ttto shifted ((move div 10)*ttt/3,(move mod 10)*ttt/3);
  fi; 
 fi; % end if (move=10

%%Now we flip the mark type and go back through the loop. We only end
%%the program if {\tt exitif} gets called.

 tttmarkx:=not tttmarkx; 
endfor; end   %quit if we exit the for loop
