Advertisement

How to program a chess: a forum based tutorial

Started by December 23, 2004 11:09 PM
276 comments, last by da_grat1 19 years, 8 months ago
Introductions (ie what the heck is this thread about): This thread was born when da_grat1 asked me about model loading. After a bit of discussion it turned out that he was trying to program a chess game and wondered if I had any advice. The result; a good excuse to talk design. Although this may seem off topic on this forum, I think nehe is best for several reasons. This forum has a wide variety of visitors, both advanced and beginner (you'll see why this is important later...keep reading :) ). I also dont have to go over OGL, which we will be using to do our graphics. Most of you have also already taken a look at some general demo design as well as loading and playing sound, which is a bonus. Also note that da_grat1 will be trying to implement this, so I'm going to try my best to keep us on topic and drive us through the end. k, so its obvious that i cant tell you that if you follow steps 1 - X you'll successfully complete your project, or game ect. (lol, its just not possible) Instead, what I want to do with this thread is to start a discussion about game design from start to where ever we take it. Consider this an online, dynamic tutorial with many authors. You guys should feel free to tell me that I'm wrong (giving a reason for your decisions is very important because we are all of different expertise in different areas). Remember that even if you feel you cannot contribute because you dont have the experience, asking questions is just as valuable (they determine where this discussion will go). Questions you guys ask will determine what issues get addressed and in what order. So sit back and get ready for what will hopefully be a long and productive discussion. I think the best place to start is at the beginning. You'd be surprised how many people dont start there. Imagine how terrible it would be if you hired a company to build you a corporate headquarters for your multi-million dollar game development studio and when you open the door, the thing crashes down on you. Then, when your in your hospital bed you find out that its because the guys who built the place didnt do any planning or draw any blue prints and just started building the place without thinking twice. The reason this kind of thing doesn't happen with building companies is because architects and engineers design and test the building long before anyone uses a hammer or saw. However, this happens all to often in software engineering; people just dont start at the beginning. They jump into projects and start coding without design documents. Remember your friend who said he would make an amazing game and ended up not finishing it? Its because when he was nailing some code together, the structure fell straight down on top of his head and he couldnt continue...anyway I tink I made my point...design twice, build once...so lets get to some code design...that and I ran out of building analogies ;) ... Programming is like chewing a pack of bubble gum. If you chew it all at once you're going to die. Its best if you divide the pack into pieces and chew each separately. There’s no guarantee you're not going to choke on a small piece but at least if you do you can probably spit it back up. So the first thing to do is establish exactly what we hope to accomplish and then keep breaking it down till we can implement it. To break it down on a business level, the "what are we going to do" is the project proposal. The "break down" is the design document/feasibility study and the implement it is "code till it works". Side trackin': In this quick paragraph I'm going to describe my tendencies when it comes to game programming. Most of the reasons for this stuff comes from code on the cob (http://www.gamedev.net/reference/list.asp?categoryid=45#115) and we'll hopefully see it used and justified further on in the discussion. Game programming (unlike word processors) are made using synthesis. We are going to take elements like graphics, audio ect and put them together to make a product. To do the synthesis I typically use function libraries as the glue that holds my program together (think OpenGL's interface). Classes and inheritance usually dont work for this kind of thing (think MFC). I'm not saying to totally abandon classes, I'm saying "use them to do a job behind a function library so that whatever uses the library doesn’t have to know about them". Keep your interfaces clean and whatever you build with them will look ok...irregardless of what is behind the interface. What are we going to do? So we're making a chess game. It will have 3d pieces that move accross the board (as apposed to appearing where ever you clicked), an animated camera, ai which you can play against (not good ai, but ai none the less), a console for testing (not as complex as you think, but it will just take a long time to implement), sound for coolness, and the ability to save your game. That sound good to everyone? How are we going to do this? Well, first step is decomposition, but what exactly does that mean? If you refer to my side track up there, why are we decomposing, shouldn’t we be synthesizing? In truth, there are actually two different phases here that use different techniques to get their jobs done. The first phase is the design phase where we decompose our problem into sub problems till we are satisfied we can tackle them. Then we go to the implementation phase where we take the easiest sub problems, solve them, and their solutions to solve larger problems till we have a final solution; our game (this is what i mean by synthesis). So what is this design thingy all about? Decomposition is the answer to the question, "how the hell am i supposed to do that?" Design is about making a decomposition that works both now and in the future (you'll see what i mean). Pop quiz: what did a software blue print look like back when king tut was writing security software for his sarcophagus (namely the 7 Egyptian curses of death)? Ans: Same as they look today ; a pyramid. On the top of the pyramid is our goal (namely, a game) and on the very bottom is stuff we know we have to use to achieve our goal (our requirements). I our case, we have stuff like OpenGL, Windows, and fmod on the bottom. At the top of our pyramid is our chess game. Let the designing begin: A quick way to start is by listing a bunch of stuff you're probably going to need. In any game, we're going to need a main screen (the thing people see when they start the game), a game screen(the game itself), a menu (drawn over the screen), a way to tell if the game is over, a way to tell what screen gets input, a way to get the input, a way to keep track of time, a way to draw objects as apposed to triangles, a way to easily play a sound, a way to load files, a way for the ai to think, a way to control the camera, and a whole bunch of other stuff. The next thing to tackle is to organize this stuff in a pyramid and then fill in the gaps where we need to. We then keep doing this (decomposing these subsystems) till we can implement each subsystem without having to decompose it. So the next thing to tackle is to rearrange the subsystems i've listed (as well as others you guys come up with) into the pyramid and this i'm going to leave to anyone with time on their hands (this is a good exercise to do) or to my next post (which ever comes first). will post later, - llvllatrix
Awesome! Maybe we can make that 'Battle Chess' where the knights,kings, and such fight! Muwahahhaha! Anyways, Can't wait for the next post [wink].
Advertisement
Thank you for starting a new thread for me.. :)
ssooo, let me get this straight, you guys are going to make a 3D chess game all the way from a design document to a completed project over this forum?????

