Skadron Prize 2014 in Computational Physics   “Erodeo”

The goal: Write a single Mathematica module that moves a cowperson on square field with 50×50 locations with the goal to catch a calf by surrounding it completely with a rope.  The cowperson starts at location (2,2) where also one end of the rope is permanently attached to the fence.  The other end of the rope is attached to the cowperson and will extend over the entire path taken by the cowperson.  The goal is to encircle the calf using the smallest number of moves until the calf has no “unroped” position available for a further move. After each (single step) move by the cowperson the calf will also move a single step.  Each move is either to the left, right, up or down.  

Rules:  If (by mistake) you try to move outside the field, your old location will stay the same but it will count as your move. Please note that the actual (possibly stochastic) “rope-escape algorithm” used by the calf in the tournament will remain secret, as well as the randomly chosen initial position of the calf. Each chase can be repeated several times and the player with the shortest average time (=number of moves) to catch the calf wins the game.  

The code:  Email a request for the actual tournament code to grobe@ilstu.edu and you can then easily modify the module  “MyName1” to implement your algorithm.  There are four (optional) input variables that you can use if you want and one required output string variable for your module:
	field:  		A 50×50 matrix with values zero (if CP has not visited this location) or 1 (CP has visited this location, this is where the rope is).
	myposition:  	A two-component list {x,y} contains your present location, where 2≤x≤51 and 2≤y≤51. 
	cowposition: 	A two-component list {x,y} contains the  present location of the cow, where 2≤x≤51 and 2≤y≤51. 
	time: 		An integer variable contains the total number of your moves so far.  
	mymove:  	Reqired output string variable equal to “up” (= increase y), “down” (= decrease y), “left” (= decrease x) or “right” (= increase x) depending on where you choose to go next. 
		
You can immediately run the complete code by typing  “⌘a”  (to select all Mathematica cells) and then ⇧⏎ (or ⌤ to run all cells).  At the end, I only need from you a single module that produces as your output a single string variable (to be either “up”, “down”, “left”, “right”) for each turn.  In its truly dumbest form, it could look like this: 
 
MyName1[field_, myposition_, cposition_, time_] := Module[{mymove},
mymove = RandomChoice[{“up”, “down”, “left”, “right”}];
mymove]

Another (slightly more sophisticated) module (representing a very systematic cowperson, try it out!) could look like this

MyName2[field_, myposition_, cposition_, time_] := Module[{mymove},
If[ EvenQ[myposition[[2]]] == True, mymove = “right”, mymove = “left”];
If[ EvenQ[myposition[[2]]] == True && myposition[[1]] == 51, mymove=”up”]; 
If[ OddQ[myposition[[2]]]  == True && myposition[[1]] == 2,   mymove=”up”];
mymove]

Deadline: Please email your Mathematica module called “MyName1” as an attachment to  grobe@ilstu.edu    by 4pm Friday, April 11th. 

Prize: The winner (or winning team) will be announced at our annual Physics Banquet (Bone Center Circus room on April 16th at 11am) and receive a check for $200.  The second prize will be $100. For a list of the winners since 1998, see www.phy.ilstu.edu/awards_and_prizes/skadron/index.shtml#skaprize.

Important legal disclaimer:  In the preparation of this software program no actual animals were hurt or animal rights violated.

Clear["Global`*"];Print["Begin at ", DateString[]];Beginminutes=SessionTime[];

Cowperson1: “random walker ”

MyName1[field_,myposition_,cposition_,time_]:=Module[{mymove},
mymove=RandomChoice[{"up","down","left","right"}];
mymove]

Cowperson2: “fill everything up systematically 2500 moves and the calf is caught”

MyName2[field_,myposition_,cposition_,time_]:=Module[{mymove},
(* move to left or right according to evenness or oddness of y *)
If[EvenQ[myposition[[2]]]==True,mymove="right",mymove="left"];
(*overwrite choice if x is at either left or right edge, then go up*)
If[EvenQ[myposition[[2]]]==True&&myposition[[1]]==51,mymove="up"];If[OddQ[myposition[[2]]]==True&&myposition[[1]]==2,mymove="up"];
mymove]

Calf1: runs away

