building glaurung2.1 from empty code project

Discussion of chess software programming and technical issues.

Moderators: bob, hgm, Harvey Williamson

Forum rules
This textbox is used to restore diagrams posted with the [d] tag before the upgrade.
Uri Blass
Posts: 8557
Joined: Wed Mar 08, 2006 11:37 pm
Location: Tel-Aviv Israel

building glaurung2.1 from empty code project

Post by Uri Blass » Sun Aug 31, 2008 9:48 am

My opinion is that the best way to understand chess program is simply trying to build them from scratch by copying minimal parts that you can compile and understand the parts that you copied and later adding more parts.

I decided in the past to start doing it with glaurung1.2.1 but stopped.

I decided to do it again with Glaurung2.1 and this time I plan to make everything that I do with Glaurung2.1 public.

Note that my knowledge about programming is limited so I may ask a lot of questions that seem to you stupid questions because of commands that I do not understand.

First step is simply generating new empty project with the name Glaurung_learn and adding the file main.cpp to it.

I copy to main.cpp the following code from Glaurung2.1


Code: Select all

#include <iostream>
int main&#40;int argc, char *argv&#91;&#93;)
&#123;
	setbuf&#40;stdin, NULL&#41;;
	setbuf&#40;stdout, NULL&#41;;
	std&#58;&#58;cout.rdbuf&#40;)->pubsetbuf&#40;NULL, 0&#41;;
	std&#58;&#58;cin.rdbuf&#40;)->pubsetbuf&#40;NULL, 0&#41;;
	return 0;
&#125;
1)When I compile it I get warning C4995\6
'setbuf': This function or variable may be unsafe. Consider using setvbuf instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.

Does it mean that Glaurung is written wrongly or maybe I do not need to care about these warning or maybe there are not going to be warning with the full glaurung program.

Except this I have the following questions

2)I am used to use int main(void)
I read the following

"The argument argc is the number of command-line arguments passed to the program. The argument argv is a pointer to an array of strings, where argv[0] is the name you used to run your program from the command-line"

What is the meaning of this command line and can you give me step by step instruction how to run a program from the command line?

3)How can the computer understand setbuf?
When I click help on the word setbuf I find that stdio.h is required header but glaurung does not use stdio.h and it seems that <iostream> is enough to compile it.

4)I am not sure if I understand exactly what setbuf does except the fact that it does some cleaning to the standard input and standard output files.

I guess that the target is that the program will get correct information when it read later some input from the interface or from the user and will forget some information that the user gave before starting to run the program but I am not sure.

An example when things do not work and explanation why they do not work can be productive.

5)I do not understand what is the purpose of the next lines of std:: with rdbuf and pubsetbuf

I do not use these commands and it can be productive if somebody explain to me what they are doing.

Uri

User avatar
sje
Posts: 4675
Joined: Mon Mar 13, 2006 6:43 pm

Re: building glaurung2.1 from empty code project

Post by sje » Sun Aug 31, 2008 9:57 am

The setbuf() routine is from the old style C library. IF you are writing a C++ program, you sholud avoid any of these old style references if a functional replacement is available in C++.

Other examples: fprintf(), scanf(), fopen()/open(), creat(), fclose()/close()

tvrzsky
Posts: 128
Joined: Sat Sep 23, 2006 5:10 pm
Location: Prague

Re: building glaurung2.1 from empty code project

Post by tvrzsky » Sun Aug 31, 2008 8:34 pm

Hi Uri,
Didn't you consider to buy some book on C++? It would save you (and us :-)) many superfluous questions.
I think that the best one is Stephen Prata's C++ Primer Plus although the first half of it could be perhaps too elementary but there is more advanced stuff as well and style of the book is really excellent.
http://www.amazon.com/Primer-Plus-5th-S ... F8&s=books
Highly recomended.
Filip

Sven
Posts: 3822
Joined: Thu May 15, 2008 7:57 pm
Location: Berlin, Germany
Full name: Sven Schüle
Contact:

Re: building glaurung2.1 from empty code project

Post by Sven » Sun Aug 31, 2008 10:22 pm

Hi Uri,

I'll try to answer your first five questions although I cannot guarantee that I will have time to answer the remaining 99.995 questions that will arise for you after adding further lines to your Glaurung learning project :-)

One important note: my explanations are meant to be simple, but do not necessarily cover all aspects of the requested topics. To go deeper you will definitely need either some literature or "google".
Uri Blass wrote:

Code: Select all

#include <iostream>
int main&#40;int argc, char *argv&#91;&#93;)
&#123;
	setbuf&#40;stdin, NULL&#41;;
	setbuf&#40;stdout, NULL&#41;;
	std&#58;&#58;cout.rdbuf&#40;)->pubsetbuf&#40;NULL, 0&#41;;
	std&#58;&#58;cin.rdbuf&#40;)->pubsetbuf&#40;NULL, 0&#41;;
	return 0;
