Beginners Observation: Fundamental Lack of Source Code Examples?
You can try to learn about alpha-beta search by reading the code in Stockfish. As a beginner you'll be confused and frustrated, because what probably started as some elegant implementation of a simple concept was complicated over the years to implement more and more bells and whistles, and by now the original structure is hard to glimpse.
Alternatively, you can read a short explanation of minimax with pseudo-code followed by an explanation of the modifications you need for alpha-beta pruning and some more pseudo-code, and you'll get the idea without any of the confusion. If you work to turn that into a working implementation, you'll learn a ton of things in the process. That is a much better resource for a beginner, if you ask me.
[EDIT: I didn't pick Stockfish because its code is overly complicated: The code is actually really nice. But my observation still stands. The code is not needlessly complicated, but it is too complicated for a beginner.]
Most programmers rely on pseudo-code to express concepts rather than actual code for the simple fact that concepts usually are universal. Once you wrap your head around the concept or method expressed in the pseudo-code then it is a matter of using a library to do what it says. In my opinion, pseudo-code makes you think more about what you are doing than just reading through the code trying to understand the examples.
I agree that pseudo-code is an invaluable asset to learning. In fact, I write up a lot of my own conceptualizations as pseudo-code. There are many great articles where I find all I need is the the idea of the code expressed in order to grasp it.
Where solid examples would be appreciated though, is getting the initialization (DirectX) code worked out, and grabbing raw input in a tiered approach. As far as the raw input, I'm not saying you have to go crazy in implementation, but a working example that can be understood so the beginner can see how it all fits together would be a great boon. The link on RAW input (from this site in the developer's journal "The Bag of Holding") was explained well for the concept, but when I open the example source code I feel an absolute Noob. If I didn't see it's immediate value, I wouldn't be banging my head against the wall as I try to figure out concepts which I have not delved into before.
I'm coming into this from the Animation side
Because we tack on the word "Engineer" to software, sometimes people get the wrong idea. There isn't a lot of engineering going on with game development. More like voodoo, duct tape, and alchemy. Game programmers should really be called "rules artists" but that just sounds silly.
Can you point me to the tutorial that shows me how to correctly animate a character? Or how about the "right" way to light a scene. Or how about the book that explains to the beginner the correct method for drawing hands? There isn't one, because it is all a matter of skill, knowledge, style, and flair. The same goes for programming. But you don't really see the code, or how easy is it to go horribly wrong, or how hard it is to get something simple working that never fails.
The more you code the more you realize that there isn't any one person out there that even knows the "right" way to do something, because thousands of changes are made to hundreds of software components every day. We're thankful if the stuff on the machine built last night.
If there was a right way, then we wouldn't have many computers, devices, programming languages, and design methods. And really, I don't want a single way, because that would be boring.
I think, therefore I am. I think? - "George Carlin"
My Website: Indie Game Programming
My Twitter: https://twitter.com/indieprogram
My Book: http://amzn.com/1305076532
Take it apart slowly. If you have to, go one word at a time - see something you don't recognize? Look it up. Play with it in isolation if you can, to understand it at even a superficial level, before moving on. Proceed until you find yourself able to read larger and larger chunks of code.
The input handling example is one of the cleanest and simplest pieces of code I've ever released. Production code would probably make you run away screaming with blood pouring from your eyes ;-)
Wielder of the Sacred Wands
[Work - ArenaNet] [Epoch Language] [Scribblings]
The input handling example is one of the cleanest and simplest pieces of code I've ever released. Production code would probably make you run away screaming with blood pouring from your eyes ;-)
Yes, I went and looked at it, but I didn't want to say "Wow, this is really clean, organized, and well documented." That could make a beginner freak out.
When I did the code for my Java book, I spent most of my time refactoring all the extra crap out of the code so it is, without a doubt, the cleanest code I've every written. And people are still saying that that 650 page book is not enough to explain everything.
I think, therefore I am. I think? - "George Carlin"
My Website: Indie Game Programming
My Twitter: https://twitter.com/indieprogram
My Book: http://amzn.com/1305076532
The third problem is, that your solution is often embedded in a quite complex program which will most likely not help any noob at all. A week ago someone asked me to show off my behavior tree implementation. Even if I have provided my 5000 lines of code, it would communicate with so many other sub-systems, that a noob coder would most likely not understand a single piece of code.
^^^ This ^^^
I frequently run into this, wanting to share small or even large chunks of my code library to help others, but then realizing I have to rip out and write replacements for alot of pieces.
Sure, I'd love to share my level-loading code! Oh wait, that depends on my Serialization library. Which depends on my ByteBuffer class.
I can no longer just share a 15 line piece of code.
My code doesn't really exist in isolation - it's built up in layers. Code ideas (in theory and in actual practice) is built up in self-contained functions and classes that are built from other self-contained functions and classes to make complex code easy to reason about at high or low levels.
I'm most pleased with my programming, when I realize a complex function can be written in only a few lines of higher level code.
I wrote this today:
//Returns the diameter needed for a circle centered at [a rectangle's center] to contain all four corners of this rect.
unsigned cRect::GetBoundingDiameter() const;
I was pleased when I realized I could write it as:
unsigned cRect::GetBoundingDiameter() const
{
//The diameter of the circle needed, is equivalent to the diagonal of the rectangle it is containing.
//The diagonal of the rectangle is equivalent to splitting the rectangle into two triangles and getting the hypotenuse of either triangle.
//So, we just use pythagorean's theorem.
return this->TopLeft().DistanceFrom(this->BottomRight());
}
Which I used to write:
//Returns a new rectangle that is large enough to contain all four points of 'rect', no matter how much 'rect' is rotated.
static cRect cRect::GetRotatedMaxBounds(const cRect &rect)
{
//If a rectangle is rotated, all the rotations together form a circle.
//The diameter of that circle is also the width and height of the square needed to contain that circle.
int size = static_cast<int>(rect.GetBoundingDiameter());
return cRect::CreateFromCenter(rect.Center(), cSize(size, size));
}
My goal isn't to cram code into a single line - often I spread out even simple equations over several lines just to help me understand them better.
My goal is to abstract ideas into their own functions, and make them easy to re-assemble as needed to accomplish tasks.
Tasks like this:
How do you load a file of lines like: "blah = 117" and "green = 35"
Into a std::map<string, int> that's case-insensitive?
Can then be solved like this:
auto myMap = StringToMap<std::string, int, case_insensitive>(LoadFileAsString("file.txt"), '\n', '=');
That's a simple line of code, but to share it, I'd have to share the implementation of 'StringToMap()', and case_insensitive, and LoadFileAsString(), which depend on other functions.
For a quick example, StringToMap() is:
template<...bunch of template args...>
std::map<...> StringToMap(...)
{
return StringListToMap<...>(String::Seperate(str, ...), ...);
}
(Using StringListToMap() and String::Seperate())
And StringListToMap() is:
template<....>
std::map<...> StringListToMap(const StringList &elements, ....)
{
std::map<...> map;
for(const auto &element : elements)
{
map.insert(StringToPair<...>(element, ...));
}
return map;
}
(Using StringToPair())
And StringToPair() is:
template<...>
std::pair<...> StringToPair(const std::string &str, ..., toKeyCallback, toValueCallback)
{
auto pair = String::Split(str, ...);
Key key = toKeyCallback(pair.first);
Value value = toValueCallback(pair.second);
return std::make_pair(key, value);
}
It's a useful piece of code. I'd like to share it with others... but it also is built on yet more parts of my library.
In this case, it'd require some string to int conversion functions and also is dependant on some functors I use that validate whether characters are certain symbols or not. I can swap them out with other functions before I share them, but many times it takes thirty minutes or more (sometimes much more) to get the code sharable enough that people can compile and run it. Sharing code has much more than a zero-cost in labor.
To share what is simple code, I have to either share five or so other functions or classes which might be built on five more which might be built upon five more, or actually make the function more complex by removing the dependencies and in-lining it in the function. The very purpose of those dependencies is to make it easier to code, and to make the use of the code more simplified and easier to read.
Neither solution is ideal, because either I'm now code-dumping dozens of pages of code and twenty or thirty functions, or I'm code-dumping a monolithic function that is poorly coded in a hurry just to share it, and hasn't been tested or debugged, neither of which is really helpful to a beginner, and both of which are very burdensome for me to do when trying to help a beginner.
So instead I make a mental todo note: "Seperate out your string parsing and conversion functions into their own self-contained library and release it as public domain.". Yeah, that's a month-long project of it's own, and I'd have to take time away from my real project to do it. I'd have to spend several weeks re-writing and re-organizing it to make it less dependant on other parts of the library, so I could release it in self-contained libraries instead of one giant library. It's something I'd like to do, but I don't want to take significant time away from my actual game development to do so.
The input handling example is one of the cleanest and simplest pieces of code I've ever released. Production code would probably make you run away screaming with blood pouring from your eyes ;-)
I knew immediately that I needed to learn this no matter how difficult [to me]. Your comment reminded me of an Indian saying, "Do not seek for enlightenment unless you seek it like a man whose hair is on fire seeks water."
The problem is that writing good, clean, and self contained example code, especially for the more advanced stuff, takes a lot of time. And then a couple of years later, the world has moved on and all that work goes to waste.
From the perspective of a noob, actual production codes wouldn't help in learning at all. When a noob will see the code, he won't understand half of the things going on and he will be like "what is this sorcery?!" Production codes will scare any beginner away.
?Pseudo codes on the other hand provide an easy to understand logic flow breakdown which can be implemented in any language.