diff --git a/60 Mastermind/python/mastermind.py b/60 Mastermind/python/mastermind.py new file mode 100644 index 00000000..adb62be3 --- /dev/null +++ b/60 Mastermind/python/mastermind.py @@ -0,0 +1,253 @@ +import random + +def main(): + + global colors, color_letters, num_positions, num_colors, human_score, computer_score + colors = ["BLACK", "WHITE", "RED", "GREEN", "ORANGE", "YELLOW", "PURPLE", "TAN"] + color_letters = "BWRGOYPT" + + num_colors = 100 + human_score = 0 + computer_score = 0 + + # get user inputs for game conditions + print("Mastermind") + print('Creative Computing Morristown, New Jersey') + while (num_colors > 8): + num_colors = int(input("Number of colors (max 8): ")) # C9 in BASIC + # TODO no more than 8 colors + num_positions = int(input("Number of positions: ")) # P9 in BASIC + num_rounds = int(input("Number of rounds: ")) # R9 in BASIC + possibilities = num_colors**num_positions + all_possibilities = [1] * possibilities + + print("Number of possibilities {}".format(possibilities)) + #TODO tab fixed formatting + print('Color Letter') + print('===== ======') + for element in range(0, num_colors): + print("{} {}".format(colors[element], colors[element][0])) + + num_moves = 1 + guesses = [] + current_round = 1 + + while current_round <= num_rounds: + print('Round number {}'.format(current_round)) + num_moves = 1 + turn_over = False + print('Guess my combination ...') + answer = int(possibilities * random.random()) # A in BASIC + numeric_answer = init_possibility() + for i in range(0, answer): + numeric_answer = get_possibility(numeric_answer) + #debug + print("{} - {}".format(numeric_answer, make_human_readable(numeric_answer))) + #human_readable_answer = make_human_readable(numeric_answer) + while (num_moves < 10 and not(turn_over)): + print('Move # {} Guess : '.format(num_moves)) + user_command = input('Guess ') + if user_command == "BOARD": + print_board(guesses) #2000 + elif user_command == "QUIT": + quit_game(numeric_answer) #2500 + quit() + elif len(user_command) != num_positions: #410 + print("BAD NUMBER OF POSITIONS") + else: + invalid_letters = get_invalid_letters(user_command) + if (invalid_letters > ""): + print("INVALID GUESS: {}".format(invalid_letters)) + else: + guess_results = compare_two_positions(user_command, make_human_readable(numeric_answer)) + print("Results: {}".format(guess_results)) + if (guess_results[1] == num_positions): # correct guess + turn_over = True + print("You guessed it in {} moves!".format(num_moves)) + human_score = human_score + num_moves + print_score() + else: + print("You have {} blacks and {} whites".format(guess_results[1], guess_results[2])) + num_moves = num_moves + 1 + guesses.append(guess_results) + if (not(turn_over)): # RAN OUT OF MOVES + print ("YOU RAN OUT OF MOVES! THAT'S ALL YOU GET!") + print("THE ACTUAL COMBINATION WAS: {}".format(make_human_readable(numeric_answer))) + human_score = human_score + num_moves + print_score() + + # COMPUTER TURN + turn_over = False + all_possibilities = [1] * possibilities + num_moves = 1 + print ("NOW I GUESS. THINK OF A COMBINATION.") + player_ready = input("HIT RETURN WHEN READY: ") + while (num_moves < 10 and not(turn_over)): + foundGuess = False + computer_guess = int(possibilities * random.random()) + if (all_possibilities[computer_guess] == 1): # random guess is possible, use it + foundGuess = True + guess = computer_guess + else: + for i in range (computer_guess, possibilities): + if (all_possibilities[i] == 1): + foundGuess = True + guess = i + break + if (not(foundGuess)): + for i in range (0, computer_guess): + if (all_possibilities[i] == 1): + foundGuess = True + guess = i + break + if (not(foundGuess)): # inconsistent info from user + print('YOU HAVE GIVEN ME INCONSISTENT INFORMATION.') + print('TRY AGAIN, AND THIS TIME PLEASE BE MORE CAREFUL.') + quit() + # TODO start computer turn over + else: + numeric_guess = init_possibility() + for i in range(0, guess): + numeric_guess = get_possibility(numeric_guess) + human_readable_guess = make_human_readable(numeric_guess) + print('My guess is: {}'.format(human_readable_guess)) + blacks, whites = input("Enter blacks, whites (e.g. 1,2): ").split(",") + blacks = int(blacks) + whites = int(whites) + if (blacks == num_positions): #Correct guess + print('I GOT IT IN {} moves'.format(num_moves)) + turn_over = True + computer_score = computer_score + num_moves + print_score() + else: + num_moves += 1 + for i in range (0, possibilities): + if(all_possibilities[i] == 0): #already ruled out + continue + numeric_possibility = init_possibility() + for j in range (0, i): + numeric_possibility = get_possibility(numeric_possibility) + human_readable_possibility = make_human_readable(numeric_possibility) #4000 + comparison = compare_two_positions(human_readable_possibility, human_readable_guess) + print("{} {} {}".format(human_readable_guess, human_readable_possibility, comparison)) + if ((blacks != comparison[1]) or (whites != comparison[2])): + all_possibilities[i] = 0 + if (not(turn_over)): # COMPUTER DID NOT GUESS + print("I USED UP ALL MY MOVES!") + print("I GUESS MY CPU IS JUST HAVING AN OFF DAY.") + computer_score = computer_score + num_moves + print_score() + current_round += 1 + +def get_invalid_letters(user_command): + #TODO + return "" + +def validate_human_guess(user_input): + + guess_results = compare_two_positions(user_input, answer) + return guess_results + +#2000 +def print_board(guesses): + print("Board") + print("Move Guess Black White") + for guess in guesses: + print('{} {} {} {}'.format(guess[0], guess[0], guess[1], guess[2])) + +#2500 +def quit_game(numeric_answer): + human_readable_answer = make_human_readable(numeric_answer) + print('QUITTER! MY COMBINATION WAS: {}'.format(human_readable_answer)) + print('GOOD BYE') + +#3000 +def init_possibility(): + possibility = [0] * num_positions + return possibility + +#3500 +def get_possibility(possibility): + if possibility[0] > 0: #3530 + current_position = 0 # Python arrays are zero-indexed + while (True): + if possibility[current_position] < num_colors: + possibility[current_position] += 1 + return possibility + else: + possibility[current_position] = 1 + current_position += 1 + else: #3524 + possibility = [1] * num_positions + return possibility + +#4000 +def convert_q_to_a(): + return map_num_to_vals(q, color_letters) + +#4500 +def compare_two_positions(guess, answer): + f = 0 + b = 0 + w = 0 + initial_guess = guess + for pos in range(0, num_positions): + if (guess[pos] != answer[pos]): + for pos2 in range(0, num_positions): + if not(guess[pos] != answer[pos2] or guess[pos2] == answer[pos2]): # correct color but not correct place + w = w + 1 + answer = answer[:pos2] + chr(f) + answer[pos2+1:] + guess = guess[:pos] + chr(f+1) + guess[pos+1:] + f = f + 2 + else: #correct color and placement + b = b + 1 + # THIS IS DEVIOUSLY CLEVER + guess = guess[:pos] + chr(f+1) + guess[pos+1:] + answer = answer[:pos] + chr(f) + answer[pos+1:] + f = f + 2 + return [initial_guess, b, w] + + + + + +#5000 +def print_score(is_final_score=False): + if (is_final_score): + print("GAME OVER") + print("FINAL SCORE:") + else: + print("SCORE:") + print(" COMPUTER {}".format(computer_score)) + print(" HUMAN {}".format(human_score)) + +#5500 +def convert_q_to_g(): + return map_num_to_vals(q, g) + +#6000 +def convert_q_to_h(): + return map_num_to_vals(q, h) + +#6500 +def copy_g_to_h(): + g = h + +def make_human_readable(num): + retval = '' + for z in range(0, len(num)): + retval = retval + color_letters[int(num[z])] + return retval + + +def map_num_to_vals(num, v): + retval = '' + print(len(num)) + for z in range(0, len(num)): + print(num[z]) + print(v[int(num[z])]) + retval = retval + v[int(num[z])] + return retval + +if __name__ == "__main__": + main() \ No newline at end of file