Mastermind: Difference between revisions
No edit summary |
No edit summary |
||
Line 538: | Line 538: | ||
└─────────────────────────────────────────┘ |
└─────────────────────────────────────────┘ |
||
</pre> |
</pre> |
||
=={{header|Ring}}== |
|||
<lang ring> |
|||
# Project : Mastermind |
|||
# Date : 2017/12/22 |
|||
# Author : Gal Zsolt (~ CalmoSoft ~) |
|||
# Email : <calmosoft@gmail.com> |
|||
colors = ["A", "B", "C", "D"] |
|||
places = list(2) |
|||
mind = list(len(colors)) |
|||
rands = list(len(colors)) |
|||
master = list(len(colors)) |
|||
test = list(4) |
|||
guesses = 7 |
|||
repeat = false |
|||
nr = 0 |
|||
if repeat |
|||
for n = 1 to len(colors) |
|||
while true |
|||
rnd = random(len(colors)-1) + 1 |
|||
if rands[rnd] != 1 |
|||
mind[n] = rnd |
|||
rands[rnd] = 1 |
|||
exit |
|||
ok |
|||
end |
|||
next |
|||
else |
|||
for n = 1 to len(colors) |
|||
rnd = random(len(colors)-1) + 1 |
|||
mind[n] = rnd |
|||
next |
|||
ok |
|||
for n = 1 to len(colors) |
|||
master[n] = char(64+mind[n]) |
|||
next |
|||
while true |
|||
for p = 1 to len(places) |
|||
places[p] = 0 |
|||
next |
|||
nr = nr + 1 |
|||
see "Your guess (ABCD)? " |
|||
give testbegin |
|||
for d = 1 to len(test) |
|||
test[d] = testbegin[d] |
|||
next |
|||
flag = 1 |
|||
for n = 1 to len(test) |
|||
if upper(test[n]) != master[n] |
|||
flag = 0 |
|||
ok |
|||
next |
|||
if flag = 1 |
|||
exit |
|||
else |
|||
for x = 1 to len(master) |
|||
if test[x] = master[x] |
|||
places[1] = places[1] + 1 |
|||
ok |
|||
next |
|||
mastertemp = master |
|||
for p = 1 to len(test) |
|||
pos = find(mastertemp, test[p]) |
|||
if pos > 0 |
|||
del(mastertemp, pos) |
|||
places[2] = places[2] + 1 |
|||
ok |
|||
next |
|||
ok |
|||
place1 = places[1] |
|||
place2 = places[2] - place1 |
|||
place3 = len(master) - (place1 + place2) |
|||
showresult(test, place1, place2, place3) |
|||
if nr = guesses |
|||
exit |
|||
ok |
|||
end |
|||
see "Well done!" + nl |
|||
see "End of game" + nl |
|||
func showresult(test, place1, place2, place3) |
|||
see "" + nr + " : " |
|||
for r = 1 to len(test) |
|||
see test[r] |
|||
next |
|||
see " : " |
|||
for n1 = 1 to place1 |
|||
see "X" + " " |
|||
next |
|||
for n2 = 1 to place2 |
|||
see "O" + " " |
|||
next |
|||
for n3 = 1 to place3 |
|||
see "-" + " " |
|||
next |
|||
see nl |
|||
</lang> |
|||
Output: |
|||
<pre> |
|||
</B |
|||
Your guess (ABCD)? BCDA |
|||
1 : BCDA : X X O - |
|||
Your guess (ABCD)? BCDB |
|||
2 : BCDB : X X X - |
|||
Your guess (ABCD)? BCBB |
|||
3 : BCBB : X X X - |
|||
Your guess (ABCD)? BCAB |
|||
Well done! |
|||
End of game |
|||
pre> |
|||
=={{header|zkl}}== |
=={{header|zkl}}== |
Revision as of 15:10, 22 December 2017
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 will be repeated colors in the code
The 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:
first guess;
the four colors(ADEF);
result: two correct colors and spot, one correct color/wrong spot one color is not in the code.
Happy coding!
- Related tasks
C++
<lang cpp>
- include <iostream>
- include <algorithm>
- include <ctime>
- include <string>
- include <vector>
typedef std::vector<char> vecChar;
class master { public:
master( size_t code_len, size_t clr_count, size_t guess_count, bool rpt ) { std::string color = "ABCDEFGHIJKLMNOPQRST";
if( code_len < 4 ) code_len = 4; else if( code_len > 10 ) code_len = 10; if( !rpt && clr_count < code_len ) clr_count = code_len; if( clr_count < 2 ) clr_count = 2; else if( clr_count > 20 ) clr_count = 20; if( guess_count < 7 ) guess_count = 7; else if( guess_count > 20 ) guess_count = 20; codeLen = code_len; colorsCnt = clr_count; guessCnt = guess_count; repeatClr = rpt;
for( size_t s = 0; s < colorsCnt; s++ ) { colors.append( 1, color.at( s ) ); } } void play() { bool win = false; combo = getCombo();
while( guessCnt ) { showBoard(); if( checkInput( getInput() ) ) { win = true; break; } guessCnt--; } if( win ) { std::cout << "\n\n--------------------------------\n" << "Very well done!\nYou found the code: " << combo << "\n--------------------------------\n\n"; } else { std::cout << "\n\n--------------------------------\n" << "I am sorry, you couldn't make it!\nThe code was: " << combo << "\n--------------------------------\n\n"; } }
private:
void showBoard() { vecChar::iterator y; for( int x = 0; x < guesses.size(); x++ ) { std::cout << "\n--------------------------------\n"; std::cout << x + 1 << ": "; for( y = guesses[x].begin(); y != guesses[x].end(); y++ ) { std::cout << *y << " "; }
std::cout << " : "; for( y = results[x].begin(); y != results[x].end(); y++ ) { std::cout << *y << " "; }
int z = codeLen - results[x].size(); if( z > 0 ) { for( int x = 0; x < z; x++ ) std::cout << "- "; } } std::cout << "\n\n"; } std::string getInput() { std::string a; while( true ) { std::cout << "Enter your guess (" << colors << "): "; a = ""; std::cin >> a; std::transform( a.begin(), a.end(), a.begin(), ::toupper ); if( a.length() > codeLen ) a.erase( codeLen ); bool r = true; for( std::string::iterator x = a.begin(); x != a.end(); x++ ) { if( colors.find( *x ) == std::string.npos ) { r = false; break; } } if( r ) break; } return a; } bool checkInput( std::string a ) { vecChar g; for( std::string::iterator x = a.begin(); x != a.end(); x++ ) { g.push_back( *x ); } guesses.push_back( g ); int black = 0, white = 0; std::vector<bool> match( codeLen, false );
for( int b = 0; b < codeLen; b++ ) { if( a.at( b ) == combo.at( b ) ) { match[b] = true; black++; continue; }
for( int w = 0; w < codeLen; w++ ) { if( !match[b] && w != b && a.at( w ) == combo.at( b ) ) { match[b] = true; white++; continue; } } } vecChar r; for( int b = 0; b < black; b++ ) r.push_back( 'X' ); for( int w = 0; w < white; w++ ) r.push_back( 'O' ); results.push_back( r );
return ( black == codeLen ); } std::string getCombo() { std::string c, clr = colors; int l, z;
for( size_t s = 0; s < codeLen; s++ ) { z = rand() % ( int )clr.length(); c.append( 1, clr[z] ); if( !repeatClr ) clr.erase( z, 1 ); } return c; }
size_t codeLen, colorsCnt, guessCnt; bool repeatClr; std::vector<vecChar> guesses, results; std::string colors, combo;
};
int main( int argc, char* argv[] ) {
srand( unsigned( time( 0 ) ) ); master m( 4, 8, 12, false ); m.play(); return 0;
} </lang>
- Output:
Enter your guess (ABCDEFGH): gbda -------------------------------- 1: A B C D : X O O - -------------------------------- 2: A A A E : O - - - -------------------------------- 3: E E E E : - - - - -------------------------------- 4: B B B C : X - - - -------------------------------- 5: D B A F : X O O - -------------------------------- 6: G B D A : X X X - Enter your guess (ABCDEFGH): hbda -------------------------------- Very well done! You found the code: HBDA --------------------------------
Lua
Based on C++ <lang lua> math.randomseed( os.time() ) local black, white, none, code = "X", "O", "-" local colors, codeLen, maxGuess, rept, alpha, opt = 6, 4, 10, false, "ABCDEFGHIJKLMNOPQRST", "" local guesses, results function createCode()
code = "" local dic, a = "" for i = 1, colors do dic = dic .. alpha:sub( i, i ) end for i = 1, codeLen do a = math.floor( math.random( 1, #dic ) ) code = code .. dic:sub( a, a ) if not rept then dic = dic:sub(1, a - 1 ) .. dic:sub( a + 1, #dic ) end end
end function checkInput( inp )
table.insert( guesses, inp ) local b, w, fnd, str = 0, 0, {}, "" for bl = 1, codeLen do if inp:sub( bl, bl ) == code:sub( bl, bl ) then b = b + 1; fnd[bl] = true else for wh = 1, codeLen do if nil == fnd[bl] and wh ~= bl and inp:sub( wh, wh ) == code:sub( bl, bl ) then w = w + 1; fnd[bl] = true end end end end for i = 1, b do str = str .. string.format( "%s ", black ) end for i = 1, w do str = str .. string.format( "%s ", white ) end for i = 1, 2 * codeLen - #str, 2 do str = str .. string.format( "%s ", none ) end table.insert( results, str ) return b == codeLen
end function play()
local err, win, r = true, false; for j = 1, colors do opt = opt .. alpha:sub( j, j ) end while( true ) do createCode(); guesses, results = {}, {} for i = 1, maxGuess do err = true; while( err ) do io.write( string.format( "\n-------------------------------\nYour guess (%s)?", opt ) ) inp = io.read():upper(); if #inp == codeLen then err = false; for k = 1, #inp do if( nil == opt:find( inp:sub( k, k ) ) ) then err = true; break; end end end end if( checkInput( inp ) ) then win = true; break else for l = 1, #guesses do print( string.format( "%.2d: %s : %s", l, guesses[l], results[l] ) ) end end end if win then print( "\nWell done!" ) else print( string.format( "\nSorry, you did not crack the code --> %s!", code ) ) end io.write( "Play again( Y/N )? " ); r = io.read() if r ~= "Y" and r ~= "y" then break end end
end --entry point --- if arg[1] ~= nil and tonumber( arg[1] ) > 1 and tonumber( arg[1] ) < 21 then colors = tonumber( arg[1] ) end if arg[2] ~= nil and tonumber( arg[2] ) > 3 and tonumber( arg[2] ) < 11 then codeLen = tonumber( arg[2] ) end if arg[3] ~= nil and tonumber( arg[3] ) > 6 and tonumber( arg[3] ) < 21 then maxGuess = tonumber( arg[3] ) end if arg[4] ~= nil and arg[4] == "true" or arg[4] == "false" then rept = ( arg[4] == "true" ) end play() </lang>
- Output:
------------------------------- Your guess (ABCDEF)?bcde 01: BCDE : X X - - ------------------------------- Your guess (ABCDEF)?bcaf 01: BCDE : X X - - 02: BCAF : X O O - ------------------------------- Your guess (ABCDEF)?badf 01: BCDE : X X - - 02: BCAF : X O O - 03: BADF : X X O - ------------------------------- Your guess (ABCDEF)?bafe Well done! Play again( Y/N )?
Perl 6
By default, plays classic Mastermind using letters in place of colors. ( 4 chosen from 6, no repeats, 10 guess limit. ) Pass in parameters to modify the game. Enter a string of --length (default 4) letters with or without spaces. Guesses accept lower or upper case. <lang perl6>sub MAIN (
Int :$colors where 1 < * < 21 = 6, Int :$length where 3 < * < 11 = 4, Int :$guesses where 7 < * < 21 = 10, Bool :$repeat = False ) { my @valid = ('A' .. 'T')[^$colors]; my $puzzle = $repeat ?? @valid.roll($length) !! @valid.pick($length); my @guesses;
my $black = '●'; my $white = '○';
loop { clearscr(); say header(); printf " %{$length * 2}s :: %s\n", @guesses[$_][0], @guesses[$_][1] for ^@guesses; say ; lose() if @guesses == $guesses; my $guess = get-guess(); next unless $guess.&is-valid; my $score = score($puzzle, $guess); win() if $score eq ($black xx $length).join: ' '; @guesses.push: [$guess, $score]; }
sub header { my $num = $guesses - @guesses; qq:to/END/; Guess the {$length} element sequence containing the letters {@valid} Repeats are {$repeat ?? !! 'not '}allowed. You have $num guess{ $num == 1 ?? !! 'es'} remaining. END }
sub score ($puzzle, $guess) { my @score; for ^$length { if $puzzle[$_] eq $guess[$_] { @score.push: $black; } elsif $puzzle[$_] eq any(@$guess) { @score.push: $white; } else { @score.push('-'); } } @score.sort.reverse.join: ' '; }
sub clearscr { $*KERNEL ~~ /'win32'/ ?? run('cls') !! run('clear') }
sub get-guess { (uc prompt 'Your guess?: ').comb(/@valid/) }
sub is-valid (@guess) { so $length == @guess }
sub win { say 'You Win! The correct answer is: ', $puzzle; exit }
sub lose { say 'Too bad, you ran out of guesses. The solution was: ', $puzzle; exit }
}</lang>
- Sample output:
Guess the 4 element sequence containing the letters A B C D E F Repeats are not allowed. You have 5 guesses remaining. A B C D :: ○ ○ ○ - C A B E :: ● ○ ○ - D A E F :: ● ○ - - B A E C :: ● ○ ○ - D E B C :: ○ ○ ○ ○ Your guess?: cdeb You Win! The correct answer is: (C D E B)
REXX
More checks could have been added (for illegal inputs and illegal options). <lang rexx>/*REXX pgm scores mastermind game with a human or CBLFs (Carbon Based Life Forms). */ parse arg let wid mxG oRep seed _ /*obtain optional arguments from the CL*/
arg . . . rep . /*get uppercase 4th argument " " " */
if let== | let=="," then let= 20 /*Not specified? Then use the default.*/ if wid== | wid=="," then wid= 4 /* " " " " " " */ if mxG== | mxG=="," then mxG= 20 /* " " " " " " */ if rep== | rep=="," then rep= 0 /* " " " " " " */ if datatype(seed,'W') then call random ,,seed /*use a seed for random repeatability. */ if abbrev( 'REPEATSALLOWED',rep,3) then rep=1 /*allow an abbreviated option for REP. */ if abbrev('NOREPEATSALLOWED',rep,3) then rep=0 /* " " " " " " */ call vet arg(), 'args' /*Vet the number of arguments entered. */ /*◄■■■■■■ optional vetting.*/ call vet let, 'letters', 2, 20 /* " " " " letters in the code*/ /*◄■■■■■■ optional vetting.*/ call vet wid, 'width', 4, 10 /* " " " " the width of code. */ /*◄■■■■■■ optional vetting.*/ call vet mxG, 'maxGuess', 7, 20 /* " " " " maximum guesses. */ /*◄■■■■■■ optional vetting.*/ call vet rep, 'REP', 0, 1e8 /* " " value if repeats are allowed*/ /*◄■■■■■■ optional vetting.*/ call gen; yourG= 'Your guess must be exactly '
youve= "You've already tried that guess " do prompt=0 by 0 until xx==wid; say /*play until guessed or QUIT is entered*/ say id 'Please enter a guess with ' wid ' letters [or Quit]:' pull g; g=space(g,0); L=length(g); if abbrev('QUIT',g,1) then exit 0 if L\==wid then do; say id '***error***' yourG wid " letters."; iterate; end call dups /*look through the history log for dups*/ q=?; XX=0; OO=0; try=try+1 /*initialize some REXX vars; bump TRY.*/
do j=1 for L; if substr(g,j,1) \== substr(q,j,1) then iterate /*hit? */ xx=xx+1; q=overlay('▒', q, j) /*bump the XX correct count. */ end /*j*/ /* [↑] XX correct count; scrub guess.*/
do k=1 for L; _=substr(g, k, 1) /*process the count for "spots". */ if pos(_, q)==0 then iterate /*is this (spot) letter in the code? */ oo=oo+1; q=translate(q, , _) /*bump the OO spot count. */ end /*k*/ /* [↑] OO spot count; & scrub guess.*/ say @.try=id right('guess' try, 11) ' ('mxG "is the max):" g '──►' , copies('X', xx)copies("O", oo)copies('-', wid-xx-oo) call hist if try==mxG then do; say; say id "you've used the maximum guesses:" mxG say; say id "The code was: " ?; say; exit 1 end end /*prompt*/
say; say " ┌─────────────────────────────────────────┐"
say " │ │" say " │ Congratulations, you've guessed it !! │" say " │ │" say " └─────────────────────────────────────────┘"
exit 0 /*stick a fork in it, we're all done. */ /*──────────────────────────────────────────────────────────────────────────────────────*/ dups: do h=1 for try; if g\=word(@.h, 8) then iterate /*any duplicated guesses? */
say; say id youve " (guess number" h').'; iterate prompt; end /*h*/; return
/*──────────────────────────────────────────────────────────────────────────────────────*/ gen: if rep==0 then reps= 'no' /*create a literal for the prompt msg. */
else reps= @abc= 'QWERTYUIOPASDFGHJKLZXCVBNM' /*capital letters used for random code.*/ id='────────'; try=0; L@abc=length(@abc) /*identifier in front of msg from here.*/ ?= do until length(?)==wid /*gen random codes 'til there's enough.*/ r=substr(@abc, random(1, L@abc), 1) /*generate a random letter, 1 at a time*/ if \rep & pos(r, ?)\==0 then iterate /*maybe don't allow a repeated digit.*/ ?=? || r; if ?=='QUIT'&let==4 then ?= /*append random letter; ··· except this*/ end /*until*/ /* [↑] builds a unique N-letter code.*/ say say id 'A random code of ' wid "letters (out of a possible " let ' letters) ' say id 'has been generated (with' reps "repeats)." return
/*──────────────────────────────────────────────────────────────────────────────────────*/ hist: do hist=1 for try; say @.hist; end; return /*show "guess" history.*/ s: if arg(1)==1 then return ; return "s" /*a simpler pluraizer. */ ser: say; say; say '***error***' arg(1); say; say; exit 13 /*──────────────────────────────────────────────────────────────────────────────────────*/ /*◄■■■■■■ optional vetting.*/ vet: parse arg val,?,mn,mx /*vet (validate) a specified argument. */ /*◄■■■■■■ optional vetting.*/
if ?=="args" & (val>1 | _\=) then call ser "Too many arguments specified. " _ /*◄■■■■■■ optional vetting.*/ if ?=="args" then return /*◄■■■■■■ optional vetting.*/ if \datatype(val, 'N') then call ser ? "isn't numeric: " val /*◄■■■■■■ optional vetting.*/ if \datatype(val, 'W') then call ser ? "isn't an integer: " val /*◄■■■■■■ optional vetting.*/ if val < mn then call ser ? "has a value less than " mn /*◄■■■■■■ optional vetting.*/ if val > mx then call ser ? "has a value greater than " mx /*◄■■■■■■ optional vetting.*/ if ?=='REP' & \datatype(val,W) then call ser "Value for REPEATS isn't valid: " oRep /*◄■■■■■■ optional vetting.*/ return 1</lang>
output
──────── A random code of 4 letters (out of a possible 20 letters) ──────── has been generated (with no repeats). ──────── Please enter a guess with 4 letters [or Quit]: abcd ◄■■■■■■ user input ──────── guess 1 (20 is the max): ABCD ──► ---- ──────── Please enter a guess with 4 letters [or Quit]: efgh ◄■■■■■■ user input ──────── guess 1 (20 is the max): ABCD ──► ---- ──────── guess 2 (20 is the max): EFGH ──► ---- ──────── Please enter a guess with 4 letters [or Quit]: ijkl ◄■■■■■■ user input ──────── guess 1 (20 is the max): ABCD ──► ---- ──────── guess 2 (20 is the max): EFGH ──► ---- ──────── guess 3 (20 is the max): IJKL ──► O--- ──────── Please enter a guess with 4 letters [or Quit]: mnop ◄■■■■■■ user input ··············································· · (Some of the output has been elided.) · ··············································· ──────── Please enter a guess with 4 letters [or Quit]: yinp ◄■■■■■■ user input ──────── guess 1 (20 is the max): ABCD ──► ---- ──────── guess 2 (20 is the max): EFGH ──► ---- ──────── guess 3 (20 is the max): IJKL ──► O--- ──────── guess 4 (20 is the max): MNOP ──► XO-- ──────── guess 5 (20 is the max): WXYZ ──► O--- ──────── guess 6 (20 is the max): LKHI ──► O--- ──────── guess 7 (20 is the max): PONM ──► XO-- ──────── guess 8 (20 is the max): ZYXW ──► O--- ──────── guess 9 (20 is the max): YZWX ──► X--- ──────── guess 10 (20 is the max): MOPN ──► OO-- ──────── guess 11 (20 is the max): OMPN ──► OO-- ──────── guess 12 (20 is the max): LKJI ──► O--- ──────── guess 13 (20 is the max): JILK ──► X--- ──────── guess 14 (20 is the max): YINP ──► XXXX ┌─────────────────────────────────────────┐ │ │ │ Congratulations, you've guessed it !! │ │ │ └─────────────────────────────────────────┘
Ring
<lang ring>
- Project : Mastermind
- Date : 2017/12/22
- Author : Gal Zsolt (~ CalmoSoft ~)
- Email : <calmosoft@gmail.com>
colors = ["A", "B", "C", "D"] places = list(2) mind = list(len(colors)) rands = list(len(colors)) master = list(len(colors)) test = list(4) guesses = 7 repeat = false nr = 0
if repeat
for n = 1 to len(colors) while true rnd = random(len(colors)-1) + 1 if rands[rnd] != 1 mind[n] = rnd rands[rnd] = 1 exit ok end next
else
for n = 1 to len(colors) rnd = random(len(colors)-1) + 1 mind[n] = rnd next
ok
for n = 1 to len(colors)
master[n] = char(64+mind[n])
next while true
for p = 1 to len(places) places[p] = 0 next nr = nr + 1 see "Your guess (ABCD)? " give testbegin for d = 1 to len(test) test[d] = testbegin[d] next flag = 1 for n = 1 to len(test) if upper(test[n]) != master[n] flag = 0 ok next if flag = 1 exit else for x = 1 to len(master) if test[x] = master[x] places[1] = places[1] + 1 ok next mastertemp = master for p = 1 to len(test) pos = find(mastertemp, test[p]) if pos > 0 del(mastertemp, pos) places[2] = places[2] + 1 ok next ok place1 = places[1] place2 = places[2] - place1 place3 = len(master) - (place1 + place2) showresult(test, place1, place2, place3) if nr = guesses exit ok
end see "Well done!" + nl see "End of game" + nl
func showresult(test, place1, place2, place3)
see "" + nr + " : " for r = 1 to len(test) see test[r] next see " : " for n1 = 1 to place1 see "X" + " " next for n2 = 1 to place2 see "O" + " " next for n3 = 1 to place3 see "-" + " " next see nl
</lang> Output:
</B Your guess (ABCD)? BCDA 1 : BCDA : X X O - Your guess (ABCD)? BCDB 2 : BCDB : X X X - Your guess (ABCD)? BCBB 3 : BCBB : X X X - Your guess (ABCD)? BCAB Well done! End of game pre> =={{header|zkl}}== {{trans|C++}} <lang zkl>class MasterMind{ fcn init(code_len,guess_count){ var codeLen =code_len.max(4).min(10); var guessCnt=guess_count.max(7).min(20); var colors ="ABCDEFGHIJKLMNOPQRST"[0,codeLen]; } fcn play{ guesses,win,blackWhite:=List(),False,Void; code:=codeLen.pump(String,'wrap(_){ colors[(0).random(codeLen)] }); do(guessCnt){ str:=getInput(); win,blackWhite = checkInput(str,code); guesses.append(T(str,blackWhite)); showBoard(guesses); if(win) break; } if(win) println("--------------------------------\n", "Very well done!\nYou found the code: ",code); else println("--------------------------------\n", "I am sorry, you didn't discover the code!\nThe code was: ",code); } fcn [private] showBoard(guesses){ foreach n,gbw in ([1..].zip(guesses)){ guess,blackWhite := gbw; println("%2d: %s :% s %s".fmt(n, guess.split("").concat(" "), blackWhite.split("").concat(" "), "- "*(codeLen - blackWhite.len()))); } } fcn [private] getInput{ while(True){ a:=ask("Enter your guess (" + colors + "): ").toUpper()[0,codeLen]; if(not (a-colors) and a.len()>=codeLen) return(a); } } fcn [private] checkInput(guess,code){ // black: guess is correct in both color and position // white: correct color, wrong position matched,black := guess.split("").zipWith('==,code), matched.sum(0); // remove black from code, prepend null to make counting easy code = L("-").extend(matched.zipWith('wrap(m,peg){ m and "-" or peg },code)); white:=0; foreach m,p in (matched.zip(guess)){ if(not m and (z:=code.find(p))){ white+=1; code[z]="-"; } } return(black==codeLen,"X"*black + "O"*white) } }(4,12).play();</lang> {{out}} <pre> Enter your guess (ABCD): abcd 1: A B C D : X O O - Enter your guess (ABCD): abcc 1: A B C D : X O O - 2: A B C C : O O - - Enter your guess (ABCD): aaad 1: A B C D : X O O - 2: A B C C : O O - - 3: A A A D : X - - - Enter your guess (ABCD): bccd 1: A B C D : X O O - 2: A B C C : O O - - 3: A A A D : X - - - 4: B C C D : X X O - Enter your guess (ABCD): dcbd 1: A B C D : X O O - 2: A B C C : O O - - 3: A A A D : X - - - 4: B C C D : X X O - 5: D C B D : X X X X -------------------------------- Very well done! You found the code: DCBD