I'm completely new to programming, I have just picked up C a month ago in the completely random attempt to code my own chess engine (my goal being to create something that can best myself. fascinating.) so please try to be as clear as possible with your answers and please ask for clarifications when my explanation is lacking.
At the moment my engine can analyze around 0.5 to 0.8 million positions per second on my 1.8Ghz processor, any ideas on that would be welcome too but anyway it looked obvious to me that the only way to make my engine faster was to try moves in fixed order so that bad moves will just be excluded from the search.
In order to do that I changed my code from passing int
variables into passing int
pointers. My idea being to just stick to the score the move that generated it. The code still works but grows in size. I have googled and tried some memory leak tools but they only tell me where the leaked memory has been allocated, which I already know, but not when it's address has been lost.
I've figured that if I just post my code some guy with experience could just spot the leak right away. Now that I have hit the Internet looking for help I have found out that my code is logically equivalent to an algorithm that has existed for decades under the name of minimax with alpha beta pruning. Cool.
int evaluate(int *board, int capture) { ... return board evaluation; }
int *Black(int *board, int depth, int *max, int *min) {
if (depth == 0) {
temp = malloc(20 * sizeof(int)); //eventually i will store
}
minlocal = malloc(20 * sizeof(int)); //moves next to the score
*minlocal = *min; //this is what i came up with so that min/max
//of a higher function call doesn't get changed
for (all moves) {
if (depth > 0) {
temp = whitemove(board, depth - 1, max, minlocal);
} else {
*temp = evaluate(board, capture);
}
if (*temp <= *max) {
;free(minlocal);
return temp;
}
if (*temp < *minlocal) {
*minlocal = *temp;
}
if (depth > 0) {
free(temp);
}
}
if (depth = 0) { //<====== silly bug!
free(temp);
}
return minlocal;
}
int *whitemove(int *board, int depth, int *max, int *min) {
temp = malloc(20 * sizeof(int));
maxlocal = malloc(20 * sizeof(int));
*temp = -30000;
*maxlocal = *max;
for (all moves) {
v = blackmove(board, depth - 1, maxlocal, min);
if (*v > *temp) {
free(temp);
temp = v;
} else {
free(v);
}
if (*temp > *maxlocal) {
*maxlocal = *temp;
}
if (*temp >= *min) {
free(maxlocal);
return temp;
}
}
free(maxlocal);
return temp;
}
Reading the code you probably noticed that my thing can only play white and depth can only be an even number, this doesn't matter to me for now.
As far as I know this approach I took might be absolutely dumb, but it doesn't seem to be any slower than before and it should be able to store lines of play instead of a the simple first move. Any opinion on alternatives is welcome as well.
You seem to have picked up good programming skills in C in a very short time.
Yet you still need to improve your style: presentation is very important as it helps avoid many stupid bugs and makes your code more readable to both other programmers ans yourself.
Also use all warnings tha compiler can produce with the appropriate flags, such as gcc -Wall -Wextra
.
There is a silly bug at the end of the Black
function:
if (depth = 0)
Should obviously read
if (depth == 0)
This is where you never free the memory.
There might be other places where you lose track of allocated blocks, as well as places where allocation is not required, using a local array is much quicker if you do not need to return it to the caller. Passing a pointer to a local array as a destination array could also reduce the amount of memory allocation.