In this project you’ll learn how to adapt source-code to TI-84.
I’ve used this code as a base: Mastermind
The game
If you want to play the game you have to know the rules of Mastermind.
There are 6 colors, each of them have a different number:
1 – RED, 2 – GREEN, 3 – YELLOW, 4 – BLUE, 5 – BLACK, 6 – ORANGE
Example: RED YELLOW ORANGE BLACK —> 1 3 6 5
After entering your code (for instance 1 1 2 2) you’ll get back feedback with two characters:
R – color and position is OK
W – only the color is OK
The source code
I’ve checked the sample program in in Github, file MASTR002.py. I’ve made several commits with comments to make it easier for you to follow the steps.
There were several challenges to solve.
The “random” functionality of the TI-84 lacks a function “shuffle”, so I had to rewrite the code like this:
Original code:
random.shuffle(colors)
passcode = colors[:4]
Changed code:
col1 = random.randrange(1, 6)
col2 = random.randrange(1, 6)
col3 = random.randrange(1, 6)
col4 = random.randrange(1, 6)
# passcode = colors[:4]
passcode = []
passcode.clear()
passcode.append(colors[col1])
passcode.append(colors[col2])
passcode.append(colors[col3])
passcode.append(colors[col4])
You see, quite a change! In the first part (col1..col4) the variables are filled with a random number between 1 and 6. In the second part, the table passcode is filled with the generated codes (col1..col4)
Then, there was this problem with the display: the display of the TI-84 is quite small.
So, I’ve defined a variable called dottedline and initialized it with a much smaller value.
BEFORE print("-----------------------------------------") print("\t MASTERMIND") print("-----------------------------------------") AFTER dottedline="------------------------" print(dottedline) print(" MASTERMIND") print(dottedline)
TESTING and REFACTORING
While testing the mastermind.py script I discovered that the setting of the guess_flags was not always correct.
Steps to improve it:
Take the original code and make a function out of it:
# Function to set the guess_flags
def setGuessflags(guess_flags, turn, code, colors_map, passcode):
dummy_passcode = [x for x in passcode]
pos = 0
for x in code:
if colors_map[x] in dummy_passcode:
if code.index(x) == passcode.index(colors_map[x]):
guess_flags[turn][pos] = 'R'
else:
guess_flags[turn][pos] = 'W'
pos += 1
dummy_passcode.remove(colors_map[x])
return guess_flags
Test the function “setGuessflags” to see if it works like before.
Afterward: implement a simpler version of setGuessflags
Build unit tests first, check Stackoverflow how to do that:
import unittest
from MASTR002 import setGuessflags
# https://stackoverflow.com/questions/52013612/python-unittest-does-not-run-tests
class Mastr002TestCase(unittest.TestCase):
def test_setGuessflagsRed(self):
chances = 8
passcode = []
passcode.append(1)
passcode.append(6)
passcode.append(2)
passcode.append(5)
turn=1
guess_flags = [['-', '-', '-', '-'] for x in range(chances)]
guess_codes = [['1', '6', '2', '5'] for x in range(chances)]
newguessflags = setGuessflags(guess_flags,turn,guess_codes,passcode)
self.assertEqual(['R', 'R', 'R', 'R'], newguessflags[1])
def test_setGuessflagsRedWhite(self):
chances = 8
passcode = []
passcode.append(1)
passcode.append(6)
passcode.append(2)
passcode.append(5)
turn=1
guess_flags = [['-', '-', '-', '-'] for x in range(chances)]
guess_codes = [['1', '6', '5', '2'] for x in range(chances)]
newguessflags = setGuessflags(guess_flags,turn,guess_codes,passcode)
self.assertEqual(['R', 'R', 'W', 'W'], newguessflags[1])
def test_setGuessflagsNone(self):
chances = 8
passcode = []
passcode.append(1)
passcode.append(6)
passcode.append(2)
passcode.append(5)
turn=1
guess_flags = [['-', '-', '-', '-'] for x in range(chances)]
guess_codes = [['2', '2', '3', '3'] for x in range(chances)]
newguessflags = setGuessflags(guess_flags,turn,guess_codes,passcode)
self.assertEqual(['W', '-', '-', '-'], newguessflags[1])
def test_setGuessflagsSimulation2262(self):
chances = 8
passcode = []
passcode.append(2)
passcode.append(2)
passcode.append(6)
passcode.append(2)
turn=1
guess_flags = [['-', '-', '-', '-'] for x in range(chances)]
guess_codes = [['1', '1', '2', '2'] for x in range(chances)]
newguessflags = setGuessflags(guess_flags,turn,guess_codes,passcode)
self.assertEqual(['-', '-', 'W', 'W'], newguessflags[1])
def test_setGuessflagsSimulation4464(self):
chances = 8
passcode = []
passcode.append(4)
passcode.append(4)
passcode.append(6)
passcode.append(4)
turn = 1
guess_flags = [['-', '-', '-', '-'] for x in range(chances)]
guess_codes = [['4', '4', '4', '4'] for x in range(chances)]
newguessflags = setGuessflags(guess_flags, turn, guess_codes, passcode)
self.assertEqual(['R', 'R', 'W', '-'], newguessflags[1])
if __name__ == '__main__':
unittest.main()
After successful unit tests the code looks like this:
# Function to set the guess_flags
def setGuessflags(guess_flags, turn, code, passcode):
ii = 0
passcodeItemChecked=[]
for x in code:
if (ii==turn):
cc=0
for codeitem in x:
pp=0
for passcodeitem in passcode:
# check if passworditem is already processed
toprocess = True
for pitem in passcodeItemChecked:
if pitem == pp:
toprocess = False
if toprocess == True:
if (str(codeitem)==str(passcodeitem)):
if cc==pp:
guess_flags[turn][cc] = 'R'
else:
guess_flags[turn][cc] = 'W'
passcodeItemChecked.append(pp)
break
pp +=1
cc +=1
ii +=1
return guess_flags
Fine Tuning
After further testing I’ve discovered another smaller problem: I’ve forgotten to prioritize:
The most important are the RED colors (code and position).
So, I’ve added another Unittest (test first!):
def test_setGuessflagsSimulation4464(self):
chances = 8
passcode = []
passcode.append(4)
passcode.append(4)
passcode.append(6)
passcode.append(4)
turn = 1
guess_flags = [['-', '-', '-', '-'] for x in range(chances)]
guess_codes = [['4', '4', '4', '4'] for x in range(chances)]
newguessflags = setGuessflags(guess_flags, turn, guess_codes, passcode)
self.assertEqual(['R', 'R', '-', 'R'], newguessflags[1])
And changed (and tested) the method “setGuessflags”:
def setGuessflags(guess_flags, turn, code, passcode):
ii = 0
passcodeItemChecked=[]
# check code and position
for x in code:
if (ii==turn):
cc=0
for codeitem in x:
pp=0
# check code and position
for passcodeitem in passcode:
# check if passworditem is already processed
toprocess = True
for pitem in passcodeItemChecked:
if pitem == pp:
toprocess = False
if toprocess == True:
if (str(codeitem)==str(passcodeitem)):
if cc==pp:
guess_flags[turn][cc] = 'R'
passcodeItemChecked.append(pp)
break
pp +=1
cc +=1
ii += 1
ii = 0
# check code independent of position
for x in code:
if (ii == turn):
cc = 0
for codeitem in x:
pp = 0
# check code
for passcodeitem in passcode:
# check if passworditem is already processed
toprocess = True
for pitem in passcodeItemChecked:
if pitem == pp:
toprocess = False
if toprocess == True:
if (str(codeitem) == str(passcodeitem)):
if cc == pp:
guess_flags[turn][cc] = 'R'
else:
guess_flags[turn][cc] = 'W'
passcodeItemChecked.append(pp)
break
pp += 1
cc +=1
ii +=1
return guess_flags
Next challenges
Try to define more functions in the source code MASTR002 and test it with Unit-Tests
Try to implement Mastermind in another language like react.
You can see a sample here:
https://react.rocks/example/Mastermind