&#125;
1)When I compile it I get warning C4995\6
'setbuf': This function or variable may be unsafe. Consider using setvbuf instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.

Does it mean that Glaurung is written wrongly or maybe I do not need to care about these warning or maybe there are not going to be warning with the full glaurung program.
1) add the -D_CRT_SECURE_NO_WARNINGS preprocessor switch to your project settings if you want to make these warnings go away without changing the existing code. With Visual Studio Express 2005 (that's what I expect you might be using, 2008 would be similar): "Project properties" -> "Configuration properties" -> "C/C++" -> "Preprocessor" -> "Preprocessor definitions" -> "..." -> add the string above without the preceding "-D" -> "Ok" as often as necessary.

When writing a new engine from scratch in C++, you may decide not to use these "old-style C functions" like setbuf, fprintf and so on if you want to be perfectly safe. But I think initially you should not bother with this at all, and go on with these "old" functions as usual.
2)I am used to use int main(void)
I read the following

"The argument argc is the number of command-line arguments passed to the program. The argument argv is a pointer to an array of strings, where argv[0] is the name you used to run your program from the command-line"

What is the meaning of this command line and can you give me step by step instruction how to run a program from the command line?
Although I cannot really imagine that you never used a command line interpreter like "command.com" (MS-DOS), "cmd" (the "modern" command.com of newer Windows) or "bash" (CygWin, originally from UNIX), from your posting I assume you didn't. I further assume you have Windows XP on your PC.

Click "Start" -> "Execute", type "cmd" and you have a command prompt. Type for example "ping -n 10 localhost". This should start the program "ping.exe" (since "ping" is usually not a "builtin" command that the interpreter "cmd" knows by itself) and passes three strings as parameters to it: "-n", "10", and "localhost". The "ping.exe" program stores these parameters such that they can be accessed by its function "main". "argc" has the value 4 (program name and 3 parameters), and the "argv[]" pointer array points to these four strings that are null-terminated and do physically reside in memory that is owned by the internal startup code of "ping.exe" from where the entry point function "main()" is called.

The code of main() in "ping.exe" will then loop somehow through the argv[] array, will recognize that "-n" has been given as option, will expect an option argument for it that is given as "10", will now understand that it shall repeat the "ping" operation 10 times, and will finally see "localhost" as program argument that it shall use as target address where ping packets shall be sent to.
3)How can the computer understand setbuf?
When I click help on the word setbuf I find that stdio.h is required header but glaurung does not use stdio.h and it seems that <iostream> is enough to compile it.
The header file "iostream", at least in case of MSVC++ Express 2005, indirectly includes "cstdio" via several steps, which in turn serves as C++ equivalent to "stdio.h". But I would never rely on such possibly "accidental" include relationships, and prefer to explicitely write down all include statements that are required by the code of a given source file, so when using "setbuf" I would also #include <cstdio> or even #include <stdio.h>. But that's not really a critical issue, one can spend very much time on such problems without getting it even close to perfect.
4)I am not sure if I understand exactly what setbuf does except the fact that it does some cleaning to the standard input and standard output files.

I guess that the target is that the program will get correct information when it read later some input from the interface or from the user and will forget some information that the user gave before starting to run the program but I am not sure.

An example when things do not work and explanation why they do not work can be productive.
setbuf(stdin, NULL) makes the standard input of the current process unbuffered. So when you read a line, say with fgets(), you immediately get an input line when it's available. Otherwise it could happen that input is collected in a buffer which will only be flushed (and then received by the reading function) when it is "full enough". In case of chess engine play, this could mean that you receive a command from the GUI at the wrong time (too late).

setbuf(stdout, NULL) does the same in the output direction. When you write a line it will immediately be put to the standard output. Without this call, lines will be buffered and "sometimes" the buffer will be flushed. In case of chess engine play, this could mean that the GUI receives a command sent by your engine at the wrong time (too late).

For testing and debugging purposes, and/or when the engine is running in console mode, it may be good to keep buffered output as default in case you write much output in a short time. In this case you must use fflush(stdout) after each sending of important commands to the GUI, like sending the engine's move.
5)I do not understand what is the purpose of the next lines of std:: with rdbuf and pubsetbuf

I do not use these commands and it can be productive if somebody explain to me what they are doing.
These do essentially the same as setbuf(stdin, NULL) resp. setbuf(stdout, NULL). But I think they are necessary only if a program uses the C++ input/output style that is based on stream objects (e.g. using "cin" or "cout").

