def startMenu(win): startMenu = True while startMenu: pygame.time.delay(25) #Creates the start button from the button class startButton = Button((255, 255, 0), 200, 300, 100, 50) startButton.draw(win, "Start", screenWidth / 2, (screenHeight / 2) + 50) pygame.display.update() for event in pygame.event.get(): if (event.type == pygame.QUIT or event.type == pygame.KEYDOWN and event.key == pygame.K_ESCAPE): quit() if event.type == pygame.KEYDOWN and event.key == pygame.K_SPACE: startMenu = False if event.type == pygame.MOUSEBUTTONDOWN: #Checks if the button was clicked by invoking the button class method 'checkIfClicked' if startButton.checkIfClicked() == True: startMenu = False #Draws the text on the button win.fill((255, 255, 255)) titleText = pygame.font.SysFont("arialblack", 25) titleText = titleText.render("Welcome to Pong!", 1, (0, 0, 0)) win.blit(titleText, (125, 150)) win.fill((255, 255, 255)) pygame.display.update()
def alertMessage(message): """Displays an error message in a new window""" win = graphics.GraphWin('Alert Message', 300, 100) win.setBackground('#6FF3CC') text = graphics.Text(graphics.Point(win.getWidth()/2, win.getHeight()/2 - 20), message) text.setSize(11) text.setFace('times roman') text.draw(win) okButton = Button(win, graphics.Point(win.getWidth()/2 - 70, win.getHeight()/2 + 30), 80, 25, 'lightgrey', 'OK') okButton.setSizeText(10) cancelButton = Button(win, graphics.Point(win.getWidth()/2 + 70, win.getHeight()/2 + 30), 80, 25, 'lightgrey', 'CANCEL') cancelButton.setSizeText(10) #Press OK button to continue with function or cancel to quit alert window loop = True while loop: mousePress = win.getMouse() if okButton.clicked(mousePress): win.close() loop = False return True elif cancelButton.clicked(mousePress): win.close() loop = False return False
def main_func(): # Sets the directory name back to python final project # This solves file not found errors if you start the code from one of the games rather than this main file if os.getcwd().split("\\")[-1] != "Python_Final_Project": abspath = os.path.abspath(__file__) dname = os.path.dirname(os.path.dirname(abspath)) os.chdir(dname) # Starts the game and creates the window display_width = 800 display_height = 600 gameDisplay = pygame.display.set_mode((display_width, display_height)) # Defines welcome text title = Text("Welcome to Our Game!", (255, 255, 255), "comicsans", 100) # Defines the buttons to navigate to the tetris and minesweeper games button_width = display_width/3 tetris_button = Button((50,50,225), display_width/4 - button_width/2, 250, button_width, 100, tetris_main.tetris_main_function,"Tetris", 0, None, 'comicsans', 60, (255,255,255), (40,40,150)) minesweeper_button = Button((255,50,50), display_width/4 - button_width/2 + display_width/2, 250, button_width, 100, minesweeper_main.main,"Minesweeper", 0, None, 'comicsans', 60, (255,255,255), (150,40,40)) typing_button = Button((255,193,69), display_width/2 - button_width/2, 400, button_width, 100, typing_test_main.main,"Typing Test", 0, None, 'comicsans', 60, (255,255,255), (128,95,35)) button_list = [tetris_button, minesweeper_button, typing_button] # Game Loop gameExit = False while not gameExit: # Ends the game loop if the user tries to closes the window for event in pygame.event.get(): if event.type == pygame.QUIT: gameExit = True break # Calls each buttons action function if they have been clicked elif pygame.mouse.get_pressed()[0]: for button in button_list: if button.isOver((pygame.mouse.get_pos())): button.action() # Draws background pygame.draw.rect(gameDisplay, (255,50,50), (pygame.Rect(0,0,display_width/2,display_height))) pygame.draw.rect(gameDisplay, (50,50,225), (pygame.Rect(display_width/2,0,display_width/2,display_height))) # Draws buttons for button in button_list: button.draw(gameDisplay) # Displays welcome text title.display_text(gameDisplay, display_width/2 - title.text.get_width()/2, 50) #updates the window pygame.display.update() # closes the window when the game loop ends pygame_exit()
def loadButtons(self): self.playingButtons.append( Button(20, 40, WIDTH // 7, 40, function=self.checkAllCells, colour=(27, 142, 207), text='Check'))
def numPlayerInput(win): numPlayerInput = True while numPlayerInput: pygame.display.update() numPlayersFont = pygame.font.SysFont("arialblack", 20) numPlayersText = numPlayersFont.render("How many players?", 1, (0, 0, 0)) win.blit(numPlayersText, (140, 265)) OnePlayerButton = Button((255, 255, 0), 180, 300, 50, 50) OnePlayerButton.draw(win, "1", 200, 317.5) TwoPlayerButton = Button((255, 255, 0), 235, 300, 50, 50) TwoPlayerButton.draw(win, "2", 255, 317.5) for event in pygame.event.get(): if (event.type == pygame.QUIT or event.type == pygame.KEYDOWN and event.key == pygame.K_ESCAPE): quit() if event.type == pygame.KEYDOWN and (event.key == pygame.K_SPACE or event.key == pygame.K_1): numPlayers = 1 numPlayerInput = False if event.type == pygame.KEYDOWN and (event.key == pygame.K_2): numPlayers = 2 numPlayerInput = False if event.type == pygame.MOUSEBUTTONDOWN: #Checks if the button was clicked by invoking the button class method 'checkIfClicked' if OnePlayerButton.checkIfClicked() == True: numPlayers = 1 numPlayerInput = False elif TwoPlayerButton.checkIfClicked() == True: numPlayers = 2 numPlayerInput = False win.fill((255, 255, 255)) pygame.display.update() return numPlayers
def errorMessage(message): """Displays an error message in a new window""" win = graphics.GraphWin('Error Message', 350, 175) win.setBackground('#F75454') error = graphics.Text(graphics.Point(win.getWidth()/2, win.getHeight()/2 - 50), 'Error') error.setSize(30) error.setStyle('bold') error.draw(win) text = graphics.Text(graphics.Point(win.getWidth()/2, win.getHeight()/2), message) text.setFace('times roman') text.draw(win) #Press OK button to close the window okButton = Button(win, graphics.Point(win.getWidth()/2, win.getHeight()/2 + 55), 100, 30, 'lightgrey', 'OK') loop = True while loop: mousePress = win.getMouse() if okButton.clicked(mousePress): win.close() loop = False
def create_buttons(self): # append button objects to the playing buttons array self.playing_buttons.append(Button(88, 40, self.grid_offset + 96, 520, self.off_button_color, self.off_button_color, self.off_button_hover, self.off_button_hover, self.button_off_font_color, self.button_off_font_color, "Reset", self.reset_board)) self.playing_buttons.append(Button(88, 40, self.grid_offset + 35, 465, self.off_button_color, self.off_button_color, self.off_button_hover, self.off_button_hover, self.button_off_font_color, self.button_off_font_color, "Hint", self.display_hint)) self.playing_buttons.append(Button(88, 40, self.grid_offset + 158, 465, self.off_button_color, self.on_button_color, self.off_button_hover, self.on_button_hover, self.button_off_font_color, self.button_on_font_color, "Check", self.check_cells)) self.playing_buttons.append(Button(88, 40, self.grid_offset + 281, 465, self.off_button_color, self.off_button_color, self.off_button_hover, self.off_button_hover, self.button_off_font_color, self.button_off_font_color, "Solve", self.solve_board)) self.playing_buttons.append(Button(88, 40, self.grid_offset + 221, 520, self.off_button_color, self.off_button_color, self.off_button_hover, self.off_button_hover, self.button_off_font_color, self.button_off_font_color, "New", self.new_board)) self.play_again.append(Button(88, 40, self.grid_offset + 158, 465, self.off_button_color, self.off_button_color, self.off_button_hover, self.off_button_hover, self.button_off_font_color, self.button_off_font_color, "New", self.new_board))
def main(): # Adds the current directory to the list of directories that the program uses to check for modules sys.path.append('.') sys.path.append('..') from project_main import main_func from buttonClass import Button, Text, pygame_exit from Typing_Test.typing_test_engine import Word, Display_Text, Text_Box # Sets the current working directory to the directory that the minesweeper_main.py file is in # This fixes some problems that occur when trying to load images if os.getcwd().split("\\")[-1] != "Typing_Test ": abspath = os.path.abspath(__file__) dname = os.path.dirname(abspath) os.chdir(dname) # updates the color of the overlay on the current word by checking to see if what the user typed could possibly match the current word def update_word_overlay(): if text_box.word_match(text_display): text_display.current_word.overlay = Word.GRAY else: text_display.current_word.overlay = Word.RED # Defines the screen global screen, screen_width, screen_height screen_width = 800 screen_height = 600 screen = pygame.display.set_mode((screen_width, screen_height)) background_color = (135, 206, 235) # Sets caption at top of window to "Typing Test" pygame.display.set_caption('Typing Test') # Defines header header = Text("Typing Test", (255, 255, 255), "comicsans", 75) # Defines the menu button button_width = 0.8 * (screen_width - screen_height) button_height = 50 menu_button = Button((50, 50, 255), screen_width - button_width - 20, screen_height - button_height - 20, button_width, button_height, main_func, "MENU", 0, None, 'comicsans', 30, (255, 255, 255), (40, 40, 150)) stats_button = Button((255, 191, 0), screen_width - button_width - 20, 20, button_width, button_height, stats_page, "STATS", 0, None, 'comicsans', 30, (255, 255, 255), (191, 143, 0)) button_list = [menu_button, stats_button] global game_state, game_start_time, game_time_passed, game_time_left, text_display, text_box, timer_text, wpm_text # Defines the text display and textbox for displaying text to the user and for the user to enter text text_display = Display_Text(600, 120, "comicsans", 40, (255, 255, 255), (25, 25, 25), 2, 15, 10, 5) text_box = Text_Box((200, 300), 400, 48, "comicsans", 40, (255, 255, 255), (0, 0, 0), (255, 255, 0), 2, 10) text_box_background_rect = pygame.Rect(100, 290, 600, 68) # Timer setup code timer_background_rect = pygame.Rect(110, 300, 80, 48) timer_text = Text("1:00", (255, 255, 255), "comicsans", 50) game_state = "not_started" game_start_time = None game_time_passed = 0 game_time_left = 60 wpm_text = Text("0 WPM", (255, 255, 255), "comicsans", 80) scores_text = Text("", (255, 255, 255), "comicsans", 40) def reset_game(): global game_state, game_start_time, game_time_passed, game_time_left, text_display, text_box, timer_text, wpm_text game_state = "not_started" game_start_time = None game_time_passed = 0 game_time_left = 60 text_display = Display_Text(600, 120, "comicsans", 40, (255, 255, 255), (25, 25, 25), 2, 15, 10, 5) text_box = Text_Box((200, 300), 400, 48, "comicsans", 40, (255, 255, 255), (0, 0, 0), (255, 255, 0), 2, 10) timer_text = Text("1:00", (255, 255, 255), "comicsans", 50) wpm_text = Text("0 WPM", (255, 255, 255), "comicsans", 80) scores_text = Text("", (255, 255, 255), "comicsans", 40) # Define reset button reset_button = Button((31, 109, 204), 625, 300, 48, 48, reset_game, hover_color=(51, 91, 156)) button_list.append(reset_button) reset_icon = pygame.image.load("typing_test_image_assets/reload.png") # saves the games start time # Used to calculate wpm start_time = time.time() # Game loop running = True while running: # Updates the current time current_time = time.time() - start_time # Clears the screen screen.fill(background_color) # Starts looping through all events for event in pygame.event.get(): # Checks if the game was closed if event.type == pygame.QUIT: running = False break # Checks if the mouse was clicked if event.type == pygame.MOUSEBUTTONDOWN: # Checks if the left mouse button was clicked if pygame.mouse.get_pressed()[0]: # Iterates through all of the buttons and checks if they were clicked for button in button_list: # Checks if the button was clicke and if so it calls the buttons action function if button.isOver((pygame.mouse.get_pos())): button.action() # Tells the program that the text_box was selected if the click was over the text box # Otherwise it deselects the text box text_box.is_selected = text_box.click_in_box( (pygame.mouse.get_pos())) # Checks if a key was pressed own if event.type == pygame.KEYDOWN and game_state != "game over": # Checks if the text box was selected # Key board input only matters when the text box is selected so othwise the program does nothing if text_box.is_selected: # Starts the game if any key is pressed if game_state == "not_started": game_state = "started" game_start_time = time.time() # Checks if the backspace key was pressed and if so it deletes the last character typed if event.key == pygame.K_BACKSPACE: text_box.text = text_box.text[:-1] # Checks if the space key was pressed and if so it enters the word which includes logging the word, updating the current word, and clearing the text box elif event.key == pygame.K_SPACE: text_box.log_word(text_display) text_display.next_word( text_display.current_word.string == text_box.text) text_box.clear_text() # Adds the key pressed to text box as long as it is one character long and is not the return key # Prints the wpm for debugging(making sure the program is working correctly) purposes elif len(event.unicode ) == 1 and event.key != pygame.K_RETURN: text_box.text += event.unicode text_box.log_stroke(text_display) # Animates the flashing cursor if the text box is selected but is empty if text_box.text == "": current_time = time.time() - start_time # Uses the current time to make the cursor invisible if time's tenths digit is greater than 0.25 if abs(round(current_time, 1) - round(current_time)) > 0.25: text_box.cursor_color = text_box.background_color # Otherwise the cursor is black else: text_box.cursor_color = (0, 0, 0) else: # Sets the cursor color back to black incase the textbox becomes not empty while the cursor color is set to white text_box.cursor_color = (0, 0, 0) #Stops the game from updating or checking any other conditions if the window is quit if not running: break # Draws header header.display_text(screen, screen_width / 2 - header.text.get_width() / 2, 50) # Updates the word overlay color in the text display update_word_overlay() # Display text text_display.display_text_display(screen, (100, 150)) # Display textbox pygame.draw.rect(screen, (118, 160, 245), text_box_background_rect) text_box.display_text_box(screen) # Display timer pygame.draw.rect(screen, (38, 54, 94), timer_background_rect) if game_state == "started": time.sleep(0.0000000001) game_time_passed = time.time() - game_start_time game_time_left = 60 - game_time_passed if game_time_left <= 0: with open('user_typing_data.txt', 'a') as data: data.write( str(round(text_box.calc_wpm(game_time_passed))) + " " + str(strokes) + " " + str(correct_strokes) + " " + str(wrong_strokes) + " " + str(accuracy) + " " + str(correct_words) + " " + str(wrong_words) + "\n") game_state = "game over" seconds_left = str(round(game_time_left) % 60) if int(seconds_left) == 0: seconds_left += "0" elif int(seconds_left) < 10: seconds_left = "0" + seconds_left timer_text.update_text( str(round(game_time_left) // 60) + ":" + str(seconds_left)) timer_text.display_text(screen, 115, 307) # Update current wpm if the game is being played and displays it to the screen if game_state == "started": wpm_text.update_text( str(round(text_box.calc_wpm(game_time_passed))) + " WPM") wpm_text.display_text(screen, 450, 450) # Display the users stats strokes = text_box.get_stroke_counts()['total'] correct_strokes = text_box.get_stroke_counts()['correct'] wrong_strokes = text_box.get_stroke_counts()['wrong'] accuracy = int(text_box.calc_accuracy() * 100) correct_words = text_box.get_word_counts()['correct'] wrong_words = text_box.get_word_counts()['wrong'] scores_text.update_text("Keystrokes: " + str(strokes) + "(C: " + str(correct_strokes) + " | W: " + str(wrong_strokes) + ")" + "\nAccuracy: " + str(accuracy) + "%" + "\nCorrect Words: " + str(correct_words) + "\nWrong Words: " + str(wrong_words)) scores_text.display_text(screen, 100, 400) # Draws the buttons for button in button_list: button.draw(screen) # Display image screen.blit(reset_icon, (633, 308)) # Saves the visual changes to the screen pygame.display.update() # Closes the game if the exit button is pressed pygame_exit()
def stats_page(): global screen, screen_width, screen_height # Adds the current directory to the list of directories that the program uses to check for modules sys.path.append('.') sys.path.append('..') from project_main import main_func from buttonClass import Button, Text, pygame_exit from Typing_Test.typing_test_engine import Word, Display_Text, Text_Box, Test_Data background_color = (135, 206, 235) header = Text("Avg User Stats", (255, 255, 255), "comicsans", 75) # Defines buttons button_width = 0.8 * (screen_width - screen_height) button_height = 50 menu_button = Button((50, 50, 255), screen_width - button_width - 20, screen_height - button_height - 20, button_width, button_height, main_func, "MENU", 0, None, 'comicsans', 30, (255, 255, 255), (40, 40, 150)) back_button = Button((255, 191, 0), screen_width - button_width - 20, 20, button_width, button_height, None, "BACK", 0, None, 'comicsans', 30, (255, 255, 255), (191, 143, 0)) button_list = [menu_button, back_button] stats_text = Text("", (255, 255, 255), "comicsans", 50) avg_data = { 'wpm': 0, "strokes": 0, "correct_strokes": 0, "wrong_strokes": 0, "accuracy": 0, "correct_words": 0, "wrong_words": 0 } with open('user_typing_data.txt', 'r') as data: text_lines = data.readlines() score_data = [] for line in text_lines: line = line.replace('\n', '') score_data.append(Test_Data(*list(map(int, line.split(' '))))) for data_type in avg_data.keys(): for test_data in score_data: avg_data[data_type] += getattr(test_data, data_type) avg_data[data_type] = round(avg_data[data_type] / len(score_data)) avg_wpm = avg_data['wpm'] wpm_text = Text("WPM: " + str(avg_wpm), (255, 255, 255), "comicsans", 75) avg_strokes = avg_data['strokes'] avg_correct_strokes = avg_data['correct_strokes'] avg_wrong_strokes = avg_data['wrong_strokes'] avg_accuracy = avg_data['accuracy'] avg_correct_words = avg_data['correct_words'] avg_wrong_words = avg_data['wrong_words'] stats_text.update_text("Keystrokes: " + str(avg_strokes) + "(C: " + str(avg_correct_strokes) + " | W: " + str(avg_wrong_strokes) + ")" + "\nAccuracy: " + str(avg_accuracy) + "%" + "\nCorrect Words: " + str(avg_correct_words) + "\nWrong Words: " + str(avg_wrong_words)) running = True while running: # Clears the screen screen.fill(background_color) # Starts looping through all events for event in pygame.event.get(): # Checks if the game was closed if event.type == pygame.QUIT: pygame_exit() # Checks if the mouse was clicked if event.type == pygame.MOUSEBUTTONDOWN: # Checks if the left mouse button was clicked if pygame.mouse.get_pressed()[0]: # Iterates through all of the buttons and checks if they were clicked for button in button_list: # Checks if the button was clicke and if so it calls the buttons action function if button.isOver((pygame.mouse.get_pos())): if button == back_button: running = False else: button.action() # Draws header header.display_text(screen, screen_width / 2 - header.text.get_width() / 2, 50) # Draws the buttons for button in button_list: button.draw(screen) wpm_text.display_text(screen, screen_width / 2 - wpm_text.text.get_width() / 2, 150) stats_text.display_text( screen, screen_width / 2 - stats_text.text.get_width() / 2 / 4, screen_height / 2 - stats_text.text.get_height() / 2 * 4) pygame.display.update()
def main(): # Adds the current directory to the list of directories that the program uses to check for modules sys.path.append('.') sys.path.append('..') from project_main import main_func from buttonClass import Button, Text, pygame_exit from Minesweeper.minesweeper_engine import Grid # Sets the current working directory to the directory that the minesweeper_main.py file is in # This fixes some problems that occur when trying to load images if os.getcwd().split("\\")[-1] != "Minesweeper": abspath = os.path.abspath(__file__) dname = os.path.dirname(abspath) os.chdir(dname) # Retrieves the scoreboard data for each mode and saves the list of scores in a dictionary with open("user_data_easy.txt", "r") as data_easy, open( "user_data_medium.txt", "r") as data_medium, open("user_data_hard.txt", "r") as data_hard: scores = { "easy": list(map(lambda s: int(s.replace("\n", "")), data_easy.readlines())), "medium": list( map(lambda s: int(s.replace("\n", "")), data_medium.readlines())), "hard": list(map(lambda s: int(s.replace("\n", "")), data_hard.readlines())) } scores["easy"].sort() scores["medium"].sort() scores["hard"].sort() # Code for loading in sounds global music_on music_on = True click_sound = pygame.mixer.Sound("./minesweeper_sound_effects/click.wav") flag_sound = pygame.mixer.Sound("./minesweeper_sound_effects/flag.wav") unflag_sound = pygame.mixer.Sound("./minesweeper_sound_effects/unflag.wav") bomb_sound = pygame.mixer.Sound("./minesweeper_sound_effects/ding.wav") lose_sound = pygame.mixer.Sound("./minesweeper_sound_effects/gameOver.wav") win_sound = pygame.mixer.Sound("./minesweeper_sound_effects/gameWin.wav") # Calculates the time since start of game and displays it and the timer icon on the screen def display_timer(time_passed=0): pygame.draw.rect(screen, background_color, (screen_height + 90, 36, timer_text.text.get_width(), timer_text.text.get_height())) screen.blit(timer_icon, (screen_height + 15, 20)) timer_text.update_text(str(int(time_passed))) timer_text.display_text(screen, screen_height + 90, 36) # Turns the music and sound effects on and off def toggle_music(): global music_on if music_on: pygame.mixer.set_num_channels(0) pygame.mixer.music.stop() music_on = False else: pygame.mixer.set_num_channels(8) pygame.mixer.music.play() music_on = True # Draws the speaking image ontop of the button for toggling the music def display_speaker(): global button_x if music_on: screen.blit(sound_icon, (button_x, 95)) else: screen.blit(mute_icon, (button_x, 95)) # Displays the wining and losing messages to the screen def display_message(): # Draws the message box message_box_dimensions = (screen_width * 0.5, screen_height * 0.4) message_box_position = (screen_width / 2 - message_box_dimensions[0] / 2, screen_height / 2 - message_box_dimensions[1] / 2) rectangle = pygame.Rect(message_box_position, message_box_dimensions) message_color = (51, 153, 255) pygame.draw.rect(screen, message_color, rectangle) # Defines the text if the play lost if grid.board_state == "lost": message_text = Text("You Lost", (255, 255, 255), "comicsans", 50) score_text = Text("0", (255, 255, 255), "comicsans", 50) # Defines the text if the play won elif grid.board_state == "won": message_text = Text("You Won", (255, 255, 255), "comicsans", 50) score_text = Text(timer_text.string, (255, 255, 255), "comicsans", 50) # Displays the previously defined text message_text.display_text( screen, message_box_position[0] + message_box_dimensions[0] / 2 - message_text.text.get_width() / 2, message_box_position[1] + message_box_dimensions[1] / 4 - message_text.text.get_height() / 2) # Draws the timer icon and score under the text in the message box screen.blit(timer_icon, (screen_width / 2 - 32, screen_height / 2 - 32)) score_text.display_text( screen, message_box_position[0] + message_box_dimensions[0] / 2 - score_text.text.get_width() / 2, message_box_position[1] + message_box_dimensions[1] * 3 / 4 - score_text.text.get_height() / 2) # Defines the global mode variable which stores the current game mode global mode mode = "easy" # update mode is a decorator that adds the feature of updating the global mode variable to the set mode function # the reason I used a decorator instead of just adding a mode parameter to the set_mode function is because the button class only takes the name of a function to call but not what parameter to call with it. # this means that I can only use buttons with functions that don't have parameters so I used a decorator instead of changing the button class def update_mode(func, new_mode): def set_mode_modified(): global mode mode = new_mode func() return set_mode_modified # Original set mode function that resets the grid, timer, and music def set_mode(): global mode, grid, start_time grid = Grid(mode, screen_height) start_time = None pygame.mixer.music.stop() pygame.mixer.music.load("./minesweeper_sound_effects/gameMusic.mp3") if music_on: pygame.mixer.music.play(-1) # Functions for changing the mode to easy, medium, and hard set_mode_easy = update_mode(set_mode, "easy") set_mode_medium = update_mode(set_mode, "medium") set_mode_hard = update_mode(set_mode, "hard") # Defines the screen screen_width = 800 screen_height = 600 screen = pygame.display.set_mode((screen_width, screen_height)) background_color = (2, 1, 34) # Sets caption at top of window to "Minsweeper" pygame.display.set_caption('Minesweeper') # Defines the grid with a size of 10 by 10 global grid grid = Grid("easy", screen_height) # Defines a variable to store the starting time of the game. global start_time start_time = None timer_text = Text("0", (255, 255, 255), "comicsans", 64) # Loads and resizes the timer icon timer_icon = pygame.image.load("minesweeper_image_assets/timer.png") # Loads the speaker images sound_icon = pygame.image.load("minesweeper_image_assets/volume.png") mute_icon = pygame.image.load("minesweeper_image_assets/mute.png") # Defines difficulty buttons, sound button, and menu button button_width = 0.8 * (screen_width - screen_height) button_height = 50 global button_x button_x = screen_height + 0.5 * (screen_width - screen_height - button_width) sound_button = Button(background_color, button_x, 95, 32, 32, toggle_music, "", 0, None, 'comicsans', 30, None, background_color) easy_button = Button((50, 255, 50), button_x, (button_height + 20) + 75, button_width, button_height, set_mode_easy, "EASY", 0, None, 'comicsans', 30, (255, 255, 255), (40, 150, 40)) medium_button = Button( (255, 165, 0), button_x, (button_height + 20) * 2 + 75, button_width, button_height, set_mode_medium, "MEDIUM", 0, None, 'comicsans', 30, (255, 255, 255), (150, 120, 0)) hard_button = Button( (255, 50, 50), button_x, (button_height + 20) * 3 + 75, button_width, button_height, set_mode_hard, "HARD", 0, None, 'comicsans', 30, (255, 255, 255), (150, 40, 40)) menu_button = Button( (50, 50, 255), button_x, screen_height - button_height - 20, button_width, button_height, main_func, "MENU", 0, None, 'comicsans', 30, (255, 255, 255), (40, 40, 150)) # defines the reset button reset_button_width = screen_width * 0.5 reset_button_height = screen_height * 0.1 reset_button_x = screen_width / 2 - reset_button_width / 2 reset_button_y = screen_height / 2 + screen_height * 0.4 / 2 + reset_button_height # Uses a dictionary to get the set_mode method that corresponds to the current mode and assigns it to the reset button action attribute modes = { "easy": set_mode_easy, "medium": set_mode_medium, "hard": set_mode_hard } reset_button = Button((0, 102, 0), reset_button_x, reset_button_y, reset_button_width, reset_button_height, modes[mode], "Try Again", font_color=(255, 255, 255), font_size=50) # Creates two list of buttons # Button list stores all the button that are displayed during the game # menu button list stores all the buttons displayed after the game is won/lost button_list = [ sound_button, easy_button, medium_button, hard_button, menu_button ] menu_button_list = [sound_button, reset_button, menu_button] # Plays game music pygame.mixer.music.load("./minesweeper_sound_effects/gameMusic.mp3") pygame.mixer.music.play(-1) # Game Loop running = True screen.fill(background_color) while running: if grid.board_state != "revealing_mines": pygame.draw.rect(screen, background_color, (screen_height, 0, screen_width - screen_height, screen_height)) for event in pygame.event.get(): # Ends the game loop if the user tries to close the window if event.type == pygame.QUIT: running = False break # Checks if mouse button was pressed if event.type == pygame.MOUSEBUTTONDOWN: mouse_pos = grid.mouse_to_index(pygame.mouse.get_pos()) # Checks if mouse is somewhere above the grid and the grid is in play if mouse_pos and grid.board_state == "in_play": if start_time == None: start_time = time.time() if pygame.mouse.get_pressed()[0]: if not grid.cells[mouse_pos[0]][ mouse_pos[1]].marked: # keeps regenerating the grid until the first uncovered square is not a mine and is not next to a mine and until the number of mines is at least 10 percent the number of cells while ( grid.cells[mouse_pos[0]][mouse_pos[1]]. mine or grid.cells[mouse_pos[0]] [mouse_pos[1]].mine_count != 0) or len( grid.mine_locations) < 0.1 * len( grid.cells) * len(grid.cells[0]): for row in grid.cells: for cell in row: cell.mine = grid.generate_mine_bool( ) for y in range(len(grid.cells)): for x in range(len(grid.cells[0])): grid.cells[y][ x].mine_count = grid.cells[y][ x].count_mines( grid.cells, (y, x)) grid.mine_locations = [ [row, col] for row in range(len(grid.cells)) for col in range(len(grid.cells[row])) if grid.cells[row][col].mine ] # Checks if the left mouse button was pressed if pygame.mouse.get_pressed()[0]: # Checks if the cells that the mouse is over is not marked and if so it makes that cell visible if not grid.cells[mouse_pos[0]][ mouse_pos[1]].marked and not grid.cells[ mouse_pos[0]][mouse_pos[1]].visible: click_sound.play() grid.uncover_cell(mouse_pos[0], mouse_pos[1], screen) # Checks if the right mouse button was pressed and if so it togles whether the cell is marked if pygame.mouse.get_pressed()[2]: if not grid.cells[mouse_pos[0]][mouse_pos[1]].marked: flag_sound.play() else: unflag_sound.play() grid.cells[mouse_pos[0]][ mouse_pos[1]].marked = not grid.cells[ mouse_pos[0]][mouse_pos[1]].marked # Checks if the left mous button was pressed off of the grid and checks if the user is clicking a button elif pygame.mouse.get_pressed()[0]: if grid.board_state == "lost" or grid.board_state == "won": # Updates what mode the reset button sets the game to reset_button.action = modes[mode] #Checks if the mouse is clicking one of the menu button for button in menu_button_list: button.draw(screen) if button.isOver((pygame.mouse.get_pos())): pygame.mixer.music.stop() button.action() else: # Checks if the mouse is clicking one of the button for button in button_list: if button.isOver((pygame.mouse.get_pos())): pygame.mixer.music.stop() button.action() # stops the rest of the game loop if the running variable is false meaning exit button was pressed if not running: break # Draws the difficulty buttons if the game in play if grid.board_state != "lost" and grid.board_state != "won": for button in button_list: button.draw(screen) # draws the speaker image display_speaker() # Defines Scoreboard text object top_scores = "" for i in range(5): top_scores += str(i + 1) + ". " try: top_scores += str(scores[mode][i]) except IndexError: pass top_scores += "\n" # Displays the scoreboard text on the screen # The text is enlarged on the menu screen if grid.board_state == "won" or grid.board_state == "lost": score_text = Text("SCORE\nBOARD\n\n" + top_scores, (255, 255, 255), "comicsans", 40) score_text.display_text(screen, button_x, 150) else: score_text = Text("SCORE BOARD\n\n" + top_scores, (255, 255, 255), "comicsans", 30) score_text.display_text(screen, button_x, (button_height + 20) * 3 + 150) # Draws the grid if grid.board_state == "in_play": grid.draw(screen) # Displays the image and text for the timer if start_time: display_timer(time.time() - start_time) else: display_timer() # Reveals one mine at a time from the grid's list of mine locations elif grid.board_state == "revealing_mines" and len( grid.mine_locations) > 0: pygame.mixer.music.stop() bomb_sound.play() grid.uncover_cell(grid.mine_locations[0][0], grid.mine_locations[0][1], screen) grid.mine_locations.pop(0) # Ends the game once all of the mines have been revealed elif grid.board_state == "revealing_mines" and len( grid.mine_locations) == 0: time.sleep(1) grid.board_state = "lost" screen.fill(background_color) lose_sound.play() time.sleep(3) pygame.mixer.music.load( "./minesweeper_sound_effects/menuMusic.mp3") if music_on: pygame.mixer.music.play(-1) # Displays the won or lost message if grid.board_state == "lost": display_message() reset_button.draw(screen) menu_button.draw(screen) elif grid.board_state == "won": display_message() reset_button.draw(screen) menu_button.draw(screen) # Updates screen pygame.display.update() # Checks if the game is won if grid.board_state == "in_play" and grid.win(): # Updates the scoreboard data file with the players score with open("user_data_" + mode + ".txt", "a") as data: if scores[mode] == []: data.write(timer_text.string) else: data.write("\n" + timer_text.string) scores[mode].append(int(timer_text.string)) scores[mode].sort() pygame.mixer.music.stop() time.sleep(1) grid.board_state = "won" screen.fill(background_color) win_sound.play() time.sleep(3) pygame.mixer.music.load( "./minesweeper_sound_effects/menuMusic.mp3") if music_on: pygame.mixer.music.play(-1) # Closes the window when the game loop ends pygame_exit()
def createBoard(win): """Creates program boad & instructions""" #list of graphics positions, convert to fit monLen, monHeight, some vars gLen = [498, 498, 0, 498, 250, 250, 1000, 250, 175, 425, 1000, 250, 300, 400, 100, 100, 100, 100, 100, 100, 100, 350, 350, 350, 100] gLen = [(num / 500) * (monLen - 1000) for num in gLen] gHt = [0, 1000, 600, 600, 25, 625, 500, 75, 140, 140, 500, 190, 700, 700, 680, 750, 785, 820, 855, 890, 925, 845, 800, 900, 600] gHt = [monHeight * num / 1000 for num in gHt] #Create line diving instructions, toolbar, and image divideLine1 = graphics.Line(graphics.Point(monLen - 1000, gHt[0]), graphics.Point(monLen - 1000, gHt[1])) divideLine1.setWidth(2) divideLine1.draw(win) divideLine2 = graphics.Line(graphics.Point(gLen[2], gHt[2]), graphics.Point(gLen[3], gHt[3])) divideLine2.setWidth(2) divideLine2.draw(win) instructionLable = graphics.Text(graphics.Point(gLen[4], gHt[4]), 'Instructions') instructionLable.setSize(20) instructionLable.setStyle('italic') instructionLable.draw(win) toolLabel = graphics.Text(graphics.Point(gLen[5], gHt[5]), 'Toolbar') toolLabel.setSize(20) toolLabel.setStyle('italic') toolLabel.draw(win) imageLabel = graphics.Text(graphics.Point(gLen[6], gHt[6]), 'Upload Image Here') imageLabel.setSize(20) imageLabel.setStyle('italic') imageLabel.draw(win) #INSTRUCTIONS instruction1 = graphics.Text(graphics.Point(gLen[7], gHt[7]), "1.) Enter the name of the image file, then click ENTER. \ \n Note that the file must be saved as .png \n (ex. filename.png)") instruction1.draw(win) entry1 = graphics.Entry(graphics.Point(gLen[8], gHt[8]), 25) entry1.draw(win) enterButton1 = Button(win, graphics.Point(gLen[9], gHt[9]), 80, 20, '#52E643', 'ENTER') #Click enterButton, open the image, deactivate image loop = True while loop: if enterButton1.clicked(win.getMouse()): global imageName imageName = entry1.getText() #Check user imput for name of file if imageName != '' and imageName[-4:] == '.png': loop = False else: errorMessage('Please enter a PNG image file. \n (ex. filename.png)') enterButton1.activate() #Upload image into window myImage = graphics.Image(graphics.Point(monLen - 500, monHeight/2), imageName) myImage.draw(win) enterButton1.deactivate() instruction2 = graphics.Text(graphics.Point(gLen[11], gHt[11]), "2.) Click on the buttons below to place an atom or ring center. \ \n Double click to place the object on the image. \ \n Then click FINISH when all of the objects have been placed.") instruction2.draw(win) #Create TOOLBAR siButton = Button(win, graphics.Point(gLen[12], gHt[12]), 40, 25, '#1DAA43', 'Si') oButton = Button(win, graphics.Point(gLen[13], gHt[13]), 40, 25, '#FF1D0F', 'O') generalRing = Button(win, graphics.Point(gLen[14], gHt[14]), 140, 34, '#F8A61E', 'General Ring') button4MR = Button(win, graphics.Point(gLen[15], gHt[15]), 140, 22, '#9E4BF6', '4 Membered Ring') button5MR = Button(win, graphics.Point(gLen[16], gHt[16]), 140, 22, '#4BB0F6', '5 Membered Ring') button6MR = Button(win, graphics.Point(gLen[17], gHt[17]), 140, 22, '#43C47F', '6 Membered Ring') button7MR = Button(win, graphics.Point(gLen[18], gHt[18]), 140, 22, '#F9DE3E', '7 Membered Ring') button8MR = Button(win, graphics.Point(gLen[19], gHt[19]), 140, 22, '#F94C3E', '8 Membered Ring') button9MR = Button(win, graphics.Point(gLen[20], gHt[20]), 140, 22, '#F726E8', '9 Membered Ring') removeButton = Button(win, graphics.Point(gLen[21], gHt[21]), 100, 25, '#F96A61', 'REMOVE') doneButton = Button(win, graphics.Point(gLen[22], gHt[22]), 100, 25, '#41EFC9', 'DONE') finishButton = Button(win, graphics.Point(gLen[23], gHt[23]), 120, 30, '#D4FF33', 'FINISH') autoPlaceButton = Button(win, graphics.Point(gLen[24], gHt[24]), 140, 22, '#F8A61E', 'Auto Place') return [siButton, oButton, generalRing, button4MR, button5MR, button6MR, button7MR, button8MR, button9MR, autoPlaceButton, removeButton, finishButton, doneButton]
def main(win): """The main code of the program""" #Create the board & buttons buttons = createBoard(win) # Make a nested list for ring centers centerLst = [] for i in range(9): centerLst.append([]) #centerLst = [[Si Centers], [O], [General Ring], [4 Membered], [5 Membered], [6 Membered], # [7 Membered], [8 Membered], [9 Membered]] # Define Lists to be used later colorLst = ['#1DAA43', '#FF1D0F', '#F8A61E', '#9E4BF6', '#4BB0F6', \ '#43C47F', '#F9DE3E', '#F94C3E', '#F726E8'] #Colors for rings labelLst = ['Si', 'O', 'GR', '4', '5', '6', '7', '8', '9'] #Labels for rings ringLst = [] #List to store ring objects #Check if a button is clicked & place rings until user clicks FINISH loop1 = True while loop1: mousePress = win.getMouse() #Place rings when button is clicked for i in range(9): if buttons[i].clicked(mousePress): placeCenter(win, buttons[i], buttons[12], centerLst[i], \ ringLst, buttons, colorLst[i], labelLst[i]) #REMOVE atoms/rings when button is clicked if buttons[10].clicked(mousePress): #Deactivate all buttons except REMOVE and DONE for i in range(10): buttons[i].deactivate() buttons[11].deactivate() #Select rings to remove while buttons[10].getOutlineColor() == 'yellow': mousePress = win.getMouse() for ring in ringLst: if ring.clicked(mousePress): #Remove center from corresponding list center = ring.getCenter() for j in range(len(labelLst)): if ring.getLabel() == labelLst[j]: print(labelLst[j]) print("alppage") centerLst[j].remove(center) #remove the ring ring.removeRing() ringLst.remove(ring) if checkDone(mousePress, buttons[12]) == True: resetButtons(buttons) #if autofind buttons pressed, run autofind function if buttons[9].clicked(mousePress): autoFind(win, centerLst, ringLst, colorLst, labelLst) #Input dimensions of photo when FINISH is clicked elif buttons[11].clicked(mousePress): #Exist fist while loop loop1 = False #Deactivate all buttons for i in buttons: i.deactivate() #Find pixel -> nm conversion factor #Enter Pixel dimensions instruction3 = graphics.Text(graphics.Point(250, 265), "3.) Enter the size of the image file in pixels. \ \n Note that the entry must include a decimal point.\n(ex. 900.0 x 900.0 pixels)") instruction3.draw(win) #Enter nm dimensions instruction4 = graphics.Text(graphics.Point(250, 360), "4.) Enter the size of the image file in nanometers (nm). \ \n Note that the entry must include a decimal point.\n(ex. 5.0 x 5.0 nm)") instruction4.draw(win) #Set up entry boxes for user nmBoxH = graphics.Entry(graphics.Point(282, 405), 7) nmBoxH.draw(win) text2 = graphics.Text(graphics.Point(237.5, 405), "X") text2.draw(win) txtLabel2 = graphics.Text(graphics.Point(330, 405), "nm") txtLabel2.draw(win) nmBoxW = graphics.Entry(graphics.Point(194, 405), 7) nmBoxW.draw(win) pixBoxH = graphics.Entry(graphics.Point(282, 310), 7) pixBoxH.draw(win) text = graphics.Text(graphics.Point(237.5, 310), "X") text.draw(win) txtLabel = graphics.Text(graphics.Point(340, 310), "pixels") txtLabel.draw(win) pixBoxW = graphics.Entry(graphics.Point(194, 310), 7) pixBoxW.draw(win) enterButton2 = Button(win, graphics.Point(425, 405), 85, 20, '#52E643', 'ENTER') #Program dimensions enter button loop2 = True while loop2: mousePress = win.getMouse() if enterButton2.clicked(mousePress): #enterButton2.deactivate() #Sore values of dimensions nmHeight = nmBoxH.getText() nmWidth = nmBoxW.getText() pixHeight = pixBoxH.getText() pixWidth = pixBoxW.getText() #Check the user input values are decimals if checkDecimal(nmHeight) and checkDecimal(nmWidth) and checkDecimal(pixHeight) \ and checkDecimal(pixWidth): #Calculate average conversion factor convtFact = (((float(nmWidth) / float(pixWidth)) + \ (float(nmHeight) / float(pixHeight))) / 2) #Finish the program after user has input dimensions instruction5 = graphics.Text(graphics.Point(250, 450), "5.) Click on the buttons below to finish the program.") instruction5.draw(win) enterButton2.deactivate() #Exit second while loop loop2 = False else: errorMessage('Please enter dimensions as decimals. \n (ex. 900.0 x 900.0 pixels)') enterButton2.activate() #Create final buttons exportButton = Button(win, graphics.Point(100, 520), 100, 40, '#FFEE33', 'Export to \n xyz File') exportButton.setBoldText() distButton = Button(win, graphics.Point(250, 520), 150, 40, '#33D6FF', 'Show Distribution \n Graph') distButton.setBoldText() quitButton = Button(win, graphics.Point(400, 520), 100, 40, '#FF3369', 'QUIT') quitButton.setBoldText() #List of labels textLst = ['Si', 'O ', 'GR', '4M', '5M', '6M', '7M', '8M', '9M'] #Print lists in pixels #for i in range(len(textLst)): # print(textLst[i] + ' Centers (pixels) = ' + str(centerLst[i])) #Convert list of centers in pixels -> nm for i in range(len(centerLst)): for j in range(len(centerLst[i])): centerLst[i][j] = convertCenter2nm(centerLst[i][j], convtFact) #Print lists in nm #for i in range(len(textLst)): # print(textLst[i] + 'Centers (nm) = ' + str(centerLst[i])) #Program last three buttons loop3 = True while loop3: mousePress = win.getMouse() if exportButton.clicked(mousePress): #Export to xyz file (cords in Angstroms) if alertMessage('Export coordinates to xyz file \n saved as ringAnalyzerCoordinates.txt'): writeXYZ('ringAnalyzerCoordinates.txt', textLst, centerLst) exportButton.deactivate() else: exportButton.activate() elif distButton.clicked(mousePress): #PLOT atom / ring distribution plotDistribution(textLst, colorLst, centerLst) distButton.deactivate() elif quitButton.clicked(mousePress): if alertMessage('Click OK to exit the program \n (The image file will not be saved)'): win.close() loop3 = False else: quitButton.activate()
def q20(): # Setting up graphics window and making it visually appealing. win = GraphWin("20 Questions", 800, 600) win.setCoords(0.0, 0.0, 8.0, 6.0) win.setBackground("LightGray") title = Text(Point(4.0, 5.5), "20 Questions") title.setTextColor("SteelBlue") title.setFace("times roman") title.setSize(32) title.draw(win) # Prompting the user to interact with the program in a visually pleasing way. instructions = Text( Point(3.5, 4.5), "Welcome to 20 Questions! Please think of an item to begin the game.") instructions.setTextColor("SlateGray") instructions.setFace("times roman") instructions.setSize(24) instructions.draw(win) startButton = Button(win, Point(4, 3), 2, .6, "start") startButton.activate() begin = False while not begin: pt = win.getMouse() if startButton.clicked(pt): instructions.undraw() startButton.remove() begin = True # Prompting the user to interact with the program in a visually pleasing way. instructions = Text(Point(2.2, 4.5), "Great! Let's get started. Is this thing a(n):") instructions.setTextColor("SlateGray") instructions.setFace("times roman") instructions.setSize(24) instructions.draw(win) animalButton = Button(win, Point(2, 3), .8, .5, "animal") animalButton.activate() mineralButton = Button(win, Point(3.3, 3), .8, .5, "mineral") mineralButton.activate() vegetableButton = Button(win, Point(4.6, 3), .8, .5, "vegetable") vegetableButton.activate() otherButton = Button(win, Point(5.9, 3), .8, .5, "other") otherButton.activate() nextQ = False while not nextQ: pt = win.getMouse() if animalButton.clicked(pt): instructions.undraw() animalButton.remove() mineralButton.remove() vegetableButton.remove() otherButton.remove() nextQ = True elif mineralButton.clicked(pt): instructions.undraw() animalButton.remove() mineralButton.remove() vegetableButton.remove() otherButton.remove() nextQ = True elif vegetableButton.clicked(pt): instructions.undraw() animalButton.remove() mineralButton.remove() vegetableButton.remove() otherButton.remove() nextQ = True elif otherButton.clicked(pt): instructions.undraw() animalButton.remove() mineralButton.remove() vegetableButton.remove() otherButton.remove() nextQ = True qCount = 1 while qCount < 20: ans = nextQuestion(win, " ___ ") qCount += 1 win.close()
def nextQuestion(win, myO): instructions = Text(Point(1.2, 4.5), "Is this thing a {}".format(myO)) instructions.setTextColor("SlateGray") instructions.setFace("times roman") instructions.setSize(24) instructions.draw(win) yesButton = Button(win, Point(3.2, 3), .8, .5, "yes") yesButton.activate() noButton = Button(win, Point(4.8, 3), .8, .5, "no") noButton.activate() nextQ = False yes = False while not nextQ: pt = win.getMouse() if yesButton.clicked(pt): instructions.undraw() yesButton.remove() noButton.remove() nextQ = True yes = True elif noButton.clicked(pt): instructions.undraw() yesButton.remove() noButton.remove() nextQ = True return yes