; BULLS AND COWS
; VERSION 0.03
; PROGRAMMED BY STARWINDZ
; 2014.10

INCLUDE "H:RUNTIME.ACT"

;=========================================
MODULE
BYTE ARRAY TARGET_NUMBER(4)
BYTE ARRAY USER_NUMBER(10)
BYTE COWS, BULLS
BYTE DIGIT_NUM
        
;=========================================
PROC SHOW_NUMBER(BYTE ARRAY A)
BYTE I

FOR I = 0 TO DIGIT_NUM - 1
DO
  PRINTB(A(I))
  PRINT("")
OD
PRINTE("")

RETURN


;=========================================
PROC MAKE_TARGET()
BYTE I, K1, K2
BYTE ARRAY DUP(4)
BYTE DUP_SUM

DO
  FOR I = 0 TO DIGIT_NUM - 1
  DO
    TARGET_NUMBER(I) = RAND(10)
  OD

  ; DUPLICATION CHECK
  FOR K1 = 0 TO DIGIT_NUM - 1
  DO
    DUP(K1) = 0
    FOR K2 = 0 TO DIGIT_NUM - 1
    DO
      IF K1 <> K2 THEN
        IF TARGET_NUMBER(K1) = TARGET_NUMBER(K2) THEN
          DUP(K1) = DUP(K1) + 1
        FI  
      FI        
    OD
  OD
      
  DUP_SUM = 0
  FOR K1 = 0 TO DIGIT_NUM - 1
  DO
    DUP_SUM = DUP_SUM + DUP(K1)
    ;PRINTF("DUP[] = %D", DUP(K1))
    ;PRINTE("")
  OD    
  ;PRINTF("DUP_SUM = %D", DUP_SUM)
  ;PRINTE("")
      
  IF DUP_SUM = 0 THEN
    EXIT
  FI
OD
RETURN


;=========================================
PROC CHECK_NUMBER()
BYTE I, J
BYTE B, C   ; B: BULLS, C: COWS 

B = 0
C = 0

FOR I = 0 TO DIGIT_NUM - 1
DO
  IF TARGET_NUMBER(I) = USER_NUMBER(I) THEN
    B = B + 1
  FI
OD

FOR I = 0 TO DIGIT_NUM - 1
DO
  FOR J = 0 TO DIGIT_NUM - 1
  DO
    IF I <> J THEN
      IF TARGET_NUMBER(I) = USER_NUMBER(J) THEN
        C = C + 1
      FI      
    FI
  OD
OD

BULLS = B
COWS = C

PRINTF("BULLS AND COWS: %DB, %DC", BULLS, COWS)
PRINTE("")

RETURN


;=========================================
PROC MAIN()         
BYTE I, J, K1, K2
BYTE ARRAY S(10)
INT YN
BYTE ARRAY DUP(4)
BYTE DUP_SUM
BYTE ARRAY OK_CHECK(4)
BYTE OK_CHECK_SUM
      
PRINTE("== BULLS AND COWS (V0.03) ==")
PRINTE("2014, PROGRAMMED BY STARWINDZ");
PRINTE("")

;PRINT("PRESS ANY KEY TO CONTINUE.");
;INPUTS(S)

DO
  PRINTE("CHOOSE YOUR GAME MODE")
  PRINT("(3: 3 DIGITS, 4: 4 DIGITS)")
  DIGIT_NUM = INPUTI()
  
  IF (DIGIT_NUM <> 3) AND (DIGIT_NUM <> 4) THEN
    EXIT
  FI

  MAKE_TARGET()
  
  PRINTE("")
  PRINTE("TARGET NUMBER HAS BEEN GENERATED. ")
  ;SHOW_NUMBER(TARGET_NUMBER)

  I = 0
  DO
    I = I + 1
    IF I > 9 THEN
      PRINTE("* FAILED. MAX TRIAL COUNT EXCEEDED. *")
      PRINT("TARGET NUMBER IS ")
      SHOW_NUMBER(TARGET_NUMBER)
      EXIT
    FI    

    DO
      PRINTF("%D: ENTER %D DIGITS NUMBER => ", I, DIGIT_NUM)
      INPUTS(S)
      FOR J = 0 TO DIGIT_NUM - 1
      DO
        USER_NUMBER(J) = S(J + 1) - 48
        ;PRINTF("%D", USER_NUMBER(J))
        ;PRINTE("")    
      OD
      
      ; DUPLICATION CHECK
      FOR K1 = 0 TO DIGIT_NUM - 1
      DO
        DUP(K1) = 0
        FOR K2 = 0 TO DIGIT_NUM - 1
        DO
          IF K1 <> K2 THEN
            IF USER_NUMBER(K1) = USER_NUMBER(K2) THEN
              DUP(K1) = DUP(K1) + 1
            FI  
          FI        
        OD
      OD
      
      DUP_SUM = 0
      FOR K1 = 0 TO DIGIT_NUM - 1
      DO
        DUP_SUM = DUP_SUM + DUP(K1)
        ;PRINTF("DUP[] = %D", DUP(K1))
        ;PRINTE("")
      OD    
      ;PRINTF("DUP_SUM = %D", DUP_SUM)
      ;PRINTE("")
      
      IF DUP_SUM <> 0 THEN
        PRINTE("DIGIT NUMBER DUPLICATED. ENTER AGAIN!")        
      ELSE
        FOR K1 = 0 TO DIGIT_NUM - 1
        DO
          OK_CHECK(K1) = 0
        OD

        FOR K1 = 0 TO DIGIT_NUM - 1
        DO
          IF (USER_NUMBER(K1) >=0) AND (USER_NUMBER(K1) <= 9) THEN
            OK_CHECK(K1) = 0
          ELSE
            OK_CHECK(K1) = 1
          FI
        OD     
        
        OK_CHECK_SUM = 0
        FOR K1 = 0 TO DIGIT_NUM - 1
        DO
          OK_CHECK_SUM = OK_CHECK_SUM + OK_CHECK(K1)
        OD       
      
        IF OK_CHECK_SUM <> 0 THEN
          PRINTF("%D DIGIT NUMBER REQUIRED. ENTER AGAIN!", DIGIT_NUM)
          PRINTE("")
        ELSE
          EXIT
        FI  
      FI
    OD
  
    CHECK_NUMBER()
    IF BULLS = DIGIT_NUM THEN
      PRINTE("*** SUCCESS! YOU WON THE GAME ***")
      PRINTE("")
      EXIT  
    FI    
  OD

  PRINT("PLAY AGAIN? (1:YES, 2:NO) ")
  YN = INPUTI()
  
  IF YN = 2 THEN
    EXIT
  FI
  
OD

;DO
;OD
;BREAK()

RETURN
