Create a simple version of the board game:   Mastermind.

It must be possible to:

   choose the number of colors will be used in the game (2 - 20)
   choose the color code length (4 - 10)
   choose the maximum number of guesses the player has (7 - 20)
   choose whether or not colors may be repeated in the code


The (computer program) game should display all the player guesses and the results of that guess.

Display (just an idea):



 Feature 
 Graphic Version 
 Text Version


 Player guess

 Colored circles

 Alphabet letters


Correct color & position

Black circle

X


Correct color

White circle

O


None

Gray circle

 -




A text version example:        1.   ADEF   -   XXO- 

Translates to:

the first guess;

the four colors (ADEF);

result:

 two correct colors and spot, 
 one correct color/wrong spot, one color isn't in the code.
Happy coding!



Related tasks

   Bulls and cows
   Bulls and cows/Player
   Guess the number
   Guess the number/With Feedback


#!/usr/local/bin/apl -s -f -- 
 
⍝ Define the alphabet
A←'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
 
⍝ Make ASCII values upper case
∇n←AscUp c
        n←c-32×(c≥97)∧(c≤122)
∇
 
⍝ Does a list have repeated values?
∇r←Rpts l
        r←(l⍳l)≢⍳⍴l
∇
 
⍝ Keyboard input using ⎕ and ⍞ doesn't work well using GNU APL in script mode,
⍝ so you kind of have to write your own.
⍝ Read a line of text from the keyboard
∇l←ReadLine up;k;z;data
        data←'' ⋄ csr←0 ⍝ Start out with empty string and cursor at 0
 
        ⍝⍝⍝ Keyboard input
in:     k←1⎕fio[41]1    ⍝ Read byte from stdin
handle: →(k>127)/skip   ⍝ Unicode is not supported (Wumpus doesn't need it)
        →(k∊8 127)/back ⍝ Handle backspace
        →(k=10)/done    ⍝ Newline = Enter key pressed
        →(k<32)/in      ⍝ For simplicity, disregard terminal control entirely
 
        k←(AscUp⍣up)k   ⍝ Make key uppercase if necessary 
        z←k⎕fio[42]0    ⍝ Echo key to stdout
        data←data,k     ⍝ Insert key into data
        →in             ⍝ Go get next key
 
        ⍝⍝⍝ Skip UTF-8 input (read until byte ≤ 127)
skip:   k←1⎕fio[41]1 ⋄ →(k>127)/skip ⋄ →handle
 
        ⍝⍝ Backspace
back:   →(0=⍴data)/in   ⍝ If already at beginning, ignore
        z←k⎕fio[42]0    ⍝ Backspace to terminal
        data←¯1↓data    ⍝ Remove character 
        →in             ⍝ Get next key
 
        ⍝⍝ We are done, return the line as text
done:   l←⎕UCS data
∇
 
⍝ Read a positive number from the keyboard in the range [min...max]
∇n←min ReadNum max;l;z
in:     l←ReadLine 0
        z←10⎕fio[42]0
        →(~l∧.∊'0123456789')/no
        →((min≤n)∧max≥n←⍎l)/0
no:     ⍞←'Please enter a number between ',(⍕min),' and ',(⍕max),': '
        →in
∇
 
⍝ Ask a numeric question 
∇n←q Question lim;min;max
        (min max)←lim
        ⍞←q,' [',(⍕min),'..',(⍕max),']? '
        n←min ReadNum max
∇
 
⍝ Read a choice from the keyboard
∇c←Choice cs;ks;k;z
        ks←AscUp ⎕UCS ↑¨cs              ⍝ User should press first letter of choice
in:     →(~(k←AscUp 1⎕fio[41]1)∊ks)/in  ⍝ Wait for user to make choice
        z←(c←⊃cs[↑ks⍳k])⎕fio[42]0       ⍝ Select and output correspoinding choice
∇
 
⍝ Ask the user for game parameters
∇parms←InitGame;clrs;len;gss;rpts
        ⎕←'∘∘∘ MASTERMIND ∘∘∘' ⋄ ⎕←''
        clrs←'How many colors' Question 2 20
        len←'Code length' Question 4 10
        gss←'Maximum amount of guesses' Question 7 20
        ⍞←'Allow repeated colors in code (Y/N)? '
        rpts←'Yes'≡Choice 'Yes' 'No'
        parms←clrs len gss rpts
∇
 
⍝ Generate a code.
∇c←rpts MakeCode parms;clrs;len
        (clrs len)←parms
        c←A[(1+rpts)⊃(len?clrs)(?len/clrs)]
∇
 
⍝ Let user make a guess and handle errors
∇g←parms Guess code;clrs;rpts;l;right;in
        (clrs rpts num)←parms
 
guess:  ⍞←'Guess ',(¯2↑⍕num),': ' ⋄ g←ReadLine 1      ⍝ Read a guess from the keyboard
 
        ⍝ Don't count obvously invalid input against the user
        →((⍴code)≢⍴g)/len               ⍝ Length is wrong
        →(~g∧.∊A[⍳clrs])/inv            ⍝ Invalid code in input
        →((~rpts)∧Rpts g)/rpt           ⍝ No repeats allowed 
 
        ⍝ Give feedback
        right←g=code                    ⍝ Colors in right position
        in←g∊code                       ⍝ Colors not in right position
        fb←(+/right)/'X'                ⍝ X = amount of matching ones
        fb←fb,(+/in∧~right)/'O'         ⍝ O = amount of non-matching ones
        fb←fb,(+/~in)/'-'               ⍝ - = amount of colors not in code
        ⍞←' --→ ',fb,⎕UCS 10
        →0
len:    ⎕←'Invalid length.' ⋄ →guess
inv:    ⎕←'Invalid color.' ⋄ →guess
rpt:    ⎕←'No repeats allowed.' ⋄ →guess
∇
 
⍝ Play the game
∇ Mastermind;clrs;len;gsmax;rpts;code;gs
        ⎕rl←(2*32)|×/⎕ts                ⍝ initialize random seed 
        (clrs len gsmax rpts)←InitGame
        code←rpts MakeCode clrs len
        ⎕←2 0⍴''
        ⎕←'The code consists of: ',A[⍳clrs]
        gs←0
loop:   gs←gs+1 
        →(gs>gsmax)/lose
        →(code≢(clrs rpts gs)Guess code)/loop
        ⎕←'○○○ Congratulations! ○○○'
        ⎕←'You won in ',(⍕gs),' guesses.'
        →0
lose:   ⎕←'Alas, you are out of guesses.'
        ⎕←'The code was: ',code
∇
 
Mastermind
)OFF