Sven

Uri Blass
Posts: 8557
Joined: Wed Mar 08, 2006 11:37 pm
Location: Tel-Aviv Israel

Re: building glaurung2.1 from empty code project

Post by Uri Blass » Sun Aug 31, 2008 11:02 pm

Thanks for your reply
I will also try to use other sources before asking question so thanks also for the suggestion about a book from another poster.

Uri

User avatar
sje
Posts: 4675
Joined: Mon Mar 13, 2006 6:43 pm

Re: building glaurung2.1 from empty code project

Post by sje » Mon Sep 01, 2008 12:09 am

Unless you really have to code in C, I'd suggest concentrating on C++ as the better of the two.

C in 2008 is kind of like what Fortran was 25 years ago. The language is still around, but few people are using it for new projects.

User avatar
Zach Wegner
Posts: 1922
Joined: Wed Mar 08, 2006 11:51 pm
Location: Earth
Contact:

Re: building glaurung2.1 from empty code project

Post by Zach Wegner » Mon Sep 01, 2008 12:19 am

Some people prefer C. I think it looks a lot nicer, and it's easier to code in.

All IMO of course...

bob
Posts: 20478
Joined: Mon Feb 27, 2006 6:30 pm
Location: Birmingham, AL

Re: building glaurung2.1 from empty code project

Post by bob » Mon Sep 01, 2008 12:30 am

Zach Wegner wrote:Some people prefer C. I think it looks a lot nicer, and it's easier to code in.

All IMO of course...
I agree. Because most quickly learn that the "object-oriented" approach is NFG for chess, and so they start to get rid of the dynamically created objects and then start writing plain C code that looks like C++. Sometimes it is nicer to see things like board.MakeMove(......) than the more Cish MakeMove(board, etc...) but if you castrate the language to get around the performance issues, ugh. reminds me of the days when someone first declared that "goto's are bad". And then there were dozens of creative ways to avoid gotos that were actually gotos in every way except for spelling...

It is hard to do anything bad in C from a performance perspective, while in C++ it is quite easy. Yes, you can write a good chess engine in C++, it's been done. But for the most part, such attempts are really C in C++ clothing

User avatar
sje
Posts: 4675
Joined: Mon Mar 13, 2006 6:43 pm

Re: building glaurung2.1 from empty code project

Post by sje » Mon Sep 01, 2008 6:23 am

bob wrote:
Zach Wegner wrote:Some people prefer C. I think it looks a lot nicer, and it's easier to code in.

All IMO of course...
I agree. Because most quickly learn that the "object-oriented" approach is NFG for chess, and so they start to get rid of the dynamically created objects and then start writing plain C code that looks like C++. Sometimes it is nicer to see things like board.MakeMove(......) than the more Cish MakeMove(board, etc...) but if you castrate the language to get around the performance issues, ugh. reminds me of the days when someone first declared that "goto's are bad". And then there were dozens of creative ways to avoid gotos that were actually gotos in every way except for spelling...

It is hard to do anything bad in C from a performance perspective, while in C++ it is quite easy. Yes, you can write a good chess engine in C++, it's been done. But for the most part, such attempts are really C in C++ clothing
Well, it is certainly true that careless C++ programming will produce slower code than clever C coding.

But I say that it's really not all that difficult to code C++ with a view towards decent run time speed.

1) Don't use non-pure virtual methods where they're not needed. Polymorphism can be a big slow-down when not done properly. Alas, some coders add this where it's not justified, maybe just to show that they know how.

2) Don't do unneeded heap allocation of objects. Recall that an object at a fixed location in a data segment or on the stack has zero allocation overhead. Also, where heap allocation is a requirement, often the objects can be pre-allocated at start up time and recycled thereafter.

3) Don't use vendor specific class inheritance unless really, really necessary. Having unneeded superclasses, sometimes poorly written, can be a drag both in space and time.

4) While it is true that instance methods will have an implied dereference of their current object, it's also true that most machines today have enough registers to spare to hold a dereferencing pointer.

mcostalba
Posts: 2684
Joined: Sat Jun 14, 2008 7:17 pm

Re: building glaurung2.1 from empty code project

Post by mcostalba » Mon Sep 01, 2008 7:34 am

IMHO the only real way to get fast code is profiling.

All the other stuff is guessing / hand waving.

Sorry but I couldn't resist :)


P.S: I agree that C++ is prone to hidden copies, on the other side can greatly simplify a lot of low level details.

P.P.S: The difference between C++ and C is not because the first is object oriented (this is only scratching the surface), although this is one of the more visible things to novices is indeed little more then syntactic sugar for function names mangling and smart function pointers handling (read polymorphism). There are much deeper differences...

Post Reply