Mastermind: Difference between revisions

9,354 bytes removed ,  3 months ago
m
No edit summary
 
(24 intermediate revisions by 14 users not shown)
Line 1:
[[Category:Puzzles]]
 
{{task|Games}}
 
Create a simple version of the board game:   [https://en.wikipedia.org/wiki/Mastermind_(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 willcolors may be repeated colors in the code
 
<br>
The (computer program) game should display all the player guesses and the results of that guess.
 
Display (just an idea.):
:::::: {| class="wikitable" border="1"
|-
! Feature !! Graphic Version !! Text Version
Line 37 ⟶ 36:
|}
 
 
A text version example:
A text version example: &nbsp; &nbsp; &nbsp; <big> 1. &nbsp; ADEF &nbsp; - &nbsp; XXO- </big>
1: ADEF - XXO-
<br>Translates to:
<br>the first guess;
<br>the four colors (ADEF);
<br>result:
<br>result: two correct colors and spot, one correct color/wrong spot one color is not in the code.
:::: two correct colors and spot,
:::: one correct color/wrong spot, one color isn't in the code.
 
Happy coding!
Line 53 ⟶ 54:
* &nbsp; [[Guess the number/With Feedback]]
<br><br>
 
=={{header|11l}}==
{{trans|Python}}
 
<syntaxhighlight lang="11l">F encode(correct, guess)
[String] output_arr
 
L(i) 0 .< correct.len
output_arr [+]= I guess[i] == correct[i] {‘X’} E I guess[i] C correct {‘O’} E ‘-’
 
R output_arr
 
F safe_int_input(prompt, min_val, max_val)
L
V user_input_str = input(prompt)
 
X.try
V user_input = Int(user_input_str)
I user_input C min_val .. max_val
R user_input
X.catch ValueError
L.continue
 
F play_game()
print(‘Welcome to Mastermind.’)
print(‘You will need to guess a random code.’)
print(‘For each guess, you will receive a hint.’)
print(‘In this hint, X denotes a correct letter, and O a letter in the original string but in a different position.’)
print()
 
V number_of_letters = safe_int_input(‘Select a number of possible letters for the code (2-20): ’, 2, 20)
V code_length = safe_int_input(‘Select a length for the code (4-10): ’, 4, 10)
 
V letters = ‘ABCDEFGHIJKLMNOPQRST’[0 .< number_of_letters]
V code = ‘’
L 0 .< code_length
code ‘’= random:choice(letters)
[String] guesses
 
L
print()
V guess = input(‘Enter a guess of length #. (#.): ’.format(code_length, letters)).uppercase()
 
I guess.len != code_length | any(guess.map(char -> char !C @letters))
L.continue
E I guess == code
print("\nYour guess "guess‘ was correct!’)
L.break
E
guesses.append(‘#.: #. => #.’.format(guesses.len + 1, Array(guess).join(‘ ’), encode(code, guess).join(‘ ’)))
 
L(i_guess) guesses
print(‘------------------------------------’)
print(i_guess)
print(‘------------------------------------’)
 
play_game()</syntaxhighlight>
 
{{out}}
<pre>
Welcome to Mastermind.
You will need to guess a random code.
For each guess, you will receive a hint.
In this hint, X denotes a correct letter, and O a letter in the original string but in a different position.
 
Select a number of possible letters for the code (2-20): 4
Select a length for the code (4-10): 4
 
Enter a guess of length 4 (ABCD): abcd
------------------------------------
1: A B C D => X X O O
------------------------------------
 
Enter a guess of length 4 (ABCD): abcc
------------------------------------
1: A B C D => X X O O
------------------------------------
2: A B C C => X X O X
------------------------------------
 
Enter a guess of length 4 (ABCD): abdc
 
Your guess ABDC was correct!
</pre>
 
=={{header|Action!}}==
<syntaxhighlight lang="action!">DEFINE MINCOLORS="2"
DEFINE MAXCOLORS="20"
DEFINE MINLENGTH="4"
DEFINE MAXLENGTH="10"
DEFINE MINGUESS="7"
DEFINE MAXGUESS="20"
TYPE Score=[BYTE spot,corr,err]
TYPE Settings=[BYTE colors,length,guesses,repeat]
 
PROC GetSettings(Settings POINTER s)
CHAR ARRAY tmp(10)
 
DO
PrintF("Enter number of colors (%B-%B):",MINCOLORS,MAXCOLORS)
s.colors=InputB()
UNTIL s.colors>=MINCOLORS AND s.colors<=MAXCOLORS
OD
DO
PrintF("Enter length of code (%B-%B):",MINLENGTH,MAXLENGTH)
s.length=InputB()
UNTIL s.length>=MINLENGTH AND s.length<=MAXLENGTH
OD
DO
PrintF("Enter max number of guesses (%B-%B):",MINGUESS,MAXGUESS)
s.guesses=InputB()
UNTIL s.guesses>=MINGUESS AND s.guesses<=MAXGUESS
OD
IF s.colors<s.length THEN
s.repeat=1
ELSE
DO
Print("Allow repeated colors (Y/N):")
InputS(tmp)
IF tmp(0)=1 THEN
IF tmp(1)='y OR tmp(1)='Y THEN
s.repeat=1 EXIT
ELSEIF tmp(1)='n OR tmp(1)='N THEN
s.repeat=0 EXIT
FI
FI
OD
FI
RETURN
 
PROC Generate(CHAR ARRAY code Settings POINTER s)
CHAR ARRAY col(MAXCOLORS)
BYTE i,j,d,tmp,count
 
FOR i=0 TO MAXCOLORS-1
DO
col(i)=i+'A
OD
code(0)=s.length
count=s.colors
FOR i=1 TO s.length
DO
d=Rand(count)
code(i)=col(d)
IF s.repeat=0 THEN
count==-1
col(d)=col(count)
FI
OD
RETURN
 
BYTE FUNC GetCount(CHAR ARRAY s CHAR c)
BYTE i,count
 
count=0
FOR i=1 TO s(0)
DO
IF s(i)=c THEN
count==+1
FI
OD
RETURN (count)
 
PROC CheckScore(CHAR ARRAY code,guess
Settings POINTER s Score POINTER res)
BYTE i,j,codeCount,guessCount
 
res.spot=0
res.corr=0
IF guess(0)#s.length THEN
res.err=1
RETURN
FI
res.err=0
 
FOR i=0 TO s.colors-1
DO
codeCount=GetCount(code,i+'A)
guessCount=GetCount(guess,i+'A)
IF codeCount<guessCount THEN
res.corr==+codeCount
ELSE
res.corr==+guessCount
FI
OD
FOR i=1 TO s.length
DO
IF guess(i)=code(i) THEN
res.spot==+1
res.corr==-1
FI
OD
RETURN
 
PROC ToUpper(CHAR ARRAY s)
BYTE i,c
 
IF s(0)=0 THEN RETURN FI
FOR i=1 TO s(0)
DO
c=s(i)
IF c>='a AND c<='z THEN
s(i)=c-'a+'A
FI
OD
RETURN
 
PROC PrintScore(Score POINTER res Settings POINTER s)
INT i
 
FOR i=1 TO res.spot
DO Put('X) OD
FOR i=1 TO res.corr
DO Put('O) OD
FOR i=1 TO s.length-res.spot-res.corr
DO Put('-) OD
RETURN
 
PROC Main()
CHAR ARRAY code(MAXLENGTH+1),guess(255)
Score res
Settings s
BYTE tries
 
PrintE("Mastermind") PutE()
GetSettings(s) PutE()
Generate(code,s)
tries=s.guesses
PrintF("Enter your guess (%B tries):%E",tries)
DO
InputS(guess) ToUpper(guess)
CheckScore(code,guess,s,res)
Put(28) ;cursor up
PrintF("%S -> ",guess)
IF res.err THEN
Print("Wrong input")
ELSE
PrintScore(res,s)
IF res.spot=s.length THEN
PutE() PutE()
PrintE("You won!")
EXIT
FI
tries==-1
IF tries=0 THEN
PutE() PutE()
PrintE("You lost!")
EXIT
FI
FI
PrintF(", try again (%B tries):%E",tries)
OD
RETURN</syntaxhighlight>
{{out}}
[https://gitlab.com/amarok8bit/action-rosetta-code/-/raw/master/images/Mastermind.png Screenshot from Atari 8-bit computer]
<pre>
Mastermind
 
Enter number of colors (2-20):6
Enter length of code (4-10):5
Enter max number of guesses (7-20):20
Allow repeated colors (Y/N):Y
 
Enter your guess (20 tries):
AAAA -> Wrong input, try again (20 tries):
AAAAA -> -----, try again (19 tries):
BBBBB -> -----, try again (18 tries):
CCCCC -> -----, try again (17 tries):
DDDDD -> XX---, try again (16 tries):
EEEEE -> X----, try again (15 tries):
DDEFF -> XXXXX
 
You won!
</pre>
 
=={{header|Ada}}==
{{works with|Ada|Ada|2012}}
 
<langsyntaxhighlight Adalang="ada">with Ada.Text_IO;
with Ada.Numerics.Discrete_Random;
with Ada.Strings.Fixed;
Line 218 ⟶ 493:
end;
end MasterMind;
</syntaxhighlight>
</lang>
{{out}}
<pre>How many colors? 9
Line 267 ⟶ 542:
You won, congratulations!
</pre>
 
=={{header|APL}}==
{{works with|GNU APL}}
 
<syntaxhighlight lang="apl">#!/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</syntaxhighlight>
 
=={{header|AutoHotkey}}==
<syntaxhighlight lang="autohotkey">w := h := 32, maxRows := 10, numPegs := 8
ww := floor(w/2-2), hh := floor(h/2-2)
grid := [], dx := w*4.5
gosub, Decode
 
Gui, Font, S18, Consolas
loop, 4
{
i := A_Index-1
Gui, add, button, % "x" (Mod(i, 4)?"+0":"30") " y"
. (Mod(i, 4)?"10" : "10") " w" w " h" h " vGoal" A_Index , ?
}
 
Gui, Add, Text, % "section x30 h1 0x1000 w" w*6
loop, % maxRows
{
Gui, Font, S18, consolas
row := maxRows - A_Index + 1
loop 4
{
col := A_Index, i:= col-1
Gui, add, button, % "x" (Mod(i, 4)?"+0":"s") " y" (Mod(i, 4)?"p":"+2")
. " w" w " h" h " vButton" row "_" col " gButton"
}
Gui, Font, S13, wingdings 2
loop 2
{
col := A_Index, i:= col-1
Gui, add, text, % "x" (Mod(i,2)?"+1":"s+" dx) " y" (Mod(i,2)?"p":"p+1")
. " w" ww " h" hh " vKeyPeg" row "_" col, % Chr(167)
}
loop 2
{
col := A_Index+2, i:= col-1
Gui, add, text, % "x" (Mod(i,2)?"+1":"s+" dx) " y" (Mod(i,2)?"p":"+1")
. " w" ww " h" hh " vKeyPeg" row "_" col, % Chr(167)
}
Gui, Add, Text, % "section xs h1 0x1000 w" w*6 " y+4"
}
Gui, Font, S12, consolas
Gui, add, Button, % "xs y+10 gSubmit w" W*2 , Submit
Gui, add, Button, % "x+0 gResetMM w" W*2, Reset
Gui, add, Checkbox, % "x+4 vNoDup", No`nDuplicates
Gui, Font, S18
for i, v in pegs
Gui, add, Radio, % "x" (!Mod(i-1, 4)?"10":"+10") " h" h " w" w+20 " vRadio" A_Index, % v
Gui, show
Row := 1
return
;-----------------------------------------------------------------------
GuiClose:
ExitApp
return
;-----------------------------------------------------------------------
Decode:
Gui, Submit, NoHide
pegs:=[], goal := [], usedPeg :=[]
pool := ["😺","🎃","🧨","⚽","😀","☠","👽","❄","🙉","💗"
,"💥","🖐","🏈","🎱","👁","🗨","🤙","👄","🐶","🐴"
,"🦢","🐍","🐞","💣","🐪","🐘","🐰","🐸","🌴","🏀"]
 
loop, % numPegs
{
Random, rnd, 1, % pool.count()
pegs[A_Index] := pool.RemoveAt(rnd)
}
i := 1
while (goal.count()<4)
{
Random, rnd, 1, % pegs.count()
if (NoDup && usedPeg[pegs[rnd]])
continue
goal[i++] := pegs[rnd]
usedPeg[pegs[rnd]] := true
}
return
;-----------------------------------------------------------------------
Button:
if GameEnd
return
 
Gui, Submit, NoHide
RegExMatch(A_GuiControl, "Button(\d+)_(\d+)", m)
if (m1 <> row)
{
thisPeg := Grid[m1, m2]
for i, v in pegs
if (v=thisPeg)
GuiControl,, Radio%i%, 1
GuiControl,, % "Button" row "_" m2, % thisPeg
Grid[row,m2] := thisPeg
}
else
{
loop, % pegs.count()
if Radio%A_Index%
GuiControl,, % A_GuiControl , % grid[m1, m2] := pegs[A_Index]
}
return
;-----------------------------------------------------------------------
Submit:
if (grid[row].count()<4) || GameEnd
return
 
Gui, submit, NoHide
Ans := [], FIP := [], inGoal := []
CIP := CNP := 0, KeyPeg := 1
 
for i, G in Goal
inGoal[G] := (inGoal[G] ? inGoal[G] : 0) +1 ; save inGoal
loop, 4
Ans[A_Index] := Grid[row, A_Index] ; save Ans
for i, A in Ans
if (goal[A_Index] = A)
CIP++, FIP.push(i), inGoal[A]:=inGoal[A] -1 ; Correct In Place, inGoal--
for i, v in FIP
Ans.RemoveAt(v-i+1) ; remove Correct In Place from Answers
for i, A in Ans
if (inGoal[A] > 0)
CNP++, inGoal[A] := inGoal[A] -1 ; Correct Not in Place
loop % CIP
GuiControl,, % "KeyPeg" row "_" KeyPeg++, % Chr(82) ; "✔"
loop % CNP
GuiControl,, % "KeyPeg" row "_" KeyPeg++, % Chr(83) ; "X"
 
if (CIP=4 || row=maxRows)
{
loop 4
GuiControl,, Goal%A_Index%, % Goal[A_Index]
MsgBox % CIP = 4 ? "You Win" : "You lose"
GameEnd := true
}
Row++
return
;-----------------------------------------------------------------------
LAlt:: ; peak at solution (for troubleshooting purposes only!)
loop 4
GuiControl,, Goal%A_Index%, % Goal[A_Index]
While GetKeyState("Lalt", "P")
continue
loop 4
GuiControl,, Goal%A_Index%, % "?"
return
;-----------------------------------------------------------------------
ResetMM:
Grid :=[], GameEnd:= false
loop, 4
{
Random, rnd, 1, % pegs.count()
goal[A_Index] := pegs[rnd]
GuiControl,, Goal%A_Index%, ?
}
 
loop, % maxRows
{
row := maxRows - A_Index + 1
loop 4
{
col := A_Index
GuiControl,, % "KeyPeg" row "_" col, % Chr(167) ; "O"
GuiControl,, % "Button" row "_" col
}
}
gosub Decode
loop, 8
GuiControl,, Radio%A_Index%, % pegs[A_Index]
return
;-----------------------------------------------------------------------</syntaxhighlight>
 
=={{header|BASIC}}==
==={{header|FreeBASIC}}===
<syntaxhighlight lang="freebasic">'--- Declaration of global variables ---
Dim As String colors(1 To 4) => {"A", "B", "C", "D"}
Dim Shared As Integer nr, ub', numlet=4, lencod=4
Dim Shared As String*4 master, pz
ub = Ubound(colors)
nr = 0
 
'--- SUBroutines and FUNCtions ---
Sub Encabezado
Dim As String dup
Color 11: Print "Welcome to Mastermind"
Print "=====================" + Chr(13) + Chr(10) : Color 15
Print "You will need to guess a random code."
Print "For each guess, you will receive a hint:"
Print "X - denotes a correct letter,"
Print "O - denotes a letter in the original"
Print " string but a different position."
Print "You have 12 attempts."
Print "Duplicates are not allowed." + Chr(10)
Print "Good luck!" + Chr(10) + Chr(10) : Color 7
End Sub
 
Sub showresult(test() As String, place1 As Byte, place2 As Byte, place3 As Byte)
Dim As Integer r, n1, n2, n3
Print Using "##: "; nr;
For r = 1 To Ubound(test)
Print test(r);
Next R
Print " : ";
For n1 = 1 To place1
Print "X"; " ";
Next N1
For n2 = 1 To place2
Print "O"; " ";
Next N2
For n3 = 1 To place3
Print "-"; " ";
Next N3
Print : Print
End Sub
 
Sub Inicio
Dim As Integer mind(ub), rands(ub)
Dim As Integer n, aleat
Dim As Boolean repeat = false
For n = 1 To ub
While true
aleat = (Rnd * (ub-1)) + 1
If rands(aleat) <> 1 Then
mind(n) = aleat
rands(aleat) = 1
Exit While
End If
Wend
Next n
For n = 1 To ub
Mid(master,n,1) = Chr(64 + mind(n))
pz &= Chr(64 + mind(n))
Next n
End Sub
 
 
'--- Main Program ---
Randomize Timer
Cls
Dim As Integer guesses = 12
Encabezado
Inicio
Color 15: Print pz : Color 7
Do
Dim As Integer n, p, d, x, posic
Dim As Integer places(1 To 2), place1, place2, place3
Dim As String*4 testbegin
Dim As String test(ub), mastertemp, tmp
Dim As Boolean flag = True
For p = 1 To Ubound(places)
places(p) = 0
Next p
nr += 1
Input "Your guess (ABCD)? " , testbegin
For d = 1 To Ubound(test)
test(d) = Mid(testbegin,d,1)
Next d
For n = 1 To Ubound(test)
If Ucase(test(n)) <> Mid(master,n,1) Then flag = False
Next n
If flag = True Then
Color 10: Print !"\nWell done! You guess correctly." : Sleep : Exit Do
Else
For x = 1 To Len(master)
If Ucase(test(x)) = Mid(master,x,1) Then places(1) += 1
Next x
mastertemp = master
For p = 1 To Ubound(test)
posic = Instr(mastertemp, Ucase(test(p)))
If posic > 0 Then
tmp = mastertemp
mastertemp = Left(tmp,posic-1) + Mid(tmp, posic+1, Len(tmp)-1)
places(2) += 1
End If
Next p
End If
place1 = places(1)
place2 = places(2) - place1
place3 = Len(master) - (place1 + place2)
showresult(test(), place1, place2, place3)
Loop Until nr = guesses
Color 14: Print "The correct combination was: "; pz
Color 7: Print !"\nEnd of game"
Sleep</syntaxhighlight>
 
=={{header|C++}}==
<langsyntaxhighlight lang="cpp">#include <iostream>
#include <algorithm>
#include <ctime>
Line 417 ⟶ 1,114:
return 0;
}
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 446 ⟶ 1,143:
=={{header|EasyLang}}==
 
[https://easylang.onlinedev/apps/mastermind.html Run it]
 
<syntaxhighlight>
<lang>col[] = [ 902 990 171 229 960 808 ]
col[] = [ 802 990 171 229 950 808 ]
len code[] 4
len guess[] 4
#
subr init_vars
row = 70
.
funcproc draw_rate r black white . .
for j rangerange0 2
for c rangerange0 2
move c * 3.5 + 7671.5 r * 11.5 + 109.4 +- j * 3.5
if black > 0
color 000
circle 1.4
black -= 1
elif white > 0
color 999
circle 1.4
white -= 1
else
color 310
circle 0.7
.
.
.
.
.
funcproc show_code . .
color 531
move 2722 092
rect 46 8
for i rangeto 4
move i * 8 + 3320 397
color col[code[i]]
circle 2
.
.
funcproc draw_guess . .
for c rangeto 4
move c * 12 + 258 row * 11.5 + 127.5
color col[guess[c]]
circle 3.8
.
.
funcproc next_row . .
color 420
linewidth 11
move 2217 row * 11.5 + 127.5
line 6560 row * 11.5 + 127.5
call draw_guess
move 7873.5 row * 11.5 + 127.5
color 310
circle 5.0
color 753
move 75.7 row * 11.5 + 9.8
move 71.5 row * 11.5 + 5
color 753
textsize 7
text "OK"
text "✓"
.
funcproc rate . .
move 7873.5 row * 11.5 + 127.5
color 531
circle 5.2
c[] = code[]
g[] = guess[]
for i rangeto 4
if c[i] = g[i]
black += 1
c[i] = -1
g[i] = -2
.
.
for i range 4
for j range 4
if c[i] = g[j]
white += 1
c[i] = -1
g[j] = -2
.
.
for i to 4
.
for j to 4
call draw_rate row black white
if c[i] = g[j]
color 531
white += 1
linewidth 12
move 22 row * 11.5 + 12 c[i] = -1
line 65 row * 11.5 + 12 g[j] = -2
.
call draw_guess
row -= 1 .
if black = 4.
draw_rate row =black -1white
color 531
.
if rowlinewidth = -112
move 17 row * 11.5 + 7.5
call show_code
line 60 row * 11.5 + 7.5
timer 1
draw_guess
else
row call+= next_row1
if black = 4
.
row = 8
.
if row = 8
show_code
timer 2
else
next_row
.
.
on timer
row = -2
.
funcproc new . .
call init_vars
for i rangeto 4
code[i] = randomrandint 6
.
color 531
move 1510 10
rect 70 80
linewidth 10
move 10 5 95
line 105 955
line 9085 955
line 9085 595
line 10 5 95
color 310
linewidth 7
move 3328 396.5
line 6358 396.5
move 3530 195
color 864
textsize 4.5
text "Mastermind"
color 310
linewidth 0.5
move 15 10 90
line 1510 964
move 7267 1090
line 7267 964
move 8580 1090
line 8580 964
for r rangerange0 8
for c rangerange0 4
move c * 12 + 2520 r * 11.5 + 127.5
circle 2
.
call draw_rate r 0 0
.
for iguess[1] range= 41
guess[i2] = i1
guess[3] = 2
.
guess[4] = 2
call next_row
next_row
.
funcproc do_move . .
c = floor ((mouse_x - 2015) /div 12)
guess[c + 1] = (guess[c] + 1)] mod 6 + 1
call draw_guess
.
on mouse_down
if row = -2
call new
elif mouse_y > row * 11.5 + 70.5 and mouse_y < row * 11.5 + 1710.5 and row < 8
if mouse_x > 2015 and mouse_x < 6661
call do_move
elif mouse_x > 7267 and mouse_x < 8580
call rate
.
.
.
new
call new</lang>
</syntaxhighlight>
 
=={{header|Go}}==
 
<langsyntaxhighlight Golang="go">package main
 
import (
Line 795 ⟶ 1,496:
none := m.holes - black - white
return blacks[:black] + whites[:white] + nones[:none], black == m.holes
}</langsyntaxhighlight>
{{out|note=using Knuth's five-guess algorithm}}
<pre>
Line 815 ⟶ 1,516:
 
You found the code in 5 guesses.
</pre>
 
=={{header|Java}}==
<syntaxhighlight lang="java">
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Scanner;
import java.util.concurrent.ThreadLocalRandom;
 
public final class MastermindTask {
 
public static void main(String[] aArgs) {
Mastermind mastermind = new Mastermind(4, 8, 12, false);
mastermind.play();
}
private static final class Mastermind {
public Mastermind(int aCodeLength, int aLetterCount, int aGuessCount, boolean aRepeatLetters) {
if ( aCodeLength < 4 ) {
aCodeLength = 4;
} else if ( aCodeLength > 10 ) {
aCodeLength = 10;
}
if ( aLetterCount < 2 ) {
aLetterCount = 2;
} else if ( aLetterCount > 20 ) {
aLetterCount = 20;
}
if ( aGuessCount < 7 ) {
aGuessCount = 7;
} else if ( aGuessCount > 20 ) {
aGuessCount = 20;
}
if ( ! aRepeatLetters && aLetterCount < aCodeLength ) {
aLetterCount = aCodeLength;
}
codeLength = aCodeLength;
letterCount = aLetterCount;
guessCount = aGuessCount;
repeatLetters = aRepeatLetters;
 
String validLetters = "ABCDEFGHIJKLMNOPQRST";
letters = "";
for ( int i = 0; i < letterCount; i++ ) {
letters += validLetters.charAt(i);
}
}
public void play() {
boolean playerWin = false;
goal = createGoal();
 
while ( guessCount > 0 && ! playerWin ) {
showBoard();
if ( checkUserInput(obtainUserGuess()) ) {
playerWin = true;
reader.close();
}
guessCount--;
}
if ( playerWin ) {
System.out.println(newLine + newLine + "--------------------------------" + newLine +
"Very well done! " + newLine + "You found the code: " + goal +
newLine + "--------------------------------" + newLine + newLine);
} else {
System.out.println(newLine + newLine + "--------------------------------" + newLine +
"I'm sorry, you couldn't make it! " + newLine + "The code was: " + goal +
newLine + "--------------------------------" + newLine + newLine);
}
}
private void showBoard() {
for ( int i = 0; i < guesses.size(); i++ ) {
System.out.print(newLine + "--------------------------------" + newLine);
System.out.print(( i + 1 ) + ": ");
for ( char ch : guesses.get(i) ) {
System.out.print(ch + " ");
}
 
System.out.print(" : ");
for ( char ch : results.get(i) ) {
System.out.print(ch + " ");
}
 
final int errorCount = codeLength - results.get(i).size();
for ( int j = 0; j < errorCount; j++ ) {
System.out.print("- ");
}
}
System.out.print(newLine + newLine);
}
private String obtainUserGuess() {
String result = "";
do {
System.out.print("Enter your guess (" + letters + "): ");
result = reader.nextLine().toUpperCase();
if ( result.length() != codeLength ) {
System.out.println("Please try again, your guess should have " + codeLength + " letters");
}
} while ( result.length() != codeLength );
return result;
}
private boolean checkUserInput(String aUserInput) {
List<Character> userInputCharacters = new ArrayList<Character>();
for ( char ch : aUserInput.toCharArray() ) {
userInputCharacters.add(ch);
}
guesses.add(userInputCharacters);
int xCount = 0;
int oCount = 0;
List<Boolean> fullMatches = new ArrayList<Boolean>(Collections.nCopies(codeLength, false));
List<Boolean> partialMatches = new ArrayList<Boolean>(Collections.nCopies(codeLength, false));
for ( int i = 0; i < codeLength; i++ ) {
if ( aUserInput.charAt(i) == goal.charAt(i) ) {
fullMatches.set(i, true);
partialMatches.set(i, true);
xCount++;
}
}
for ( int i = 0; i < codeLength; i++ ) {
if ( fullMatches.get(i) ) {
continue;
}
for ( int j = 0; j < codeLength; j++ ) {
if ( i == j || partialMatches.get(j) ) {
continue;
}
if ( aUserInput.charAt(i) == goal.charAt(j) ) {
partialMatches.set(j, true);
oCount++;
break;
}
}
}
List<Character> nextResult = new ArrayList<Character>();
for ( int i = 0; i < xCount; i++ ) {
nextResult.add('X');
}
for ( int i = 0; i < oCount; i++ ) {
nextResult.add('O');
}
results.add(nextResult);
 
return xCount == codeLength;
}
private String createGoal() {
String result = "";
String lettersCopy = letters;
 
for ( int i = 0; i < codeLength; i++ ) {
final int index = random.nextInt(lettersCopy.length());
result += lettersCopy.charAt(index);
if ( ! repeatLetters ) {
lettersCopy = lettersCopy.substring(0, index) + lettersCopy.substring(index + 1);
}
}
return result;
}
private int codeLength, letterCount, guessCount;
private String letters, goal;
private boolean repeatLetters;
private Scanner reader = new Scanner(System.in);
private List<List<Character>> guesses = new ArrayList<List<Character>>();
private List<List<Character>> results = new ArrayList<List<Character>>();
private final ThreadLocalRandom random = ThreadLocalRandom.current();
private final String newLine = System.lineSeparator();
}
 
}
</syntaxhighlight>
{{ out }}
<pre>
Enter your guess (ABCDEFGH): abcd
 
--------------------------------
1: A B C D : X O O -
 
Enter your guess (ABCDEFGH): bcde
 
--------------------------------
1: A B C D : X O O -
--------------------------------
2: B C D E : O O O -
 
Enter your guess (ABCDEFGH): fbcd
 
--------------------------------
1: A B C D : X O O -
--------------------------------
2: B C D E : O O O -
--------------------------------
3: F B C D : X O O O
 
Enter your guess (ABCDEFGH): fbdc
 
--------------------------------
1: A B C D : X O O -
--------------------------------
2: B C D E : O O O -
--------------------------------
3: F B C D : X O O O
--------------------------------
4: F B D C : X X O O
 
Enter your guess (ABCDEFGH):
 
// continues ...
</pre>
 
Line 820 ⟶ 1,745:
You can try it [http://paulo-jorente.de/webgames/repos/mastermind/ here].
 
<langsyntaxhighlight lang="javascript">
class Mastermind {
constructor() {
Line 1,053 ⟶ 1,978:
mm.check()
});
</syntaxhighlight>
</lang>
 
To test you'll need a HTML file
Line 1,189 ⟶ 2,114:
=={{header|Julia}}==
GUI version, uses the Gtk toolkit.
<langsyntaxhighlight lang="julia">using Gtk, Colors, Cairo, Graphics
 
struct Guess
Line 1,398 ⟶ 2,323:
 
mastermindapp()
</syntaxhighlight>
</lang>
 
=={{header|Kotlin}}==
{{trans|C++}}
<langsyntaxhighlight lang="scala">// version 1.2.51
 
import java.util.Random
Line 1,519 ⟶ 2,444:
val m = Mastermind(4, 8, 12, false)
m.play()
}</langsyntaxhighlight>
 
Sample input/output (showing last 2 guesses only):
Line 1,559 ⟶ 2,484:
=={{header|Lua}}==
Based on C++
<langsyntaxhighlight lang="lua">
math.randomseed( os.time() )
local black, white, none, code = "X", "O", "-"
Line 1,638 ⟶ 2,563:
if arg[4] ~= nil and arg[4] == "true" or arg[4] == "false" then rept = ( arg[4] == "true" ) end
play()
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 1,662 ⟶ 2,587:
Play again( Y/N )?
</pre>
 
=={{header|Nim}}==
{{trans|Python}}
<syntaxhighlight lang="nim">import random, sequtils, strformat, strutils
 
proc encode(correct, guess: string): string =
result.setlen(correct.len)
for i in 0..correct.high:
result[i] = if correct[i] == guess[i]: 'X' else: (if guess[i] in correct: 'O' else: '-')
result.join(" ")
 
proc safeIntInput(prompt: string; minVal, maxVal: Positive): int =
while true:
stdout.write prompt
let userInput = stdin.readLine()
result = try: parseInt(userInput)
except ValueError: continue
if result in minVal..maxVal:
return
 
 
proc playGame() =
 
echo "You will need to guess a random code."
echo "For each guess, you will receive a hint."
echo "In this hint, X denotes a correct letter, " &
"and O a letter in the original string but in a different position."
echo ""
 
let numLetters = safeIntInput("Select a number of possible letters for the code (2-20): ", 2, 20)
let codeLength = safeIntInput("Select a length for the code (4-10): ", 4, 10)
let letters = "ABCDEFGHIJKLMNOPQRST"[0..<numLetters]
let code = newSeqWith(codeLength, letters.sample()).join()
var guesses: seq[string]
 
while true:
echo ""
stdout.write &"Enter a guess of length {codeLength} ({letters}): "
let guess = stdin.readLine().toUpperAscii().strip()
if guess.len != codeLength or guess.anyIt(it notin letters):
continue
elif guess == code:
echo &"\nYour guess {guess} was correct!"
break
else:
guesses.add &"{guesses.len + 1}: {guess.join(\" \")} => {encode(code, guess)}"
for guess in guesses:
echo "------------------------------------"
echo guess
echo "------------------------------------"
 
 
randomize()
playGame()</syntaxhighlight>
 
{{out}}
<pre>You will need to guess a random code.
For each guess, you will receive a hint.
In this hint, X denotes a correct letter, and O a letter in the original string but in a different position.
 
Select a number of possible letters for the code (2-20): 4
Select a length for the code (4-10): 4
 
Enter a guess of length 4 (ABCD): ABCD
------------------------------------
1: A B C D => - O - X
------------------------------------
 
Enter a guess of length 4 (ABCD): BDBD
------------------------------------
1: A B C D => - O - X
------------------------------------
2: B D B D => X X O X
------------------------------------
 
Enter a guess of length 4 (ABCD): BDDD
 
Your guess BDDD was correct!</pre>
 
=={{header|Perl}}==
{{trans|Raku}}
<langsyntaxhighlight lang="perl">use List::Util qw(any);
 
print 'Enter pool size, puzzle size, attempts allowed: ';
Line 1,716 ⟶ 2,719:
 
sub lose { print 'Too bad, you ran out of guesses. The solution was: ' . join(' ',@puzzle) . "\n"; exit }
</syntaxhighlight>
</lang>
Sample output, omitting redundant instructions.
{{out}}
Line 1,738 ⟶ 2,741:
=={{header|Phix}}==
OTT GUI solution, fully configurable with solver.
<langsyntaxhighlight Phixlang="phix">-- demo/rosetta/mastermind.exw
constant SET_LIMIT = 1_000_000 -- above this, it uses random sampling.
 
Line 2,306 ⟶ 3,309:
IupClose()
end procedure
main()</langsyntaxhighlight>
 
=={{header|Prolog}}==
 
<langsyntaxhighlight Prologlang="prolog">mastermind :- mastermind(7, 4, 8, no_duplicates).
 
mastermind(Colours, Length, Guesses, Duplicates) :-
Line 2,410 ⟶ 3,413:
N > 0,
N1 is N - 1,
truncate_list(T, N1, R).</langsyntaxhighlight>
{{out}}
<pre>
Line 2,461 ⟶ 3,464:
{{works with|cpython|3.7.3}}
Tested in Python 3.7.3. Includes input verification.
<langsyntaxhighlight lang="python">
import random
 
Line 2,522 ⟶ 3,525:
play_game()
 
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 2,551 ⟶ 3,554:
{{works with|Rakudo|2017.01}}
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.
<syntaxhighlight lang="raku" perl6line>sub MAIN (
Int :$colors where 1 < * < 21 = 6, Int :$length where 3 < * < 11 = 4,
Int :$guesses where 7 < * < 21 = 10, Bool :$repeat = False
Line 2,609 ⟶ 3,612:
 
sub lose { say 'Too bad, you ran out of guesses. The solution was: ', $puzzle; exit }
}</langsyntaxhighlight>
{{out|Sample output}}
<pre>Valid letter, but wrong position: ○ - Correct letter and position: ●
Line 2,626 ⟶ 3,629:
=={{header|REXX}}==
More checks could have been added &nbsp; (for illegal inputs and illegal options).
<langsyntaxhighlight 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 " " " */
Line 2,703 ⟶ 3,706:
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</langsyntaxhighlight>
'''output'''
<pre>
Line 2,760 ⟶ 3,763:
 
=={{header|Ring}}==
<langsyntaxhighlight lang="ring">
# Project : Mastermind
 
Line 2,854 ⟶ 3,857:
next
see nl
</syntaxhighlight>
</lang>
Output:
<pre>
Line 2,870 ⟶ 3,873:
=={{header|Rust}}==
{{libheader|rand}}
<langsyntaxhighlight lang="rust">extern crate rand;
 
use rand::prelude::*;
Line 3,032 ⟶ 4,035:
res.sort_by(|a, b| b.cmp(a));
res.into_iter().collect()
}</langsyntaxhighlight>
{{out}}
<pre>
Line 3,085 ⟶ 4,088:
 
=={{header|SQL}}==
<langsyntaxhighlight lang="sql">
-- Create Table
-- Distinct combination
Line 3,156 ⟶ 4,159:
check_white(guesses.*, mastermind.*)
FROM guesses, mastermind
</syntaxhighlight>
</lang>
 
=={{header|Wren}}==
{{trans|Kotlin}}
{{libheader|Wren-ioutil}}
{{libheader|Wren-str}}
<syntaxhighlight lang="wren">import "random" for Random
import "./ioutil" for Input
import "./str" for Str
 
var Rand = Random.new()
 
class Mastermind {
construct new(codeLen, colorsCnt, guessCnt, repeatClr) {
var color = "ABCDEFGHIJKLMNOPQRST"
_codeLen = codeLen.clamp(4, 10)
var cl = colorsCnt
if (!repeatClr && cl < _codeLen) cl = _codeLen
_colorsCnt = cl.clamp(2, 20)
_guessCnt = guessCnt.clamp(7, 20)
_repeatClr = repeatClr
_colors = color.take(_colorsCnt).join()
_combo = ""
_guesses = []
_results = []
}
 
play() {
var win = false
_combo = getCombo_()
while (_guessCnt != 0) {
showBoard_()
if (checkInput_(getInput_())) {
win = true
break
}
_guessCnt = _guessCnt - 1
}
System.print("\n\n--------------------------------")
if (win) {
System.print("Very well done!\nYou found the code: %(_combo)")
} else {
System.print("I am sorry, you couldn't make it!\nThe code was: %(_combo)")
}
System.print("--------------------------------\n")
}
 
showBoard_() {
for (x in 0..._guesses.count) {
System.print("\n--------------------------------")
System.write("%(x + 1): ")
for (y in _guesses[x]) System.write("%(y) ")
System.write(" : ")
for (y in _results[x]) System.write("%(y) ")
var z = _codeLen - _results[x].count
if (z > 0) System.write("- " * z)
}
System.print("\n")
}
 
getInput_() {
while (true) {
var a = Str.upper(Input.text("Enter your guess (%(_colors)): ", 1)).take(_codeLen)
if (a.all { |c| _colors.contains(c) } ) return a.join()
}
}
 
checkInput_(a) {
_guesses.add(a.toList)
var black = 0
var white = 0
var gmatch = List.filled(_codeLen, false)
var cmatch = List.filled(_codeLen, false)
for (i in 0..._codeLen) {
if (a[i] == _combo[i]) {
gmatch[i] = true
cmatch[i] = true
black = black + 1
}
}
for (i in 0..._codeLen) {
if (gmatch[i]) continue
for (j in 0..._codeLen) {
if (i == j || cmatch[j]) continue
if (a[i] == _combo[j]) {
cmatch[j] = true
white = white + 1
break
}
}
}
var r = []
r.addAll(("X" * black).toList)
r.addAll(("O" * white).toList)
_results.add(r)
return black == _codeLen
}
 
getCombo_() {
var c = ""
var clr = _colors
for (s in 0..._codeLen) {
var z = Rand.int(clr.count)
c = c + clr[z]
if (!_repeatClr) Str.delete(clr, z)
}
return c
}
}
 
var m = Mastermind.new(4, 8, 12, false)
m.play()</syntaxhighlight>
 
{{out}}
Sample game:
<pre>
Enter your guess (ABCDEFGH): abcd
 
--------------------------------
1: A B C D : X - - -
 
Enter your guess (ABCDEFGH): efgh
 
--------------------------------
1: A B C D : X - - -
--------------------------------
2: E F G H : O O - -
 
Enter your guess (ABCDEFGH): aefa
 
--------------------------------
1: A B C D : X - - -
--------------------------------
2: E F G H : O O - -
--------------------------------
3: A E F A : X X - -
 
Enter your guess (ABCDEFGH): aagh
 
--------------------------------
1: A B C D : X - - -
--------------------------------
2: E F G H : O O - -
--------------------------------
3: A E F A : X X - -
--------------------------------
4: A A G H : X O O O
 
Enter your guess (ABCDEFGH): agah
 
--------------------------------
1: A B C D : X - - -
--------------------------------
2: E F G H : O O - -
--------------------------------
3: A E F A : X X - -
--------------------------------
4: A A G H : X O O O
--------------------------------
5: A G A H : X X O O
 
Enter your guess (ABCDEFGH): agha
 
 
--------------------------------
Very well done!
You found the code: AGHA
--------------------------------
</pre>
 
=={{header|zkl}}==
{{trans|C++}}
<langsyntaxhighlight lang="zkl">class MasterMind{
fcn init(code_len,guess_count){
var codeLen =code_len.max(4).min(10);
Line 3,206 ⟶ 4,377:
return(black==codeLen,"X"*black + "O"*white)
}
}(4,12).play();</langsyntaxhighlight>
{{out}}
<pre>
Line 3,233 ⟶ 4,404:
You found the code: DCBD
</pre>
 
=={{header|Basic/Assembler for ZX Spectrum}}==
Written for ZX Spectrum microcomputer. Can be run using an emulator.
All infos and program at: https://www.dropbox.com/s/gggcpdpoze9brq9/ZXMasterMind.zip?dl=0
 
10 REM Version MM62 - BASIC Parts - Roberto Zaffanella
20 BRIGHT 1
30 BORDER 7
 
40 REM FILE .BAS
50 LOAD "MM.BIN"CODE 48000,1608
60 LOAD "UDG.BIN"CODE 65368,168
70 LOAD "MM.SCR"SCREEN$
80 REM
 
90 REM FILE TAP PER EMULATORE - MMEMUXX.TAP
100 REM LOAD ""CODE 48000,1608
110 REM LOAD ""CODE 65368,168
120 REM LOAD ""SCREEN$
130 REM
 
140 REM FILE TAP PER FILE WAV - MMVAWXX.WAV
150 REM NEL TAP SCREEN$, MM.BAS, OBJ E UDG
160 REM TUTTI I LOAD IN REM. LASCIARE SOLO I POKE
170 REM LOAD ""CODE 48000,1608
180 REM LOAD ""CODE 47830,168
190 REM LOAD ""SCREEN$
200 REM POKE 23675,214
210 REM POKE 23676,186
220 REM
 
230 PRINT AT 20,20; INK 7; PAPER 0; FLASH 1;"Setting..."
240 LET LM=48000
250 LET VAR=49620
260 LET C1=49728
270 LET ROUTINE=VAR+0
280 LET MEMFT=VAR+1
300 LET MEMTUTTICP=VAR+4
310 LET C0=VAR+6
320 LET CS=VAR+18
330 LET MEMVR=VAR+31
340 LET MEMLASTPRT=VAR+32
350 LET MEMNUMCPPRT=VAR+34
360 LET MEMPESOMIN=VAR+84
370 LET MEMR=VAR+86
380 LET MEMBC=VAR+87
390 LET MEME=VAR+89
395 REM
 
400 REM CODIFICA ROUTINE LM
410 LET INIZ=1
420 LET CLEANVIDEO=2
430 LET DEFNUMCOL=3
440 LET TROVACH=4
450 LET ELIMINACP=5
460 LET VISFT=6
470 LET SIMULA=7
490 LET VISBC=8
500 LET GIOCATAPRG=9
550 REM
 
560 REM SET PER ROUTINE INPUT CP/CS - Q e Q$
580 DIM Q$(7,8)
590 DIM Q(7,8)
610 FOR I=4 TO 7
620 FOR J=1 TO 8
630 LET Q(I,J)=J
640 IF J=7 THEN LET Q(I,J)=0
650 LET Q$(I,J)="\j"
660 IF J=7 THEN LET Q$(I,J)="\i"
670 IF J=8 THEN LET Q(I,J)=2+(I-1)*2
680 NEXT J
690 NEXT I
700 LET Q(1,8)=4: LET Q(2,8)=5: LET Q(3,8)=6
710 FOR J=1 TO 8: LET Q$(1,J)="X": NEXT J
720 REM
 
730 REM SET PER ROUTINE INPUT CH - H e H$
740 DIM H$(6,4)
750 DIM H(6,4)
770 FOR I=1 TO 6
780 FOR J=1 TO 4
790 IF J=1 THEN LET H$(I,J)="\g": LET H(I,J)=1
800 IF J=2 THEN LET H$(I,J)="\h": LET H(I,J)=1
810 IF J=3 THEN LET H$(I,J)="\k": LET H(I,J)=3
820 IF I=1 THEN LET H$(I,J)="X"
830 IF I=2 THEN LET H$(I,J)="F"
840 IF J=4 THEN LET H(I,J)=I
850 NEXT J
860 NEXT I
870 REM
 
872 LET OPZ=1: LET OPZOLD=1
874 DIM G(2,10): REM SCORE
876 LET G1=0: LET G2=0
878 LET G$="OK"
890 DIM V(4):DIM W(7)
910 REM
 
920 FOR I=1 TO 10: BEEP .05,20+(10-I): NEXT I
930 REM
 
940 REM MAIN LOOP DEL GIOCO ******************
950 REM
960 POKE ROUTINE,INIZ: RANDOMIZE USR LM
962 LET FT=1296
970 REM
980 REM CALL MENU
990 GO SUB 6800
1000 REM
1010 IF G$="FINITA" THEN PRINT AT 20,1; INK 1;" Press any key to play again "; INK 0: GO SUB 6720: GO TO 500
1020 REM
1030 IF OPZ=1 THEN GO SUB 1150: REM GIO>PRG
1050 IF OPZ=2 THEN GO SUB 2940: REM PRG>GIO
1070 IF OPZ=3 THEN GO SUB 4470: REM DEMO
1090 IF OPZ=4 THEN GO SUB 7090: REM ISTRUZIONI
1092 IF OPZ=5 THEN GO SUB 7300: REM STAT
1100 REM
1110 IF G$="G1_ANNULLATA" THEN LET G(OPZ,G1)=0: LET G1=G1-1
1120 IF G$="G2_ANNULLATA" THEN LET G(OPZ,G2)=0: LET G2=G2-1
1125 REM VAI A LOOP PRINCIPALE
1130 GO TO 940
1140 REM
 
1150 REM GIO > PRG ++++++++++
1160 REM ++++++++++++++++++++
1170 CLS
1180 REM CALL DRAW BOARD
1190 GO SUB 5960
1200 REM
1205 REM SET MATRICE PER INPUT CP
1210 FOR J=1 TO 8: LET Q$(2,J)="B": NEXT J
1220 FOR J=1 TO 8: LET Q$(3,J)="F": NEXT J
1230 REM
1250 LET G1=G1+1
1260 IF G1>=7 THEN LET G1=6
1270 LET G(OPZ,G1)=0
1280 REM
1290 REM PRG TROVA CS CON RND E LO METTE IN CS
1300 RANDOMIZE
1310 LET E=INT (RND*1296)
1320 FOR I=0 TO 9
1330 POKE (CS+I),PEEK (C1+E*12+I)
1340 NEXT I
1350 REM
1360 REM METTE CS IN V(4)
1370 FOR I=1 TO 4: LET V(I)=PEEK (CS+I-1): NEXT I
1400 REM
1410 REM VIS CS OSCURATO
1440 LET R=1
1450 GO SUB 6320
1470 REM
1480 LET R=22
1490 REM ** PUNTO DI LOOP PER TUTTE LE GIOCATE **
1500 REM
1510 LET R=R-2
1525 LET S$="RUN_SIMULA"
1530 REM
1540 REM TROPPI TENTATIVI
1550 IF R=2 THEN GO SUB 2350: RETURN
1560 REM
1570 PRINT AT 1,18;" "
1580 PRINT AT 1,18;"Fit Codes:";FT
1590 PRINT AT 2,18;" "
1600 REM
1635 REM CALL INPUT CP/CS - RITORNA TENTATIVO IN W(1) W(2) W(3) W(4)
1640 GO SUB 1900
1645 REM
1655 PRINT AT 1,1;" "; AT 2,1;" ":
1660 IF G$="G1_ANNULLATA" THEN RETURN
1670 REM
1680 REM CALL METTE W(4) IN C0 E DEFINISCE NUM COL IN C0
1690 GO SUB 2590
1700 REM
1710 REM CALL TROVA CH TRA C0 E CS
1720 POKE ROUTINE,TROVACH: RANDOMIZE USR LM
1730 LET NERI=PEEK (C0+10)
1740 LET BIAN=PEEK (C0+11)-NERI
1750 REM
1760 REM CALL VIS CH
1770 GO SUB 5840
1780 REM
1785 REM CALL CS INDOVINATO
1790 IF NERI=4 THEN GO SUB 2670: RETURN
1800 REM
1810 REM CALL ELIMINA CP
1840 POKE ROUTINE,ELIMINACP: RANDOMIZE USR LM
1850 LET FT=PEEK (MEMFT)+PEEK (MEMFT+1)*256
1860 REM
1870 REM VAI A PUNTO DI LOOP PER TUTTE LE GIOCATE
1880 GO TO 1490
1890 REM
 
1900 REM ROUTINE DI INPUT CP SE OPZ=1 O CS SE OPZ=2
1910 REM
1920 LET G$="OK"
1930 FOR I=1 TO 7: LET W(I)=7: NEXT I
1960 LET U=0
1980 LET X=4: LET XOLD=4
1990 LET Y=7: LET YOLD=7
2000 PRINT AT R,4; INK 0;Q$(1,7);Q$(2,7);Q$(3,7)
2010 REM
2020 REM INPUT X B F CP o X H R CS
2030 PRINT AT R,Q(XOLD,8); INK Q(XOLD,YOLD); FLASH 0;Q$(XOLD,YOLD)
2040 PRINT AT R,Q(X,8); INK Q(X,Y); FLASH 1;Q$(X,Y)
2050 LET XOLD=X: LET YOLD=W(X)
2060 REM CALL INPUT
2070 GO SUB 6570
2080 REM
2090 IF K=8 AND X=1 THEN LET Y=W(X): REM SX
2100 IF K=8 AND X>1 THEN LET X=X-1: LET Y=W(X): REM SX
2110 IF K=9 AND X=7 THEN LET Y=W(X): REM DX
2120 IF K=9 AND X<7 THEN LET X=X+1: LET Y=W(X): REM DX
2130 IF K=10 THEN LET Y=Y-1: LET W(X)=Y: IF Y=0 THEN LET Y=7: LET W(X)=Y: REM GIU
2140 IF K=11 THEN LET Y=Y+1: LET W(X)=Y: IF Y=8 THEN LET Y=1: LET W(X)=Y: REM SU
2160 IF K=13 AND OPZ=1 THEN GO SUB 2220
2170 IF K=13 AND OPZ=2 THEN GO SUB 3820
2175 IF U=1 THEN RETURN
2180 REM
2190 REM RIPETI INPUT X B F CP o X H R CS
2200 GO TO 2020
2210 REM
 
2220 REM ROUTINE TASTO INVIO INPUT CP - 1900
2240 REM VF=1 VIS FIT CODES - VF=2 VIS BEST CODES
2250 LET K=13
2255 REM INVIO SU F CALL VIS FT/BC
2260 IF X=3 THEN PRINT AT R,6; INK 0;"F": LET X=X+1: LET Y=W(X): LET VF=1: GO SUB 5170
2265 REM
2270 REM INVIO SU B CALL BEST CODES
2280 IF X=2 THEN PRINT AT R,5; INK 0;"B": LET X=X+2: LET Y=W(X): LET VF=2: GO SUB 2440
2285 REM
2290 REM CODICE COMPLETATO + TASTO INVIO
2300 IF W(4)<7 AND W(5)<7 AND W(6)<7 AND W(7)<7 AND X>3 AND K=13 THEN PRINT AT R,2+(XOLD-1)*2; INK YOLD; FLASH 0;"\j": LET G(OPZ,G1)=G(OPZ,G1)+1: FOR I=4 TO 7: LET W(I-3)=W(I): NEXT I: POKE ROUTINE,CLEANVIDEO: RANDOMIZE USR LM: LET U=1: RETURN
2310 REM
2320 REM INVIO SU X PARTITA ANNULLATA
2330 IF X=1 THEN LET G$="G1_ANNULLATA": LET U=1: RETURN
2340 RETURN
 
2350 REM ROUTINE TROPPI TENTATIVI - OPZ 1
2360 PRINT AT 1,8; INK V(1);"\j";" "; INK V(2);"\j";" "; INK V(3);"\j";" "; INK V(4);"\j"; INK 0
2370 PRINT AT 7,17;" No more space": PRINT AT 8,20;"for codes": PRINT AT 10,20;"Score 10": PRINT AT 11,18;"for this game"
2380 PRINT AT 20,18;"Press any key": BEEP .6,-10
2390 LET G(OPZ,G1)=10
2400 REM CALL PRESS ANY KEY
2410 GO SUB 6720
2420 RETURN
2430 REM
 
2440 REM ROUTINE BEST CODES - 2220
2460 IF S$="RUN_SIMULA" THEN GO SUB 2530: LET S$="NO_RUN_AGAIN":REM CALL SIMULA
2485 LET BC=PEEK MEMBC+PEEK (MEMBC+1)*256
2490 LET VF=2: GO SUB 5170: RETURN: REM CALL VIS FT/BC
2520 RETURN
 
2530 REM ROUTINE SIMULA - opz 2 3 2440
2535 POKE ROUTINE,CLEANVIDEO: RANDOMIZE USR LM
2540 PRINT AT R,18; FLASH 1;"Processing:";FT
2550 POKE MEMR,R
2560 POKE ROUTINE,SIMULA: RANDOMIZE USR LM
2570 PRINT AT R,18;" "
2580 RETURN
 
2590 REM ROUTINE METTE W() IN C0 - OPZ 1 3
2600 POKE C0+0,W(1)
2610 POKE C0+1,W(2)
2620 POKE C0+2,W(3)
2630 POKE C0+3,W(4)
2640 POKE ROUTINE,DEFNUMCOL: RANDOMIZE USR LM
2650 RETURN
2660 REM
 
2670 REM CS INDOVINATO - OPZ 1 2 3
2680 LET W$=" GUESSED! "
2690 IF OPZ>1 THEN GO TO 2770
2700 LET Z=1
2710 LET J=G(OPZ,G1)
2720 IF J<4 THEN LET W$=" VERY LUCKY! "
2730 IF J=5 OR J=4 THEN LET W$=" WELL DONE! "
2740 IF J=6 THEN LET W$=" NOT SO BAD! "
2750 IF J>6 THEN LET W$="CAN DO BETTER"
2760 LET J=1
2770 IF OPZ>1 THEN LET Z=20: LET J=-1
2780 INK INT (RND*4)+1
2790 PRINT AT 1,18;" "
2800 FOR I=Z TO R STEP J
2810 IF I<20 THEN PRINT AT I-J,18;" "
2820 PRINT AT I,18+13-LEN W$;W$
2830 BEEP 0.04,-4
2840 NEXT I
2850 PRINT AT R,18+13-LEN W$; FLASH 1;W$
2860 INK 0: INVERSE 0
2870 IF OPZ=1 THEN PRINT AT Z,8; INK V(1);"\j";" "; INK V(2);"\j";" "; INK V(3);"\j";" "; INK V(4);"\j"
2880 FOR I=0 TO 19: BEEP .05,20-I: NEXT I
2890 PRINT AT 20,18;"Press any key"
2895 REM CALL PRESS ANY KEY
2900 GO SUB 6720
2910 RETURN
2930 REM
 
2940 REM PRG > GIO +++++++++
2950 REM +++++++++++++++++++
2960 CLS
2980 REM CALL DRAW BOARD
2990 GO SUB 6140
2995 REM
2997 REM SETTA H R PER MENU INPUT CS
3000 FOR J=1 TO 8: LET Q$(2,J)="H": NEXT J
3010 FOR J=1 TO 8: LET Q$(3,J)="R": NEXT J
3020 REM
3030 LET NERI=0: LET S$="NO_RUN_AGAIN"
3060 LET G2=G2+1
3070 IF G2>=7 THEN LET G2=6
3080 LET G(OPZ,G2)=0
3090 REM
3110 LET R=20
3120 REM CALL INPUT CP/CS
3130 GO SUB 1900
3140 IF G$="G2_ANNULLATA" THEN RETURN
3160 LET R=-1:
3170 REM
3180 REM ** PUNTO DI LOOP PER TUTTE LE GIOCATE **
3190 LET R=R+2
3200 LET G(OPZ,G2)=G(OPZ,G2)+1
3210 REM
3220 PRINT AT 1,18;" "
3230 PRINT AT 1,18;"Fit Codes:";FT
3240 PRINT AT 2,18;" "
3250 REM
3265 LET BC=PEEK MEMBC+PEEK (MEMBC+1)*256
3270 REM CALL GIOCATA PRG - RITORNA GIOCATA IN C0
3280 GO SUB 4030
3290 REM
3300 REM METTE C0 IN V(4)
3310 FOR I=1 TO 4: LET V(I)=PEEK (C0+I-1): NEXT I
3320 REM
3330 REM VIS CP GIOCATO DA PRG
3370 GO SUB 6450
3380 REM
3420 REM SE FT=1, PRG HA INDOVINATO. CALL VIS CH: CALL CS INDOVINATO
3430 IF FT=1 THEN LET BIAN=0: LET NERI=4: GO SUB 5840: GO SUB 2670: RETURN
3440 REM
3450 REM CALL INPUT CH - RITORNA W(4)
3460 GO SUB 4110
3470 IF G$="G2_ANNULLATA" THEN RETURN
3480 REM
3490 REM CONTA I NERI E BIANCHI DI W(4)
3500 LET BIAN=0: LET NERI=0
3510 FOR I=1 TO 4
3520 IF W(I)=1 THEN LET NERI=NERI+1
3530 IF W(I)=2 THEN LET BIAN=BIAN+1
3540 NEXT I
3550 REM
3560 REM CALL VIS CH
3570 GO SUB 5840
3580 REM
3600 POKE ROUTINE,CLEANVIDEO: RANDOMIZE USR LM
3610 REM
3620 REM CS INDOVINATO
3630 IF NERI=4 THEN GO SUB 2670: RETURN
3640 REM
3650 REM METTI BIANCHI E NERI IN C0+10/11
3660 POKE C0+10,NERI
3670 POKE C0+11,BIAN+NERI
3680 REM
3690 REM CALL ELIMINA CP
3700 POKE ROUTINE,ELIMINACP: RANDOMIZE USR LM
3710 LET FT=PEEK MEMFT+PEEK (MEMFT+1)*256
3720 IF FT=0 THEN PRINT AT 7,17; INK 0;" One Key Code": PRINT AT 8,20; INK 0;"is wrong": PRINT AT 10,19; INK 0;"No score for": PRINT AT 11,20; INK 0;"this game": PRINT AT 20,18;"Press any key": BEEP .6,-10: LET G$="G2_ANNULLATA": GO SUB 6720: RETURN
3730 REM
3740 REM CALL SIMULA
3750 GO SUB 2530
3760 REM
3770 REM VAI A PROSSIMA GIOCATA
3780 GO TO 3180
3790 REM
 
3820 REM ROUTINE TASTO INVIO INPUT CS - 1900
3830 REM CS COMPLETATO + ENTER
3840 IF W(4)<7 AND W(5)<7 AND W(6)<7 AND W(7)<7 AND X>3 THEN PRINT AT 20,4;" ": PRINT AT 20,Q(XOLD,8); INK YOLD; FLASH 0;"\j": LET U=1: RETURN
3850 REM
3860 REM INVIO SU H - CS SCRITTO SU CARTA
3870 IF X=2 THEN PRINT AT 20,5; INK 0;"H": LET R=20: GO SUB 6320: PRINT AT 20,4;" ": LET U=1: RETURN
3880 REM
3890 REM INVIO SU X - PARTITA ANNULLATA
3900 IF X=1 THEN LET G$="G2_ANNULLATA": LET U=1: RETURN
3910 REM
3920 REM INVIO SU R - CS RANDOM
3930 IF X=3 THEN PRINT AT 20,6; INK 0;"R": LET R=20: GO SUB 3950: PRINT AT 20,4;" ": LET U=1: RETURN
3940 RETURN
 
3950 REM ROUTINE CS RANDOM - 3820
3970 FOR I=1 TO 4
3980 LET V(I)=INT (RND*6)+1
3990 NEXT I
4000 REM CALL VIS CS
4010 GO SUB 6450
4020 RETURN
 
4030 REM GIOCATA PRG - OPZ 2 3
4035 REM RITORNA GIOCATA IN C0
4040 RANDOMIZE
4050 LET E=INT (RND*BC)+1
4060 POKE MEME,(E-INT (E/256)*256)
4070 POKE MEME+1,INT (E/256)
4080 POKE ROUTINE,GIOCATAPRG: RANDOMIZE USR LM
4090 RETURN
4100 REM
 
4110 REM ROUTINE INPUT CH - OPZ 2
4120 REM
4130 LET G$="OK"
4140 FOR I=1 TO 6
4150 LET W(I)=3
4160 NEXT I
4170 REM
4180 LET X=3: LET XOLD=3
4190 LET Y=3: LET YOLD=3
4200 PRINT AT R,1; INK 0;H$(1,3);H$(2,3);H$(3,3);H$(4,3);H$(5,3);H$(6,3)
4210 REM
4220 REM LOOP INPUT CH
4230 PRINT AT R,H(XOLD,4); INK 0; FLASH 0;H$(XOLD,YOLD)
4240 PRINT AT R,H(X,4); INK 0; FLASH 1;H$(X,Y)
4250 LET XOLD=X: LET YOLD=W(X)
4260 REM CALL INPUT
4270 GO SUB 6570
4280 REM
4290 IF K=8 AND X=1 THEN LET Y=W(X): REM SX
4300 IF K=8 AND X>1 THEN LET X=X-1: LET Y=W(X): REM SX
4310 IF K=9 AND X=6 THEN LET Y=W(X): REM DX
4320 IF K=9 AND X<6 THEN LET X=X+1: LET Y=W(X): REM DX
4330 IF K=10 THEN LET Y=Y-1: LET W(X)=Y: IF Y=0 THEN LET Y=3: LET W(X)=Y: REM GIU
4340 IF K=11 THEN LET Y=Y+1: LET W(X)=Y: IF Y=4 THEN LET Y=1: LET W(X)=Y: REM SU
4350 REM
4360 REM CH COMPLETATO + ENTER
4370 IF K=13 AND X>2 THEN PRINT AT R,H(XOLD,4); INK 0; FLASH 0;H$(XOLD,YOLD): FOR I=3 TO 6: LET W(I-2)=W(I): NEXT I: RETURN
4380 REM
4390 REM INVIO SU F CALL "VIS CP
4400 IF K=13 AND X=2 THEN PRINT AT R,2; INK 0;"F": LET VF=1: GO SUB 5170: REM VIS FT E BC
4410 REM
4420 REM INVIO SU X - PARTITA ANNULLATA
4430 IF K=13 AND X=1 THEN LET G$="G2_ANNULLATA": RETURN
4432 REM
4435 REM VAI A LOOP INPUT CH
4440 GO TO 4220
4450 REM
 
4470 REM DEMO +++++++++++
4480 REM ++++++++++++++++
4490 CLS
4500 LET G$="OK": LET NERI=0
4505 REM
4510 REM CALL DRAW BOARD
4520 GO SUB 6140
4530 REM
4580 REM METTE RND IN CS
4590 REM RANDOMIZE
4600 LET E=INT (RND*1296)
4610 FOR I=0 TO 9
4620 POKE (CS+I),PEEK (C1+E*12+I)
4630 NEXT I
4640 REM
4650 REM METTE CS IN V(4) PER VIS CS
4660 FOR I=1 TO 4: LET V(I)=PEEK (CS+I-1): NEXT I
4690 REM
4710 LET R=20
4720 REM CALL VIS CS
4730 GO SUB 6450
4740 REM
4750 LET R=-1
4760 REM
4770 REM **PUNTO DI LOOP PER TUTTE LE GIOCATE**
4780 LET R=R+2
4790 REM
4800 PRINT AT 1,18;" "
4810 PRINT AT 1,18;"Fit Codes:";FT;
4820 REM
4835 LET BC=PEEK MEMBC+PEEK (MEMBC+1)*256
4837 REM
4840 REM CALL GIOCATA PRG - RITORNA CP IN C0
4850 GO SUB 4030
4860 REM
4870 REM METTE C0 IN V()
4880 FOR I=1 TO 4: LET V(I)=PEEK (C0+I-1): NEXT I
4890 REM
4900 REM CALL VIS CP
4910 GO SUB 6450
4930 REM
4935 REM CALL TROVA CH TRA C0 E CS
4960 POKE ROUTINE,TROVACH: RANDOMIZE USR LM
4970 REM
4980 REM VIS CH
4990 LET NERI=PEEK (C0+10)
5000 LET BIAN=PEEK (C0+11)-NERI
5010 GO SUB 5840
5020 REM
5030 IF NERI=4 THEN GO SUB 2670: RETURN
5040 REM
5045 REM CALL ELIMINA CP
5080 POKE ROUTINE,ELIMINACP: RANDOMIZE USR LM
5090 LET FT=PEEK (MEMFT)+PEEK (MEMFT+1)*256
5112 REM
5115 REM CALL SIMULA
5125 GO SUB 2530
5130 REM
5140 REM VAI ALLA PROSSIMA GIOCATA
5150 GO TO 4770
5160 REM
 
5170 REM VIS FIT E BEST CODES - 2220 2440 4110
5190 PRINT AT 1,18;" "
5200 IF VF=1 THEN PRINT AT 1,18;"Fit Codes:";FT
5205 IF VF=1 AND OPZ=1 THEN PRINT AT 1,1;" "; AT 2,1;" ":
5210 IF VF=2 THEN PRINT AT 1,18;"BestCodes:";BC
5315 IF VF=2 THEN PRINT AT 1,1;"FitCod"; AT 2,2;FT
5220 REM
5230 REM PASSAGGIO VARIABILI PER ROUTINE VISFT E VISBC
5250 IF VF=1 THEN POKE MEMTUTTICP,(FT-INT (FT/256)*256)
5260 IF VF=1 THEN POKE MEMTUTTICP+1,INT (FT/256)
5270 IF VF=2 THEN POKE MEMTUTTICP,(1296-INT (1296/256)*256)
5280 IF VF=2 THEN POKE MEMTUTTICP+1,INT (1296/256)
5290 POKE MEMLASTPRT,(C1-INT (C1/256)*256)
5300 POKE MEMLASTPRT+1,INT (C1/256)
5310 POKE MEMNUMCPPRT,0
5320 POKE MEMNUMCPPRT+1,0
5325 REM
5330 REM ** LOOP VIS PAGINA DI FT/BC **
5340 POKE MEMVR,2
5350 REM
5360 IF VF=1 THEN POKE ROUTINE,VISFT: RANDOMIZE USR LM
5370 IF VF=2 THEN POKE ROUTINE,VISBC: RANDOMIZE USR LM
5380 LET VR=PEEK MEMVR
5390 LET NUMCPPRT=PEEK MEMNUMCPPRT+PEEK (MEMNUMCPPRT+1)*256
5400 PRINT AT 2,28;" "
5410 PRINT AT 2,18;"Displayed:";NUMCPPRT
5420 REM
5460 REM IF VF=1 THEN IF NUMCPPRT=FT THEN POKE MEMNUMCPPRT,0: POKE MEMNUMCPPRT+1,0
5470 REM IF VF=2 THEN IF NUMCPPRT=BC THEN POKE MEMNUMCPPRT,0: POKE MEMNUMCPPRT+1,0
5480 REM CALL MENU SCELTA/VIS FT/BC
5490 GO SUB 5550
5500 IF Z=1 THEN RETURN
5505 REM SE FT/BC SONO FINITI, RICOMINCIA DAL PRIMO
5510 IF VF=1 THEN IF NUMCPPRT=FT THEN GO TO 5250
5520 IF VF=2 THEN IF NUMCPPRT=BC THEN GO TO 5250
5525 REM VAI ALLA PROSSIMA PAGINA
5530 GO TO 5330
5540 REM
 
5550 REM MENU SCELTA/VIS FT/BC - 5170
5560 LET F=1: GO SUB 5800: REM VIS MENU A FRECCE - F=1 FLASH ON
5570 REM
5580 LET FR=VR: LET FROLD=VR
5590 REM CALL INPUT
5600 GO SUB 6570
5610 IF K=8 THEN LET Z=1: PRINT AT 20,18;" ": RETURN : REM SX
5620 IF K=10 THEN LET Z=2: RETURN : REM GIU
5630 IF K=11 AND OPZ=1 THEN LET F=0: GO SUB 5800: GO SUB 5670: IF Z=1 THEN RETURN : REM SU
5640 IF K=14 AND VF=1 AND S$="NO_RUN_AGAIN" AND FT<317 THEN GO SUB 5935: REM VIS PESI FT E BC
5642 IF K=14 AND VF=2 AND S$="NO_RUN_AGAIN" AND FT<317 THEN PRINT AT R,0;" "; AT R,0;PEEK (MEMPESOMIN)
5650 GO TO 5590
5660 REM
 
5670 REM SELEZIONE FT/BC DA GIOCARE - 5550
5680 LET FR=VR: LET FROLD=VR
5690 PRINT AT FR,30; FLASH 1;"\d"
5700 REM
5710 REM CALL INPUT
5720 GO SUB 6570
5725 IF K=8 THEN LET F=1: GO SUB 5800: PRINT AT FR,30;" ": LET Z=3: RETURN : REM SX
5730 IF K=11 THEN LET FR=FR-2: IF FR=2 THEN LET FR=VR: REM SU
5740 IF K=10 THEN LET FR=FR+2: IF FR=VR+2 THEN LET F=1: GO SUB 5800: PRINT AT VR,30;" ": LET Z=3: RETURN : REM GIU
5750 IF FR<>FROLD THEN PRINT AT FROLD,30;" ": PRINT AT FR,30; FLASH 1;"\d": LET FROLD=FR
5760 IF K=13 THEN PRINT AT FR,30;" ": PRINT AT 20,23;" ": FOR I=6 TO 0 STEP -2: LET TT=ATTR (FR,22+I)-120: PRINT AT R,8+I; INK TT;"\j": LET W(4+I/2)=TT: NEXT I: LET Y=TT: LET Z=1: PRINT AT R,4;" ": RETURN
5770 GO TO 5710
5780 REM
 
5800 REM VIS MENU A FRECCE - 5550
5805 PRINT AT 20,23; FLASH F;"\d";" "; FLASH F;"\f";" ";
5810 IF OPZ=1 THEN PRINT AT 20,27; FLASH F;"\e"
5820 RETURN
5830 REM
 
5840 REM ROUTINE VIS CH - OPZ 1 2 3
5850 LET I=6: LET Y=BIAN: LET X=NERI
5860 IF OPZ=1 THEN PRINT AT R,4;" "
5870 IF OPZ=2 THEN PRINT AT R,0;" "
5880 REM RIPETI PRINT DEI NERI
5890 IF X>0 THEN PRINT AT R,I;"\g": BEEP .04,-4: LET X=X-1: LET I=I-1: GO TO 5880
5900 REM RIPETI PRINT DEI BIANCHI
5910 IF Y>0 THEN PRINT AT R,I;"\h": BEEP .04,-4: LET Y=Y-1: LET I=I-1: GO TO 5900
5920 BEEP .04,-4
5925 RETURN
5930 REM
 
5935 REM ROUTINE VIS PESI DEI FT E BC - 5550
5936 PRINT AT R,0;PEEK (MEMPESOMIN)
5937 LET DS=PEEK (MEMLASTPRT)+PEEK (MEMLASTPRT+1)*256-12
5938 LET DT=NUMCPPRT-INT(NUMCPPRT/8)*8
5939 IF DT=0 THEN LET DT=8
5941 LET DT=DS-(DT-1)*12
5942 LET J=VR
5943 FOR I = DS TO DT STEP -12
5944 PRINT AT J,19;" ";AT J,19; PEEK (I+11)
5946 LET J=J-2
5948 NEXT I
5950 RETURN
5955 REM
 
5960 REM ROUTINE DRAW BOARD - OPZ 1
5970 PLOT 59,171
5980 DRAW 0,-14
5990 DRAW 64,0
6000 DRAW 0,14
6010 DRAW -64,0
6020 PRINT AT 1,8;"\i";" ";"\i";" ";"\i";" ";"\i";
6030 PLOT 59,4
6040 DRAW 0,146
6050 DRAW 64,0
6060 DRAW 0,-146
6070 DRAW -64,0
6080 REM
6090 FOR I=4 TO 20 STEP 2
6100 PRINT AT I,8;"\i";" ";"\i";" ";"\i";" ";"\i";AT I,16;(22-I)/2
6110 NEXT I
6120 RETURN
6130 REM
 
6140 REM ROUTINE DRAW BOARD - OPZ 2 3
6150 PLOT 59,26
6160 PRINT AT 20,8;"\i";" ";"\i";" ";"\i";" ";"\i"
6170 DRAW 0,146
6180 DRAW 64,0
6190 DRAW 0,-146
6200 DRAW -64,0
6210 REM
6220 FOR I=1 TO 17 STEP 2
6230 PRINT AT I,8;"\i";" ";"\i";" ";"\i";" ";"\i";AT I,16;(I+1)/2
6240 NEXT I
6250 PLOT 59,4
6260 DRAW 0,14
6270 DRAW 64,0
6280 DRAW 0,-14
6290 DRAW -64,0
6300 RETURN
6310 REM
 
6320 REM ROUTINE VIS CS OSCURATO - OPZ 1 2
6330 FOR I=1 TO 4
6340 LET Z=0
6350 FOR J=1 TO INT (RND*10)+1
6360 LET Z=Z+1
6370 IF Z=7 THEN LET Z=1
6380 PRINT AT R,6+2*I; INK Z;"\j"
6390 BEEP .02,-Z
6400 NEXT J
6410 PRINT AT R,6+2*I; INK 0;"\j"
6420 NEXT I
6430 RETURN
6440 REM
 
6450 REM ROUTINE VIS V() (CP O CS) - OPZ 2 3 3950
6460 FOR I=1 TO 4
6470 LET Z=0
6480 FOR J=1 TO V(I)
6490 LET Z=Z+1
6500 IF Z=7 THEN LET Z=1
6510 PRINT AT R,6+2*I; INK Z;"\j"
6520 BEEP .02,-Z
6530 NEXT J
6540 NEXT I
6550 RETURN
6560 REM
 
6570 REM ROUTINE INPUT
6580 PAUSE 0
6590 LET K=CODE INKEY$
6600 LET J=IN 31
6610 IF K=111 OR J=2 THEN LET K=8
6620 IF K=112 OR J=1 THEN LET K=9
6630 IF K=97 OR J=4 THEN LET K=10
6640 IF K=113 OR J=8 THEN LET K=11
6650 IF K=109 OR J=16 THEN LET K=13
6660 IF K=32 THEN LET K=14
6670 IF K<8 OR K>14 THEN GO TO 6570
6680 BEEP .04,-4
6690 RETURN
6700 REM
 
6720 REM ROUTINE PRESS ANY KEY
6730 PAUSE 0
6740 LET K=CODE INKEY$
6750 LET J=IN 31
6760 IF K=0 AND (J>16 OR J=0) THEN GO TO 6740
6770 BEEP .04,-4
6780 RETURN
6790 REM
 
6800 REM ROUTINE MENU
6810 CLS
6820 LET G(1,10)=0: LET G(2,10)=0
6830 FOR I=1 TO 5: LET G(1,10)=G(1,10)+G(1,I): LET G(2,10)=G(2,10)+G(2,I): NEXT I
6840 PRINT AT 2,9; INK 2; BRIGHT 1;"ZX MASTER MIND"
6850 PRINT AT 4,1; INK 8;"\j You guess my Secret Code \c\b\a"
6860 PRINT AT 6,1; INK 8;"\j I guess your Secret Code \a\b\c"
6870 PRINT AT 8,1; INK 8;"\j Demo \a\b\a"
6880 PRINT AT 10,1; INK 8;"\j Instructions"
6890 PRINT AT 13,1;" SCORE TOTAL "
6900 PRINT AT 15,2;"\c YOU:";AT 15,9;G(1,1);AT 15,12;G(1,2);AT 15,15;G(1,3);AT 15,18;G(1,4);AT 15,21;G(1,5);AT 15,26; INK 2;G(1,10)
6910 PRINT AT 17,2;"\a ME :";AT 17,9;G(2,1);AT 17,12;G(2,2);AT 17,15;G(2,3);AT 17,18;G(2,4);AT 17,21;G(2,5);AT 17,26; INK 2;G(2,10)
6920 PRINT AT 20,1;"\* 1985-2020 Zaffa Research Ltd"
6930 PLOT 12,76
6940 DRAW 230,0
6950 DRAW 0,-48
6960 DRAW -230,0
6970 DRAW 0,48
6980 REM
6990 PRINT AT 2+OPZ*2,1; FLASH 1; INK 2;"\j"
7000 IF G(1,5)<>0 AND G(2,5)<>0 THEN PRINT AT 15,26; FLASH 1; INK 1;G(1,10): PRINT AT 17,26; FLASH 1; INK 1;G(2,10): LET G$="FINITA": RETURN
7010 REM CALL INPUT
7020 GO SUB 6570
7030 IF K=10 THEN LET OPZ=OPZ+1: IF OPZ=5 THEN LET OPZ=1: REM GIU
7040 IF K=11 THEN LET OPZ=OPZ-1: IF OPZ=0 THEN LET OPZ=4: REM SU
7050 IF OPZ<>OPZOLD THEN PRINT AT 2+OPZOLD*2,1; FLASH 0; INK 0;"\j": PRINT AT 2+OPZ*2,1; FLASH 1; INK 2;"\j": LET OPZOLD=OPZ
7060 IF K=13 THEN RETURN
7065 REM IF K=14 THEN LET OPZ=5: RETURN
7070 GO TO 7010
7080 REM
 
7090 REM ISTRUZIONI
7100 LET G$="OK"
7110 CLS
7120 PRINT AT 0,1; INK 1;"KEYBOARD OR KEMPSTON JOYSTICK"
7130 REM PRINT AT 1,6; INK 1;"KEMPSTON JOYSTICK"
7140 PRINT AT 2,1; INK 1;"KEYS:"; INK 0;" \e or Q, \d or O"
7150 PRINT AT 3,6; INK 0;" \f or A, \b or P"
7160 PRINT AT 4,8;"Enter or M or Fire"
7170 PRINT AT 6,1; INK 1;"Game Options";
7180 PRINT AT 8,1; INK 1;"R"; INK 0;" - Random Secret Code"
7190 PRINT AT 10,1; INK 1;"H"; INK 00;" - Hide your Secret Code."
7200 PRINT AT 11,1;" (Write it down)"
7210 PRINT AT 13,1; INK 1;"F"; INK 0;" - Displays the Fit Codes"
7220 PRINT AT 15,1; INK 1;"B"; INK 0;" - Displays the Best Codes"
7230 PRINT AT 17,1; INK 1;"X"; INK 0;" - Exit from current game"
7240 PRINT AT 19,1; INK 1;"README.PDF"; INK 0;" For more information"
7250 PRINT AT 21,9;"Press any key"
7255 REM CALL PRESS ANY KEY
7260 GO SUB 6720
7270 RETURN
 
7300 REM STAT +++++++++++
7310 REM ++++++++++++++++
7312 LET TX=0: LET TN=0: LET TT=0
7315 FOR C= 1 TO 1296
7317 POKE ROUTINE,INIZ: RANDOMIZE USR LM
7319 LET FT=1296
7320 CLS
7330 LET G$="OK": LET NERI=0
7340 REM
7350 REM CALL DRAW BOARD
7360 GO SUB 6140
7370 REM
7380 REM METTE E IN CS
7410 FOR I=0 TO 9
7420 POKE (CS+I),PEEK (C1-12+C*12+I)
7430 NEXT I
7440 REM
7450 REM METTE CS IN V(4)
7460 FOR I=1 TO 4: LET V(I)=PEEK (CS+I-1): NEXT I
7470 REM
7480 LET R=20
7490 REM CALL VIS CS
7500 GO SUB 6450
7510 REM
7512 IF TN>TX THEN LET TX=TN
7514 PRINT AT 20,0;"MAX ";TX
7516 LET TT=TT+TN:
7518 IF C>1 THEN PRINT AT 18,0;"AVG ";TT/(C-1)
7520 LET R=-1: LET TN=0
7530 REM
7540 REM ** LOOP GIOCATE **
7550 LET R=R+2: LET TN=TN+1
7560 REM
7600 LET BC=PEEK MEMBC+PEEK (MEMBC+1)*256
7610 REM
7620 REM CALL GIOCATA PRG
7630 GO SUB 4030
7640 REM
7650 REM METTE C0 IN V()
7660 FOR I=1 TO 4: LET V(I)=PEEK (C0+I-1): NEXT I
7670 REM
7680 REM CALL VIS CP
7690 GO SUB 6450
7700 REM
7710 REM CALL TROVA CH
7720 POKE ROUTINE,TROVACH: RANDOMIZE USR LM
7730 REM
7740 REM VIS CH
7750 LET NERI=PEEK (C0+10)
7760 LET BIAN=PEEK (C0+11)-NERI
7770 GO SUB 5840
7780 REM
7790 IF NERI=4 THEN NEXT C:LET OPZ=1:PAUSE 0:RETURN
7800 REM
7810 REM CALL ELIMINA CP
7820 POKE ROUTINE,ELIMINACP: RANDOMIZE USR LM
7830 LET FT=PEEK (MEMFT)+PEEK (MEMFT+1)*256
7840 REM
7870 REM CALL SIMULA
7880 GO SUB 2530
7890 REM
7900 REM VAI A LOOP
7910 GO TO 7540
7920 REM
 
;ZX Master Mind
;Version MM62 - ASSEMBLER Part - Roberto Zaffanella
 
LM EQU 48000 ;INDIRIZZO PER IL CODICE OGGETTO
 
VAR EQU 49620 ;PUNTO DI PARTENZA PER LE VARIABILI
;LE VARIABILI USATE ANCHE DAL PROGRAMMA BASIC, INIZIANO CON "MEM"
 
C1 EQU 49728 ;1296 * 12 BYTES
;C1 PUNTA AL PRIMO FT (FT= FIT CODE)
 
ROUTINE EQU VAR+0 ;1 BYTE
;IL PRG BASIC CODIFICA OGNI ROUTINE CON UN NUMERO.
 
MEMFT EQU VAR+1 ;2 BYTES
;NUMERO TOTALE DEI CP RIMANENTI CIOE' DEI FT
 
;MEMVFLAG EQU VAR+3 ;1 BYTE
;NON USATA
 
MEMTUTTICP EQU VAR+4 ;2 BYTES
;USATA DA VISFT E VISBC. SETTATO UGUALE A FT O 1296
 
C0 EQU VAR+6 ;10 BYTES
;CODICE TENTATIVO
 
CH EQU VAR+16 ;2 BYTES
;CODICE CHIAVE. PUNTATO CON IX O IY +10 E +11
 
CS EQU VAR+18 ;12 BYTES
;CODICE SEGRETO
 
MEMVR EQU VAR+31 ;1 BYTE
;USATA DA VISFT E VISBC. RIGA IN CUI STAMPARE L'FT O BC
 
MEMLASTPRT EQU VAR+32 ;2 BYTES
;USATA DA VISFT E VISBC. INDIRIZZO DI MEMORIA DELL'ULTIMO FT O BC STAMPATO
 
MEMNUMCPPRT EQU VAR+34 ;2 BYTES
;USATA DA VISFT E VISBC. NUMERO DI FT O BC STAMPATI
 
CONTROV EQU VAR+36 ;2 BYTES
;SETTATA COME NUMCP DA SIMULACORE PER IL CONTO ALLA ROVESCIA
 
; 2 BYTES LIBERI 38 E 39
 
OFFSETXO EQU VAR+40 ;XX BYTES
;USATA DA SIMULACORE
 
;NUMCS EQU VAR+80 ;2 BYTE
;NON USATA
 
NUMCP EQU VAR+82 ;2 BYTE
;NUMERO DI CP CONSIDEARTI NELLA ROUTINE SIMULACORE
 
MEMPESOMIN EQU VAR+84 ;2 BYTE
;USATA DA TROVAPESOMINORE. CONTIENE IL PESO DEL CP CHE HA IL PESO PIU' BASSO
 
MEMR EQU VAR+86 ;1 BYTE
;USATA SOLO DA CONTOROVESCIA. RIGA DEL CP GIOCATO PASSATA DAL BASIC
 
MEMBC EQU VAR+87 ;2 BYTE
;NUMERO TOTALE DEI BC. USATA SOLO DA NUMBESTCODES
 
MEME EQU VAR+89 ;2 BYTE
;(MEME)CONTIENE E=INT (RND*BC)+1 - BC E' IL TOTALE DEI BC
;USATA SOLO DA GIOCATAPRG
 
TEMP EQU VAR+91 ;12 BYTES
;USATA DA "COMPATTA" PER SWAP CP
 
 
;----------------------------------------------------
ORG LM
 
LD A,(ROUTINE)
 
CP 1
JP Z,INIZ
 
CP 2
JP Z,CLEANVIDEO
 
CP 3
JP Z,DEFNUMCOL
 
CP 4
JP Z,TROVACH
 
CP 5
JP Z,ELIMINACP
 
CP 6
JP Z,VISFT
 
CP 7
JP Z,SIMULA
 
CP 8
JP Z,VISBC
 
CP 9
JP Z,GIOCATAPRG
 
RET
 
 
;-----------------------------------------------------
;INIZIALIZZAZIONE DEI CP (CP SONO IN GENERALE I CODICI POSSIBILI)
;I CP PARTONO DA 1296 E POI DIMINUISCONO AD OGNI GIOCATA
;INIZ VIENE CHIAMATA PRIMA DI OGNI PARTITA
INIZ
CALL INIZ_CODICI
CALL INIZ_NUMCOL
CALL INIZ_PESI
CALL TROVAPESOMINORE
CALL NUMBESTCODES
LD HL,1296
LD (MEMFT),HL
RET
 
 
;INIZIALIZZA I PRIMI 4 BYTE DEL CODICE
;UN BYTE PER OGNI POSIZIONE VALORIZZATO CON IL NUMERO DEL COLORE
INIZ_CODICI
LD IX,C1
LD D,1
LOOP_E
LD E,1
LOOP_B
LD B,1
LOOP_C
LD C,1
NEXT_CP
LD (IX+0),D
LD (IX+1),E
LD (IX+2),B
LD (IX+3),C
PUSH BC
LD BC,12
ADD IX,BC
POP BC
INC C
LD A,7
CP C
JR NZ,NEXT_CP
INC B
LD A,7
CP B
JR NZ,LOOP_C
INC E
LD A,7
CP E
JR NZ,LOOP_B
INC D
LD A,7
CP D
JR NZ,LOOP_E
RET
 
 
;INIZIALIZZA 6 BYTE DA C1+4. OGNI BYTE CORRISPONE A UN COLORE
;E CONTIENE IL NUMERO DI VOLTE CHE QUESTO COLORE E' PRESENTE NEL CP
INIZ_NUMCOL
LD IX,C1
LD BC,1296 ; 1296 CP
RPT_NEXT_CP
LD D,0
LD (IX+4),0
LD (IX+5),0
LD (IX+6),0
LD (IX+7),0
LD (IX+8),0
LD (IX+9),0
 
LD A,(IX+0)
ADD A,3 ;PER PUNTARE AI BYTE DI NUMCOL
LD E,A
PUSH IX
POP HL
ADD HL,DE ;HL PUNTA AL BYTE DEL COLORE
INC (HL)
 
LD A,(IX+1)
ADD A,3
LD E,A
PUSH IX
POP HL
ADD HL,DE
INC (HL)
 
LD A,(IX+2)
ADD A,3
LD E,A
PUSH IX
POP HL
ADD HL,DE
INC (HL)
 
LD A,(IX+3)
ADD A,3
LD E,A
PUSH IX
POP HL
ADD HL,DE
INC (HL)
 
LD DE,12 ;PASSA AL CP SUCCESSIVO
ADD IX,DE
DEC BC
LD A,B
OR C
JP NZ,RPT_NEXT_CP
RET
 
 
;INIZIALIZZA I CAMPI PESO.
;IX+10 E' IL CAMPO FIT E VIENE SETTATO A $FF. UN FT ESCLUSO VERRA' FLAGGATO COME "AA"
;IX+11 E' IL CAMPO BC E VIENE SETTATO A $BC SE IL CODICE E' DI TIPO 1234 1123 1122.
;SETTATO A $EE SE E'DEL TIPO 1112 O 1111
 
INIZ_PESI
 
LD IX,C1
LD BC,1296 ; 1296 CP
LD DE,12
 
RPT_SETPESI
LD (IX+10),$FF
LD (IX+11),$EE
 
LD A,(IX+4)
CP 3 ;SE A=>3 ALLORA NO CARRY
JR NC,NOBC
 
LD A,(IX+5)
CP 3
JR NC,NOBC
 
LD A,(IX+6)
CP 3
JR NC,NOBC
 
LD A,(IX+7)
CP 3
JR NC,NOBC
 
LD A,(IX+8)
CP 3
JR NC,NOBC
 
LD A,(IX+9)
CP 3
JR NC,NOBC
 
LD (IX+11),$BC ;CAMPO BC SETTATO A $BC
 
NOBC
ADD IX,DE ;PASSA AL CP SUCCESSIVO
DEC BC
LD A,B
OR C
JP NZ,RPT_SETPESI
LD A,$BC
LD (MEMPESOMIN),A
RET
 
 
;--------------------------------------------------------
;PULISCE LA ZONA VIDEO DI VISUALIZZA FIT E BEST CODES
CLEANVIDEO
 
LD IY,23610
LD A,2
CALL 5633
 
;PRTENZA DA RIGA 2
LD B,2
 
NEXTRIGA
;PARTENZA DA COLONNA 18
LD C,18
 
NEXTCOL
LD A,22 ;AT
RST 16
 
LD A,B ;RIGA
RST 16
 
LD A,C ;COLONNA
RST 16
 
LD A,32 ; METTI IN A UNO SPAZIO " "
RST 16 ; STAMPA AT B,C;" "
 
INC C
LD A,C
CP 31 ; FINO A COLONNA 30
JR NZ,NEXTCOL
 
INC B
LD A,B
CP 21 ;FINO A RIGA 20
JR NZ,NEXTRIGA
 
RET
 
;-----------------------------------------------------
;PASSA IL CODICE DA BASIC IN MEMORIA.
;RICEVE I CAMPI "CODICE" CON UNA POKE DAL BASIC (C0 +0 +1 +2 +3)
;VALORIZZA I CAMPI NUMCOL DI C0
 
DEFNUMCOL
LD IX,C0
 
LD (IX+4),0 ;RESETTA I CAMPI "NUMERO DI COLORI"
LD (IX+5),0
LD (IX+6),0
LD (IX+7),0
LD (IX+8),0
LD (IX+9),0
LD D,0
 
LD A,(IX+0)
ADD A,3 ;PER PUNTARE AI BYTE DI NUMCOL
LD E,A
PUSH IX
POP HL
ADD HL,DE ;HL PUNTA AL BYTE DEL COLORE
INC (HL)
 
LD A,(IX+1)
ADD A,3
LD E,A
PUSH IX
POP HL
ADD HL,DE
INC (HL)
 
LD A,(IX+2)
ADD A,3
LD E,A
PUSH IX
POP HL
ADD HL,DE
INC (HL)
 
LD A,(IX+3)
ADD A,3
LD E,A
PUSH IX
POP HL
ADD HL,DE
INC (HL)
 
RET
 
 
;----------------------------------------------------------
;CONFRONTA CS CON C0 E METTI I NERI IN C0+10 E
;I BIACHI+NERI IN C0+11
;CHIAMATA DA GIOC>PRG
TROVACH
LD IY,C0
LD IX,CS
CALL TEST
LD A,C
LD (C0+10),A ;NUMERO DI NERI
LD A,B
LD (C0+11),A ;NUMERO DI NERI + BIANCHI
RET
 
 
;--------------------------------------------------------------------
;TROVA IL NUMERO DI NERI+BIANCHI CONFRONTANDO C0 NUM COLORI
;PUNTATO DA IY E UN CP PUNTATO DA IX
;RITORNA B CON IL NUMERO DI X+O (VIENE MODIFICATO AF E BC
;IX^CP o IX^CS IY^C0 B=NUM DI NERI+BIANCHI
TEST
 
LD C,(IX+4)
LD A,(IY+4)
CP C
JR C,JUMP1 ;SE A<C SALTA
LD A,C ;METTI IN A IL NUN COL MINORE TRA (IX+3) E (IY+3)
JUMP1
LD B,A ;TIENE IN B IL NUMERO DI NERI+BIANCHI
 
LD C,(IX+5)
LD A,(IY+5)
CP C
JR C,JUMP2
LD A,C
JUMP2
ADD A,B
LD B,A
 
LD C,(IX+6)
LD A,(IY+6)
CP C
JR C,JUMP3
LD A,C
JUMP3
ADD A,B
LD B,A
 
LD C,(IX+7)
LD A,(IY+7)
CP C
JR C,JUMP4
LD A,C
JUMP4
ADD A,B
LD B,A
 
LD C,(IX+8)
LD A,(IY+8)
CP C
JR C,JUMP5
LD A,C
JUMP5
ADD A,B
LD B,A
 
LD C,(IX+9)
LD A,(IY+9)
CP C
JR C,JUMP6
LD A,C
JUMP6
ADD A,B
LD B,A
 
;------------------------------------------------------------------
;TROVA IL NUMERO DI NERI CONFRONTANDO C0 PUNTATO DA IY
;E UN CP PUNTATO DA IX. ;RITORNA C CON IL NUMERO DI NERI
;VIENE MODIFICATO AF E BC
;IX^CP IY^C0 C=NUM DI NERI
 
 
LD C,0
PEG1
LD A,(IX+0)
CP (IY+0)
JP NZ, PEG2
INC C
PEG2
LD A,(IX+1)
CP (IY+1)
JP NZ, PEG3
INC C
PEG3
LD A,(IX+2)
CP (IY+2)
JP NZ, PEG4
INC C
PEG4
LD A,(IX+3)
CP (IY+3)
RET NZ
INC C
RET
 
 
 
 
;---------------------------------------------------------------------------
;ELIMINAZIONE CODICI IMPOSSIBILI
;CONFRONTA C0 CON I CP. SE CH NON E' UGUALE A QUELLO IN C0+10/11
;ELIMINA IL CP.
;I CP BUONI CIOE' I FIT CODE VENGONO SPOSTATI DA C1 FINO A FT
;FT E' IL TOTALE DEL NUMERO DI CP RIMASTI
ELIMINACP
 
CALL FLAG_CP
LD A,E
OR D
RET Z ;FT=0 ALMOST ONE KEY CODE WRONG
 
CALL COMPATTA
 
RET
 
 
;--------------------------------------
;METTE FF IN IX+10 PER TUTTI I CP BUONI
FLAG_CP
LD HL,(MEMFT) ;HL=NUMERO DI FT DI PARTENZA
 
LD A,0 ;RESETTA IL TOTALE DEI FT
LD (MEMFT),A
LD (MEMFT+1),A
 
LD DE,(MEMFT) ;DE E' IL NUOVO CONTATORE FT
 
LD IX,C1
LD IY,C0
 
LOOP5
LD (IX+10),$AA ;SETTA DI DAFAULT IL CP IN C1 COME UN FIT CODE ELIMINATO
CALL TEST ;RITORNA C=NUM DI X E B=O+X
LD A,(IY+10) ;A=NUMERO DI X DI C0 QUELLE DATE DAL GIOCATORE O DAL COMPUTER
CP C
JR NZ,NEGATIVO1 ;SE IL NUM DI X E' DIVERSO, ELIMINA IL CP
 
LD A,(IY+11) ;METTE IN A IL NUM DI O+X DI C0
CP B ;SE IL NUM DI X+O E' DIVERSO, ELIMINA IL CP
JR NZ,NEGATIVO1
 
LD (IX+10),$FF ;SE IL CP NON VIENE ELIMINATO, VIENE FLAGGATO COME FT CON IL VALORE $FF
INC DE ;INCREMENTA IL TOTALE DEI FT
 
NEGATIVO1
PUSH DE ;AL CP RIMANE IL FLAG $AA E QUINDI VIENE ELIMINATO
LD DE,12
ADD IX,DE ;IX PASSA AL CP SUCCESSIVO
POP DE
 
DEC HL
LD A,H
OR L
JP NZ,LOOP5 ;RIPETI PER TUTTI I CP
LD (MEMFT),DE ;AGGIORNA IL NUMERO TOTALE DI FT
 
RET
 
;---------------------------------------
;COMPATTA TUTTI GLI FT, QUELLI CON $FF A PARTIRE DA C1
;CALCOLA L'INDIRIZZO DEL PRIMO CP NELL'AREA FT+1 CIOE' NELL'AREA
;DEI CP ESCLUSI. CERCA PARTENDO DA C1 IL PRIMO CP ELIMINATO E QUANDO LO TROVA,
;CERCA IL PRIMO FT NELL'AREA DEGLI ESCLUSI. qUANDO LO TROVA LI SCAMBIA DI POSIZIONE.
;RIPETE FINO A CHE TUTTI GLI FT PARTONO DA C1 E ARRIVANO FINO A FT
 
 
COMPATTA
 
 
LD IX,C1-12 ;IX PUNTA AI CP A PARTIRE DA C1
LD BC,(MEMFT) ;BC E' IL NUMERO DI CONFRONTI PER LO SWAP
INC BC
 
LD HL,(MEMFT) ;CALCOLO DELL'OFFSET PER L'AREA DEI CP NON BUONI
DEC HL
LD DE,12
; HL=HL*DE
CALL $30A9
LD DE,C1
ADD HL,DE
PUSH HL
POP IY ;IY PUNTA ALLA POSIZIONE DEL PRIMO CP NON BUONO
 
LD DE,12
 
FINDDELETEDCP
ADD IX,DE ;CERCA I CP NON BUONI NELL'AREA DEI BUONI
DEC BC ;
LD A,B
OR C
RET Z ;RITORNA QUANDO FINISCE LA ZONA DEI CP BUONI
LD A,$AA ;SE IX+10 E'$AA IL CP NON E' BUONO E QUINDI FAI LO SWAP
CP (IX+10)
JR Z,READYFORSWAP
JR FINDDELETEDCP
 
READYFORSWAP
 
CERCAFT
ADD IY,DE ;CERCA I CP BUONI NELL'AREA DEI NON BUONI
LD A,$FF
CP (IY+10)
JR NZ,CERCAFT ;QUANDO TROVATO, PROCEDI CON LO SWAP
 
PUSH BC ;SALVA BC
PUSH DE ;SALVA DE
 
PUSH IX
POP HL ;HL SOURCE DATA
LD DE,TEMP ;DE TARGET DATA
LD BC,12 ;NUMERB OF BYTE TO MOVE
LDIR
 
PUSH IY
POP HL ;HL SOURCE DATA
PUSH IX
POP DE ;DE TARGET DATA
LD BC,12 ;NUMERB OF BYTE TO MOVE
LDIR
 
LD HL,TEMP ;HL SOURCE DATA
PUSH IY
POP DE ;DE TARGET DATA
LD BC,12 ;NUMERB OF BYTE TO MOVE
LDIR
POP DE ;RIPRISTINA DE
POP BC ;RIPRISTINA BC
 
JR FINDDELETEDCP
 
 
;----------------------------------------------------
;VISUALIZZA FIT CODES
VISFT
 
CALL CLEANVIDEO
 
LD IX,(MEMLASTPRT) ;VIENE PASSATO DAL BASIC E SETTATO COME C1
LD B,8 ;NUMERO DI FT DA VISUALIZZARE PRIMA DI TORNARE AL BASIC
LD C,0
 
NEXTFT
PUSH BC
CALL PRINTCP
POP BC
LD HL,(MEMNUMCPPRT) ;NUMERO DI FT VISUALIZZATI. SETTATO A 0 DAL BASIC
INC HL
LD (MEMNUMCPPRT),HL
LD DE,12
ADD IX,DE
LD HL,(MEMTUTTICP) ;SETTATO INIZIALMENTE UGUALE A FT DAL BASIC
DEC HL
LD (MEMTUTTICP),HL
LD (MEMLASTPRT),IX ;SALVA L'INDIRIZZO DELL'ULTIMO FT VISUALIZZATO
LD A,H
OR L
RET Z ;SE I FT DA VISUALIZZARE SONO FINITI, RITORNA
DJNZ NEXTFT ;RIPETI PER 8 FT DA VISUALIZZARE
RET
 
 
;-------------------------------------------------------
;VISUALIZZA BEST CODES
VISBC
 
CALL CLEANVIDEO
 
LD IX,(MEMLASTPRT)
LD B,8
LD C,0
 
NEXTBC
LD A,(MEMPESOMIN) ;VISUALIZZA SOLO SE (IX+11) E' UGUALE A PESOMIN
CP (IX+11)
JR Z,CONTINUAPRINTBC
LD DE,12
ADD IX,DE
LD HL,(MEMTUTTICP) ;SETTATO A 1296 DAL BASIC
DEC HL
LD (MEMTUTTICP),HL
LD A,H
OR L
RET Z
JR NEXTBC
 
 
CONTINUAPRINTBC
PUSH BC
CALL PRINTCP
POP BC
LD HL,(MEMNUMCPPRT)
INC HL
LD (MEMNUMCPPRT),HL
LD DE,12
ADD IX,DE
LD HL,(MEMTUTTICP)
DEC HL
LD (MEMTUTTICP),HL
LD A,H
OR L
RET Z
DJNZ NEXTBC
LD (MEMLASTPRT),IX
RET
 
 
 
;-------------------------
PRINTCP
LD HL,MEMVR ;VISUALIZZA RIGA. SETTATA INIZIALMENTE A 2 DAL BASIC
INC (HL)
INC (HL)
 
LD IY,23610
 
LD A,2
CALL 5633
 
LD A,22 ;AT
RST 16
 
LD A,(MEMVR) ;RIGA
RST 16
 
LD A,20 ;COLONNA
RST 16
 
 
LD A,$AA ;SE E' BC INCONSISTENTE STAMPA *
CP (IX+10)
JR Z,STAMPA_ASTERISCO
 
LD A,32 ;ALTRIMENTI STAMPA SPAZIO
RST 16 ;STAMPA UNO SPAZIO
JR CONT765
 
 
STAMPA_ASTERISCO
LD A,42 ;*
RST 16 ;STAMPA UN "*"
 
 
CONT765
 
 
;................ primo piolo
LD A,16 ;INK
RST 16
 
LD A,(IX+0) ;VALORE INK
RST 16
 
LD A,22 ;AT
RST 16
 
LD A,(MEMVR) ;RIGA
RST 16
 
LD A,22 ;COLONNA
RST 16
 
LD A,153
RST 16
 
;................ secondo
 
LD A,16 ;INK
RST 16
 
LD A,(IX+1) ;VALORE INK
RST 16
 
LD A,22 ;AT
RST 16
 
LD A,(MEMVR) ;RIGA
RST 16
 
LD A,24 ;COLONNA
RST 16
 
LD A,153
RST 16
 
;.................... terzo
 
LD A,16 ;INK
RST 16
 
LD A,(IX+2) ;VALORE INK
RST 16
 
LD A,22 ;AT
RST 16
 
LD A,(MEMVR) ;RIGA
RST 16
 
LD A,26 ;COLONNA
RST 16
 
LD A,153
RST 16
 
;.................... quarto
 
LD A,16 ;INK
RST 16
 
LD A,(IX+3) ;VALORE INK
RST 16
 
LD A,22 ;AT
RST 16
 
LD A,(MEMVR) ;RIGA
RST 16
 
LD A,28 ;COLONNA
RST 16
 
LD A,153
RST 16
 
RET
 
 
;------------------------------------------
SIMULA
 
LD BC,(MEMFT)
LD HL,317 ;SE FT > 317 ESEGUI SOLO ELIMINA BC INCONSISTENTI E NUMBESTCODES
OR A ;AZZERA I FLAG
SBC HL,BC
JP NC,CONT741
CALL ELIMINAINCONSISTENTI
CALL NUMBESTCODES
RET
 
CONT741
CALL CLSPESI
CALL SIMULACORE
CALL TROVAPESOMINORE
CALL ELIMINAINCONSISTENTI
CALL NUMBESTCODES
RET
 
;-----------------
;CLS PESI - SETTA A $FF I CAMPI PESO DI TUTTI I CP
CLSPESI
 
LD BC,1296
LD IX,C1
LD DE,12
CLS
LD (IX+11),$FF
ADD IX,DE
DEC BC
LD A,B
OR C
JR NZ,CLS
RET
 
 
;------------------
;IY PUNTA AI CP - IX PUNTA AI CS
SIMULACORE
 
LD HL,(MEMFT)
 
LD BC,50 ;SE FT <= 50 CONSIDERA SOLO I FIT, ALTRIMENTI CONSIDERA TUTTI I 1296 CODICI
PUSH HL
OR A ;AZZERA I FLAG
SBC HL,BC
POP HL
JR NC,CONTINUA888 ; SE HL>BC CIOE' FT>50 SALTA A CONTINUA888. SE I FT SONO PIU' DI 50 USA SOLO I FT
 
LD BC,3 ;SE FT<3 CONSIDERA SOLO I FIT, ALTRIMENTI CONSIDERA TUTTI I 1296 CODICI
PUSH HL
OR A ;AZZERA I FLAG
SBC HL,BC
POP HL
JR C,CONTINUA888 ; SE HL<=BC CIOE' SE FT<=3 SALTA A CONTINUA888
LD HL,1296 ; SIMULA CON TUTTI I CP
 
CONTINUA888
LD (NUMCP),HL ;SE FT>50 OR FT<3 THEN NUMCP=FT ELSE NUMCP=1296
LD (CONTROV),HL ;SALVA (NUMCP) IN CONTO ALLA ROVESCIA
LD IY,C1 ;IY PUNTA AI CP
;INC (IY+11) ;SETTA IL PESO A ZERO DOPO CHE CLSPESI LO HA SETTATO A $FF
 
NEXTCP88
INC (IY+11) ;SETTA IL PESO A ZERO DOPO CHE CLSPESI LO HA SETTATO A $FF
LD IX,C1 ;IX PUNTA AI CS
LD DE,12
;CLEAN OFFSET
LD B,14
LD HL,OFFSETXO ;HL PUNTA ALL'OFFSET DEI NERI E BIANCHI
AZZERAOFFSET
LD (HL),0 ; SETTA 0 NELLE 14 CASELLE DELL'OFFSET
INC HL
DJNZ AZZERAOFFSET
LD HL,(MEMFT) ;HL E' IL NUMERO DI CS
 
RIPETISETTAOFFSET
CALL SETTAOFFSET ;CONFRONTA IY (CP) CON IX (CS) E METTE CH NELL'OFFSET
DEC HL ;DECREMENTA IL NUMERO DI CS E QUANDO SONO FINITI VAI A CALCPESO
LD A,H
OR L
JP Z,CALCPESO ;SE I CS SONO FINITI VAI A CALCOLA PESO
ADD IX,DE ;PASSA AL PROSSIMO CS
JR RIPETISETTAOFFSET
 
CALCPESO
LD A,0
LD B,14 ;NUMERO DI TIPI DI CH NELL'OFFSET
LD HL,OFFSETXO
 
NEXTCH01
LD A,(IY+11) ;A= PESO DEL CP. AL PRIMO CICLO E' ZERO
OR A
SBC A,(HL) ;PESO DEL CP - PESOOFFSET
JR NC,CONT456
LD A,(HL) ;SE PESO DEL CP < PESOOFFSET ALLORA METTI IL PESO DELL'OFFSET NEL CP
LD (IY+11),A
 
CONT456
INC HL ;HL PUNTA AL PROSSIMO CH DELL'OFFSET
DJNZ NEXTCH01
 
LD HL,(NUMCP) ;DECREMENTA IL NUMERO DI CP. SE FINITI, ROTORNA.
DEC HL
LD A,H
OR L
RET Z
 
ADD IY,DE ;IY PASSA AL PROSSIMO CP
LD (NUMCP),HL ;SALVA IL NUMERO DI CP
PUSH IY
CALL CONTOROVESCIA ;VISUALIZZA A VIDEO IL CONTATORE
POP IY
;INC (IY+11) ;SETTA IL PESO A ZERO DOPO CHE CLSPESI LO HA SETTATO A $FF
JP NEXTCP88
 
SETTAOFFSET ;INCREMENTA IL CH RISULTANTE DAL TEST DI IX E IY
CALL TEST ;TORNA C CON IL NUMERO DI NERI E B CON IL NUMERO DI NERI+BIANCHI
LD A,B
SUB C
LD B,A ;METTE IN B IL NUMERO DI BIANCHI
;C=NUMERO DI NERI
;B=NUMERO DI BIANCHI
 
LD A,0
CP C
JR Z,ZERO_NERI
 
LD A,1
CP C
JR Z,UNO_NERO
 
LD A,2
CP C
JR Z,DUE_NERI
 
LD A,3
CP C
JR Z,TRE_NERI
 
LD A,4
CP C
JR Z,QUATTRO_NERI
 
 
ZERO_NERI
LD A,0
CP B
JR Z,CH_
 
LD A,1
CP B
JR Z,CH_O
 
LD A,2
CP B
JR Z,CH_OO
 
LD A,3
CP B
JR Z,CH_OOO
 
LD A,4
CP B
JR Z,CH_OOOO
 
 
UNO_NERO
LD A,0
CP B
JR Z,CH_X
 
LD A,1
CP B
JR Z,CH_OX
 
LD A,2
CP B
JR Z,CH_OOX
 
LD A,3
CP B
JR Z,CH_OOOX
 
 
DUE_NERI
LD A,0
CP B
JR Z,CH_XX
 
LD A,1
CP B
JR Z,CH_OXX
 
LD A,2
CP B
JP Z,CH_OOXX
 
 
TRE_NERI
LD A,(OFFSETXO+12)
INC A
LD (OFFSETXO+12),A
RET
 
QUATTRO_NERI
LD A,(OFFSETXO+13)
INC A
LD (OFFSETXO+13),A
RET
 
CH_
LD A,(OFFSETXO+0)
INC A
LD (OFFSETXO+0),A
RET
 
CH_O
LD A,(OFFSETXO+1)
INC A
LD (OFFSETXO+1),A
RET
 
CH_OO
LD A,(OFFSETXO+2)
INC A
LD (OFFSETXO+2),A
RET
 
CH_OOO
LD A,(OFFSETXO+3)
INC A
LD (OFFSETXO+3),A
RET
 
CH_OOOO
LD A,(OFFSETXO+4)
INC A
LD (OFFSETXO+4),A
RET
 
CH_X
LD A,(OFFSETXO+5)
INC A
LD (OFFSETXO+5),A
RET
 
CH_OX
LD A,(OFFSETXO+6)
INC A
LD (OFFSETXO+6),A
RET
 
CH_OOX
LD A,(OFFSETXO+7)
INC A
LD (OFFSETXO+7),A
RET
 
CH_OOOX
LD A,(OFFSETXO+8)
INC A
LD (OFFSETXO+8),A
RET
 
CH_XX
LD A,(OFFSETXO+9)
INC A
LD (OFFSETXO+9),A
RET
 
CH_OXX
LD A,(OFFSETXO+10)
INC A
LD (OFFSETXO+10),A
RET
 
CH_OOXX
LD A,(OFFSETXO+11)
INC A
LD (OFFSETXO+11),A
RET
 
 
;---------
;TROVA PESOMIN
TROVAPESOMINORE
 
LD BC,1296
LD DE,12
LD IX,C1
LD HL,MEMPESOMIN
LD (HL),255 ;SETTA PESOMIN=255
 
LOOP6
LD A,(HL) ;A=255 AL PRIMO GIRO
CP (IX+11)
JR C,CONTINUA01 ;SE (IX+11) > (PESOMIN) THEN (PESOMIN)= (IX+11)
 
LD A,(IX+11)
LD (HL),A
 
CONTINUA01
ADD IX,DE
DEC BC
LD A,B
OR C
JP NZ,LOOP6
RET
 
 
;---------
;ELIMINA BC INCONSISTENTI
;SE CI SONO BC CHE SONO ANCHE FT, QUELLI INCONSISTENTI VANNO ELIMINATI
;
ELIMINAINCONSISTENTI
 
LD BC,(MEMFT)
LD DE,12
LD IX,C1
LD H,0 ;H E' IL FLAG. SE H=0 NON CI SONO BC TRA I FT
 
LOOP888
LD A,(MEMPESOMIN)
CP (IX+11)
JR NZ, CONT333 ;SETTA IL FLAG H A 1 SE TROVATO UN BC TRA I FT
LD H,1
CONT333
ADD IX,DE
DEC BC
LD A,B
OR C
JR NZ,LOOP888 ;CICLA PER TUTTI GLI FT
 
XOR A
CP H
RET Z ;SE NON E' STATO TROVATO UN BC TRA I FT, RITORNA
 
LD HL,1296
LD BC,(MEMFT)
OR A ;AZZERA I FLAG
SBC HL,BC ;HL E' IL NUMERO DEI CP NON FT
RET Z ;SE FT=1296 TORNA. CASO DEL PRIMO TENTATIVO GIOC>PRG
 
 
LOOP546
LD (IX+11),$FF ;SETTA IL PESO A FF PER ELIMINARE TUTTI I BC NON FT
ADD IX,DE
DEC HL
LD A,H
OR L
JR NZ,LOOP546 ;RIPETI PER TUTTI I CP NON FT
 
RET
 
 
 
 
;---------
CONTOROVESCIA
 
LD HL,(CONTROV)
DEC HL
LD (CONTROV),HL
 
LD IY,23610
LD A,2
CALL 5633
 
; IMPOSTA FLASH 1
LD A,18
RST 16
 
LD A,1
RST 16
 
; AZZERA COL 30 31
LD A,22 ;AT
RST 16
 
LD A,(MEMR) ;RIGA
RST 16
 
LD A,30 ;COLONNA
RST 16
 
LD A,32
RST 16
 
LD A,32
RST 16
 
; PRINT CONTROV A COL 29
LD A,22 ;AT
RST 16
 
LD A,(MEMR) ;RIGA
RST 16
 
LD A,28 ;COLONNA
RST 16
 
LD BC,(CONTROV)
CALL 6683
 
RET
 
 
;-----------------------------------
NUMBESTCODES
;CONTA BEST CODES
 
LD A,0
LD (MEMBC),A
LD (MEMBC+1),A
LD BC,1296
LD DE,12
LD IX,C1
 
LOOP444
LD A,(MEMPESOMIN)
CP (IX+11)
JR NZ, CONT335
LD HL,(MEMBC) ;SE (IX+11)=(MEMPESOMIN) THEN INC (MEMBC)
INC HL
LD (MEMBC),HL ;(MEMBC) E' IL NUMERO DI BC
 
CONT335
ADD IX,DE
DEC BC
LD A,B
OR C
JR NZ,LOOP444
RET
 
 
;-------------------------------
GIOCATAPRG
 
LD IX,C1
LD IY,C0
 
LD BC,(MEME) ;(MEME)CONTIENE E=INT (RND*BC)+1 - BC E' IL TOTALE DEI BC
LD DE,12
 
 
NEXTBC1
LD A,(MEMPESOMIN)
CP (IX+11)
JR NZ,NEXTCP
DEC BC
LD A,B
OR C
JR Z,TROVATOCP
NEXTCP
ADD IX,DE
JR NEXTBC1
 
TROVATOCP
LD A,(IX+0)
LD (IY+0),A
LD A,(IX+1)
LD (IY+1),A
LD A,(IX+2)
LD (IY+2),A
LD A,(IX+3)
LD (IY+3),A
LD A,(IX+4)
LD (IY+4),A
LD A,(IX+5)
LD (IY+5),A
LD A,(IX+6)
LD (IY+6),A
LD A,(IX+7)
LD (IY+7),A
LD A,(IX+8)
LD (IY+8),A
LD A,(IX+9)
LD (IY+9),A
LD A,(IX+10)
LD (IY+10),A
LD A,(IX+11)
LD (IY+11),A
RET
 
 
;-------------------------------
 
;PER DEBUG
;ATTENDI2
;LD A,1
;CP 2
;JR Z,ATTENDI2
1,973

edits