Advertisement
Guest User

Untitled

a guest
Jun 26th, 2019
81
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.98 KB | None | 0 0
  1. import tkinter as tk
  2. from random import choices
  3. import itertools as it
  4.  
  5.  
  6. class Mastermind(tk.Frame):
  7.  
  8. def __init__(self, master, holes=5, colours=8, guesses=12, bg="white", fg="black", **kwargs):
  9. self.numberOfHoles = holes
  10. self.numberOfColours = colours
  11. self.numberOfGuesses = guesses
  12. self.bg = bg
  13. self.fg = fg
  14. self.master = master
  15. self.colours = ["#9E5D00", "#FF0000", "#FF7F00", "#FFFF00", "#00FF00",
  16. "#0000FF", "#FF00FF", "#8C44FF", "#FFFFFF", "#000000"][:self.numberOfColours]
  17. self.reset_cycles()
  18. self.answer = choices(self.colours, k=self.numberOfHoles)
  19. super().__init__(self.master, bg=self.bg, **kwargs)
  20. print(self.answer)
  21. self.create_gui()
  22.  
  23.  
  24. def create_gui(self):
  25. self.allGuesses = [tk.Frame(self, bg=self.bg) for _ in range(self.numberOfGuesses)]
  26. self.allMarks = [tk.Frame(self, bg=self.bg) for _ in range(self.numberOfGuesses)]
  27. self.answerFrame = tk.Frame(self, bg=self.bg)
  28. self.answerCover = tk.Frame(self, bg=self.fg, relief=tk.RAISED)
  29. self.allGuessPins = [[tk.Label(self.allGuesses[i], width=2, height=1, bg="grey", relief=tk.SUNKEN)
  30. for _ in range(self.numberOfHoles)]
  31. for i in range(self.numberOfGuesses)]
  32. self.allMarkPins = [[tk.Label(self.allMarks[i], width=1, height=1, bg="lightgrey", relief=tk.SUNKEN)
  33. for _ in range(self.numberOfHoles)]
  34. for i in range(self.numberOfGuesses)]
  35. self.answerPins = [tk.Label(self.answerFrame, width=2, height=1, bg=colour, relief=tk.RAISED) for colour in self.answer]
  36. self.guessBtn = tk.Button(self, text="Guess", command=self.next_guess, bg=self.bg, fg=self.fg)
  37. self.activeGuess = 0
  38.  
  39. for rowIndex in range(self.numberOfGuesses):
  40. for holeIndex in range(self.numberOfHoles):
  41. self.allGuessPins[rowIndex][holeIndex].grid(row=0, column=holeIndex, padx=1, pady=4)
  42. self.allMarkPins[rowIndex][holeIndex].grid(row=0, column=holeIndex, padx=1, pady=4)
  43. tk.Label(self, text=str(rowIndex+1), bg=self.bg, fg=self.fg).grid(row=self.numberOfGuesses-rowIndex, column=0)
  44. self.allGuesses[rowIndex].grid(row=rowIndex+1, column=1)
  45. self.allMarks[rowIndex].grid(row=rowIndex+1, column=3)
  46.  
  47. for i, a in enumerate(self.answerPins):
  48. a.grid(row=0, column=i, padx=1)
  49.  
  50. tk.Label(self, text=" ", bg=self.bg).grid(row=0, column=2)
  51. tk.Label(self, text=" ", bg=self.bg).grid(row=0, column=4)
  52. for a in [tk.Label(self.answerCover, width=2, height=1, bg=self.fg) for _ in range(self.numberOfHoles)]:
  53. a.pack(side=tk.LEFT, padx=1)
  54.  
  55. self.answerCover.grid(row=0, column=1, pady=15)
  56. self.guessBtn.grid(column=1, row=999, pady=10)
  57. self.next_guess(start=True)
  58.  
  59.  
  60. def next_guess(self, start=False):
  61. # Check there are no blanks
  62. for colour in self.get_pin_colours():
  63. if colour == "grey" and not start:
  64. return None
  65.  
  66. # Stop responding to mouse button and remove highlighting
  67. self.reset_cycles()
  68. self.allGuesses[self.activeGuess].config(bg=self.bg)
  69. for pin in self.allGuessPins[self.activeGuess]:
  70. pin.unbind("<1>")
  71. pin["cursor"] = ""
  72.  
  73. # Add the mark pins for the guess
  74. score = self.score_guess(self.get_pin_colours(), self.answer)
  75. if not start and len(score) != 0:
  76. score = self.score_guess(self.get_pin_colours(), self.answer)
  77. for i, pin in enumerate(self.allMarkPins[self.activeGuess]):
  78. if i > len(score)-1:
  79. break
  80. pin.config(bg=score[i], relief=tk.RAISED)
  81.  
  82. # Check for a win
  83. if score == ["Black" for _ in range(self.numberOfHoles)]:
  84. self.answerCover.grid_forget()
  85. self.answerFrame.grid(row=0, column=1, pady=15)
  86. self.guessBtn["command"] = None
  87. return None
  88.  
  89. # Move the guess up 1, bind mouse button and highlight row
  90. try:
  91. self.activeGuess -= 1
  92. self.allGuesses[self.activeGuess].config(bg=self.fg)
  93. for i, pin in enumerate(self.allGuessPins[self.activeGuess]):
  94. pin.bind("<1>", lambda event, i=i: self.change_pin_colour(event, i))
  95. pin["cursor"] = "hand"
  96. except IndexError:
  97. raise NotImplementedError()
  98. # add lose condition
  99.  
  100.  
  101. @staticmethod
  102. def score_guess(guess, answer):
  103. answer = answer.copy()
  104. blacks = ["Black" for secret, guess_item in zip(answer, guess) if secret == guess_item]
  105. whites = []
  106. for guess_item in guess:
  107. if guess_item in answer:
  108. answer[answer.index(guess_item)] = None
  109. whites.append("White")
  110. return blacks + whites[:-len(blacks)]
  111.  
  112.  
  113. def get_pin_colours(self):
  114. return [pin["bg"] for pin in self.allGuessPins[self.activeGuess]]
  115.  
  116. def change_pin_colour(self, event, i):
  117. event.widget.config(bg=next(self.colourCycles[i]), relief=tk.RAISED)
  118.  
  119. def reset_cycles(self):
  120. self.colourCycles = it.tee(it.cycle(self.colours), self.numberOfHoles)
  121.  
  122.  
  123. if __name__ == "__main__":
  124. root = tk.Tk()
  125. root.title("Mastermind")
  126. x = Mastermind(root)
  127. x.pack()
  128. root.mainloop()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement