def startGame(settings, restart, code, load, loadData): def drawInterface(): guesses = settings["guesses"] colourNo = settings["colours"] pegNo = settings["pegs"] colourList = settings["colourList"] # Draw interface frame layout #================================================ frame = GUI.Frame(gameScr, relief=GUI.RAISED, borderwidth=1, bg="white") frame.pack(fill=GUI.BOTH, expand=1) # Draw game board #================================================ hintWidth = 8 + int((pegNo + 1) / 2) * 12 gridWidth = 50 * pegNo + hintWidth cvsGrid = GUI.Canvas(frame, width=gridWidth, height=((guesses + 1) * 50 + guesses), bg="white") cvsGrid.pack(side=GUI.RIGHT) gridPegs = [] hintPegs = [] row = 0 while row < guesses + 1: gridPegs.append([]) hintPegs.append([]) col = 0 while col < pegNo: # Draw rows of pegs #================================================ xPos = 50 * col + 3 yPos = 50 * row + row + 3 gridPegs[row].append(cvsGrid.create_oval(xPos, yPos, xPos + 44, yPos + 44, fill="black")) # Draw hint pegs #================================================ if row < guesses: hintX = 50 * pegNo + 6 + int(col / 2) * 12 if col % 2 == 0: hintY = 50 * row + 15 + row else: hintY = 50 * row + 27 + row hintPegs[row].append(cvsGrid.create_oval(hintX, hintY, hintX + 8, hintY + 8, fill="black")) # Separate rows with lines #================================================ if row != 0: cvsGrid.create_line(0, yPos - 3, gridWidth, yPos - 3) col += 1 row += 1 # Draw common interface buttons #================================================ btnQuit = GUI.Button(gameScr, text="Quit Game", fg="red", command=quitGame) btnQuit.pack(side=GUI.RIGHT) btnMenu = GUI.Button(gameScr, text="Back to Menu", command=openMenu) btnMenu.pack(side=GUI.RIGHT) btnRestart = GUI.Button(gameScr, text="Restart Game", command=restartGame) btnRestart.pack(side=GUI.RIGHT) btnNew = GUI.Button(gameScr, text="New Game", command=newGame) btnNew.pack(side=GUI.RIGHT) # Draw human codebreaker buttons #================================================ if settings["mode"] == 1: for i in range(0, colourNo): btnColour = GUI.Button(frame, text=colourList[i], bg=colourList[i], width=12, height=5, command=lambda a=colourList[i]: selectPeg(a)) btnColour.pack(anchor=GUI.W) btnDel = GUI.Button(frame, text="Undo", width=12, command=undo) btnDel.pack(anchor=GUI.W) btnSave = GUI.Button(gameScr, text="Save Game", command=lambda a=settings, b=gameEnded: file.saveGame(a, b)) btnSave.pack(side=GUI.RIGHT) # Draw CPU codebreaker buttons #================================================ if settings["mode"] == 2: btnAI = GUI.Button(gameScr, text="Start AI", fg="blue", command=lambda a=settings, b=GUI, c=gameScr, d=gameEnded, e=selectPeg: AI.startAI(a, b, c, d, e)) btnAI.pack(side=GUI.RIGHT) # Set up canvas objects for manipulation #================================================ settings["grid"] = gridPegs settings["hints"] = hintPegs settings["canvas"] = cvsGrid # Resume a loaded game #================================================ if load == True: loadGrid = loadData[0] loadHints = loadData[1] for row in range(0, settings["guesses"]): for col in range(0, settings["pegs"]): settings["canvas"].itemconfig(settings["grid"][row][col], fill=loadGrid[row][col]) settings["canvas"].itemconfig(settings["hints"][row][col], fill=loadHints[row][col]) def quitGame(): if tkMessageBox.askyesno("Quit", "Are you sure you want to quit this game?"): sys.exit() def restartGame(): if not settings["AIstarted"]: if tkMessageBox.askyesno("Restart", "Are you sure you want to restart this game?"): settings["restart"] = True gameScr.destroy() else: tkMessageBox.showinfo("Start AI", "Please wait for the AI to finish guessing.") def newGame(): if not settings["AIstarted"]: if tkMessageBox.askyesno("New", "Are you sure you want to start a new game?"): gameScr.destroy() else: tkMessageBox.showinfo("Start AI", "Please wait for the AI to finish guessing.") def undo(): if not gameEnded() and not settings["col"] == 0: canvas = settings["canvas"] row = settings["row"] col = settings["col"] - 1 if col >= 0: canvas.itemconfig(settings["grid"][row][col], fill="black") settings["col"] -= 1 elif gameEnded(): tkMessageBox.showinfo("Undo", "You can't undo once the game has ended.") elif settings["col"] == 0 and settings["row"] == 0: tkMessageBox.showinfo("Undo", "There is nothing to undo!") else: tkMessageBox.showinfo("Undo", "You can't undo a finished guess, that's cheating!") def selectPeg(pegColour): canvas = settings["canvas"] if not gameEnded(): row = settings["row"] col = settings["col"] canvas.itemconfig(settings["grid"][row][col], fill=pegColour) settings["col"] += 1 if settings["col"] == settings["pegs"]: # If the row has been filled correct = checkRow() if correct == False: settings["row"] += 1 settings["col"] = 0 else: endGame(True) else: tkMessageBox.showinfo("Game Over", "You have already guessed the code.") if settings["row"] == settings["guesses"]: endGame(False) return def gameEnded(): canvas = settings["canvas"] if canvas.itemcget(settings["grid"][settings["guesses"]][0], "fill") == "black" and settings["row"] != settings["guesses"]: # If the game is still going return False else: return True def checkRow(): rowNo = settings["row"] canvas = settings["canvas"] correct = True hints = [] code = settings["code"][:] # First, check correct positions #================================================ p = 0 while p < settings["pegs"]: pegColour = canvas.itemcget(settings["grid"][rowNo][p], "fill") if pegColour == settings["code"][p]: hints.append(0) # 0 means colour is in correct position code[p] = "used" # Set the colour to used so we don't use it for hints again else: correct = False p += 1 # Next, check correct colours in wrong positions #================================================ p = 0 while p < settings["pegs"]: pegColour = canvas.itemcget(settings["grid"][rowNo][p], "fill") if pegColour in code and pegColour != settings["code"][p]: hints.append(1) # 1 means colour exists but is not in correct position i = 0 while i < settings["pegs"]: if code[i] == pegColour: code[i] = "used" break i += 1 p += 1 hints.sort() # Fill in the hint pegs #================================================ h = 0 while h < len(hints): if hints[h] == 0: canvas.itemconfig(settings["hints"][rowNo][h], fill="red") elif hints[h] == 1: canvas.itemconfig(settings["hints"][rowNo][h], fill="white") h += 1 return correct def endGame(win): canvas = settings["canvas"] code = settings["code"] p = 0 while p < settings["pegs"]: canvas.itemconfig(settings["grid"][settings["guesses"]][p], fill=code[p]) p += 1 if win == True: tkMessageBox.showinfo("Win", "Congratulations, you found the code in " + str(settings["row"] + 1) + " guesses!") else: tkMessageBox.showinfo("Lose", "Sorry, you've used all of your " + str(settings["guesses"]) + " guesses!") def openMenu(): if not settings["AIstarted"]: if tkMessageBox.askyesno("Menu", "Are you sure you want to leave this game and return to the menu?"): settings["menu"] = True gameScr.destroy() else: tkMessageBox.showinfo("Start AI", "Please wait for the AI to finish guessing.") # Set up variables #==================================================== settings["colourList"] = ["red", "green", "blue", "yellow", "purple", "orange", "pink", "white"] settings["guesses"] = 12 settings["restart"] = False settings["menu"] = False settings["AIstarted"] = False if load == False: settings["row"] = 0 settings["col"] = 0 # Draw interface #==================================================== gameScr = GUI.Tk() drawInterface() # Generate/reload the answer #==================================================== if restart == True: settings["code"] = code elif load == False: settings["code"] = AI.codeMaker(settings["pegs"], settings["colours"], settings["colourList"]) gameScr.mainloop() # Return instructions for menu when game is stopped #================================================ return (settings["restart"], settings["code"], settings["menu"])