' Make it with Micromite (MIWM)

' PE magazine: April 2020

'

' MasterMind Game

'

' Requires an ILI9341 TFT and an IR receiver (as documented in User Manual and MIWM series)

' UNCOMMENTED VERSION of program code

'

' Email any questions to: contactus@micromite.org

'

' HAVE FUN!

'



Option autorun on

CPU 40

CLS

Dim IR_Col(3) As integer

IR_Col(0)=RGB(white):IR_Col(1)=RGB(red): IR_Col(2)=RGB(yellow): IR_Col(3)=RGB(green)

Dim IR_But(6), BestTime

Dim Keyboard(6)

Keyboard(1)=65:Keyboard(2)=66:Keyboard(3)=68:Keyboard(4)=67:Keyboard(5)=13:Keyboard(6)=77

BestTime=1200000

Dim but$(6): but$(1)="UP":but$(2)="DOWN":but$(3)="LEFT":but$(4)="RIGHT":but$(5)="ENTER":but$(6)="MENU"



IR DevCode,KeyCode, myIR



EnsureIRisSetup:

  For x=1 To 6:IR_But(x)=0:Next x

  VAR Restore

  If IR_But(1)+IR_But(2) = 0 Then SetUpIR:Print "CHECK AGAIN":GoTo EnsureIRissetup

  Print



SetTick 250,myInt



'IR_But(1)=80, IR_But(2)=48, IR_But(3)=144, IR_But(4)=96, IR_But(5)=123, IR_But(6)=250



L1$="MASTERMIND"

L2$="colour"

Dim Code(4)

Dim Temp(4)

Dim Guess(11,4)

Dim Response(11,4) As integer

Dim ColQty As integer

ColQty=4

Dim GuessNo As integer

Dim ScoreTmr As integer

Dim SelectedColumn=1

Dim SelectionTog As integer

SelectionTog=1  ' used to flash current input box (value toggles between 1 and -1)

Dim ScrnNo As integer

ScrnNo = 0   '0=Main Menu, 1=Play, 2=Level, 3=Instructions, 4=Settings (clear best score AND set IR buttons)

Dim P0sel As integer

P0Sel=1  '1=Play, 2=Level, 3=Settings

Dim P4sel As integer

P4Sel=1  '1=Conitnue, 2=Quit

Dim As integer col(12)

col(0)=RGB(black)

col(1)=RGB(yellow)

col(2)=RGB(red)

col(3)=RGB(green)

col(4)=RGB(blue)

col(5)=RGB(magenta)

col(6)=RGB(cyan)

col(7)=RGB(0,128,128)

col(8)=RGB(128,0,233)

col(9)=RGB(252,188,178)

col(10)=RGB(yellow)

Col(11)=RGB(magenta)

Col(12)=RGB(white) 'ScrnNo=1=used to flash 'selected (input) column'

Col(12)=RGB(red)

Dim As integer RotCol(12)

For i=1 To 12

  RotCol(i)=Col(i)  'load initial colours

Next i



Sub ResetBoard

  GuessNo=1

  WinFlag=0

  LoseFlag=0

  SelectedColumn=1

  tmpTimer=0

  ' reset all guesses to 0 (i.e. 'black'), and all clear all responses

  For i=1 To 10

    For ii=1 To 4

      Guess(i,ii)=0

      Response(i,1)=0  ' clear all Black pegs

      Response(i,2)=0  ' clear all White pegs

    Next ii

  Next i

  Randomize Timer

  Print

  For i = 1 To 4

    Code(i)=Int(Rnd()*ColQty)+1

    Print i,code(i)

  Next i

End Sub



Sub CheckCode

' count black pegs

  BlackCnt=0

  For i = 1 To 4

     If Guess(GuessNo,i)=Code(i) Then BlackCnt=BlackCnt+1

  Next i

  If BlackCnt=4 Then

    Response(GuessNo,1)=99

    SelectedColumn=0

  Else

     Response(GuessNo,1)=BlackCnt

     ' count white pegs

     WhiteCnt=0

     'load code(4) into Temp(4)

     For i = 1 To 4

       Temp(i)=Code(i)

     Next i

     '

     For ig = 1 To 4

       For ic = 1 To 4

         If Guess(GuessNo,ig)=Temp(ic) Then

           WhiteCnt=WhiteCnt+1

           Temp(ic)=-1

           Exit For

         End If

       Next ic

     Next ig

     Response(GuessNo,2)=WhiteCnt-BlackCnt

  End If

End Sub







'ResetBoard



Do    ' MAIN LOOP - Finish drawing current screen; and then check if need to change screen. DO THIS CONTINUALLY

  Select Case ScrnNo

    Case 0  'main menu

      DrawMainMenu

    Case 1  'play

      DrawBoard

    Case 2  'level



    Case 3  'settings (clear best score AND set IR buttons)



    Case 4  'Game Paused - Continue/MainMenu

      DrawPaused

  End Select



  If NewScrnNo<>ScrnNo Then  'before entering the following screen - do??

    Select Case NewScrnNo

      Case 0

        col(12)=RGB(red)

      Case 1

        Timer=tmpTimer

        col(12)=RGB(white)

      Case 2

      Case 3

      Case 4  'game paused

        tmpTimer=Timer

        col(12)=RGB(red)

        P4Sel=1

    End Select

    ScrnNo=NewScrnNo

    CLS

  End If

  a$=Inkey$:KeyIn$=a$

  Do While a$<>"":KeyIn$=a$:a$=Inkey$:Loop

  If KeyIn$<>"" Then

    Keycode=0

    For keyx=1 To 6

      If UCase$(keyIn$)=Chr$(Keyboard(keyx)) Then keycode=IR_But(keyx): Exit For

    Next keyx

    If KeyCode Then myIR

  End If

Loop

End Sub





Sub DrawMainMenu

  For i=1 To Len(L1$)

    Text 2*i*(MM.FontWidth+3),20,Mid$(L1$,i,1),cm,1,2,RGB(blue)

  Next i

  Text 120,50,"Try solving",cm,1,2,RGB(white)

  Text 120,75,"the secret",cm,1,2,RGB(white)

  i = 0

  For i = 1 To Len(L2$)

    Text 22+2*i*MM.FontWidth,100,Mid$(L2$,i,1),cm,1,2,RotCol(i)

  Next i

  Text 168,100,"-code",cm,1,2,RGB(white)

  Text 120,125,"as quickly as",cm,1,2,RGB(white)

  Text 120,150,"you can!",cm,1,2,RGB(white)

  Text 120,185,"Fastest time so far",cm,1,1,RGB(yellow)

  mm=(BestTime\1000)\60

  ss=(BestTime\1000) Mod 60

  wwTime$=Str$(MM,2,0,"0")+":"+Str$(SS,2,0,"0")

  Text 120,210,wwTime$,cm,1,2,RGB(green)

  P0Selection

End Sub



Sub P0Selection

  If P0Sel=1 Then

    Text 120,245,"PLAY",cm,1,2,col(12)

  Else

    Text 120,245,"PLAY",cm,1,2,RGB(128,64,64)

  End If

  If P0Sel=2 Then

    Text 120,270,"LEVEL",cm,1,2,col(12)

  Else

    Text 120,270,"LEVEL",cm,1,2,RGB(128,64,64)

  End If

  If P0Sel=3 Then

    Text 120,295,"SETTINGS",cm,1,2,col(12)

  Else

    Text 120,295,"SETTINGS",cm,1,2,RGB(128,64,64)

  End If

End Sub



Sub DrawPaused

  Text 120,50,"Game",cm,1,3,RGB(white)

  Text 120,100,"Paused",cm,1,3,RGB(white)

  P4Selection

End Sub



