version 4.00 0 frmMain 3 2 0 4 0 8 0 0 8 0 0 1 2 1 0 0 1 0 0 0 238 268 0 0 0 Sub designer addform(frmMain,"GALTON BOARD","",211,211,211)@ addtextbox(frmmain,txtbxMarbles,10,65,40,22,"",255,255,255,0,0,0,True,True,False,9)@ addbutton(frmmain,btnEXIT,10,205,40,30,"EXIT",212,208,200,0,0,0,True,True,9)@ addbutton(frmmain,btnRun,10,175,40,20,"RUN",212,208,200,0,0,0,True,True,9)@ addtextbox(frmmain,txtbxQ,10,145,40,22,"",255,255,255,0,0,0,False,True,False,9)@ addlabel(frmmain,lblQ,10,130,45,20,"q = 1-p",211,211,211,0,0,0,True,True,9)@ addtextbox(frmmain,txtbxP,10,105,40,22,"",255,255,255,0,0,0,True,True,False,9)@ addlabel(frmmain,lblP,10,90,20,20,"p",211,211,211,0,0,0,True,True,9)@ addtextbox(frmmain,txtbxRows,10,25,40,22,"",255,255,255,0,0,0,True,True,False,9)@ addlabel(frmmain,lblRows,10,10,35,20,"Rows",211,211,211,0,0,0,True,True,9)@ addlabel(frmmain,lblMarbles,10,50,45,20,"Marbles",211,211,211,0,0,0,True,True,9)@ addmenuitem(frmmain,frmAbout,"About",True,False)@r addmenuitem(frmmain,frmHelp,"Help",True,False)@ End Sub End Sub End Sub End Sub End Sub End Sub End Sub End Sub End Sub End Sub End Sub End Sub End Sub End Sub End Sub End Sub End Sub End Sub End Sub End Sub End Sub End Sub End Sub End Sub End Sub @EndOfDesignText@Sub Globals NM = 100 'nr of marbles NR = 10 'nr of rows MaxMarbles = 1000 MinMarbles = 1 MaxRows = 30 MinRows = 1 MaxP = 0.9 MinP = 0.1 p = 0.5 q = 1-p xl1 = 2 yl1 = 2 xl2 = 58 yl2 = frmMain.Height-2 xt1 = xl2+2 yt1 = yl1 xt2 = frmMain.Width-2 yt2 = yl2 x1 = xt1 x2 = xt2 y1 = yl1 y2 = yl2 a = 1 BoxWidth = x2-x1 BoxHeight = y2-y1 pY = 1 pX = 1 zz =1 tt = 1 Radius = 1 xFactor = 1 yFactor = 1 yFactor2 = 1 mu = 1 Counter = 1 xtx = 1 RN = 1 RC = 1 ChiSq = 0 E = 1 O = 1 RunFirst = True End Sub '******************************* Sub App_Start SIP(False) txtbxMarbles.Text = NM txtbxRows.Text = NR txtbxP.Text = p txtbxQ.Text = q 'set arrays for amount of marbles 'and coordinates ideal curve AddArraylist("arrlstPX") AddArraylist("xP") AddArraylist("yP") frmMain.Forelayer =true frmMain.FLINE(xt1,yt1,xt2,yt2,cBlack,B) frmMain.FLINE(xl1,yl1,xl2,yl2,cBlack,B) InitParameters DrawGrid DrawBoard DrawCurve frmMain.show End Sub '******************************* Sub btnEXIT_Click AppClose End Sub '******************************* Sub btnRun_Click 'WaitCursor(True) 'erase graph frmMain.FErase(x1+1,y1+1,x2-1,y2-1) 'read out variables 'set min and max marbles and rows InitParameters 'draw grid DrawGrid 'draw Galtonboard DrawBoard 'draw expected curve DrawCurve 'RANDOMIZE MINUTE + SECOND 'function to install later 'Every marble passes the rows 'ACTION!!! Action 'WaitCursor(False) End Sub '******************************* Sub InitParameters 'set min and max marbles/rows IF RunFirst = True then RunFirst = False NR = txtbxRows.Text NM = txtbxMarbles.Text p = txtbxP.Text END IF IF RunFirst = False then DO UNTIL NR<=MaxRows AND NR>=MinRows NR = txtbxRows.Text LOOP DO UNTIL NM<=MaxMarbles AND NM>=MinMarbles NM = txtbxMarbles.Text LOOP DO UNTIL p<=MaxP AND p>=MinP p = txtbxP.Text LOOP END IF IF NR >= 20 then Radius = 1 ELSE Radius = 2 END IF q = 1-p txtbxQ.text = q 'midpoint curve is: 'one point if NR+1 is odd 'two points if NR+1 is even 'remember NR+1 points 'to include zero 'include value of p IF ODD(NR+1) = True then mu = Round(p*NR) ELSE mu = p*(NR+1) END IF 'set max width for bottom row 'with space xFactor 'set max height for rows 'with space yFactor 'max curve at mu 'regarding p zz = Binomial(NR,mu,p) 'width columns xFactor = int((BoxWidth-2)/(NR+1)) 'height scalefactor yFactor = (BoxHeight/3)/zz yFactor2 = ((BoxHeight/4)/NR) pY = y2 '// bottom of graph 'setup the arraylist of marbles For Counter = 0 to NR arrlstPX.ADD(0) NEXT End Sub '******************************* Sub DrawGrid For Counter = 0 to NR+1 frmMain.FLINE(x1+1+xFactor*Counter,y1+1,x1+1+xFactor*Counter,y2-1,cWhite) NEXT End Sub '******************************* Sub DrawBoard 'formula for 1st nail = -0.5*RC+NR/2 'multiplied by xFactor xtx = x1+((NR+1)/2+0.5)*xFactor FOR RC = 1 to NR FOR RN = 1 to RC dX = 0.5*RC*xFactor frmMain.FCIRCLE(xtx-dX+(RN-1)*xFactoR,yt1+(RC-1)*yFactor2+5,Radius,cRed,F) NEXT NEXT End Sub '******************************* Sub DrawCurve 'draw PolygonArray for the storage of the coordinates 'Add starting point for pY xP.Add(x1+2+0.5*xFactor) yP.Add(pY) FOR Counter = 0 to NR zz = Binomial(NR,Counter,p) zz = zz*yFactor xP.Add(x1+2+(Counter+0.5)*xFactor) yP.Add(pY-zz) NEXT 'Add last point for pY xP.Add(x1+2+(NR+0.5)*xFactor) yP.Add(pY) frmMain.FPOLYGON(xP,0,yP,0,xP.Count,cRed,F) End Sub '******************************* Sub Action FOR a = 1 to NM '// marble count IF (A MOD 10)=0 then txtbxMarbles.Text = a END IF pX = 0 '// number the cups from left to right, start with zero! FOR Counter = 1 to NR PP = RND(1,101) IF PP >= p*100 then 'no action to the left ELSE IF PP < p*100 then pX=pX+1 'to the right set cupnumber END IF NEXT DoEvents 'increase number of marbles in row arrlstPX.item(pX) = arrlstPX.item(pX)+1 frmMain.fline((x1+2+pX*xFactor+1),INT(pY),(x1+(pX+1)*xFactor),INT(pY-arrlstPX.item(pX)*yFactor),cBlack,BF) NEXT 'clear arrays arrlstPX.Clear xP.Clear yP.Clear End Sub '******************************* Sub Odd(x) if (x mod 2) <> 0 then return true else return false end if End Sub '******************************* Sub Binomial(n,r,p) 'n!/(r!(n-r)!).p^r.(1-p)^(n-r) t = fac(n)/(fac(n-r)*fac(r)) tt = (p^r)*((1-p)^(n-r)) tt = t*tt*NM tt = Round(tt) return tt End Sub '******************************* SUB Fac(x) F = 1 IF x >= 1 then For t = 1 to x F = F*t NEXT END IF RETURN F END Sub