I have learned so much from it. Especially my OOPs concepts just elevated. I have seen the full video end to end and also created my own Minesweeper. It took me only 2 days to create the game end to end. I can not believe I completed that within 3 to 4 long steak in 2 days. The video is too engaging and Jim, you the best.
In order to test the success message, I added a static method to the class to show all the mines: @staticmethod def show_all_mines(): for cell in Cell.all: if cell.is_mine: cell.cell_btn_object.configure(bg='yellow') In the main program, after randomize the mine placement: Cell.show_all_mines() Just for testing of course.
how can I show all the mines at the game over?????????????????????????any one please, I tried this but it does not work def show_mine(self): for cell in Cell.all: if cell.is_mine: cell.cell_btn_object.configure(bg='yellow') ctypes.windll.user32.MessageBoxW(0, 'You clicked on a mine', 'Game Over', 0) sys.exit()
i created a button and bind it to the function. # Debugging mine_viewer = Button( left_frame, bg='black', fg= 'white', text= 'View Mines', font=('', 10), ) mine_viewer.place( x= utils.width_prct(2), y= utils.height_prct(25) ) mine_viewer.bind('', Cell.show_all_mines) #replace the Cell.show_all_mines() & add the above code to the main module. #just a nice touch. and great job on creating the function :)
and also changes on the real function @staticmethod def show_all_mines(event): mine_cell = [] for cell in Cell.all: if cell.is_mine: mine_cell.append(cell.cell_btn_object.configure(bg='yellow')) return mine_cell #added a list
Thank you for the great tutorial. I just wanted to leave a quick note for anyone using Linux. The background color specified @2:05:11 bg="SystemButtonFace" will generate an error. Use bg="gray85" instead
Piggy-backing your comment to deliver another message to Linux users: as Jim mentions in the video, the ctypes module won't work for you. However, tkinter already has dialog box functionality. In `cell.py` add `messagebox` to this list of `tkinter` imports. Then, down in the `show_mine` method add: `messagebox.showinfo("title here", "message text here.")`
Very nice. I've got 2 things: 1. You should definitely add unbiding of events not only in the "current cell", but also in the loop of surrounding cells, so also all other surrounding cells that were open together with "current cell" are unbinded rright away as well, something like this: if self.is_mine: self.show_mine() else: self.show_cell() if self.surrounding_mines_count == 0: for cell in self.surrounding_cells: cell.show_cell() if Cell.CELL_COUNT == settings.MINES_COUNT: self._game_won() self._unbind_events(cell) self._unbind_events(self) 2. I would really like to know how to restart game (without close the window and open again). Just reset, clean everything. I cannot somehow figure it out :)
Hi Jim, excellent job! You are the best Python OOP Teacher ever, never experienced such good mentor, u are true talent !!! Got 1 question to project though: Although we placed bg="red", before calling ctype window, it executes in way window pops up and only then background color changes to red. Why is that? And how to solve it? Is it solvable using infinite loop?
Thank's a lot for this tutorial. Great job. You not only declared how to code this game but you really explained every step including your thoughts why to chose a certain implementation.
@anon only kotlin course is available.. There is an android studio course but they use Java in the course not kotlin... And they use xml not jet pack compose...Java and xml are old.. And nowadays people use kotlin and jet pack compose
I noticed that when you click on a cell with 0 surrounding cells, the cells get open too, but if around those cells there are 0 surrounding mines, it is not opened recursively at all. Here is what I implemented in my code: def show_cell(self): if not self.is_opened: Cell.cell_count -= 1 self.cell_btn_object.configure(text=self.surrounded_cells_mines_length) # Update the text of cell count label if Cell.cell_count_label_object: Cell.cell_count_label_object.configure( text=f"Cells left: {Cell.cell_count}" ) # If this was marked as a marked_flag, must update to the default color self.cell_btn_object.configure( bg='SystemButtonFace' ) # Mark the cell as opened self.is_opened = True if self.surrounded_cells_mines_length == 0: for cell in self.surrounded_cells: if not cell.is_opened: cell.show_cell() At first it was on the left clicked actions, but I changed it to the function show_cell, hope it helps :D
nice. just starting to learn oop. easy to follow along. thanks jim. going to take a break now before designing. if you get to static method part 55:47 make sure to indent! lol
Te felicito, te segui desde el inicio y me andubo perfecto el juego!!; solo que la salida por perder no me funciona bien, osea, si solo escrivo exit() sale en la segunda vez que perdes.
He is the best teacher and instructor that I have seen , to be fair I love Bro chanell very much but in development I can't imagine there is a better way to describe
@1:14:15 my code didn't give any colour after I used configure, I ran the code using printf"clicked mine", and it proved the random cell and show mine were working, but whenever I used "self.cell_btn_object.configure(bg='red')", it just didn't work. Any ideas as to why this might have happened?
@@pearlr.2411 Aaah! Coding can be frustrasting lol. I would see if you have the same issue with the tutorial's code. The github link is provided up in the description.
If you're using mac, it handles buttons differently and won't let you change the background color. I got around it by highlighting the cell in the show_mine method instead: self.cell_btn_object.configure(highlightbackground="red")
When trying to follow this tutorial in 2024 using python version 3.12 I am running into an exception 'TypeError: 'NoneType' object is not callable' when the tutorial arrives at the point where cells are defined in the Cell.py file and in the main game file the testing of creating a cell starts. About 43 minutes in. The statement 'c1.cell_button_object(center_frame)' creates the runtime exception. Any insights in how to solve this or why this is happening are welcome. Edit: I found the error in my code. I tried to place the create_button_object() method instead of the cell_button_object-field. Note to self: bugs can be avoided and also found by attentive and comprehensive reading.
this is an awesome tutorial but I have a question by we created cell.all list before init function did we create it as global variable which can be achievable by all other classes, I couldn't get that part. normally I know that list must be different for every each cell object since it's part of class declaration
Thank you -what is the IDE you are using? I am using IDLE on MacOS, and when I try an Run the file it doens't launch Python, I have to launch Python fis then run the file. Your integrated IDE looks a btter option!
First to all Thank you very much for this excellente video. I have a question. How can I do if I want to restart the game. For example: I used the message box from tkinter to interact with the user once that game have over. If the user say no, I use the command sys.exit() but what command can I use if the user want restart the game from the begining?? One more time Thank you very much for everything.
Hello, I've encountered an error on line 46 of the main file "c.cell_btn_object.grid(" I receive this error when trying to run program: "Traceback (most recent call last): File "c:\Users\Jamie\Documents\Python\VirtualEnvironment\Minesweeper\Minesweeper.py", line 46, in c.cell_btn_object.grid( AttributeError: 'NoneType' object has no attribute 'grid'" As far as I can tell my code is identical to that in the video. Any ideas? Thanks
AttributeError: module 'ctypes' has no attribute 'windll' as I am using Ubuntu. I tried to find to replace the code with Ubuntu environment, but failed to find one. Could you please help?
43:20 is anyone able to explain more why the binding method was written within the button object creation function? I thought that was a function which was run to make a button and stopped being in use after that button had been created.
I find this tutorial so helpful and itneresting! But I got stuck very fast, because I keep getting the error "Unknow option "-Height" when runing the code after having added the top_frame. Anyone who has any idea what I am doing wrong? Her is my code: from tkinter import * root = Tk() # Override the setting of the window root.configure(bg='yellow') root.geometry('1200x600') root.title('Minesweeper Game') root.resizable(False, False) top_frame = Frame( root, bg="red", width=1200, hight=150 ) top_frame.place(x=0, y=0) ) # Run the window root.mainloop()
Thanks for the video, was great to follow along with! @ 1:40:16 How could recursion be used when a cell has 0 mines adjacent to also show the cells adjacent that also have 0 mines nearby? I have tried it but run into a recursion depth error so I don't think I'm doing it very efficiently
def left_click_actions(self,event): self.is_opened=True if self.is_mine: self.show_mine() else: self.cell_btn_object.configure(bg="SystemButtonFace") if self.surrounded_cells_mines_length==0: for cell_obj in self.surrounded_cells: if cell_obj.is_opened==False: cell_obj.left_click_actions('') cell_obj.show_cell() self.show_cell() if Cell.cell_count==settings.MINES_COUNT: ctypes.windll.user32.MessageBoxW(0,'You won!','Game Over',0) Note : I had to move the is_opened logic a bit and rewrite the Cell Left count. It's not terribly efficient but checks all of the cells for is_opened on each click. def show_cell(self): #if not self.is_opened: self.cell_btn_object.configure(text=self.surrounded_cells_mines_length) x=0 for celly in Cell.all: if celly.is_opened==True: x += 1 print(x) Cell.cell_count=settings.CELL_COUNT-x # Replace the text of the cell with a newer count if Cell.create_cell_count_label_object: Cell.create_cell_count_label_object.configure( text=f'Cells Left : {Cell.cell_count}' ) self.is_opened = True
Also trying to work this out. Have tried a recursive method that calls itself, but getting the same recursion depth error you're getting. Laurie's solution doesn't seem very efficient.
@@Sebastianimator You're most likely getting the recursion depth error because you check the surrounding cells on the clicked square, which checks the cells surrounding each of the cells surrounding the original cell including that original cell (amongst the other 8), which restarts the check again. Without a breaker you hit the native recursion limit. The cell count is affected by all of this virtual clicking. You can end up with a negative count unless you implement an alternate approach.
@@ravag3 That's the intended functionality though. Logically, the method should first check if there's 0 mines, and if true, then loop through each surrounding cell that's not been opened, show it, then check if it's zero again. I'm not really following why the recursion depth would be a problem in this instance (though to be fair I haven't added any debugging to show how deep it's recurring).
Can someone help me please? For some reason, everything works except it saying that I have lost and the red colour showing for the mines. I have literally tried everythiiing!
If you're using mac, it handles buttons differently and won't let you change the background color. I got around it by highlighting the cell in the show_mine method instead: self.cell_btn_object.configure(highlightbackground="red")
Hey, Free code Camp make some Courses on topics which developers use the most like Mongoose js, Pymongo, mysql(node js or django) and socket.io and other important modules which are used by most web developers.
hey how are you can someone help me please with this error : c=Cell(x,y) TypeError: Cell() takes no arguments i have the __init__ like it need to be but it keep giving me this error, help please.
Here's my class and __init__. Note there are two underscores before and after init. These are called Dunder methods (double underscores). class Cell: def __init__(self, x, y, is_mine=False): self.is_mine = is_mine self.cell_btn_object = None self.x = x self.y = y
@@soumobratamanna6681 I'm also working on a Mac in my create_btn_object method, I have these binds and they are working for left and right clicks. btn.bind("", self.left_click_actions) btn.bind("", self.right_click_actions)
@@BlitheBrandon Only the left button is working , I am follwoing the same thing like the way u said but still it's not working , after clicking right button its showing that I am left clicked .
You don't mention what specific problems you've encountered, but I'm going to go out on a limb and point a finger at the dot between the f and the initial double quote. It should look like: f"{self.x}, {self.y}"