Search and Mobility

Discussion of chess software programming and technical issues.

Moderators: hgm, Rebel, chrisw

Sven
Posts: 4052
Joined: Thu May 15, 2008 9:57 pm
Location: Berlin, Germany
Full name: Sven Schüle

Re: Search and Mobility

Post by Sven »

outAtime wrote:
mcostalba wrote:
outAtime wrote: returns a compile warning 'q' might be used uninitialized in this function.
Try this:

Code: Select all

int piece_mobility_white(int sq, int offsets[])
{
  int q, *c = offsets, t = 0;

  do {
       for (q = sq + *c; board[q] == npiece; q += *c)
           t++;
  } while (*++c);

  if (board[q] && ((board[q] & 1) == 0))
      t++;

  return t;
}
Please note that the code above is wrong. The final "if (...)" prior to "return t;" must go into the outer loop since it has to test, for each of the slider directions, whether the first non-empty square is occupied by an enemy piece. The code above does this for the last direction only, and will therefore produce wrong values (too small in many cases).

An improved version (though still without weights) could look like this:

Code: Select all

int slider_mobility(int sq, int color, int offsets[])
{
  // parameter "color": 0 for white,  for black

  int q, *c = offsets, t = 0;

  do {
    for (q = sq + *c; board[q] == npiece; q += *c) {
      t++;
    }
    // if white pieces are encoded by odd numbers and black by even numbers
    // then the test for enemy pieces is "!= color"
    if (board[q] && ((board[q] & 1) != color)) {
      t++;
    }
  } while (*++c);

  return t;
}
Sven
outAtime
Posts: 226
Joined: Sun Mar 08, 2009 3:08 pm
Location: Canada

Re: Search and Mobility

Post by outAtime »

Thanks for the help. I've been trying to find more information about for loops and if statements etc.... from what I'm reading so far I can do only one "if" within the for loop so what can I do if I wanted to add another "for" in there?

e.g.

Code: Select all

int slider_mobility(int sq, int color, int offsets[])
{
  // parameter "color": 0 for white,  for black

  int q, *c = offsets, t = 0;

  do {
    for (q = sq + *c; board[q] == npiece; q += *c) {
      t++;
    }
*******************************************    
    if (board[q] && ((board[q] & 1) != color)) {
      t++;
    }
   if (board[q] == bking)) {
      t++;
    }
*******************************************
  } while (*++c);

  return t;
}
From what i have read, adding a second "if" wont work, is that right?
Having the same problem with the knights, trying to use a second "if"

Code: Select all