Sub P4Selection

  If P4Sel=1 Then

    Text 120,180,"NEW GAME",cm,1,2,col(12)

  Else

    Text 120,180,"NEW GAME",cm,1,2,RGB(128,64,64)

  End If

  If P4Sel=2 Then

    Text 120,225,"CONTINUE",cm,1,2,col(12)

  Else

    Text 120,225,"CONTINUE",cm,1,2,RGB(128,64,64)

  End If

  If P4Sel=3 Then

    Text 120,270,"QUIT",cm,1,2,col(12)

  Else

    Text 120,270,"QUIT",cm,1,2,RGB(128,64,64)

  End If

End Sub





Sub DispTimer

  ' display score

  If WinFlag Then Timer=winTimer

  mm=(Timer\1000)\60

  ss=(Timer\1000) Mod 60

  wwTime$=Str$(MM,2,0,"0")+":"+Str$(SS,2,0,"0")

  If GuessNo<11 Then

    Text 238,20,wwTime$,rm,1,2,RGB(green)

  Else

    Text 200,20," LOSE ",cm,1,2,RGB(RED)

    If LoseFlag=0 Then Beep_Lose

  End If

End Sub



Sub DrawBoard

  DispTimer

  'coloured guess pegs

  For y = 10 To 1 Step -1

    ' guess counter

    If y=11-GuessNo Then

      Text 25,y*27+15,Str$(11-y),rt,1,1,RGB(white)

    'big coloured pegs

      For x = 1 To 4

        If x=SelectedColumn Then

          Box x*30+8,y*27+15,20,14,1,col(12), col(Guess(11-y,x))

        Else

          Box x*30+8,y*27+15,20,14,1,RGB(white), col(Guess(11-y,x))

        End If

      Next x



    ElseIf y>10-GuessNo Then

      Text 25,y*27+15,Str$(11-y),rt,1,1,RGB(white)

      ' big coloured pegs

      For x = 1 To 4

        If Guess(11-y,x)>0 Then

          Box x*30+8,y*27+15,20,14,0,, col(Guess(11-y,x))

        Else

          Box x*30+8,y*27+15,20,14,1,RGB(50,50,50),RGB(black)

        End If

    Next x

    Else

      Text 25,y*27+15,Str$(11-y),rt,1,1,RGB(50,50,50)

      'big coloured pegs

       For x = 1 To 4

         Box x*30+8,y*27+15,20,14,1,RGB(50,50,50), RGB(black)

       Next x

  End If





  'scoring pegs

  tempx=168

  tmpPegCount=0

  If Response(11-y,1)=99 Then

    Text 192,y*27+22," WIN ",cm,1,2,RGB(green)

    If WinFlag=0 Then

      Print "WIN!"

      Beep_Win

      WinFlag=1

      winTimer=Timer

    End If

    If winTimer<BestTime Then

      BestTime=winTimer

      VAR save IR_But(), Keyboard(), BestTime

    End If

  Else

    If Response(11-y,1) Then 'draw black peg(s)

      For i = 1 To Response(11-y,1)

        Circle tempx,y*27+22,5,1,1,RGB(white),RGB(black)

        tempx=tempx+18

        tmpPegCount=tmpPegCount+1

      Next  i

    End If

    If Response(11-y,2) Then 'draw white peg(s)

      For i = 1 To Response(11-y,2)

        Circle tempx,y*27+22,5,1,1,RGB(white),RGB(white)

        tempx=tempx+18

        tmpPegCount=tmpPegCount+1

      Next  i

    End If

  End If

  Next y

  For i = 1 To 4

    If GuessNo<11 Then

      If WinFlag=0 Then

        Box i*30+8,8,20,24,1,RGB(red)

        Text i*30+18,20,"?",cm,1,1,RGB(white)

      Else

        'Box i*30+8,8,20,24,1,RGB(black),RGB(Black)

        Text 4,20,"Solved in",lm,1,2,RGB(yellow),0

      End If

    Else

      Box i*30+8,8,20,24,1,col(code(i)),col(code(i))

    End If

  Next i