Interesting.
some thing about :
"
To do the synthesis I typically use function libraries as the glue that holds my program together (think OpenGL's interface). Classes and inheritance usually dont work for this kind of thing
"

in my experience classes always work, especially in big projects - it's more readable and understandable,and it give more flexibility to the code.
I have to agree with shadowwz, even though I'm not that much experienced.
Classes can come in very handy, expecially to do the "pyramid" stuff.
Advertisement
Quote:
in my experience classes always work, especially in big projects - it's more readable and understandable,and it give more flexibility to the code.


Its not the classes per say that is the main issue. Its the inheritance. Inheritance takes an abstract concept and derive more and more specialized versions of the original abstract concept. Also note that the term "big projects" is a bit misleading. When I say big, I mean in excess of 100 000 lines of code and several programmers.

Quote:
Classes can come in very handy, expecially to do the "pyramid" stuff.


While this is very true, and indeed there are many big projects that do use classes, you will find that most large scale games use only functions. In fact developers have only recently started moving from c to c++. The reason you avoid using inheritance to implement your code is because it is not synthesis (its decomposotion). In inheritance you start at the top of your parymid and work to the bottom. While this is fine for a word processor (where things are fairly related) it does not work for a game. The subsystems of a game are just too diverse. We need to start from the bottom of the pyramid. You cant have, for example start off with chess and derive graphics chess and sound chess (unrealistic example, but it still holds). This doesnt mean you dont use inheritance in your project, it just means you dont use inheritance to hold it together.

Inheritance is also fairly anoying to work with on a large project. With function libraries, you can reference the implementation of a function and then keep going deeper and deeper into implementation without much throuble. With inheritance and polymorphisms you have to look at what all of your code is doing to figure out what is being called at what time (this is called nondeterminism, and its nasty).

This also doesnt mean that you cant use classes to do your synthesis. Note that functions usually map to actions while classes map to objects. If you do use classes, you get locked into a paradym where every function you call (even if you call it from a singleton) must have an associated object for every action. You can pick and choose with function libraries (by implementing an object manager you can choose to combine an object with an action).

2 more misc reasons to hide your classes away:
- Classes expose the private information in the definition of the class. The private keyword in the header means that anyone can remove it to make the entire contents of the class public.
- Because of this private exposure, classes do not work well for dll interfaces because it means that if you need another private variable for your class, your are going to have to recompile the parent program because the stack size of your class changes. Why is this important for a game (dlls)? I'll get to that later...its more important than you might think ;)

I dont use classes for these given reasons. However, if you do find a reason that makes the ones mentioned acceptable then by all means use classes :) Thats how we advance technology right ;)

will post later,
- llvllatrix
Quote: Original post by llvllatrix
Quote:
in my experience classes always work, especially in big projects - it's more readable and understandable,and it give more flexibility to the code.


Its not the classes per say that is the main issue. Its the inheritance. Inheritance takes an abstract concept and derive more and more specialized versions of the original abstract concept. Also note that the term "big projects" is a bit misleading. When I say big, I mean in excess of 100 000 lines of code and several programmers.


Classes and inheritance are completely separate issues. Classes are about encapsulation, inheritance is about code reuse. Because classes are about encapsulation they are often better for "big projects", however you choose to define "big".

Quote:
Quote:
Classes can come in very handy, expecially to do the "pyramid" stuff.