int knight_mobility_white(int sq)
{
  int n;
  int g = 0;
    
  for &#40;n = 0; n < 8; n++) 
    if &#40;board&#91;sq + n_ofs&#91;n&#93;&#93; == npiece&#41; &#123;
      g++;
    &#125;
	else if &#40;board&#91;sq + n_ofs&#91;n&#93;&#93; == bking&#41; &#123;
     g += 20;	
    &#125;
	return g;
&#125; 
for example, isn't working either... There are lots of things I would like to add other than just empty sqaures, like attacking near the king, or a higher bonus for attacking queen etc.. ideas. Anyhow, I really appreciate the advice, thanks again.
outAtime
UncombedCoconut
Posts: 319
Joined: Fri Dec 18, 2009 11:40 am
Location: Naperville, IL

Re: Search and Mobility

Post by UncombedCoconut »

outAtime wrote:from what I'm reading so far I can do only one "if" within the for loop so what can I do if I wanted to add another "for" in there?
You can put as many if-statements in any block you want. For instance, this:
outAtime wrote:

Code: Select all

int slider_mobility&#40;int sq, int color, int offsets&#91;&#93;)
&#123;
  // parameter "color"&#58; 0 for white,  for black

  int q, *c = offsets, t = 0;

  do &#123;
    for &#40;q = sq + *c; board&#91;q&#93; == npiece; q += *c&#41; &#123;
      t++;
    &#125;
*******************************************    
    if &#40;board&#91;q&#93; && (&#40;board&#91;q&#93; & 1&#41; != color&#41;) &#123;
      t++;
    &#125;
   if &#40;board&#91;q&#93; == bking&#41;) &#123;
      t++;
    &#125;
*******************************************
  &#125; while (*++c&#41;;

  return t;
&#125;
will do run two if-statements, in order, inside the loop body.
You can also put an if-statement inside the body of another if-statement.
For instance, if your intent was to give an extra one-square bonus if the slider checks an enemy king, you might say:

Code: Select all

    if &#40;board&#91;q&#93; && (&#40;board&#91;q&#93; & 1&#41; != color&#41;) &#123;
      t++;
       if (&#40;board&#91;q&#93; & ~1&#41; ==  &#40;bking & ~1&#41;) &#123;
          t++;
        &#125;
    &#125;
This would mean: if you've found board[q] is an enemy piece, also check whether it's a king (of either color -- but you already know it's an enemy) and add a bonus in that case.
outAtime wrote: Having the same problem with the knights, trying to use a second "if"

Code: Select all

int knight_mobility_white&#40;int sq&#41;
&#123;
  int n;
  int g = 0;
    
  for &#40;n = 0; n < 8; n++) 
    if &#40;board&#91;sq + n_ofs&#91;n&#93;&#93; == npiece&#41; &#123;
      g++;
    &#125;
	else if &#40;board&#91;sq + n_ofs&#91;n&#93;&#93; == bking&#41; &#123;
     g += 20;	
    &#125;
	return g;
&#125; 
for example, isn't working either... There are lots of things I would like to add other than just empty sqaures, like attacking near the king, or a higher bonus for attacking queen etc.. ideas. Anyhow, I really appreciate the advice, thanks again.
This one actually looks OK. I'd recommend {curly brackets} around the body of the for-loop, but they aren't required.
Sven
Posts: 4052
Joined: Thu May 15, 2008 9:57 pm
Location: Berlin, Germany
Full name: Sven Schüle

Re: Search and Mobility

Post by Sven »

UncombedCoconut wrote:This one actually looks OK. I'd recommend {curly brackets} around the body of the for-loop, but they aren't required.
"Not required" if the body is just one statement. Otherwise they are required to preserve the desired semantics, since this code:

Code: Select all

for (........)
    STATEMENT1;
    STATEMENT2;
would not have STATEMENT2 as part of the loop, despite its wrong indentation.

@Kenny:
For less experienced C/C++ programmers I would always recommend to use curly brackets around single-statement loop bodies etc. Otherwise there will be a lot of surprises. Using the shorter version is o.k. as soon as the long version is understood, of course.

The absence of the curly brackets did obviously also cause some of the problems you reported above.

Code: Select all

if &#40;condition&#41; STATEMENT1; // not recommended for beginners

if &#40;condition&#41;
    STATEMENT2; // not recommended for beginners

for (...)
    STATEMENT3; // not recommended for beginners

for (...) &#123;
    if &#40;condition&#41; &#123;
        STATEMENT4;
    &#125;
&#125; // OK
Sven
outAtime
Posts: 226
Joined: Sun Mar 08, 2009 3:08 pm
Location: Canada

Re: Search and Mobility

Post by outAtime »

Thanks again for good advice, obviously I've been working on this for a while (quite) and would like to have it bug-free soon! I was wondering if maybe this is wrong anyways:

Code: Select all

int slider_mobility&#40;int sq, int color, int offsets&#91;&#93;)
&#123;
  // parameter "color"&#58; 0 for white,  for black

  int q, *c = offsets, t = 0;

  do &#123;
**************************************************
    for &#40;q = sq + *c; board&#91;q&#93; == npiece; q += *c&#41; &#123;
      t++;
    &#125;
**************************************************
    // if white pieces are encoded by odd numbers and black by even numbers
    // then the test for enemy pieces is "!= color"
    if &#40;board&#91;q&#93; && (&#40;board&#91;q&#93; & 1&#41; != color&#41;) &#123;
      t++;
    &#125;
  &#125; while (*++c&#41;;

  return t;
&#125;
The second part of the for loop is also a sort of boolean entry control isn't it? So I have been reading... the "for" loop will only loop as long as the 2nd condition is true..... but if the second condition is true (== npiece) what would be the point of checking for attacked pieces in a following "if" statement if we already know it is npiece? Im a bit confused, maybe im missing something important...
Thanks.
outAtime
Sven
Posts: 4052
Joined: Thu May 15, 2008 9:57 pm
Location: Berlin, Germany
Full name: Sven Schüle

Re: Search and Mobility

Post by Sven »

outAtime wrote:Thanks again for good advice, obviously I've been working on this for a while (quite) and would like to have it bug-free soon! I was wondering if maybe this is wrong anyways:

Code: Select all

int slider_mobility&#40;int sq, int color, int offsets&#91;&#93;)
&#123;
  // parameter "color"&#58; 0 for white,  for black

  int q, *c = offsets, t = 0;

  do &#123;
**************************************************
    for &#40;q = sq + *c; board&#91;q&#93; == npiece; q += *c&#41; &#123;
      t++;
    &#125;
**************************************************
    // if white pieces are encoded by odd numbers and black by even numbers
    // then the test for enemy pieces is "!= color"
    if &#40;board&#91;q&#93; && (&#40;board&#91;q&#93; & 1&#41; != color&#41;) &#123;
      t++;
    &#125;
  &#125; while (*++c&#41;;

  return t;
&#125;
The second part of the for loop is also a sort of boolean entry control isn't it? So I have been reading... the "for" loop will only loop as long as the 2nd condition is true..... but if the second condition is true (== npiece) what would be the point of checking for attacked pieces in a following "if" statement if we already know it is npiece? Im a bit confused, maybe im missing something important...
Thanks.
As you wrote, the "for" loop will loop as long as board[q] == npiece, so the loop will be left as soon as board[q] != npiece. So the "if" below the "for" loop can now rely on that when testing for an enemy piece.

Sven