End Sub



Sub myInt

  Select Case ScrnNo

    Case 0  'main menu

      For i = 1 To 5

        RotCol(i)=RotCol(i+1)

      Next i

      RotCol(6)=RotCol(1)

      SelectionTog=SelectionTog*-1

      If SelectionTog>0 Then

        col(12)=RGB(red)

      Else

        col(12)=RGB(128,0,0)

      End If

    Case 1  'play

      DispTimer

      SelectionTog=SelectionTog*-1

      If SelectionTog>0 Then

        col(12)=RGB(white)

      Else

        col(12)=RGB(black)

      End If

      Box SelectedColumn*30+8,(11-GuessNo)*27+15,sx,sy,1,col(12), col(Guess(GuessNo,SelectedColumn))

    Case 4  'game paused

      SelectionTog=SelectionTog*-1

      If SelectionTog>0 Then

        col(12)=RGB(red)

      Else

        col(12)=RGB(128,0,0)

      End If

  End Select

End Sub



Sub myIR

  If IR_SetUpFlag=1 Then beep: Exit Sub  'returns with a keycode value only

  Select Case ScrnNo

    Case 0

      Select Case Keycode

        Case IR_But(1) 'UP

          P0Sel=P0Sel-1: If P0Sel<1 Then P0Sel=1

        Case IR_But(2) 'DOWN

          P0Sel=P0Sel+1: If P0Sel>3 Then P0Sel=3

        Case IR_But(5) 'select

          Select Case P0Sel

            Case 1

              NewScrnNo=1

              ResetBoard

          End Select

      End Select

    Case 1 'play

      Select Case Keycode

        Case IR_But(1) 'UP

          If (WinFlag=0) And (GuessNo<11) Then Guess(GuessNo,SelectedColumn)=Guess(GuessNo,SelectedColumn)+1

          If Guess(GuessNo,SelectedColumn)>6 Then Guess(GuessNo,SelectedColumn)=0

        Case IR_But(2)  'DOWN

          If (WinFlag=0) And (GuessNo<11) Then Guess(GuessNo,SelectedColumn)=Guess(GuessNo,SelectedColumn)-1

          If Guess(GuessNo,SelectedColumn)<0 Then Guess(GuessNo,SelectedColumn)=6

        Case IR_But(4)  'RIGHT

          If (WinFlag=0) And (GuessNo<11) Then SelectedColumn=SelectedColumn+1

          If SelectedColumn>4 Then SelectedColumn=4

        Case IR_But(3)  'LEFT

          If (WinFlag=0) And (GuessNo<11) Then

            SelectedColumn=SelectedColumn-1

            If SelectedColumn<1 Then SelectedColumn=1

          End If

        Case IR_But(5)  'SELECT (Play button on Apple Remote)

          CheckCode

          If (BlackCnt<4) And (GuessNo<11) Then

            SelectedColumn=1

            GuessNo=GuessNo+1

            beep_blip

          End If

        Case IR_But(6) 'Menu TEST

          NewScrnNo=4

      End Select

      'update colour/position

      Box SelectedColumn*30+8,(11-GuessNo)*27+15,sx,sy,1,col(12), col(Guess(GuessNo,SelectedColumn))

    Case 4 'game paused

      Select Case Keycode

        Case IR_But(1) 'UP

          P4Sel=P4Sel-1: If P4Sel<1 Then P4Sel=1

        Case IR_But(2) 'DOWN

          P4Sel=P4Sel+1: If P4Sel>3 Then P4Sel=3

        Case IR_But(5) 'select

          Select Case P4Sel

            Case 1

              ResetBoard

              NewScrnNo=1

            Case 2

              NewScrnNo=1

            Case 3

              NewScrnNo=0

          End Select

      End Select

  End Select

End Sub