While this is very true, and indeed there are many big projects that do use classes, you will find that most large scale games use only functions.


And many business code is still written in Cobol. The reason is legacy code and legacy programmers. While there is nothing wrong with using "just functions", doing so just because "that what most games use" is a bad reason. Also note that it is entirely possible to write object-oriented code without using classes. cstdio's FILE objects are an example of this.

Quote: In fact developers have only recently started moving from c to c++. The reason you avoid using inheritance to implement your code is because it is not synthesis (its decomposotion). In inheritance you start at the top of your parymid and work to the bottom. While this is fine for a word processor (where things are fairly related) it does not work for a game. The subsystems of a game are just too diverse. We need to start from the bottom of the pyramid. You cant have, for example start off with chess and derive graphics chess and sound chess (unrealistic example, but it still holds). This doesnt mean you dont use inheritance in your project, it just means you dont use inheritance to hold it together.


This discussion has nothing to do with inheritance. This is about design. Inheritance is a tool to be applied when you discover related classes during the design phase of a project.

Quote: Inheritance is also fairly anoying to work with on a large project. With function libraries, you can reference the implementation of a function and then keep going deeper and deeper into implementation without much throuble. With inheritance and polymorphisms you have to look at what all of your code is doing to figure out what is being called at what time (this is called nondeterminism, and its nasty).


And again has nothing to do with inheritance. Poorly designed inheritance heirarchies will naturally be awkward to work with, but no more so that poorly designed function hierarches.

Quote: This also doesnt mean that you cant use classes to do your synthesis. Note that functions usually map to actions while classes map to objects. If you do use classes, you get locked into a paradym where every function you call (even if you call it from a singleton) must have an associated object for every action. You can pick and choose with function libraries (by implementing an object manager you can choose to combine an object with an action).


This is an argument for "right tool for the job". All classes is just as bad as no classes. If it's an object, or can easily be abstracted as an object, then use a class. If not then consider using a function.

Quote: 2 more misc reasons to hide your classes away:
- Classes expose the private information in the definition of the class. The private keyword in the header means that anyone can remove it to make the entire contents of the class public.
- Because of this private exposure, classes do not work well for dll interfaces because it means that if you need another private variable for your class, your are going to have to recompile the parent program because the stack size of your class changes. Why is this important for a game (dlls)? I'll get to that later...its more important than you might think ;)


?!?!? With functions you have no concept of information hiding anyway. Also, somebody removing 'private' qualifiers would be a Maciavellian act (see protecting against Murphy vs. protecting against Machiavelli). C++ does not provide the tools to protect against Machiavelli. If you're worried about people changing the header to remove a 'private' qualifier you should be equally worried about somebody changing your function headers to rewrite a function. With classes you can also use the pImpl idiom/bridge pattern to completely hide the private members of the class in a file that does not need to be redistributed.

Regarding DLLs: Using virtual interfaces once your public interface is stabilised you should never have to recompile the project because of a change in the private implementation.

I dont use classes for these given reasons. However, if you do find a reason that makes the ones mentioned acceptable then by all means use classes :) Thats how we advance technology right ;)

will post later,
- llvllatrix

By all means use functions instead of classes, but don't do so for the (IMHO) poorly defined reasons above.

Enigma
I programmed a chess app a while back as part of a research expo I was involved in (it mostly was about a hybrid type of AI I'm developing and actually now using in a stock market sim I created, working quite well). I originally figured it would be easier to implement a simple c-style function based app, but things can get out of hand pretty quickly without any sort of object-oriented approach (though I'm no expert programmer). In my experience using a moderate class-based OOP approach works excellently, especially if you're planning on implementing AI (I recommend the genetic algorithm/Chaos Theory approach :))

Just my two cents.

Videege
"Honesty, hard work, and determination are the keys to success in life...if you can fake that, you''ve got it made. " -- Groucho Marx
hi,it's me again &) ( i see i started a small war here)

"Also note that the term "big projects" is a bit misleading.When I say big, I mean in excess of 100 000 lines of code and several programmers."
in my mean big it's not number of lines or programmers,it's how the project is complicated,and chess game is one of them for shure.

also about classes,do as you want,use what is comfortable for you,but saying "don't use classes" is wrong.

i always use classes ,not for everything of course:
- the main reason,debuging - it's more easy to find errors,memory leaks(for me at least).
- they organize my code and save me a lot of time.
- it's more understandable when code is writen with classes.
- easy to manipulate.

* anything can be done without classes,and i pointed in previous my post about classes only because - "Classes and inheritance usually dont work for this kind of thing" for me it works,and i'm sure "i'm not alone",but how to write the program is up to programmer.

This topic is closed to new replies.

Advertisement