#echo
#echo ----------------- MASTER MIND ---------------------
#echo           Game with 4 digits from 1 to 7
#echo --------- 2007 guillaume.tello@orange.fr ----------
#echo
#echo Compile for printer (Y/N) ?
#ask YN PRINT /

; procedures

#label A guess
#label E init

; variables

#reg 15 seed
#reg 13 secret
#reg 12 answer
#reg 09 guess_ptr
#reg 00 secret_ptr
#reg 10 my_guess
#reg 14 secret_temp

?PRINT #reg 16 save_guess

; arrays

#array Gtab 1 4     ; array for guess digits
#array Stab 5 8     ; array for secret digits

; macro

#MACRO PopOneDigit 1
        $10 INV PRD &1  ; shift right (see NOTE)
        RCL &1 frac     ; right most digit 0,n
        INV SUM &1	; removed from register
        * $10 =		; back to integer
#ENDM

;-------------------------------------------------
; nnnn A to make a guess, answer is nn,gw
; nn:number of guesses, g=number in good position,
; w=number in wrong position (nn,40 = won!)
;-------------------------------------------------

    LBL guess 
        STO my_guess                           ; 4 digits combination stored
        ?PRINT STO save_guess
        guess_ptr={ TOP Gtab }
        secret_ptr={ TOP Stab }
        secret_temp={ @secret }
        answer={ 1 + @answer = INT }           ; one more guess, remove fractional part (0,gw)

        ;------------------------------------------------------
        ; first part: dispach 4 digits in 4 registers for
        ;             my guess and the secret combination
        ;             At the same time, looks for right numbers
        ;             in the right place
        ;------------------------------------------------------
        
        FOR guess_ptr

            PopOneDigit my_guess

            STO Gtab(guess_ptr) X/T         ; n sored into array and in T

            PopOneDigit secret_temp
        
            IF(x=t)         		        ; are digits equal?
            		                    ; if so, stores 0 as my_digit (to avoid later use)
                     Gtab(guess_ptr)={ 0 }
            	   answer+{ $.1 }         ; and one more good digit in nn,gw (+0.1)
	      ENDIF

            STO Stab(secret_ptr)            ; stores digit (or 0,1 if equals to avoid later use)

            DEC secret_ptr                  ; decrement pointer
        LOOP                                ; loop from 4 to 1

        ;-------------------------------------
        ; second part: looks for right numbers
        ;              in the wrong place
        ;-------------------------------------
        
            secret_ptr={ TOP Stab }             ; loop through secret digits (reg 8,7,6,5)
            
            DO                              
                RCL Stab(secret_ptr) X/T        ; one secret digit in T to compare

                guess_ptr={ TOP Gtab }          ; to loop through my digits (reg 4,3,2,1)

                FOR guess_ptr
                    RCL Gtab(guess_ptr)
                UNTIL(x=t) wrong_place
                
                GTO lb4
                
            wrong_place:                        ; here a good digit in the wrong place
                Gtab(guess_ptr)={ 0 }           ; deletes my digit to avoid later use
                answer+{ $.01 }                 ; and one more wrong in nn,gw (+0.01)
                
            lb4:
                5 X/T                           ; 5 in T
                DEC secret_ptr
                RCL secret_ptr
            UNTIL(x<t)                          ; while >=5, go on!

            RCL answer                      ; displays nn,gw
            ?PRINT SBR print_result
            FIX 2                           ; with 2 decimals

RTN                                         ; stop

;-------------------------------------
; E to init game, secret comb is built
;-------------------------------------

#reg 09 counter

    LBL init
        answer,secret={ 0 }
        counter={ 4 }
        
        FOR counter
            secret*{ $10 }              ; shift to the left

                                        ; ramdom x'=frac[(x+pi)^5]
                                        ; converted to 1->7 digit
            secret+{                    ; and add new digit
                        seed={ @seed + PI = YX 5 = frac }
                        * 7 + 1 =                  
                        INT
                   }
        LOOP
        ?PRINT ClrLine "Go! line>> PrtLine
        CLR                             ; hide all
    RTN

!PRINT #end                             ; if not printer version, end compiling here

#reg 0 I
#reg 9 J
#reg 1 x
#reg 2 char
#reg 3 result

print_result:
    frac STO x
    2 STO I
    0 STO result x%t
    "* STO char
    FOR I
        $10 PRD x
        RCL x int      
        IF(x<>t)
            INV SUM x
            STO J
            FOR J
                $100 PRD result
                RCL char
                SUM result
            NEXT
        ENDIF
        "- STO char
    NEXT
    INV FIX
    RCL result line>>
    RCL save_guess
    MixLine
    RCL answer
RTN

#end

NOTE: "1 0 INV PRD nn" could have been replaced by ". 1 PRD nn" to save one step
    This is correct with the TI 59 but...
    Under the emulator, calculation is not exact! So the digits can't be compared correctly.
    It can be that 4 is in fact 4.000000000001, so not exactly equal to 4.
    So, tu run under the emulator and the TI 59, I made this concession.
    