def __init__(self): """ the constactor of the game gui,and creating the first user's menu. """ self._game_modes_options = { 1: PERSON_VS_COMPUTER, 2: PERSON_VS_PERSON, 3: COMP_VS_COMP } self._player_colors = {1: 'red', 2: 'blue'} self._column = 0 self._root = tk.Tk() self._disks = [] self._game_logic = Game() self._choice = tk.StringVar() self._choice.set('choose game type, Default game is p vs p') self._menu = tk.OptionMenu(self._root, self._choice, PERSON_VS_COMPUTER, PERSON_VS_PERSON, COMP_VS_COMP) self._choose_button = tk.Button(self._root, text='press OK', command=self.init_single_game) self._choose_button.pack() self._menu.pack() self._ai_first = None self._ai_second = None
def reset(self): """this function reset the board""" self.__c.delete("all") self.__c.create_image(0, 0, image=self.__backgroundimage, anchor=tk.NW) self.__game = Game() self.__board_state = self.create_board() self.__player_display_label.config(image=self.__down)
def __init__(self, master): """ Initialize an App object. :param master: The main root of the game """ self.__master = master self.__master.protocol("WM_DELETE_WINDOW", self.__press_x) self.__master.geometry("850x550") self.__master.title(self.GAME_TITLE) self.__game = Game() self.__enter_frame = tk.Frame(self.__master, height=550, width=850, bg=self.BG) self.__game_frame = tk.Frame(self.__master, height=550, width=850, bg=self.BG) self.__board_canvas = tk.Canvas(self.__game_frame, height=450, width=550, highlightthickness=2, highlightbackground="black") self.__player1_canvas = tk.Canvas(self.__game_frame, height=130, width=100, highlightbackground=self.GOLD, highlightthickness=4, bg=self.BG) self.__player2_canvas = tk.Canvas(self.__game_frame, height=130, width=100, bg=self.BG, highlightthickness=2, highlightbackground="black") self.__available_rows = { col: self.ROWS_SIZE - 1 for col in range(self.COLS_SIZE) } self.__ai_players = {1: None, 2: None} self.__circles_dict = {} self.__after_id = "" self.__entrance_frame()
def reset(self): """ the function that is resetting the game if the user chooses to play another game. filling the board with empty slots and the pointer to player 1 turn. and also creating a new game and updating the computers in that game. """ for row in self._disks: for element in row: self._canvas.itemconfig(element, fill='white') self._game_logic = Game() self._canvas.itemconfig( self._pointer, fill=self._player_colors[self._game_logic.get_current_player()]) if self._choice.get() == COMP_VS_COMP: self._ai_first.set_game(self._game_logic) self._ai_second.set_game(self._game_logic) self.comp_turn(self._ai_first) if self._choice.get() == PERSON_VS_COMPUTER: self._ai_first.set_game(self._game_logic)
def __init__(self, root, users): """This function is a constructor for graphic game object""" self.__dir_path = os.path.dirname(os.path.realpath(__file__)) self.__img1 = PhotoImage(file=self.__dir_path + '/EAsportslogo.png') self.__img2 = PhotoImage(file=self.__dir_path + '/_board.png') self.__cur_game = Game() self.__root = root if users: self.__ai = users else: self.WANT_PLAY = False return self.__can = self.create_canvas() self.__turns = [] self.__cur_player = 0 self.__label_img = self.post_background(self.__img1) self.__label_img = self.__root.after(3000, self.post_background, self.__img2) self.__buttons = [] self.__root.after(3000, self.create_buttons) self.__ai_list = self.create_AI() self.__root.after(3050, self.whos_begin) self.WANT_PLAY = False self.__nonvalids = []
class Gui: def __init__(self): """ the constactor of the game gui,and creating the first user's menu. """ self._game_modes_options = { 1: PERSON_VS_COMPUTER, 2: PERSON_VS_PERSON, 3: COMP_VS_COMP } self._player_colors = {1: 'red', 2: 'blue'} self._column = 0 self._root = tk.Tk() self._disks = [] self._game_logic = Game() self._choice = tk.StringVar() self._choice.set('choose game type, Default game is p vs p') self._menu = tk.OptionMenu(self._root, self._choice, PERSON_VS_COMPUTER, PERSON_VS_PERSON, COMP_VS_COMP) self._choose_button = tk.Button(self._root, text='press OK', command=self.init_single_game) self._choose_button.pack() self._menu.pack() self._ai_first = None self._ai_second = None def init_single_game(self): """ the initiator of the first game, creating the game by the user's choices. creating the board and the instructions menu and the game itself. """ top = tk.Frame(self._root, bg='burlywood4') instruction = tk.Label( top, text= "Move instructions:\n move right- right arrow\nmove left - left arrow\nshoot ball: Space", font=('Helvetica', 13)) instruction.pack(side=tk.RIGHT) arba_beshora = tk.Label(top, text="Four in a row", font=('Helvetica', 10)) arba_beshora.pack(side=tk.TOP) top.pack(side=tk.TOP, fill=tk.BOTH) self._canvas = tk.Canvas(top, bg='saddle brown', height=700, width=700) self._root.bind('<Left>', lambda event: self.move_pointer(-1, True)) self._root.bind('<Right>', lambda event: self.move_pointer(1, True)) self._root.bind('<space>', lambda event: self.one_turn(True)) self._pointer = self._canvas.\ create_oval(0, 0, 100, 100, fill='red', outline='red') self._canvas.pack() self.check_if_over() self._choose_button.pack_forget() self._menu.pack_forget() self.create_board() # creating the computers according the the user's choice if (self._choice.get() == COMP_VS_COMP): self._ai_first = AI(self._game_logic, 1) self._ai_second = AI(self._game_logic, 2) self.comp_turn(self._ai_first) elif (self._choice.get() == PERSON_VS_COMPUTER): self._ai_first = AI(self._game_logic, 2) def comp_turn(self, ai_player_x): """ this function is creating the move of the computer, according to the ai, and creates it in a way that it is visible for the user if the game is comp vs comp. :param ai_player_x: an ai type. :return: None """ # so the game wont sleep before its started. if not self._game_logic.is_board_empty(): time.sleep(0.7) # finding the computer's move. comp_move = ai_player_x.find_legal_move() # if the function returns None, the board is full or 1 player won the game. if comp_move is None: self.check_if_over() return # moving the pointer to the place that the comp is playing the turn, # so we can see the comp turn visible. while self._column != comp_move: if self._column < comp_move: self.move_pointer(1) else: self.move_pointer(-1) self.one_turn() def reset(self): """ the function that is resetting the game if the user chooses to play another game. filling the board with empty slots and the pointer to player 1 turn. and also creating a new game and updating the computers in that game. """ for row in self._disks: for element in row: self._canvas.itemconfig(element, fill='white') self._game_logic = Game() self._canvas.itemconfig( self._pointer, fill=self._player_colors[self._game_logic.get_current_player()]) if self._choice.get() == COMP_VS_COMP: self._ai_first.set_game(self._game_logic) self._ai_second.set_game(self._game_logic) self.comp_turn(self._ai_first) if self._choice.get() == PERSON_VS_COMPUTER: self._ai_first.set_game(self._game_logic) def one_turn(self, clicked=False): """ this function is running one turn in the game, both user's turn and computer's turn if there are computers playing. :param clicked: a bool expression, which shows if the function launched from a click by the user, or by the computer. True if by user, False if by the computer. :return: None, but updates the board. """ # so we wont be able to change the game of the computers. if (clicked and self._choice.get() == COMP_VS_COMP) or ( clicked and self._ai_first and self._game_logic.get_current_player() == 2): return if self._game_logic.is_possible_move(self._column): position = self._game_logic.make_move(self._column) self._canvas.itemconfigure(self._disks[position[0]][position[1]], fill=self._canvas.itemcget( self._pointer, 'fill')) self._canvas.itemconfig(self._pointer, fill=self._player_colors[ self._game_logic.get_current_player()]) self._root.update() if (self._ai_first and self._ai_second) or \ (self._ai_first and self._game_logic.get_current_player() == 2): self.comp_turn(self._ai_first) self.check_if_over() def check_if_over(self): """ a function that checks if the game is over, if the board is full or if there is a winner. also this function asks the user if he would like to play another game, or if he wishes to exit. and the function does what the user asked. """ winner = self._game_logic.get_winner() if winner is not None: if winner == 0: result = messagebox.askokcancel\ ("Hello ", "Its a tie" + " Would you like to Play again?") else: result = messagebox.askokcancel( "Hello ", "Player " + str(winner) + ' ' + "Won! " + "Would you like to Play again?") if result: self.reset() else: exit() def move_pointer(self, direction, clicked=False): """ this function moves the "pointer ball" which is the ball on top of the board. :param direction: -1 if moves to the left, 1 if moves to the right. :param clicked: if the function got called by a user click, or if the function called by the computer's turn. True if by the user's click, False if by the computer. :return: None """ if clicked and self._choice.get() == COMP_VS_COMP: return if self._ai_first and clicked: if self._game_logic.get_current_player() == 2: return if self._column == 0 and direction == -1 or \ self._column == 6 and direction == 1: return else: self._column += direction self._canvas.move(self._pointer, direction * 100, 0) self._root.update() time.sleep(0.2) def create_board(self): """ this function creates a game board for the four in a row game, alse if creates a list of all the empty places in the board, and updates the disks list. """ temporary_lst = [] for i in range(6): for j in range(7): temporary_lst.append( self._canvas.create_oval(0 + 100 * j, 200 + 100 * i, 100 + 100 * j, 100 + 100 * i, fill='white', outline='black')) self._disks.append(temporary_lst) temporary_lst = [] def run(self): """ the function that starts the game, by the mainloop. :return: """ self._root.mainloop()
############################################################# # FILE : four_in_a_row.py # WRITERs : Nir Amzaleg, Noa Moalem, nir_amzaleg, noamoa 206959686 ,208533554 # EXERCISE : intro2cs ex12 2019 # DESCRIPTION: This file create GUI object with Game() # object how run the four in a row game in fact. ############################################################# from ex12.GUI import Gui from ex12.game import Game if __name__ == '__main__': game = Game() g = Gui(game)
class Gui: """ this class create object from type gui that include: root - the current tkinter root users - list of the current players (AI / HUMAN) the class manage all the operate of the game and responsible to interface with the user """ COLUMNS_DIC = { 0: "column 1", 1: "column 2", 2: "column 3", 3: "column 4", 4: "column 5", 5: "column 6", 6: "column 7" } BALL_SIZE = 70 WIDTH_SPACE = 30 START_POINT = 25 def __init__(self, root, users): """This function is a constructor for graphic game object""" self.__dir_path = os.path.dirname(os.path.realpath(__file__)) self.__img1 = PhotoImage(file=self.__dir_path + '/EAsportslogo.png') self.__img2 = PhotoImage(file=self.__dir_path + '/_board.png') self.__cur_game = Game() self.__root = root if users: self.__ai = users else: self.WANT_PLAY = False return self.__can = self.create_canvas() self.__turns = [] self.__cur_player = 0 self.__label_img = self.post_background(self.__img1) self.__label_img = self.__root.after(3000, self.post_background, self.__img2) self.__buttons = [] self.__root.after(3000, self.create_buttons) self.__ai_list = self.create_AI() self.__root.after(3050, self.whos_begin) self.WANT_PLAY = False self.__nonvalids = [] def whos_begin(self): """the function checks whos begin. if AI is the first player to play so the function give a command to the game to start automatically""" if self.__ai: if self.__ai[0] is True: self.AI_move() def create_AI(self): """this function responsible for the create of the AI objects""" if not self.__ai: return ai_list = [] if self.__ai[0] is True: ai_list.append(AI(self.__cur_game, 1)) else: ai_list.append(None) if self.__ai[1] is True: ai_list.append(AI(self.__cur_game, 2)) else: ai_list.append(None) return ai_list def create_canvas(self): """this function create the main canvas of the game screen and post him to the window""" canvas_width = 650 canvas_height = 500 can = Canvas(self.__root, width=canvas_width, height=canvas_height) can.grid(row=0, column=0, columnspan=7, rowspan=6, padx=5, pady=5) return can def create_buttons(self): """this function create all the game buttons and post them to the game screen""" for column in range(7): self.__buttons.append( Button(self.__root, text=self.COLUMNS_DIC[column], command=self._column_event(column))) self.__buttons[column].grid(row=7, column=column, sticky='N') def post_background(self, img): """this function post image to the canva""" self.__can.create_image(10, 5, anchor='nw', image=img) return img def _column_event(self, column): """this function is the command function of all the buttons. the function responsible to update the Game object and create oval in accordance to the column that pressed""" def column_pressed(): row = self.look_for_row(column) self.__cur_game.make_move(column) if self.__cur_game.get_player_at(row, column) == 1: self.__turns.append( self.__can.create_oval(self.START_POINT + column * 90, row * 80 + 10, self.START_POINT + column * 90 + self.BALL_SIZE, row * 80 + self.BALL_SIZE + 10, fill="BLUE")) else: self.__turns.append( self.__can.create_oval(self.START_POINT + column * 90, row * 80 + 10, self.START_POINT + column * 90 + self.BALL_SIZE, row * 80 + self.BALL_SIZE + 10, fill="RED")) self.look_for_winner() self.__cur_player = (self.__cur_player + 1) % 2 if self.__ai[self.__cur_player]: for button in self.__buttons: button.config(state='disabled', bg="WHITE") self.__root.after(500, self.AI_move) return column_pressed def look_for_winner(self): """this function checks with the Game object if someone won the game and bold the winning ovals in the screen""" win_cor = self.__cur_game.win_cor() if win_cor: for cor in win_cor: column, row = cor[0], cor[1] self.__turns.append( self.__can.create_oval(self.START_POINT + column * 90, row * 80 + 10, self.START_POINT + column * 90 + self.BALL_SIZE, row * 80 + self.BALL_SIZE + 10, fill="WHITE")) self.win_func(self.__cur_game.get_player_at(row, column)) elif self.__cur_game.get_winner() == 0: self.win_func(0) def look_for_row(self, column): """this function get a column and look for empty row in that specific column to update""" for row in range(1, self.__cur_game.ROWS + 1): if self.__cur_game.get_player_at(self.__cur_game.ROWS - row, column) is None: if row == self.__cur_game.ROWS: self.__nonvalids.append(column) self.__buttons[column].config(state='disabled', bg="WHITE") return self.__cur_game.ROWS - row def AI_move(self): """this function manage the AI moves. the function look for col from the ai player and update the game""" if self.__cur_game.get_winner() is None: if self.__ai_list: column = self.__ai_list[self.__cur_player].find_legal_move() # row = self.look_for_row(column) if column is None: return column = self.__ai_list[self.__cur_player].find_legal_move() self._column_event(column)() if self.__ai[0] is False or self.__ai[1] is False: for column, button in enumerate(self.__buttons): if column not in self.__nonvalids and\ self.__cur_game.get_winner() is None: button.config(state='normal', bg="WHITE") def play_again(self): """the play again command function""" self.__root.destroy() self.WANT_PLAY = True def exit(self): """the exit command function""" self.__root.destroy() self.WANT_PLAY = False quit() def win_func(self, winner): """this function manage the win (finish) window. the function present to the user two optional buttons: play again or exit""" self.__ai_list = [] for button in self.__buttons: button.config(state='disabled', bg="WHITE") window = Toplevel(self.__root) can = Canvas(window, width=435, height=600) can.grid(row=0, column=0, columnspan=7, rowspan=6, padx=5, pady=5) self.img = PhotoImage(file='ex12/winner_img.png') self.label = can.create_image(0, 0, anchor=NW, image=self.img) winner_img = self.status_num(window, winner) can.create_image(0, 470, anchor=NW, image=winner_img) can.photo = winner_img can.config(scrollregion=can.bbox(ALL)) play_again = Button(window, text='PLAY AGAIN', command=self.play_again) play_again.grid(row=4, column=0, sticky='N', ipadx=10, ipady=20) exit = Button(window, text='I WANT TO GET OUT!', command=self.exit) exit.grid(row=4, column=6, sticky='N', ipadx=10, ipady=20) def status_num(self, window, winner): """this function load the correct img to the winning window in accordance to the winner identity""" if winner == 1: window.wm_title("Player 1 won!") winner_img = PhotoImage(file='ex12/player_one_won.png') if winner == 2: window.wm_title("Player 2 won!") winner_img = PhotoImage(file='ex12/player_two_won.png') if winner == 0: window.wm_title("It was a draw!") winner_img = PhotoImage(file='ex12/draw.png') return winner_img
class App: ROWS_SIZE = 6 COLS_SIZE = 7 PLAYERS = {1: "red4", 2: "blue4"} FONT = "Tex Gyre Schola Math" BG = "papaya whip" GOLD = "dark goldenrod" GAME_TITLE = "four in a row" QUIT_TITLE = "Game Over" GAME_M = "** FOUR IN A ROW **" CHOOSE_M = "CHOOSE PLAYERS:" GOODLUCK_M = "GOOD LUCK!" DRAW = "IT'S A TIE!" PLAY_AGAIN_M = "PLAY AGAIN" QUIT_M = "QUIT" PLAYER1_M = "PLAYER \n 1" PLAYER2_M = "PLAYER \n 2" MENU_M = "MAIN MENU" COMP_VS_COMP = "ex12/compVsComp.jpg" COMP_VS_MAN = "ex12/compVsMan.jpg" MAN_VS_MAN = "ex12/manVsMan.jpg" MAN_VS_COMP = "ex12/manVsComp.jpg" WOOD_BG = "ex12/woodBG.jpg" def __init__(self, master): """ Initialize an App object. :param master: The main root of the game """ self.__master = master self.__master.protocol("WM_DELETE_WINDOW", self.__press_x) self.__master.geometry("850x550") self.__master.title(self.GAME_TITLE) self.__game = Game() self.__enter_frame = tk.Frame(self.__master, height=550, width=850, bg=self.BG) self.__game_frame = tk.Frame(self.__master, height=550, width=850, bg=self.BG) self.__board_canvas = tk.Canvas(self.__game_frame, height=450, width=550, highlightthickness=2, highlightbackground="black") self.__player1_canvas = tk.Canvas(self.__game_frame, height=130, width=100, highlightbackground=self.GOLD, highlightthickness=4, bg=self.BG) self.__player2_canvas = tk.Canvas(self.__game_frame, height=130, width=100, bg=self.BG, highlightthickness=2, highlightbackground="black") self.__available_rows = { col: self.ROWS_SIZE - 1 for col in range(self.COLS_SIZE) } self.__ai_players = {1: None, 2: None} self.__circles_dict = {} self.__after_id = "" self.__entrance_frame() def __entrance_frame(self): """ Adds all the labels and buttons to the entrance frame, in the window that opens at the beginning of the game. :return: None """ self.__enter_frame.pack(expand=True, fill=tk.BOTH) welcome_label = tk.Label(self.__enter_frame, text=self.GAME_M, bg=self.BG, font=(self.FONT, 55, "bold")) welcome_label.place(relx=0.5, rely=0.02, anchor=tk.N) choose_label = tk.Label(self.__enter_frame, text=self.CHOOSE_M, bg=self.BG, font=(self.FONT, 35)) choose_label.place(relx=0.5, rely=0.18, anchor=tk.N) goodluck_label = tk.Label(self.__enter_frame, text=self.GOODLUCK_M, bg=self.BG, font=(self.FONT, 35)) goodluck_label.place(relx=0.5, rely=0.88, anchor=tk.N) comp_vs_comp = Image.open(self.COMP_VS_COMP).resize((220, 140), Image.ANTIALIAS) comp_vs_comp = ImageTk.PhotoImage(comp_vs_comp) cvsc_button = tk.Button(self.__enter_frame, image=comp_vs_comp, bg="black", command=self.__change_to_gamescreen( True, True)) cvsc_button.photo = comp_vs_comp cvsc_button.place(relx=0.18, rely=0.44, anchor=tk.W) comp_vs_man = Image.open(self.COMP_VS_MAN).resize((220, 140), Image.ANTIALIAS) comp_vs_man = ImageTk.PhotoImage(comp_vs_man) cvsm_button = tk.Button(self.__enter_frame, image=comp_vs_man, bg="black", command=self.__change_to_gamescreen( False, True)) cvsm_button.photo = comp_vs_man cvsm_button.place(relx=0.18, rely=0.72, anchor=tk.W) man_vs_man = Image.open(self.MAN_VS_MAN).resize((220, 140), Image.ANTIALIAS) man_vs_man = ImageTk.PhotoImage(man_vs_man) mvsm_button = tk.Button(self.__enter_frame, image=man_vs_man, bg="black", command=self.__change_to_gamescreen( False, False)) mvsm_button.photo = man_vs_man mvsm_button.place(relx=0.82, rely=0.44, anchor=tk.E) man_vs_comp = Image.open(self.MAN_VS_COMP).resize((220, 140), Image.ANTIALIAS) man_vs_comp = ImageTk.PhotoImage(man_vs_comp) mvsc_button = tk.Button(self.__enter_frame, image=man_vs_comp, bg="black", command=self.__change_to_gamescreen( True, False)) mvsc_button.photo = man_vs_comp mvsc_button.place(relx=0.82, rely=0.72, anchor=tk.E) def __change_to_gamescreen(self, player1, player2): """ This functions changes the screen from the entrance frame to the game frame, and create AI object for every player that supposed to be AI. :param player1: True if player 1 supposed to be AI, and False if not. :param player2: True if player 2 supposed to be AI, and False if not. :return: The function "gamescreen". """ def gamescreen(): self.__enter_frame.destroy() if player1: self.__ai_players[1] = AI(self.__game, 1) if player2: self.__ai_players[2] = AI(self.__game, 2) self.game_frame() return gamescreen def game_frame(self): """ Adds the board canvas, the two players canvases and the "main menu" button to the game frame. :return: None """ self.__game_frame.pack(expand=True, fill=tk.BOTH) game_label = tk.Label(self.__game_frame, text=self.GAME_M, bg=self.BG, font=(self.FONT, 35, "bold")) game_label.place(relx=0.5, rely=0.01, anchor=tk.N) self.__player1_canvas.place(relx=0.97, rely=0.3, anchor=tk.E) self.__player2_canvas.place(relx=0.03, rely=0.3, anchor=tk.W) self.__player1_canvas.create_text((57, 30), text=self.PLAYER1_M, font=(self.FONT, 15, "bold")) self.__player1_canvas.create_oval(23, 60, 83, 120, fill=self.PLAYERS[1]) self.__player2_canvas.create_text((57, 30), text=self.PLAYER2_M, font=(self.FONT, 15, "bold")) self.__player2_canvas.create_oval(23, 60, 83, 120, fill=self.PLAYERS[2]) self.__board_canvas.place(relx=0.5, rely=0.15, anchor=tk.N) wood_bg = Image.open(self.WOOD_BG).resize((560, 460), Image.ANTIALIAS) wood_bg = ImageTk.PhotoImage(wood_bg) self.__board_canvas.photo = wood_bg self.__board_canvas.create_image(0, 0, image=wood_bg, anchor=tk.NW) self.__make_circles(self.ROWS_SIZE, self.COLS_SIZE) restart_button = tk.Button(self.__game_frame, width=11, height=2, text=self.MENU_M, bg=self.BG, font=(self.FONT, 10), command=self.__play_again( self.__game_frame)) restart_button.place(relx=0.02, rely=0.9, anchor=tk.SW) if self.__ai_players[1]: self.__put_disk_in_col(self.__ai_players[1].find_legal_move()) self.__board_canvas.bind("<Motion>", self.__move_cursor) self.__board_canvas.bind("<Button-1>", self.__put_disc) def __make_circles(self, rows_size, cols_size): """ Adds circles to the board canvas, and to the circles dictionary. :param rows_size: The cols' amount in the board. :param cols_size: The rows' amount in the board. :return: None """ for row in range(rows_size): for col in range(cols_size): circle = self.__board_canvas.create_oval(35 + col * 70, 25 + row * 70, 95 + col * 70, 85 + row * 70, fill=self.BG) self.__circles_dict[(row, col)] = circle def __play_again(self, trans_root): """ This function cancels the after' if there is one at the time, destroys the trans root and the main root (to start the game from the beginning). :param trans_root: The transport root to destroy :return: The "play_again_h" function """ def play_again_h(): if self.__after_id: self.__master.after_cancel(self.__after_id) trans_root.destroy() self.__master.destroy() return play_again_h def __move_cursor(self, event): """ Checks if the cursor is on one of the columns. If it is, the function will fill the first available circle with the color of the current player. :param event: The event of the cursor moving on the board canvas :return: None """ if not self.__ai_players[self.__game.get_current_player()] \ and not self.__game.get_winner(): x_coor, y_coor = event.x, event.y # check if it's not in the margins or between the columns. if y_coor in range(25, 435) or x_coor % 70 in range(26, 35): col = (x_coor - 35) // 70 else: col = -1 cur_color = self.PLAYERS[self.__game.get_current_player()] if col in range(self.COLS_SIZE) and col not in [-1, 7]: row = self.__available_rows[col] if row >= 0: circ = self.__circles_dict[(row, col)] self.__board_canvas.itemconfig(circ, fill=cur_color) # fill all the other circles with the background color. for c, av_row in self.__available_rows.items(): if c != col and av_row >= 0: self.__board_canvas.itemconfig(self.__circles_dict[(av_row, c)], fill=self.BG) def __put_disc(self, event): """ If the current player is not an AI player, the function will put the disc in the column that was pressed. :param event: The event of clicking on the mouse :return: None """ if not self.__ai_players[self.__game.get_current_player()]: x_coor = event.x col = (x_coor - 35) // 70 if col in range(self.COLS_SIZE) or x_coor % 70 not in \ range(26, 35): self.__put_disk_in_col(col) def __put_disk_in_col(self, col): """ If it's legal to put a disc in the given column, the function will fill the first available circle in the given color with the color of the current player. If no one won in this turn and the next player is an AI player, the function will call itself after 700 ms. :param col: The col that the player want to put the disc in :return: None """ cur_player = self.__game.get_current_player() cur_color = self.PLAYERS[cur_player] row = self.ROWS_SIZE - 1 try: while self.__game.get_player_at(row, col): row -= 1 self.__game.make_move(col) except: return self.__board_canvas.itemconfig(self.__circles_dict[(row, col)], fill=cur_color) self.__available_rows[col] -= 1 self.__check_win() cur_player = self.__game.get_current_player() self.__current_player(cur_player) if self.__ai_players[cur_player]: af_id = self.__master.after(700, self.__ai_turn(cur_player)) self.__after_id = af_id def __ai_turn(self, player): """ If there are legal moves (no one won and the board isn't full), the function will col the "put_disc_in_col" function with the col the AI gave. :param player: The current player :return: The "ai_helper" function """ def ai_helper(): try: self.__put_disk_in_col( self.__ai_players[player].find_legal_move()) except: pass return ai_helper def __current_player(self, player): """ This function markers the canvas of the current player. :param player: The current player :return: None """ if player == 1: self.__player1_canvas.config(highlightbackground=self.GOLD, highlightthickness=4) self.__player2_canvas.config(highlightbackground="black", highlightthickness=2) else: self.__player2_canvas.config(highlightbackground=self.GOLD, highlightthickness=4) self.__player1_canvas.config(highlightbackground="black", highlightthickness=2) def __check_win(self): """ Checks if the game is over and if one of the players won, or the board is empty. If there is a winner, the function will marker the circles that gave the win. After that, it will open the transport window. :return: None """ winner = self.__game.get_winner() if winner in [0, 1, 2]: if winner in self.PLAYERS: win_coor = self.__game.get_win_coordinates() for coor in win_coor: self.__board_canvas.itemconfig(self.__circles_dict[coor], width=3, outline=self.GOLD) self.__trans_window() def __trans_window(self): """ Create a new window, that say why the game is over, and asks the player if he want to play again or to quit. :return: None """ trans_window = tk.Tk() trans_window.protocol("WM_DELETE_WINDOW", trans_window) trans_window.geometry("300x150") trans_window.title(self.QUIT_TITLE) winner = self.__game.get_winner() if winner in self.PLAYERS: txt = "PLAYER " + str(winner) + " HAS WON!" color = self.PLAYERS[winner] else: txt = self.DRAW color = "black" trans_frame = tk.Frame(trans_window, width=300, height=200, bg=color) trans_frame.pack(expand=True, fill=tk.BOTH) trans_label = tk.Label(trans_frame, text=txt, bg=color, font=(self.FONT, 15, "bold"), fg=self.BG) trans_label.place(relx=0.5, rely=0.01, anchor=tk.N) play_again_button = tk.Button(trans_frame, width=11, height=2, text=self.PLAY_AGAIN_M, bg=self.BG, font=(self.FONT, 10), command=self.__play_again(trans_window)) quit_button = tk.Button(trans_frame, width=11, height=2, text=self.QUIT_M, bg=self.BG, font=(self.FONT, 10), command=quit) play_again_button.place(relx=0.45, rely=0.8, anchor=tk.SE) quit_button.place(relx=0.55, rely=0.8, anchor=tk.SW) def __press_x(self): """ Create a new window that asks the player if he is sure he want to exit the game. :return: None """ if messagebox.askokcancel("Quit", "Do you want to quit?"): exit()
def move(): self.__mainscreen.destroy() self.__game = Game() MyConnectFour(self.__root, self.__game, num)
import tkinter as tk