Thanks for watching! Code Review album drops next summer 😎 Don't forget that the first 1,000 people to use this link will get a 1 month free trial of Skillshare: skl.sh/thecherno11211 Couple things I missed in the video: - The king and queen positions are flipped! Not sure how I managed to not notice… - Castling _does_ actually work, but you have to drag the king onto the rook - I’m used to castling by dragging the king two spaces over, which doesn’t work in this game
Btw, I need that compressor in my life. Where can I get one?! If you don't know what the hell I'm talking about, just point me to your audio person. Thx in advance.
Hey, did you try clicking on the king and then on the rook? I think that might trigger castling, since when you clicked the king, it showed the rook square as a possible option.
@@AgentM124 I think moving two squares with the King is like the fundamental principle of castling and “moving to the rook” is more of a quality of life improvement. Which is probably why Cherno’s assumption that castling didn’t exist is a valid one.
@@AgentM124 the concept of castling is moving your King by two squares in one move provided the following conditions are met:…. The same as moving your pawn from the 2nd or 7th rank to the 4th or 5th which is two squares in a single move given the following conditions … respectively. The idea is that they are special moves that typically involve multiple moves but only take a single move if certain conditions are met. The king swapping positions with the rook somewhere in the middle is more of a derivative idea based on the previously mentioned underlying concept as a way to better visualize the move.
As a full time C++ dev i can only say excellent code review! You pointed out all of the major pinpoints with an easy to understand explanation on why and how to improve it without going into any super advanced C++ topics that would easily confuse & overwhelm a beginner programmer. Great Job! I wish i had someone like you when i was first getting into C++.
I'm about 8 minutes into the video and I just couldn't hold back. How did no one notice that the kings and queens starting positions are switched. I wouldn't have noticed until the Cherno started playing. Maybe you'll point that out later in the video but ahhhh.
Haha lol good point! I totally missed that! I guess I didn’t notice because it changes depending on which side you play, and I must not have paid too much attention to the colours since I was playing myself here
Actually the pieces are on the correct coordinate but the color of the squares are "wrong". If you imagine the coordinates, White's King is on e1 and Black's King is on e8 which is correct. Changing places would make kings start on the D-file which would be completely wrong. The rule "White's queen on white square and Black's queen on black square" can't overrule the coords, in order to make it right, black pieces should be arranged on top of that board and white pieces on the bottom of it.
@@ScorpionG4merBr I'm not quite sure I understand what you mean by the coordinates. Currently the kings are on the D file. The only problem with the layout is that the respective kings and queens need to be switched around.
if he played chess often he'd realize absolutely no chess clone does that, you have to drag the king two squares (3 squares if it's on queen side) close to the rook to trigger castling
Lets be fair, most of the projects on github (including big name ones) have many of the same issues - missing files or the expectation that the person building the code has just the right version of python / ninja / environment paths / ceiling cat set up. A huge amount of pain and wasted time would go away if we could solve this. My steps when I'm about to put anything out public is to take a totally fresh windows/linux/mac install as necessary (a vm is fine) and then see what it takes to build / run the thing I'm putting out. I document everything needed at that point and either "fix" stupid requirements and start again or ensure all steps are clearly documented.
@@sebastianmorris5394 It's really not though, I've had just as many issues trying to install docker versions of things as non docker versions. It just adds yet another layer of potentially broken stuff. The few times I have deployed something docker based that worked right away broke within a few weeks after an update was required and pushing that update either to docker or to the thing itself left it so broken I had to start back from scratch.
6:04 I'm pretty sure you can, it's just not standard, the rook is highlighted as a possible move 34:30 isMyPiece() or canMovePiece() 36:00 still doesn't notice you can castle :) 49:50 Or create once then copy construct the rest? (not sure what the non default copy constructor did, why it set texture to null)
A video on building c++ code and about build systems will be great. The main problem for people is that they don't understand how compilation and linking works. And how to deal with libraries. Btw loved your voice 😋
I second this so much. I really wanna learn CMake as a linux user but it's just so complicated and there are pretty much no tutorials that go beyond the very basics
Even if you have a constant (like 8 tiles per row), it's good to use a constant instead if you're gonna type if more than once so that you know exactly what that 8 is. Maybe there are other things that also have the value 8. It will help you understand your code.
That's true a lot of the times, but in a situation where you are writing something like: for (int row_number = 0; row_number < 8; ++row_number) {} I think it's obvious from context what that 8 means and if you accidentally type 9 instead, you will catch that mistake immediately from context. If you write a lot of words, instead of numbers, it can infact confuse you because you need to spend some mental energy deciphering what the words mean. If you see 8, you know the loop will iterate 8 times, if you see BOARD_SIZE, you first have to find out what BOARD_SIZE is - is it 8, is it the number of pixels in one dimension, .... My point is, you have to think more when you are using words instead of numbers. In cases where it may not be clear from context what the 8 means I agree with you fully, but considering this is a chess application and the person reading your code, be it you, or someone else, is most likely not stupid, it's a reasonanble thing to assume that they know what the 8 means.
@@stewartzayat7526Literal numbers are always bad: - Forbids you to ever change. Otherwise you'll have to go replacing the entire project. - May mistake their meaning. - Words can always describe better. If the number "is obvious", the word could has it: BOARD_SIZE_8. - ~100% chance of a word typo resulting in compile error. - C++ Core Guidelines says to always avoid them.
I like how he never realised that he could castle the king because in the MoveType there was castle in the list, probably when he tried the game he couldn't castle because he had to drag the piece on top of the rook, but this is irrelevant, beautiful video!!!
The build system in C++ is one of the reason I moved to Rust. Everybody does things differently and it's so hard to put the pieces together. Most of the people uses CMake, so it makes things just a little bit easier, but it's always terrible =/
Backend eng here, which uses python, cpp, dotnet, and rust. I love cpp, but not the build system lol. I don't know why no one in 20+ years streamlined this process with a standard. If anyone is interested I created some cmake templates for sdl2 and sfml which can make life easier for simple game dev projects. Is a work in progress. Would love feedback, so far every template works on windows and Linux. Need to write docs for running.
autotools is also fairly common. its amazing once it gets working (it can make porting things into an almost trivial task in some cases), but having to mess with it is an absolute pain.
One thing to add (months later), try not to hard code values everywhere. You could calculate the division value for example as a global. So if you change the resolution, the division values also change. You could still leave them const manual updates as well, but it would be better if they were all together in one place. Not spread out through the code. Edit: Nvm, just saw he mentions it later haha
I remember the first chess game I programed with my dad, well he did all the programing as I was like 8. Done in BASIC on an old IBM computer with no hard drive and 5 1/4" floppies! It was written such that you gave the coordinate position of the piece, then named the piece and then gave the coordinate position that you wanted to move too and the name of the piece. I think most of you can guess the bug. ... As long as the move was a legal move for the piece you were moving (at the start of the movie), you could rename the piece in the destination field and promote it to anything you wanted
It's fun to see that how you quickly tested checks, castling, checkmate and prise en-passant (and later promotion), but failed to notice that the king and queen's position were inverted in the initial position, which striked me the second I saw the board :P. It perfectly illustates why it's so important to have experienced alpha/beta testers (and sometimes a few team advisers familiar with the game genre during the design and early development) when developping games.
he probably just didn't wanna spend too long on it, cuz he didnt test promotion, playing an actual game of chess or a few would have definitely been enough to make one realise
6:00 the initial position of the pieces is wrong! For both Black and White, the positions of King and Queen should be interchanged. White queen in the initial position is only on white square, and black queen is initially only on black square. Another way to have things correct, would be to keep the chessboard as it is (not rotate it in any way) but put the white pieces lower, and the Black pieces upper.
I've seen some versions of online chess where if you click the king, you have to click the corresponding rook, and when you clicked the king, the corresponding rook highlighted, so that would likely have worked.
1:58 when a C++ developers realizes that *no one, literally no one finds C++ building intuitive and understandable,* but acts annoyed and states that is everyone else's fault. EDIT : 2:55 "I tried to add SDL2, messed up everything" -- _every SDL C++ project ever_ for anyone who hasn't been a C++ programmer for at least 2 years.
3 move draw rule, 50 move without a capture rule, stalemate, insufficient material, draw offer, resigning, plenty of other test cases to deal with that are probably not implemented but more time consuming to test. It doesn't show the moves, who is to move or offer PGNs to clipboard which also is not great.
There is a cool wiki on chess programming of situations that could happen. Like en passant and ending up in check etc. There are a few cases that are difficult. Also some cool books on using bit fields to get the best speed.
16:26, sure. It's less energy spent, less thing to write, read and think, since it has the same syntax as a pointer or class object evaluated against bool. Plus, if the boolean variable ever changes to a pointer by design, no refactoring will be needed here. 23:45, since this pointer is not meant to move, it'd be better as a reference: safer, less typing and a visual hint. 24:53, struct has better performance than tupple, because it doesn't get members by number. Generates much less bytecode too. 30:45, literal numbers are dangerous due to this kind of thing. Right thing to do would be to has it attached to the screen size, either at compile time, like a global constant, or at runtime (in case of user being allowed to change it) as information from a class, calculated together with the screen size. 36:25, bold security flaw here: this f() should not be public. If a piece goes to a wrong place, he'll has to look the entire project for calls to it. Fix: remove it from public domain, get a compile error, mark the f() who is calling it as 'friend', and only if it's actually 1 of the few that should be allowed to change piece location. 38:40, a good design choice is to separate the character logic from its multimedia resources, so that its logic may go to the CPU caches, becoming much faster.
I'm sure you will find this out later in the video, but castling seems to be possible by dragging the king to the rook rather than the square next to it. (:
@@Katt1n Well there, he couldn't castle because you can't castle trough a line of check. The bishop was up there. And it was implemented in the game I think, it even lighted that line of check in order to show why the castle is not possible there.
@@alexandrucalitescu5822 I understand the rules of chess, for the first few minutes of the video he implied that castling was not implemented which is not true.
Instead of using std::pair for points he could have just used SDL_Point provided by SDL. This would then also be compatible with some other SDL functions as they only accept SDL_Points.
One thing you did not say but is something I heard as a point of graphics... If you need a texture at 80*80 and you can scale the textures... Always go larger than what you want and never smaller unless you are mapping and applying to a model. With 2d at least... Always scale down or match scale. It avoids the graphics blurring.
One thing ive noticed is that the board is not actually reversed when the white is on the top side, it's always the white king should be on a black square.
2:12 Please, make video how to make repository, project AND as bonus, include how to back it up to drop box/google drive/one drive. use several servers(gitlab+github) so when data got corrupted it's easy to restore. 5:49 "bongcloud opening" PogChamp. I didn't expect cherno to be knowledgeable in current meta 5;56 I'm not that surprised Cherno didn't notice that OOO here is done by moving to king to rook, I'm surprised he missed he didn't check king's possible moves and missed castle move type 35:30, where castle was one of the move type and as result lots of edge cases were left unchecked (castling through check, castling after rook was moved, castling after king was moved, castling after pawn was promoted to the rook and returned the rook to the position where it could be castled).
If you're corrupting a git repo, you're using it wrong. The purpose of a repo is to have complete commit history. There's no need for Google drive. I would suggest that you keep a mirror for backup. Say you push to github, them maintain a mirror on gitlab or own gitea server.
@@nobytes2 Disk failures do not care if you are using git wrong or right. Redundant backups is one of the few things in IT which is not considered harmful and not using several free GB for that is overoptimistic at best. Also git is not a backup: one pushed --force too many and years of progress are gone(which you may discover months after the fact). Any proper workflow should strife towards complete elimination of human error at best, working around at least, because human errors are unavoidable by human nature. Saying "You should not have done this" does absolutely nothing to recover lost data. Clicking "unzip src-2017-11-09T13-14.zip here" does.
@@gulneckm.3475 Well git in a professional environment is a backup 100% because the servers are set with redundancy. The maintainer has control of the default branch. Everyone else should commit to a dev branch, and maintainer merges when ready. If you can force delete your entire code base you have a bad workflow already. If you've never worked with git in a professional environment which I can tell you haven't, I suggest you look up protected branches, and permissions per user. Having Google drive, or other backup sure that's fine as long as you keep git history. Best way is to have a mirror.
Can we take a second to appreciate how good this code is for a beginner? Sure, there are some things to be improved, but this is quite remarkable. Well done!
First of all, the positioning of king and queen is reversed. Next, 6:04 you can castle. You had to release the mouse button on rook instead. See the blue background behind the rook.
22:56 I disagree with this and would even go as far as arguing that it's bad advice, and I'm going to spend the rest of this comment making the case for why you absolutely should make the comparison explicit. To your credit, you at least acknowledged that leaving the comparison in makes sense. So I guess if anyone wondered why exactly you would want the extra verbosity, you're about to find out. While you _can_ make the comparison of a character or pointer to zero by using implicit truthy/falsy semantics, it's more readable and less bug-prone (bugs from misinterpreting the intent and/or forgetting data types from lack of immediate context) to be clear about exactly what is expected, unless you are _literally_ dealing with integers that you only expect to have the value 0 or 1, like a function that returns 0 for failure or 1 for success; `if(is_valid(value)) ...` is perfectly OK, so is `while(simulation_step(...)) ;`. Otherwise, I strongly advise `ptr == NULL`, `chr == '\0'`, and `n == 0 or ENUMERATOR_CONSTANT` for pedantic clarity. Obviousness is ALWAYS an advantage. The more obvious the code, the better. So to use the code in the video as an example, just by looking at `clickedOn = game->getFieldPos(...);`, can _you_ tell what type clickedOn is? The answer is no. The context is missing, because it's like 20 lines up at the top of the function where the variable is declared, and over in another file where `Game::getFieldPos` is defined. And even then, sometimes people obscure types by overusing typedef (C++ even does this automatically). Ever seen someone typedef a struct or a pointer? Of course you have. So if clickedOn's type is not clear in the immediate context, and it may not even be clear at function scope context, then removing the `!= nullptr` check is an especially bad idea. Frankly, even if the use of an explicit comparison were to do NOTHING but tell human programmers that clickedOn is a pointer, that in itself is a huge reason to do it. And by removing it, you have just made the code less obvious, and thus harder to understand, and encouraged people to make their code harder to understand. Perhaps a counterexample would help: imagine you have an enum for return codes returned by an `int(...)` function, where 0 is ERR_OK, 1 is ERR_BADVALUE, etc. Taking the return value of that function and checking it as, say, `if(validate(value)) return 0;` would be atrocious. Yes, it'll compile and run, but who is going to read that and go "ah yes, the return value is non-zero so it's an error"? No, they're going to see it and think "so validate is returning successfully? Why is it making this function return failure? What the fuck?", look at the implementation, see it returns one of several ERR_* constants and be annoyed and salty. `if(validate(value) != ERR_OK) return 0;` is far more obvious.
When I made a chess program, I didn't instruct the computer to find all the legal moves in a position, instead I instructed it to wait for the player to make a move and then check whether the move is legal or not. I instructed the computer to make 4 checks to see whether a move is legal or not: 1) Natural Movement of a piece (for instance you want to move a bishop, computer checks whether you are trying to move the bishop diagonally or not. If you try to move a rook, then computer checks whether you are trying to move the rook horizontally/ vertically or not, if you are trying to move the knight computer checks whether you are trying to move it in L shape or not etc.) 2) Whether you are capturing your own piece 3) Whether you are jumping over a piece 4) Whether you are in check after your move (in chess you must not be in check after your own move). If those 4 checks are done then the move is legal and computer changes the location of the chess piece. If the move is illegal, then computer does nothing.
.... Add a goto.... I know, I know, goto is bad, but it does have one good use, as a multilevel break, which C++ does not have. Some other languages do, but goto is less error prone. You can also set a variable that exits the loop, but it is a bit clunky.
Thanks for watching! Code Review album drops next summer 😎 Don't forget that the first 1,000 people to use this link will get a 1 month free trial of Skillshare: skl.sh/thecherno11211
Couple things I missed in the video:
- The king and queen positions are flipped! Not sure how I managed to not notice…
- Castling _does_ actually work, but you have to drag the king onto the rook - I’m used to castling by dragging the king two spaces over, which doesn’t work in this game
Ready enjoyed the song lol
Слушай, как насчёт рассказать как ты переехал в Австралию?
I believe I'm owed some royalties. Sunglasses McCoolguyface is _my_ thing!😡... 🤪 😎😎😎
Btw, I need that compressor in my life. Where can I get one?! If you don't know what the hell I'm talking about, just point me to your audio person. Thx in advance.
Oop is not the only way... It's just the only way that is _correct!_ again, 😂... No more, I promise.
Okay I didn't expect you to go this HARD on singing
It was so good as well!
@@Keregosh Did he use autotune?
@@emty5526 I have no idea xD
It was great! Except for the last bit
i sang along, it made my day!
When my man played the bong cloud I knew he was a man of culture ♟️
I'm into chess and programming and now I like him even more.
Cue Hikaru bongcloud speedrun intro.
Hahaha
Hey, did you try clicking on the king and then on the rook? I think that might trigger castling, since when you clicked the king, it showed the rook square as a possible option.
We do see a MoveType CASTLE so I also guess it's there somewhere (haven't finished watching.. just noticed it now and ran to comments :P )
This annoyed me so much xD. Cherno bashing so hard on not being able to Castle. It's more an intuitive problem than it not being there. But ah well.
@@AgentM124 I think moving two squares with the King is like the fundamental principle of castling and “moving to the rook” is more of a quality of life improvement. Which is probably why Cherno’s assumption that castling didn’t exist is a valid one.
@@blablabla7796 the fundamentals of castling isn't to put your king behind the pawns in the corner and your rook into play?
@@AgentM124 the concept of castling is moving your King by two squares in one move provided the following conditions are met:…. The same as moving your pawn from the 2nd or 7th rank to the 4th or 5th which is two squares in a single move given the following conditions … respectively. The idea is that they are special moves that typically involve multiple moves but only take a single move if certain conditions are met. The king swapping positions with the rook somewhere in the middle is more of a derivative idea based on the previously mentioned underlying concept as a way to better visualize the move.
"What are we thinking... like, Bongcloud opening, probably?"
Ah, I see you are a man of culture as well.
Next video: How to build C++ projects and setup a git repo
(Best clip btw: th-cam.com/users/clipUgkxtL5J8amsZAOkbza7ucYwc6EDEAQEaEQ7 )
This would be so important!
would be cool
Yes
Create new repo, clone locally. Create cpp project in another directory. Then copy entire project to the repo dir. Done.
I want this
SVG (Vector) Images are perfect for these kind of simple textures, small filesize and scalable and supported in SDL
I like how he never realized that the queens and kings were placed incorrectly on the board.
Would really love to see Chess made in Hazel2D!
@@J3ekir Same lol
I too saw that.
Its not, its just turned around
@@kalilinuxuser972 king and queen need to swap or the colors need to flip
I literally thought you were trying to castle with the queen, because it was in that position 😂
As a full time C++ dev i can only say excellent code review! You pointed out all of the major pinpoints with an easy to understand explanation on why and how to improve it without going into any super advanced C++ topics that would easily confuse & overwhelm a beginner programmer. Great Job! I wish i had someone like you when i was first getting into C++.
I'm about 8 minutes into the video and I just couldn't hold back. How did no one notice that the kings and queens starting positions are switched. I wouldn't have noticed until the Cherno started playing. Maybe you'll point that out later in the video but ahhhh.
Haha lol good point! I totally missed that! I guess I didn’t notice because it changes depending on which side you play, and I must not have paid too much attention to the colours since I was playing myself here
Actually the pieces are on the correct coordinate but the color of the squares are "wrong".
If you imagine the coordinates, White's King is on e1 and Black's King is on e8 which is correct. Changing places would make kings start on the D-file which would be completely wrong.
The rule "White's queen on white square and Black's queen on black square" can't overrule the coords, in order to make it right, black pieces should be arranged on top of that board and white pieces on the bottom of it.
@@ScorpionG4merBr I'm not quite sure I understand what you mean by the coordinates. Currently the kings are on the D file. The only problem with the layout is that the respective kings and queens need to be switched around.
I don't remember exactly my line of thought but you're right.
Sorry for the confusion.
I love how he just instantly understands every function/class, tears it down and reduces the CPU usage by 99% in the first 5 mins of seeing the code 😂
Pretty sure he did castling but you need to drag the king to the rook..
Ya I saw the rook light up so it seemed like it was working.
I was so annoyed by this hahaha
Well, that would be misleading interface...
if he played chess often he'd realize absolutely no chess clone does that, you have to drag the king two squares (3 squares if it's on queen side) close to the rook to trigger castling
18:15
Everyone chilling while cpu7 is dying
18:33
Cpu7: my suffering is finally over, i am out of event polling hell
😅
I just checked the github repo, and dude didn't even made that fix. wtf. Why send code for review and then not listen to the recommendations. 🤦♂️
Another vote for a video on build and distribution processes.
I also like how you separate your own opinions on code from actual issues in the code.
I just want to say, that seeing the way you go through the code, how quick you are and all looks so damn cool holy shit-
I love you videos
Lets be fair, most of the projects on github (including big name ones) have many of the same issues - missing files or the expectation that the person building the code has just the right version of python / ninja / environment paths / ceiling cat set up. A huge amount of pain and wasted time would go away if we could solve this. My steps when I'm about to put anything out public is to take a totally fresh windows/linux/mac install as necessary (a vm is fine) and then see what it takes to build / run the thing I'm putting out. I document everything needed at that point and either "fix" stupid requirements and start again or ensure all steps are clearly documented.
Docker is the way
@@sebastianmorris5394 It's really not though, I've had just as many issues trying to install docker versions of things as non docker versions. It just adds yet another layer of potentially broken stuff. The few times I have deployed something docker based that worked right away broke within a few weeks after an update was required and pushing that update either to docker or to the thing itself left it so broken I had to start back from scratch.
@@Ken-Creates you're probably not being specific enough with your yaml file container versions
@@sebastianmorris5394 Haha, I'll take that as agreement that it's not the way. 😆
@@Ken-Creates ok kiddo
2:50 why can bro sing so well
I think one of the biggest design problems in the code that you missed is that they didn't decouple the rendering stuff from the actual chess engine
Exactly what I thought
6:04 I'm pretty sure you can, it's just not standard, the rook is highlighted as a possible move
34:30 isMyPiece() or canMovePiece()
36:00 still doesn't notice you can castle :)
49:50 Or create once then copy construct the rest? (not sure what the non default copy constructor did, why it set texture to null)
A video on building c++ code and about build systems will be great. The main problem for people is that they don't understand how compilation and linking works. And how to deal with libraries.
Btw loved your voice 😋
I second this so much. I really wanna learn CMake as a linux user but it's just so complicated and there are pretty much no tutorials that go beyond the very basics
YESYESYES
Yes would love to see that too!
Yes this would be very helpful
Build systems would be extremely helpful. I never understood it.
when he clicked the king, the rook was highlighted, suggesting that he could've castled.
Very tough to see king and queen in the wrong place at the start of every game. Otherwise very cool project and great review!
Even if you have a constant (like 8 tiles per row), it's good to use a constant instead if you're gonna type if more than once so that you know exactly what that 8 is. Maybe there are other things that also have the value 8. It will help you understand your code.
That's true a lot of the times, but in a situation where you are writing something like:
for (int row_number = 0; row_number < 8; ++row_number) {}
I think it's obvious from context what that 8 means and if you accidentally type 9 instead, you will catch that mistake immediately from context. If you write a lot of words, instead of numbers, it can infact confuse you because you need to spend some mental energy deciphering what the words mean. If you see 8, you know the loop will iterate 8 times, if you see BOARD_SIZE, you first have to find out what BOARD_SIZE is - is it 8, is it the number of pixels in one dimension, .... My point is, you have to think more when you are using words instead of numbers. In cases where it may not be clear from context what the 8 means I agree with you fully, but considering this is a chess application and the person reading your code, be it you, or someone else, is most likely not stupid, it's a reasonanble thing to assume that they know what the 8 means.
@@stewartzayat7526Literal numbers are always bad:
- Forbids you to ever change. Otherwise you'll have to go replacing the entire project.
- May mistake their meaning.
- Words can always describe better. If the number "is obvious", the word could has it: BOARD_SIZE_8.
- ~100% chance of a word typo resulting in compile error.
- C++ Core Guidelines says to always avoid them.
I like how he never realised that he could castle the king because in the MoveType there was castle in the list, probably when he tried the game he couldn't castle because he had to drag the piece on top of the rook, but this is irrelevant, beautiful video!!!
The build system in C++ is one of the reason I moved to Rust. Everybody does things differently and it's so hard to put the pieces together. Most of the people uses CMake, so it makes things just a little bit easier, but it's always terrible =/
Backend eng here, which uses python, cpp, dotnet, and rust. I love cpp, but not the build system lol. I don't know why no one in 20+ years streamlined this process with a standard. If anyone is interested I created some cmake templates for sdl2 and sfml which can make life easier for simple game dev projects. Is a work in progress. Would love feedback, so far every template works on windows and Linux. Need to write docs for running.
autotools is also fairly common. its amazing once it gets working (it can make porting things into an almost trivial task in some cases), but having to mess with it is an absolute pain.
Please more singing, I love it 😂
Why is no one talking about the fact the King and Queen are literally in the wrong squares
Best code review to date. Thanks!
I think you can castle is you click on the rook after selecting the king.. the rook square is highlighted as a valid king move bro, you missed that
One thing to add (months later), try not to hard code values everywhere. You could calculate the division value for example as a global. So if you change the resolution, the division values also change. You could still leave them const manual updates as well, but it would be better if they were all together in one place. Not spread out through the code.
Edit: Nvm, just saw he mentions it later haha
I remember the first chess game I programed with my dad, well he did all the programing as I was like 8. Done in BASIC on an old IBM computer with no hard drive and 5 1/4" floppies! It was written such that you gave the coordinate position of the piece, then named the piece and then gave the coordinate position that you wanted to move too and the name of the piece. I think most of you can guess the bug.
...
As long as the move was a legal move for the piece you were moving (at the start of the movie), you could rename the piece in the destination field and promote it to anything you wanted
that performance brought a tear to my eye. what a truly angelic voice. adele ain't shit.
His best album yet, the code review
It's fun to see that how you quickly tested checks, castling, checkmate and prise en-passant (and later promotion), but failed to notice that the king and queen's position were inverted in the initial position, which striked me the second I saw the board :P.
It perfectly illustates why it's so important to have experienced alpha/beta testers (and sometimes a few team advisers familiar with the game genre during the design and early development) when developping games.
he probably just didn't wanna spend too long on it, cuz he didnt test promotion, playing an actual game of chess or a few would have definitely been enough to make one realise
Erstmal, Yan, cooles Video! I just keep learning from every video that you post. German game engine programmer here.
6:00 the initial position of the pieces is wrong! For both Black and White, the positions of King and Queen should be interchanged. White queen in the initial position is only on white square, and black queen is initially only on black square.
Another way to have things correct, would be to keep the chessboard as it is (not rotate it in any way) but put the white pieces lower, and the Black pieces upper.
came here for the code review and now I am waiting for your debut album.
I've seen some versions of online chess where if you click the king, you have to click the corresponding rook, and when you clicked the king, the corresponding rook highlighted, so that would likely have worked.
This is so entertaining to watch as a programming student. I'm looking forward watching more code reviews 🧐
Awesome glimpse into the mind of a professional. Thanks for the opportunity.
1:58 when a C++ developers realizes that *no one, literally no one finds C++ building intuitive and understandable,* but acts annoyed and states that is everyone else's fault.
EDIT : 2:55 "I tried to add SDL2, messed up everything" -- _every SDL C++ project ever_ for anyone who hasn't been a C++ programmer for at least 2 years.
I need a full cover of hello right now Cherno!
This is what I'm looking for on TH-cam. Really learned a lot on writing clean codes. Thx!
Cherno lowkey flexing his singing skills 😂
3 move draw rule, 50 move without a capture rule, stalemate, insufficient material, draw offer, resigning, plenty of other test cases to deal with that are probably not implemented but more time consuming to test. It doesn't show the moves, who is to move or offer PGNs to clipboard which also is not great.
Did he test for discovered check?
There is a cool wiki on chess programming of situations that could happen. Like en passant and ending up in check etc. There are a few cases that are difficult. Also some cool books on using bit fields to get the best speed.
do you happen to have a link for the wiki (is it on wikipedia or something else?) im curious lol
he also needs to get rid of that class hierarchy
16:26, sure. It's less energy spent, less thing to write, read and think, since it has the same syntax as a pointer or class object evaluated against bool. Plus, if the boolean variable ever changes to a pointer by design, no refactoring will be needed here.
23:45, since this pointer is not meant to move, it'd be better as a reference: safer, less typing and a visual hint.
24:53, struct has better performance than tupple, because it doesn't get members by number. Generates much less bytecode too.
30:45, literal numbers are dangerous due to this kind of thing. Right thing to do would be to has it attached to the screen size, either at compile time, like a global constant, or at runtime (in case of user being allowed to change it) as information from a class, calculated together with the screen size.
36:25, bold security flaw here: this f() should not be public. If a piece goes to a wrong place, he'll has to look the entire project for calls to it. Fix: remove it from public domain, get a compile error, mark the f() who is calling it as 'friend', and only if it's actually 1 of the few that should be allowed to change piece location.
38:40, a good design choice is to separate the character logic from its multimedia resources, so that its logic may go to the CPU caches, becoming much faster.
With the Hello Again song you literally had me crying LOOOOL
I'm sure you will find this out later in the video, but castling seems to be possible by dragging the king to the rook rather than the square next to it. (:
You reffer to the fact that he couldn't castle there in the first minutes of the video?
@@alexandrucalitescu5822 Yeah. I didn't have time to watch the whole thing, but i thought i would point it out anyways.
@@Katt1n Well there, he couldn't castle because you can't castle trough a line of check. The bishop was up there. And it was implemented in the game I think, it even lighted that line of check in order to show why the castle is not possible there.
@@alexandrucalitescu5822 I understand the rules of chess, for the first few minutes of the video he implied that castling was not implemented which is not true.
31:19 didn't expect to see cyrillic here
He speaks Russian
great singing
OMG, the singing!! 😂😂 Epic!
Instead of using std::pair for points he could have just used SDL_Point provided by SDL. This would then also be compatible with some other SDL functions as they only accept SDL_Points.
that cpu core usage hack was cool !
One thing you did not say but is something I heard as a point of graphics... If you need a texture at 80*80 and you can scale the textures... Always go larger than what you want and never smaller unless you are mapping and applying to a model. With 2d at least... Always scale down or match scale. It avoids the graphics blurring.
31:46 "Ok. So back to blur town" DAAAAAAMN LMAO
I wish you would make a video on how to build and distribute it, Because I too am having problems with that part of it...
I would love to see a video on building C++ code :)
he did castles hahaha
You have to click the rook! :)
the singing was so on point i didn't realize it was you
Subscribed after the singing🤣🤣🤣. I love this channel already
Thank you Cherno. I learned a lot.
One thing ive noticed is that the board is not actually reversed when the white is on the top side, it's always the white king should be on a black square.
LOL that Hello rendition was bomb
What a coincidence, I was looking for graphical libraries to make a chess game right as this video dropped.
2:08
YES YES YES PLZZZZZ SHOW US HOW TO BUILD PROJECTS AND DISTRIBUTE THEM PLZZZZZZZZ
Shocking switch language to cyrilic 31:18
Lol the singing at 2:27 was so cool and funny
Useful video, thanks man!
Really Enjoyed your singing.
Learnt a lot from this review.
5:41 WAIT!!
The board is set up incorrectly.
Kings and queens are on the wrong squares.
2:27 That was amazing!
He did do castling, you just have to drag the king to the rook.
no chess game castles this way, so he has to fix it anyway
@@felipegomes6312 That one does.
2:12 Please, make video how to make repository, project AND as bonus, include how to back it up to drop box/google drive/one drive. use several servers(gitlab+github) so when data got corrupted it's easy to restore.
5:49 "bongcloud opening" PogChamp. I didn't expect cherno to be knowledgeable in current meta
5;56 I'm not that surprised Cherno didn't notice that OOO here is done by moving to king to rook, I'm surprised he missed he didn't check king's possible moves and missed castle move type 35:30, where castle was one of the move type and as result lots of edge cases were left unchecked (castling through check, castling after rook was moved, castling after king was moved, castling after pawn was promoted to the rook and returned the rook to the position where it could be castled).
If you're corrupting a git repo, you're using it wrong. The purpose of a repo is to have complete commit history. There's no need for Google drive. I would suggest that you keep a mirror for backup. Say you push to github, them maintain a mirror on gitlab or own gitea server.
@@nobytes2 Disk failures do not care if you are using git wrong or right. Redundant backups is one of the few things in IT which is not considered harmful and not using several free GB for that is overoptimistic at best.
Also git is not a backup: one pushed --force too many and years of progress are gone(which you may discover months after the fact).
Any proper workflow should strife towards complete elimination of human error at best, working around at least, because human errors are unavoidable by human nature. Saying "You should not have done this" does absolutely nothing to recover lost data. Clicking "unzip src-2017-11-09T13-14.zip here" does.
@@gulneckm.3475 Well git in a professional environment is a backup 100% because the servers are set with redundancy. The maintainer has control of the default branch. Everyone else should commit to a dev branch, and maintainer merges when ready. If you can force delete your entire code base you have a bad workflow already. If you've never worked with git in a professional environment which I can tell you haven't, I suggest you look up protected branches, and permissions per user. Having Google drive, or other backup sure that's fine as long as you keep git history. Best way is to have a mirror.
I didn't know he could sing this well lol 😂😂
That singing was pretty good actually
I wouldn't put any magic numbers in my code. They all should be a constant so it's clear, even that 8. But good job! :)
At 44 mins, i would even use std::array. Just use Point[] = {the squares}. Use array length macro which uses sizeof to iterate over them.
Can we take a second to appreciate how good this code is for a beginner? Sure, there are some things to be improved, but this is quite remarkable. Well done!
First of all, the positioning of king and queen is reversed. Next, 6:04 you can castle. You had to release the mouse button on rook instead. See the blue background behind the rook.
17:42
Electricity bills go brrrrrr
bro were you in a band? If that wasn't autotuned your voice is incredible. would def want to hear you release a single or something
A video on how to make a project would be really useful honestly
very very educational! thank you
YES, please make the video on how to properly make a project on git.
Hey Cherno, please make a video dedicated to a polymorphism in cpp.
22:56 I disagree with this and would even go as far as arguing that it's bad advice, and I'm going to spend the rest of this comment making the case for why you absolutely should make the comparison explicit. To your credit, you at least acknowledged that leaving the comparison in makes sense. So I guess if anyone wondered why exactly you would want the extra verbosity, you're about to find out.
While you _can_ make the comparison of a character or pointer to zero by using implicit truthy/falsy semantics, it's more readable and less bug-prone (bugs from misinterpreting the intent and/or forgetting data types from lack of immediate context) to be clear about exactly what is expected, unless you are _literally_ dealing with integers that you only expect to have the value 0 or 1, like a function that returns 0 for failure or 1 for success; `if(is_valid(value)) ...` is perfectly OK, so is `while(simulation_step(...)) ;`. Otherwise, I strongly advise `ptr == NULL`, `chr == '\0'`, and `n == 0 or ENUMERATOR_CONSTANT` for pedantic clarity. Obviousness is ALWAYS an advantage. The more obvious the code, the better.
So to use the code in the video as an example, just by looking at `clickedOn = game->getFieldPos(...);`, can _you_ tell what type clickedOn is? The answer is no. The context is missing, because it's like 20 lines up at the top of the function where the variable is declared, and over in another file where `Game::getFieldPos` is defined. And even then, sometimes people obscure types by overusing typedef (C++ even does this automatically). Ever seen someone typedef a struct or a pointer? Of course you have. So if clickedOn's type is not clear in the immediate context, and it may not even be clear at function scope context, then removing the `!= nullptr` check is an especially bad idea. Frankly, even if the use of an explicit comparison were to do NOTHING but tell human programmers that clickedOn is a pointer, that in itself is a huge reason to do it. And by removing it, you have just made the code less obvious, and thus harder to understand, and encouraged people to make their code harder to understand.
Perhaps a counterexample would help: imagine you have an enum for return codes returned by an `int(...)` function, where 0 is ERR_OK, 1 is ERR_BADVALUE, etc. Taking the return value of that function and checking it as, say, `if(validate(value)) return 0;` would be atrocious. Yes, it'll compile and run, but who is going to read that and go "ah yes, the return value is non-zero so it's an error"? No, they're going to see it and think "so validate is returning successfully? Why is it making this function return failure? What the fuck?", look at the implementation, see it returns one of several ERR_* constants and be annoyed and salty. `if(validate(value) != ERR_OK) return 0;` is far more obvious.
What is the shortcut for this [28:18] "Open file in solution" window?
He's using "Go to Definition" - F12 to see render() and then Ctrl+(-) to go back to where he was
When I'm writing code I like to use the principle of "least astonishment" when writing my comments.
Also the starting position is wrong. The Queens always go at their color. D1 and D8 respectively for white and black queens.
Yess. Plzz make a video for building c++ projects
"Quelle" also means source, which kind of makes sense for the water thing too since thats where the water comes from
When I made a chess program, I didn't instruct the computer to find all the legal moves in a position, instead I instructed it to wait for the player to make a move and then check whether the move is legal or not. I instructed the computer to make 4 checks to see whether a move is legal or not:
1) Natural Movement of a piece (for instance you want to move a bishop, computer checks whether you are trying to move the bishop diagonally or not. If you try to move a rook, then computer checks whether you are trying to move the rook horizontally/ vertically or not, if you are trying to move the knight computer checks whether you are trying to move it in L shape or not etc.)
2) Whether you are capturing your own piece
3) Whether you are jumping over a piece
4) Whether you are in check after your move (in chess you must not be in check after your own move).
If those 4 checks are done then the move is legal and computer changes the location of the chess piece. If the move is illegal, then computer does nothing.
If you want to creat visualisation's of possible moves as in this example you need to check before the move.
Why do you have a Cyrillic keyboard? Where are you from? :)
Forget the code review was that really him singing holy beautiful voice am shocked so angelic.
Isnt castling possible when you click the king and drag it onto the rook?
@@mikapoful you also can't castle through or into a line of check.
He meant in this game, because Cherno assumed castling is not implemented.
Bro has pipes
2:07 I'm kinda interested in that.
This man's commenting in the code is on another level 😆 🤣
At 21:00, wouldn't adding a switch there prevent the break statement from exiting the loop directly and instead only exit the switch?
.... Add a goto.... I know, I know, goto is bad, but it does have one good use, as a multilevel break, which C++ does not have. Some other languages do, but goto is less error prone. You can also set a variable that exits the loop, but it is a bit clunky.
It doesn't matter if you replace every "if". In this case every of them checks type of m_event, so they are easily convertable.