Ejemplo n.º 1
0
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"])