Computer Chess Club Archives


Search

Terms

Messages

Subject: Re: c,c++5,c#.

Author: Russell Reagan

Date: 22:52:31 08/14/04

Go up one level in this thread


On August 14, 2004 at 15:10:45, Sune Fischer wrote:

>Because of:
>"3. Write abstract code that hides the implementation details when possible."
>
>Depends to what extent you mean that of course, but in the extreme (virtual
>functions etc..) I'm afraid it will be dreadfully slow.
>
>-S.

Abstraction is possible without slower features of OOP. It's possible without
OOP at all. Let's say I'm using C, and the goal is flexibility. I would put
everything behind a function (or macro at least), use typedefs, limit the places
where data is modified to a few functions, and things like that.

Later on if I want to change a signed type to an unsigned type to avoid a sign
extension, I just change one typedef. If attack detection is a hot spot, I only
need to rewrite one function, and everything else continues to work just the
same.

Here is an example of how I might abstract the board modification in C. I would
create a few functions to modify the state of the board.

void add_piece(Piece piece);
void clear_square(Square square);
void move_piece(Square from, Square to);

Everything else is done in terms of those functions. Even a major change like
switching from 0x88 to bitboards would be less intrusive because of this
approach. My make/undo functions still work without modification.

In my evaluation function I would have functions describing what I want to know.
If I want to know if there is a possible trojan horse attack, I write a
function: bool trojan_horse_attack_exists(); Then I just write: if
(trojan_horse_attack_exists()) { ... }. So my evaluation function would still
work after a major change like switching from 0x88 to bitboards.

Even basic abstractions like these will go a very long way toward making
transition much easier in the future.

Obviously this approach is very class friendly. I would, for instance, make a
board class and make add_piece(), clear_square(), and move_piece() member
functions, and the board data would be private of course. The difference is that
with classes the compiler will enforce that only those three functions modify
the board. If my bitboards are out of sync, or my piece list doesn't match my
0x88 board, then I only have three small functions to examine. In C, I have to
rely on my own discipline to make sure I always use the modifier functions, and
being human, that usually doesn't work well in the long run.

Using this approach also gives you a cascading effect when you start optimizing.
If you speed up one function, then every function that calls that function is
faster.

When you profile, you get a more fine grained picture of where your program is
spending its time. Rather than thinking, "my evaluation takes up 90% of the
execution time," you know which parts of the evaluation take up the most time.

Programming flexibly doesn't only benefit optimization opportunites. It makes
your code better in a number of other ways as well. It's more readable and
easier to track down bugs and prevent bugs in the first place. It makes the
program less mentally complex.



This page took 0 seconds to execute

Last modified: Thu, 15 Apr 21 08:11:13 -0700

Current Computer Chess Club Forums at Talkchess. This site by Sean Mintz.