restart; randomize(): test := rand(9999): choice := rand(5): with(Maplets[Elements]): with(Maplets[Tools]): with(plottools): I0:=21: J0:=13: d:=.4: b:=0.5: ############################# # # # Maplet to do everything # # bugbox := Maplet([]): # # # ############################# bugbox := Maplet( [ [ Button( "GET DIRECTIONS", Evaluate('PL2'='directions()') ), HorizontalGlue(), "Choose a Strain of Boxbugs:", RadioButton['RB1']("1",'value'=true,'group'='BG1'), RadioButton['RB2']("2",'value'=false,'group'='BG1'), RadioButton['RB3']("3",'value'=false,'group'='BG1'), RadioButton['RB4']("4",'value'=false,'group'='BG1'), HorizontalGlue(), Button( "START SIMULATION", Evaluate('PL2'='start()') ), HorizontalGlue(), Button( "RUN ONE TIME STEP", Evaluate('PL2'='continue()') ), HorizontalGlue(), Button( "END", Shutdown() ) ], [ "PREVIOUS OBSERVATION", "CURRENT OBSERVATION" ], [ Plotter['PL1'](width=500,height=475), Plotter['PL2'](width=500,height=475) ] ], ButtonGroup['BG1'](onchange='A1'), Action['A1']( Evaluate(function="setparams") ) ): ################################## # # # Maplet to display directions # # siminfo := Maplet([]): # # # ################################## siminfo1 := Maplet( MessageDialog( "Boxbugs are virtual insects. Because they were 'bred' to introduce mathematical modeling to students, their biology is conveniently simple. They grow and reproduce without need for food or mates, and they are immobile. They begin life as larvae, metamorphose into pupae, and mature into adults. Adults give birth to new larvae, which occupy adjacent sites in the bugbox.", 'width'=500,'height'=160 ) ): siminfo2 := Maplet( MessageDialog( "There are four distinct strains of boxbugs. These are identical in appearance, but differ in some aspects of their life cycle. You will need to discover these differences by observation. You will find that each strain is a little more interesting than the previous one. It is easiest to begin with strain 1 and move on to a new strain only after you have developed a mathematical model for the previous strain.", 'width'=500,'height'=185 ) ): siminfo3 := Maplet( MessageDialog( "Begin by marking the radio button for a strain of boxbugs. Clicking the start button creates a bugbox with a small initial population. Click the continue button to run the clock ahead by one unit of time. The previous state of the bugbox is reproduced on the left side of the window, and you will soon see the new state on the right. Once you have completed your observations and data collection, you can run the clock ahead another time unit. At any point in your study, you can restart the simulation, either with the same strain or a different one.", 'width'=500,'height'=210 ) ): siminfo4 := Maplet( MessageDialog( "Your mathematical model will consist of formulas indicating the expected number of larvae, pupae, and adults at time t+1 in terms of the populations at time t.", 'width'=500,'height'=110 ) ): siminfo5 := Maplet( MessageDialog( "Test your model by writing a computer program that uses the model to run simulations. You can do additional experiments with the bugbox to test the model predictions.", 'width'=500,'height'=110 ) ): siminfo6 := Maplet( MessageDialog( "After you have studied all four strains of boxbugs, you will have acquired valuable experience of simple mathematical models for growth of structured populations.", 'width'=500,'height'=110 ) ): ####################################### # # # Procedure to set parameter values # # setparams := proc() # # # ####################################### setparams := proc() global p, a, s; if Get('RB1') then p:=1: a:=0: s:=0: elif Get('RB2') then p:=.75: a:=0: s:=0: elif Get('RB3') then p:=.75: a:=.5: s:=0: else p:=.5: a:=.5: s:=.25: fi: end proc: ################################# # # # Procedure to get directions # # directions := proc() # # # ################################# directions := proc() Maplets[Display](siminfo1); Maplets[Display](siminfo2); Maplets[Display](siminfo3); Maplets[Display](siminfo4); Maplets[Display](siminfo5); Maplets[Display](siminfo6); end proc: ################################### # # # Procedure to start simulation # # start := proc() # # # ################################### start := proc() local d2,r2,W,H; global I0,J0,d; setparams(): populate(): birthmark(): d2:=d/2: r2:=d2: W:=(3*J0+1)*r2: H:=(I0+1)*d2: Set('PL1'=plot(-1,x=0..W,y=0..H, axes=BOXED,labels=[``,``],tickmarks=[0,0])): showbox(); end proc: ############################### # # # Procedure to run one step # # continue := proc() # # # ############################### continue := proc() global currplot; update(): birthmark(): Set('PL1'=currplot); showbox(); end proc: ########################################### # # # Procedure to choose initial locations # # rowcol := proc() # # # ########################################### rowcol := proc() local k,v; k := choice(): if k=1 then v:=[4,2]: elif k=2 then v:=[4,4]: elif k=3 then v:=[6,2]: elif k=4 then v:=[6,4]: else v:=[5,3]: fi: v: end proc: ######################################## # # # Procedure to initialize the bugbox # # populate := proc() # # # ######################################## populate := proc() local i,j,k,l,numbers,orderlist,buglist,roll; global S; numbers := [1,2,3,4,5,6,7,8]: orderlist := array(1..8): buglist := array(1..8): S := array(1..I0,1..J0): for i from 1 to I0 do for j from 1 to J0 do if ((i+j) mod 2)=0 then S[i,j]:=-1 else S[i,j]:=-2 fi od od: for k from 1 to 7 do roll := rand(9-k): l := 1+roll(): orderlist[k] := numbers[l]: for i from l+1 to 9-k do numbers[i-1]:=numbers[i] od: od: orderlist[8] := numbers[1]: for i from 1 to 2 do for j from 1 to 3 do buglist[3*(i-1)+j] := [12*(i-1),4*(j-1)]+rowcol(): od: buglist[6+i] := [6,4*i-2]+rowcol(): od: for k from 1 to 8 do i := buglist[orderlist[k]][1]: j := buglist[orderlist[k]][2]: S[i,j] := 1+((k-1) mod 3): od: end proc: ############################################ # # # Procedure to mark possible birth sites # # birthmark := proc() # # # ############################################ birthmark := proc() local i,j; global S,I0,J0; for i from 1 to I0 do for j from 1 to J0 do if S[i,j]=3 then if i>2 and S[i-2,j]=-1 then S[i-2,j]:=0 fi: if i>1 and j1 and j>1 and S[i-1,j-1]=-1 then S[i-1,j-1]:=0 fi: if i1 and S[i+1,j-1]=-1 then S[i+1,j-1]:=0 fi: fi od od: end proc: #################################### # # # Procedure to update the bugbox # # update := proc() # # # #################################### update := proc() local i,j,rr; global S,I0,J0,b,p,a,s; for i from 1 to I0 do for j from 1 to J0 do if ((i+j) mod 2)=0 then rr := (test()+0.5)/10000: if S[i,j]=0 then if rrs+p then S[i,j]:=-1 fi elif S[i,j]=2 then S[i,j]:=3 elif S[i,j]=3 then if rr>a then S[i,j]:=-1 fi fi fi od od: end proc: ##################################### # # # Procedure to display the bugbox # # showbox := proc() # # # ##################################### showbox := proc() local d2,d5,d8,dd,r,r2,W,H,xj,yi,i,j,x0,plotz; global S,I0,J0,d,currplot; d2:=d/2: d5:=d/5: d8:=d/8: dd:=.15*d: r:=d/sqrt(3): r2:=r/2: W:=(3*J0+1)*r2: H:=(I0+1)*d2: xj := j -> (3*j-1)*r2: yi := i -> i*d2: plotz := plot(-1,x=0..W,y=0..H, axes=BOXED,labels=[``,``],tickmarks=[0,0]): for i from 1 to I0 do for j from 1 to J0 do if S[i,j]=1 then x0 := xj(j)+2*dd; plotz := plotz, disk([xj(j)-dd,yi(i)],d5/2,color=blue), disk([xj(j),yi(i)],d5/2,color=blue), disk([xj(j)+dd,yi(i)],d5/2,color=blue), disk([xj(j)+2*dd,yi(i)],d5/2,color=blue), plot({yi(i)+x-x0,yi(i)-x+x0},x=x0..x0+d5,color=black): elif S[i,j]=2 then plotz := plotz, disk([xj(j),yi(i)],2*dd,color=violet), disk([xj(j)+dd,yi(i)],1.8*dd,color=violet), disk([xj(j)+2*dd,yi(i)],1.6*dd,color=violet), plot([xj(j)+.8*dd-1.8*dd*sin(t),yi(i)+1.8*dd*cos(t),t=0..Pi],color=yellow), plot([xj(j)+1.9*dd-1.6*dd*sin(t),yi(i)+1.6*dd*cos(t),t=0..Pi],color=yellow), plot([xj(j)+3*dd-1.4*dd*sin(t),yi(i)+1.4*dd*cos(t),t=0..Pi],color=yellow): elif S[i,j]=3 then x0 := xj(j)+1.3*r2: plotz := plotz, disk([xj(j),yi(i)+r2/2],d8/2,color=black), disk([xj(j),yi(i)-r2/2],d8/2,color=black), disk([xj(j)-r2/2,yi(i)],d8/2,color=black), disk([xj(j)+r2/2,yi(i)],d8/2,color=black), disk([xj(j),yi(i)],r2,color=red), disk([xj(j)+d2,yi(i)+r2/4],d8/3,color=red), disk([xj(j)+d2,yi(i)-r2/4],d8/3,color=red), disk([x0,yi(i)],r2/1.5,color=black), plot({yi(i)+x-x0,yi(i)-x+x0},x=x0..x0+r2,color=black): fi od od: currplot := plots[display]([plotz]); return currplot; end proc: ################## # # # Main program # # # ################## Maplets[Display](bugbox);