#MKFiles 2

;--------------------
; Register definitons
;--------------------

#reg a GrainNum		; how many grains of sand per run
#reg b PiValue		; resulting PI approximation (for display)
#reg c Total		; accumulator of grains of sand through the runs
#reg d InsideCircle	; accumulator of grains inside the quarter of circle
#reg e Duration		; duration of a run in HH.MMSS (for display)
#reg 7 Address		; address of the subprogram corresponding to the active element
#reg 0 Hundred		; for looping
#reg 1 Iter		; idem
#reg 6 progress		; value from 9 to 116 for bar progression
#reg 5 done		; flag for second menu
#reg 4 limit		; to limit number of iterations

;--------------------
; Main Menu description
;--------------------

#MENU					; this is menu 0
	#STRING 1 "PI MonteCarlo"	; The title in big font
	#HLINE				; separator
	#VINPUTD "Hundreds grains :" 92 GrainNum verif
					; one "input" line to set GrainNum and
					; a verification routine to validate entry
	#ACTION "Run !" Calculation	; one "action" line (will go to Calculation)

	#OUTPUTD 0 "PI =" 32 PiValue	; one "output" line showing register PiValue
	#OUTPUTF 0 "Time :" 50 Duration 2 4
					; one "output" formatted line to display time
	#HLINE				; separator
	#ACTION "Exit !" ProgramEnd	; one "action" line (will go to ProgramEnd)
#ENDMENU

;--------------------
; Sub Menu description
;--------------------

#MENU					; this is menu 1
	#STRING 1 "Calculating..."	; a big title
	#BLANK 10			; jump lines
	#STARTRECT			; a rectangle to enclose...
	#PROGRESSBAR progress		; ... the progress bar based on register "progress"
	#ENDRECT			; close rectangle
	#BLANK 10			; jump lines
	#?LINK "Progress..." 0 Done "Done !"
					; conditional link, display "Progress" during calculation
					; and display "Done !" at the end (when register done=1)
					; this is a link to menu 0.
#ENDMENU

;--------------------
; My initializations
;--------------------

CX 
	=PiValue =Total =InsideCircle
	=Duration
	=done
1
	SET GrainNum				; default = 1 hundred = 100 grains per run
9
	SET progress				; 9 = 0% in the progress bar
$1000
	SET limit				; no more than 1000 hundreds
;--------------------
; The main loop here
;--------------------

#MENUMAINLOOP Address

;--------------------
; My subprograms
;--------------------

Note:						; subprogram to make a sound
	ENT $20 EXEC \Sound			; ENTERs the frequency, 20/10 sec for duration
	REPEAT
		GET \SOUND			; is sound terminated?
	UNTIL(x=0)				; if not equal to zero, go on
	RTN

Calculation:
	0 =done					; for conditional link		
	#GOTOMENU 1 0				; swap to menu 1, active element 0
	GET \TIME HMS> =Duration		; start time saved
	@GrainNum =Hundred			; for the loop
	SUM Total				; update the accumulator with new grains
	FOR Hundred				; for every hundred of grains
	    1 ENTER @Hundred @GrainNum / -	; compute progress bar position (9-116)
	    $107 * 9 + =progress		; according to loop value
	    #REDRAW				; and display new bar
	    $100 =Iter				; run for one hundred grains
	    FOR Iter
		RAN X^2 RAN X^2 + 1 -		; compare 1 with random x^2+y^2
		IF(x<0)THEN			; if <1 then
			1 SUM InsideCircle	; 1 on the accumulator
		ENDIF
	    NEXT
	NEXT
	$116 =progress				; progress bar at 100%
	1 =done					; change conditional link
	#REDRAW					; and display interface
	@InsideCircle @Total / $25 / =PiValue	; (inside/total) / 100 * 4 = PI
	GET \TIME HMS> 
	@Duration - >HMS =Duration		; newtime-starttime = duration
	$523 Gosub Note				; marvellous music to say it's done
	$880 Gosub Note
	$699 Gosub Note
	RTN

verif:
	@GrainNum 				; entered value
	/-/
	IF(X>=0)THEN		
		1 =GrainNum			; if negative or nul, then back to 1
	ELSE
		@limit +
		IF(x<0)THEN			; if limit<entry
			@limit =GrainNum	; then back to limit
		ENDIF
	ENDIF
	RTN

ProgramEnd:					; if Exit! selected, just stop.
	STOP




		