Sub SetUpIR

  IR_SetupFlag=1

  Print "IR Setup"

  Print "========"

  Print

  If IR_But(1)= 0 Then

    Print "Complete the instructions below to setup the IR remote!":Print

  Else

    Print "Current IR Button values:"

    For x = 1 To 6

      Print Right$("   "+but$(x),5) + " = " +Str$(IR_But(x))

    Next x

    Print:Print "(press ESC to exit)"

  End If

  Print



  Text 120,25,"IR Setup",cm,1,3,RGB(red)

  Text 5,67,"Press IR ",lm,1,2,RGB(cyan)

  For x = 1 To 6

    Text 50,67+(32*x),but$(x),lm,1,2,RGB(white)

  Next x



  For x=1 To 6

    tmpCnt = 0

    tmpKeyCode=0

    KeyCode=0

    Print "Press the IR '"+but$(x)+"' button three times."

    Text 10,67+(32*x),">",lm,1,2,RGB(cyan)

IR_Loop:

    a$=Inkey$:KeyIn$=a$

    Pause 10

    Do While a$<>"":KeyIn$=a$:a$=Inkey$:Loop

    If KeyIn$=Chr$(27) Then Print:Print "ABORTED (nothing saved)":Print:IR_SetupFlag=0:Beep_Exit:CLS:Exit Sub

    If KeyCode=0 Then GoTo IR_Loop



    If tmpCnt=0 Then tmpKeyCode=KeyCode

    If (tmpCnt<2) And x>1 Then 'check if used before

      IR_ButAlreadyInUse=0

      For xx=1 To x

        If KeyCode=IR_but(xx) Then IR_ButAlreadyInUse=1

      Next xx

      If IR_ButAlreadyInUse=1 Then Print "BUTTON ("+Str$(KEyCode)+") ALREADY DEFINED":Keycode=0:GoTo IR_Loop

    End If

    If KeyCode=tmpKeyCode Then

      tmpCnt=tmpCnt+1

      Print "("+Str$(tmpCnt)+"): " + Str$(KeyCode)

    Else

      tmpCnt=1

      Print "DIFFERENT ("+Str$(tmpCnt)+"): " + Str$(KeyCode)

      tmpKeyCode=KeyCode

    End If

    KeyCode=0



    k$="   ":If tmpKeyCode Then k$=" ("+Str$(tmpKeyCode)+")   "

    Text 50,67+(32*x),but$(x)+k$,lm,1,2,ir_col(tmpcnt)

    If tmpCnt<3 Then GoTo IR_Loop

    If tmpCnt > 2 Then Text 10,67+(32*x)," ",lm,1,2,RGB(cyan)

    IR_But(x)=tmpKeyCode

    Print

  Next x

  Print "IR SETUP SUCCESSFUL!":Print

  VAR save IR_But(),Keyboard(), BestTime

  IR_SetupFlag=0

  CLS

End Sub



Sub beep

  SetPin 22,dout

  PWM 2,1000,50

  Pause 50

  PWM 2,stop

  SetPin 22,off

End Sub



Sub beep_blip

  SetPin 22,dout

  PWM 2,800,50

  Pause 20

  PWM 2,stop

  SetPin 22,off

End Sub



Sub Beep_Exit

  SetPin 22,dout

  PWM 2,700,50

  Pause 100

  PWM 2,500,50

  Pause 100

  PWM 2,300,50

  Pause 150

  PWM 2,stop

  SetPin 22,off

End Sub



Sub Beep_Win

  SetPin 22,dout

  PWM 2,800,50

  Pause 90

  PWM 2,700,50

  Pause 90

  PWM 2,800,50

  Pause 120

  PWM 2,stop

  SetPin 22,off

End Sub



Sub Beep_Lose

  LoseFlag=1

  SetPin 22,dout

  Pause 200

  PWM 2,500,50

  Pause 100

  SetPin 22,off

  Pause 200

  SetPin 22,dout

  PWM 2,200,50

  Pause 300

  PWM 2,stop

  SetPin 22,off

End Sub