How To Build A Minesweeper Clone With JavaScript
Vložit
- čas přidán 5. 09. 2024
- 🚨 IMPORTANT:
JavaScript Simplified Course: javascriptsimp...
Minesweeper is a classic game that is actually pretty simple to create. In this video I show you how to create a Minesweeper clone using plain JavaScript.
📚 Materials/References:
Before GitHub Code: github.com/Web...
After GitHub Code: github.com/Web...
🌎 Find Me Here:
My Blog: blog.webdevsim...
My Courses: courses.webdev...
Patreon: / webdevsimplified
Twitter: / devsimplified
Discord: / discord
GitHub: github.com/Web...
CodePen: codepen.io/Web...
#Minesweeper #WDS #JavaScript
Why have I never thought of this missing part of actually getting the thought processes "behind the scenes" of creating projects?
Seems like I would've learned a lot faster if this was a standard part of all tutorials - bought as free!
So thank you, Kyle, for bringing this way of teaching to the table!
Please do some more of these, and may many others be inspired to be teaching in that kind of way, too!
I try to explain my thought process as much as possible in tutorials but it can be hard sometimes.
@@WebDevSimplified
Yes, you do! And that is how and why you differenciate from other web development channels in a good way!
Keep doing what you’re already doing!
This is still one of those technical tests some companies do. It tests your knowledge on navigating bidimensional arrays, add/remove event listeners, cancelling default behaviour and propagation of events, has a mini status machine, .. and it's fun. Good one WDS!
Wow I can't wait to watch this. I'm almost halfway through his course. It's so freaking amazing!
Great video! Loved the clean way how you set up the nearbyTiles() function to also be able to call it recursively afterwards.
It was cool to see the .bind() trick, but in my opinion this makes the code less readable and adds unnecessary confusion for other developers that might not be as familiar with it. I just think explicitly passing the two parameters that are being processed is a little cleaner than passing null and the first parameter, while at the same time assuming everyone knows that the bind function will automatically add the iteration value to it.
I do agree bind isn't the best but we use it here as practice for inside the course since we learn bind right before this video.
@@WebDevSimplified Okay that makes a lot more sense! It was cool to see it being used though.
@@WebDevSimplified a adequate use of bind would be to use `this` instead of `b` and to pass only one parameter to bind (without null as first parameter)
As a kid, I could never understand how to play this game. Well now I know what the rules are 😄
Same lol
Omg ditto
I have always wanted to make a minesweeper game since early days of windows 3.1. I am really enjoying your videos. Thanks for sharing your knowledge.
Kyle, you should make a behind-the-scenes channel of you making the resulting code for all of your tutorials that you re-code.
Plot twist: the original Minesweeper handled a click with BOTH mouse buttons, which did something very useful. It is left to the viewer to implement as an exercise.
This is by far the most well written piece of code I have come across.
This is really good, I learned a lot. I am returning to dev after a very long hiatus and found you using methods I didn't even know existed. I appreciate you explained the more unusual ones like bind, stopImmediatePropagation and such.
Great guide man - I love that you're direct and concise enough that you convey a lot of information to those with slightly more than a basic knowledge of JS.
Wow, thank you, so much great information. I noticed the lack of 'else' statements like you suggested in a prior video. I would love to see a video explaining why you do not use semicolons.
Minesweeper and Snake is probably the 2 best games to recreate for learning purposes. good video about Minesweeper, just as good as the Snake game! :D
Also, I love how you're saying the words "simple" and "easy" like REALLY often! x)
Super cool. Not gonna lie, felt a bit complicated in the middle but made it through. Good video. Thanks ❤️
This sounds so cool!!
Hi, Kyle! Been watching you for some time. You're doing a legendary job, sir.
Now to the point. Stopped at 18:00 and am a bit worried at how easy and right you make this look when it isn't.
Imagine you set your board size to 20(400 squares) and number of mines to 350 - which is absolutely playable. How long will it take your code to generate the field against linearly decreasing chance of hitting the proper coordinates? 5~10s? Cause last 50 mines all have less than 25% chance of generating.
Now, trying to generate something more exquisite like 100x100 with 9990 mines could make your code hang for... a minute or so, I believe? And thanks only to modern hardware power. With most of this time spent on last 90 mines, each having less that 1% of hitting the free square, which calculates for 10000+ iterations.
You shouldn't probably use Math.random inside of while for this.
Or maybe you should. In case you first determine the squares value as NUMBER_OF_MINES > BOARD_SIZE*BOARD_SIZE/2 ? "mine" : "empty", and then proceed with filling in the opposites, and then the numbers. That'd guarantee the chance of 50% or more inside that cycle.
I'm sure there are waaay more elegant solutions though.
JavaScript🔥
I finally unserstood how to play minesweeper today ! XD
Informative video, keep up the incredible work! :)
Do you have a TypeScript Tutorial? Please make one ^^
Thanks , this is very interesting , thanks.
I whached this video so many times becouse there are some many inspiration. but, tell me the true: did you do it all by your self? if yes you are incredible!!
You are the best!!
Really wish i found your channel earlier, keep up the great work
thanks for the vid! Was fun to follow along
I've been meaning to make this for so long with Lua but I haven't got round to it. Love this tutorial btw, despite it being JS
Nice and clear as always.
However, one small detail bothers me quite a bit. You say that you split the code into display and logic, but you still embed a div-element in your logic code basically mixing them anyways... Not by a lot, but still...
while (positions.length < numberOfMines ) is really smart.
I had the restriction that I only had as many loop iterations as there are numberOfMines
So I had to create a recursive random number function that doesn't allow a passed(exception) value:
function getRandomInt(min, max, exception) {
min = Math.ceil(min);
max = Math.floor(max);
const randomInt = Math.floor(Math.random() * (max - min)) + min
return (randomInt === exception) ? getRandomInt(0, max, exception) : randomInt
}
and is called like this:
mines[yPos][xPos] ?
//we don't want this combo of xPos and yPos when occupied ->
mines[getRandomInt(0, yLength, yPos)][getRandomInt(0, xLength, xPos)] = true :
//but usually we do ->
mines[yPos][xPos] = true
and then inside the creation of tile objects:
mine: mines[j][i] && true
Thanks a lot for great work!
Thanks for the great effort, Looking for the day you build a chess game application with JS !
I was unaware that Johnny Bravo knew JavaScript!
Simplified as always
I followed along and this video got a lot of cylinders firing for a novice like me. But for some reason the actual board does not populate. I then copied the code labeled "after" on your github page and still couldn't load the site properly. All I get is that background color, title and a box. @10:43 exactly like this. Can someone please help me? I'm loading the html file into the chrome browser from the file explorer and no luck.
Having this problem right now. Please tell me you have an answer
" so you want be a software engineer at google "
ikr, stfu lady, she probably doesn't even know how to code.
nice video, thanks!
I have trouble making those mines=0 opening
You do my 3 months project in less than 45 minutes I'm-
can u make a video on how to make your own music streaming server
If you're looking for a new video idea , you should definitely make a big 20-30 mins video explaining GitHub and git well (just like Tech with Tim's latest video). Your old git video is 2 years old and I feel like you could make a much better video now!
Im getting this error in the console in chrome:
Access to script at 'file:///C:/(filepath)/Minesweeper/script.js' from origin 'null' has been blocked by CORS policy: Cross origin requests are only supported for protocol schemes: http, data, chrome, chrome-extension, chrome-untrusted, https.
Anyone know what mistake I'm making? Im not that familiar with HTML so I'm probably making an obvious mistake lol
CORS policy sucks! You need to open the Html file with a server. Currently you open it in the browser with the file:/// protocol and CORS (Cross Origin Resource Sharing) policy does not allow it, but a server will use protocol. You can find an Chrome extension to open a simple server if you don't want to install any server
Why using forEach and not for of ?
I have document its not defined error please help.
Code "early" is not working for the course discount
I tried this one a 1d array and draw on canvas... I'm not okay.
5 comments and 19 likes in 12 seconds, this looks good
What kind of language needs two nested loops to declare a m x n array? 😱
It is initialization not declaration.
In js Array(m).fill(Array(n)) will create an m x n array but will be filled with undefined, while Array(m).fill( [...Array(n).fill(0)] ) should fill to 0.
But even in C you will need a double loop to initialize every cell with different values
Your advance course have this video
why don’t you just create a class called `Minesweeper`? So you could declare some private and public methods on it. Private methods are declared using ‘#’ as a prefix
awesome
Couldn't you use a Set instead of an array for the mine positions? Instead of populating with objects, populating with indices from 0 to n^2-1
I was thinking the same, but probably would not be as easy to understand.. JavaScript Sets has a major "flaw" in this regard making it basically worthless for most usages involving objects. It uses equality, which for objects are comparing references, not whether two objects contain the same data. It would have been great if we could provide our own equality function, but that has some issues as well...
Also, since we dont have 100000x100000 minesweeper boards, this probably isn't an issue really, even with O(n2)
@@HampusR indeed. That's why I proposed to use indices instead of objects. In this way this flaw is solved. 😉
@@Tferdz Yes, I understood that, I just got a bit carried away with how inadequate the Set feels in js =)
With the indices you would have to do some translation from and index to x/y and if you want to be generic you would possibly need to generate some lookup table which would probably negate any speed benefits with these small numbers. Or how would you do it?
@@HampusR yuep. But this is fairly trivial. You just need two functions to convert from and to when needed to display Additionally. Having a single array is better than arrays of arrays, speed-wisely.
@@HampusR you add to the set the indexes joined by something: x + "_" + y. Problem solved for sets. And also instead of getMinePositions you have another function setMines which is called after the grid has been created
function setMines(board) {
let positions = new Set()
while (positions.size() < NUMBER_OF_MINES) {
let x = randomNumber()
let y = randomNumber()
board[y][x].mine = true
positions.add(x + "_" + y)
}
}
Ik worked
Why install when you can code it...
Why don't you break your code down into objects / files - e.g. the "tile" should be an object and in a file called tile.js. Creating the tile object within a function just makes the code look messy and hard for maintenance.
great
29:11
I tried this a while ago on my own, using buttons through loops.. but in the end it turned into a mess. 😂
Should use math.round instead of floor, otherwise you'll never get mines on the last row or column
how to make mines game
If you'd like add some graphics for this, see here: github.com/JulianNicholls/Gosu-Minesweeper/tree/master/media
🚩 💣
Wait, u builded it?
This dude forgot to add a const for the board on the first steps of the code. If it worked for you then I must be mistaken:
// Game Controllers & settings
export function createBoard(boardSize, numberMines) {
const board = []; // Declare the board variable here
for (let x = 0; x < boardSize; x++) {
const row = [];
for (let y = 0; y < boardSize; y++) {
const tile = {
x,
y
};
row.push(tile);
}
board.push(row);
}
return board;
};
This works. If you did not include the `Const board = [];` then the code wont work
x: Math.floor(Math.random() * boardSize),
y: Math.floor(Math.random() * boardSize)
No function Needed
I’m not sure if you have a video addressing this, but I notice you are looking at another screen quite frequently. I’m guessing you’re looking at the code, because you don’t have it memorized. This is one thing I want to get out to people: YOU DONT MEMORIZE CODE!! You spend just as much time googling as you do coding. For videos sake, he obviously had already written it. This is something I struggled with, wondering why I could just sit in my IDE and write code for an hour straight
Am i only one who come here to just learn how to play minesweeper
Code is cluttered, separate the functions into separate files inside a minesweeper directory
Claim your 0-dislikes ticket here.
79th commemt😂
Create a tutorial How to make a browser game for dummies with build house and atack other players is not any tutorial to web:)
6th
1st
while re-building the game I'm really confused about something:
For some reason I'm only getting one row of tiles.
Even though my 'board' for sure is an array of arrays that is just like yours.
I'm iterating throguh it just like you:
board.forEach(row => {
row.forEach(tile => {
boardContainer.append(tile.element)
.append is getting called 100x total. but only for each of my 10 rows one tile gets appended -> boardContainer only has as many elements as there are columns
the bug was caused inside minesweeper.js
having called
const element = document.createElement('div')
element.dataset.status = "hidden"
in the outer, instead of the inner loop, where the element is assigned.
It is interresting. I would have thought each element field of each tile object gets a div no matter what.
Buth there are only ever 10 div elements created and they are simply referenced.