Calf1[field_,myposition_,cposition_]:=Module[{me=cposition,hu=myposition,cmove,pcmove,menew,dx,dy,horiz,verti},
(* compute pthe first preferred move based on hunter's position *)
horiz=me[[1]]-hu[[1]];
verti=me[[2]]-hu[[2]];
dx=If[me[[1]]≤hu[[1]],-1,1] ;
dy=If[me[[2]]≤hu[[2]],-1,1] ;

(* this line reflects the young and erratic spirit of the calf*)
danger=1*Random;
If[horiz^2+verti^2>danger,dx=RandomChoice[{-1,1}] ;dy=RandomChoice[{-1,1}]];

dx=RandomChoice[{-1,1}] ;
dy=RandomChoice[{-1,1}];

(* here are now the ranked four choices *)
choice1=If[Abs[horiz]≤Abs[verti],{dx,0},{0,dy}];  (*choice 1 avoid closest coord. *)
choice2=If[Abs[horiz]≤Abs[verti],{0,dy},{dx,0}];  (*choice 2 avoid furthest coord.*)
choice3=If[Abs[horiz]≤Abs[verti],{0,-dy},{-dx,0}]; (*choice 3 wrong for furthest coord.*)
choice4=If[Abs[horiz]≤Abs[verti],{-dx,0},{0,-dy}]; (*choice 4 wrong for furthest coord.*)

(* testing if calf's new move would bring it to a roped (forbidden) location*)
flag="try";
If[field[[ me[[1]]+choice1[[1]],me[[2]]+choice1[[2]]]]==0,choice=choice1; flag="done"];
If[flag=="try"&&field[[ me[[1]]+choice2[[1]],me[[2]]+choice2[[2]]]]==0,choice=choice2;flag="done"];
If[flag=="try"&&field[[ me[[1]]+choice3[[1]],me[[2]]+choice3[[2]]]]==0,choice=choice3;flag="done"];
If[flag=="try"&&field[[ me[[1]]+choice4[[1]],me[[2]]+choice4[[2]]]]==0,choice=choice4;flag="done"];

(* converting the choice to the direction*)
If[choice[[1]]==0&&choice[[2]]==1,cmove="up"];
If[choice[[1]]==0&&choice[[2]]==-1,cmove="down"];
If[choice[[2]]==0&&choice[[1]]==1,cmove="right"];
If[choice[[2]]==0&&choice[[1]]==-1,cmove="left"];

If[flag=="try",cmove="none"];

cmove]

Running the competition, main program  (no need to be modified)

(* initialization of the playing field *)
field=Table[0,{i,1,52},{j,1,52}];
field[[1,All]]=1;
field[[52,All]]=1;
field[[All,1]]=1;
field[[All,52]]=1;
pathme={};
pathcow={};

Num=4000;  (*maximum number of permitted steps*)
myposition={2,2};  (* initial position of the cowperson *)
cposition={40,40};  (* initial position of the calf *)
AppendTo[pathme,myposition]; (* my initial position added to my path *)
AppendTo[pathcow,cposition]; (* calf's initial position added to its path *)
AppendTo[pathcow,cposition]; (* calf's initial position added again to its path 
because the counter time means: mypos after time steps but calf's position after time-1 steps*)

Do[ 
move=MyName2[field,myposition,cposition,time]; (*replace here the name of the module *)
If[move=="left"&&myposition[[1]]>2,myposition[[1]]=myposition[[1]]-1];
If[move=="right"&&myposition[[1]]<51,myposition[[1]]=myposition[[1]]+1];
If[move=="down"&&myposition[[2]]>2,myposition[[2]]=myposition[[2]]-1];
If[move=="up"&&myposition[[2]]<51,myposition[[2]]=myposition[[2]]+1];
AppendTo[pathme,myposition];
field[[myposition[[1]],myposition[[2]]]]=1;

cmove=Calf1[field,myposition,cposition];
If[cmove=="none",Speak["moo"];Print["Calf caught after ",time," steps"]];
Nfinal=time;
If[cmove=="none",Abort[]];
If[cmove=="left"&&cposition[[1]]>2,cposition[[1]]=cposition[[1]]-1];
If[cmove=="right"&&cposition[[1]]<51,cposition[[1]]=cposition[[1]]+1];
If[cmove=="down"&&cposition[[2]]>2,cposition[[2]]=cposition[[2]]-1];
If[cmove=="up"&&cposition[[2]]<51,cposition[[2]]=cposition[[2]]+1];
AppendTo[pathcow,cposition];
,{time,1,Num,1}]

(*ListPlot[{pathme,pathcow},Joined->True,PlotRange->{{0,53},{0,53}}]*)

seqme=Table[0,{n,1,Nfinal+1}];
Do[seqme[[n]]=Take[pathme,n],{n,1,Nfinal+1}]

(* just to make blue grid points on the background graph g3*)
x=Sort[2+Table[Mod[i,50],{i,1,2500}]];
y=Flatten[Table[Table[x[[i]]+i-1,{i,1,50}],{j,1,50}]];
XYT=Partition[Riffle[x,y],2];
g3=ListPlot[XYT,Joined->False,PlotRange->{{0,53},{0,53}},AspectRatio->1,PlotStyle->PointSize[0.005]];

Animate[
g1=ListPlot[seqme[[n+1]],Joined->True,
BaseStyle->{16,FontFamily->"Times"},Frame->True,FrameLabel->{"x" ,"y"},PlotRange->{{0,53},{0,53}},PlotStyle->{Black},PlotLabel->Row[{Style["time = ",Italic],n}],AspectRatio->1];
x=pathcow[[n+1]][[1]];
y=pathcow[[n+1]][[2]];
XYcow=Partition[Riffle[{x},{y}],2];
g2=ListPlot[XYcow,Joined->False,
BaseStyle->{16,FontFamily->"Times"},Frame->True,FrameLabel->{"x" ,"y"},PlotRange->{{0,53},{0,53}},PlotStyle->{Red,PointSize[0.03]},PlotLabel->Row[{Style["time = ",Italic],n}],AspectRatio->1];
x=pathme[[n+1]][[1]];
y=pathme[[n+1]][[2]];
XYme=Partition[Riffle[{x},{y}],2];
g4=ListPlot[XYme,Joined->False,
BaseStyle->{16,FontFamily->"Times"},Frame->True,FrameLabel->{"x" ,"y"},PlotRange->{{0,53},{0,53}},PlotStyle->{Black},PlotMarkers->Automatic,AspectRatio->1];
Show[g2,g4,g1,g3,PlotLabel->Row[{Style["time = ",Italic],n}]]
,{n,1,Nfinal,1},AnimationRepetitions->1]