Mobility

Discussion of chess software programming and technical issues.

Moderators: hgm, Rebel, chrisw

outAtime
Posts: 226
Joined: Sun Mar 08, 2009 3:08 pm
Location: Canada

Mobility

Post by outAtime »

Hi, I have been struggling to add mobility to an otherwise simple evaluation, and everything I've tried makes the program weaker. I thought a good mobility function should add elo, although I'm not sure how much. Unfortunately I cant figure out a simple way to subtract attacked squares from the mobility score, so I'm at a bit of a disadvantage there already. I'm just using the piece offsets to calculate the mobility and then trying some sort of idea to make a score using sqrt(). After I have the sqrt() of the mobility I subtract the sqrt of the "centered" or middle mobility of the piece. I think one of the komodo guys had mentioned doing somthing similar. I have to say though, I cant tune the amount this final score is mutiplied by at all. Nothing is working after weeks of effort, no improvement. Any ideas would be appreciated, thanks. B.T.W. I apologize in advance if any code snippets look messy

Code: Select all

/* use piece offsets to get mobility score */

int knight_mobility(int squaren)
{
  register int n;
  register int g = 0;

  for (n = squaren+10; board[n] == npiece; n+=10)
    g++;
  for (n = squaren-10; board[n] == npiece; n-=10)
    g++;
  for (n = squaren+14; board[n] == npiece; n+=14)
    g++;
  for (n = squaren-14; board[n] == npiece; n-=14)
    g++;
  for (n = squaren+23; board[n] == npiece; n+=23)
    g++;
  for (n = squaren-23; board[n] == npiece; n-=23)
    g++;
  for (n = squaren+25; board[n] == npiece; n+=25)
    g++;
  for (n = squaren-25; board[n] == npiece; n-=25)
    g++;
	
  return g;
} 

then...

Code: Select all

score -= (sqrt (knight_mobility(i)) - 2) * nme;
or similarly for a bishop...

Code: Select all

score -= (sqrt (bishop_mobility(i)) - 2.65) * bme;
and then #define bme. I cant find any good numbers for bme, or nme, Ive tried alot of different combinations and values here. Getting a good result on a test position doesn't help, lol. Any ideas? I would really appreciate any help.

-outAtime
p.s. I also have rooks counted, but not queens. Im surprised how expensive this method seems, and is costing nodes and maybe a ply or a half ply on average. Im not sure even a great mobility can account for losing a ply in search(), but Id like to think there can be improvements made.
outAtime
Michael Sherwin
Posts: 3196
Joined: Fri May 26, 2006 3:00 am
Location: WY, USA
Full name: Michael Sherwin

Re: Mobility

Post by Michael Sherwin »

On some compilers you may need an extra set of () as the subtraction is done then the multiplication is done afterwards.

try this instead:

score -= ((sqrt (knight_mobility(i)) - 2) * nme);
If you are on a sidewalk and the covid goes beep beep
Just step aside or you might have a bit of heat
Covid covid runs through the town all day
Can the people ever change their ways
Sherwin the covid's after you
Sherwin if it catches you you're through
micron
Posts: 155
Joined: Mon Feb 15, 2010 9:33 am
Location: New Zealand

Re: Mobility

Post by micron »

1. Mobility of a piece is typically reckoned as the number of moves (attacks to squares that are empty or contain an enemy piece). Your knight_mobility() seems to calculate something different.

2. A mobility may be zero (for instance B, R, Q at the start). If you subtract a constant then pass the result as the argument to sqrt(), you are asking for something impossible in the domain of real numbers. The sqrt() function indicates its distress by returning a NAN.
http://en.wikipedia.org/wiki/NaN
Conversion of NAN to int is undefined; you may be getting something hopelessly undesirable such as -2147483648.
Don't subtract anything before calling sqrt().

Robert P.
micron
Posts: 155
Joined: Mon Feb 15, 2010 9:33 am
Location: New Zealand

Re: Mobility

Post by micron »

Duh, forget my point #2, based on hasty misreading of parentheses.
Harald
Posts: 318
Joined: Thu Mar 09, 2006 1:07 am

Re: Mobility

Post by Harald »

Code: Select all

/* use piece offsets to get mobility score */

int knight_mobility(int squaren)
{
  register int n;
  register int g = 0;

  for (n = squaren+10; board[n] == npiece; n+=10)
    g++;
  for (n = squaren-10; board[n] == npiece; n-=10)
    g++;
  for (n = squaren+14; board[n] == npiece; n+=14)
    g++;
  for (n = squaren-14; board[n] == npiece; n-=14)
    g++;
  for (n = squaren+23; board[n] == npiece; n+=23)
    g++;
  for (n = squaren-23; board[n] == npiece; n-=23)
    g++;
  for (n = squaren+25; board[n] == npiece; n+=25)
    g++;
  for (n = squaren-25; board[n] == npiece; n-=25)
    g++;
	
  return g;
} 
Loops and rays for a knight?
Try this:

Code: Select all

/* use piece offsets to get mobility score */

int offsets = [-10, 10, -14, 14, -23, 23, -25, 25];

int knight_mobility(int squaren)
{
  int n;
  int g = 0;

  for &#40;n = 0; n < 8; ++n&#41;
    if &#40;board&#91;squaren + offsets&#91;n&#93;&#93; == npiece&#41; // or == opponent
      g++;
  return g;
&#125; 
Harald
Ferdy
Posts: 4833
Joined: Sun Aug 10, 2008 3:15 pm
Location: Philippines

Re: Mobility

Post by Ferdy »

outAtime wrote:Hi, I have been struggling to add mobility to an otherwise simple evaluation, and everything I've tried makes the program weaker. I thought a good mobility function should add elo, although I'm not sure how much. Unfortunately I cant figure out a simple way to subtract attacked squares from the mobility score, so I'm at a bit of a disadvantage there already. I'm just using the piece offsets to calculate the mobility and then trying some sort of idea to make a score using sqrt(). After I have the sqrt() of the mobility I subtract the sqrt of the "centered" or middle mobility of the piece. I think one of the komodo guys had mentioned doing somthing similar. I have to say though, I cant tune the amount this final score is mutiplied by at all. Nothing is working after weeks of effort, no improvement. Any ideas would be appreciated, thanks. B.T.W. I apologize in advance if any code snippets look messy

Code: Select all

/* use piece offsets to get mobility score */

int knight_mobility&#40;int squaren&#41;
&#123;
  register int n;
  register int g = 0;

  for &#40;n = squaren+10; board&#91;n&#93; == npiece; n+=10&#41;
    g++;
  for &#40;n = squaren-10; board&#91;n&#93; == npiece; n-=10&#41;
    g++;
  for &#40;n = squaren+14; board&#91;n&#93; == npiece; n+=14&#41;
    g++;
  for &#40;n = squaren-14; board&#91;n&#93; == npiece; n-=14&#41;
    g++;
  for &#40;n = squaren+23; board&#91;n&#93; == npiece; n+=23&#41;
    g++;
  for &#40;n = squaren-23; board&#91;n&#93; == npiece; n-=23&#41;
    g++;
  for &#40;n = squaren+25; board&#91;n&#93; == npiece; n+=25&#41;
    g++;
  for &#40;n = squaren-25; board&#91;n&#93; == npiece; n-=25&#41;
    g++;
	
  return g;
&#125; 

then...

Code: Select all

score -= &#40;sqrt &#40;knight_mobility&#40;i&#41;) - 2&#41; * nme;
or similarly for a bishop...

Code: Select all

score -= &#40;sqrt &#40;bishop_mobility&#40;i&#41;) - 2.65&#41; * bme;
and then #define bme. I cant find any good numbers for bme, or nme, Ive tried alot of different combinations and values here. Getting a good result on a test position doesn't help, lol. Any ideas? I would really appreciate any help.

-outAtime
p.s. I also have rooks counted, but not queens. Im surprised how expensive this method seems, and is costing nodes and maybe a ply or a half ply on average. Im not sure even a great mobility can account for losing a ply in search(), but Id like to think there can be improvements made.
Probably just counting by offsets will not do, try the following:
1. if it attacks opp piece increment by 2
2. if it attacks empty sq increment by 1
3. if it attacks own piece decrement by 1 (defending is a sign of weakness)

Add-on / Improvements:
1a. if the attacked opp piece is protected by opp pawn decrement by 2
1b. apply 3a

2a. if the empty sq is a central sq increment by 2
2b. if the empty sq is close to opp king increment by 1
2c. if the empty sq is attacked by opp pawn decrement by 2

3a. if location of a piece (not the sq it has attacked) is already at the center (4-center sq) increment by 1
3b. if it attacks own king decrement by 1

then just use:
score += piece_type_mobility[net_mobility_counts]; or something

where:
static int piece_type_mobility[] = { -6, -4, -2, 0, 2, 4, 6, 9, 12, 17, 20, 24...}

the challenge is tuning the tablulated values and tuning your increments and decrements.

You may try also to use 2 tables, 1 for opening/middle and 1 for ending then just interpolate to get 1 final score.

Observe how the program plays :D, your goals are, opponent is restricted to have access to central squares, opponents' pieces are attacking against each other, and your pieces are somewhat interested in attacking opp king location.

It does not matter if you loss 20 elo on this as long as you get your goals :), You may tune/add other features and search algorithms later. Have fun with the tuning, seeing the tabulated values (first) is way better than using sqrt() thing :( .
outAtime
Posts: 226
Joined: Sun Mar 08, 2009 3:08 pm
Location: Canada

Re: Mobility

Post by outAtime »

Thanks everyone, I'll try these ideas and post results later today.
outAtime
AlvaroBegue
Posts: 931
Joined: Tue Mar 09, 2010 3:46 pm
Location: New York
Full name: Álvaro Begué (RuyDos)

Re: Mobility

Post by AlvaroBegue »

Michael Sherwin wrote:On some compilers you may need an extra set of () as the subtraction is done then the multiplication is done afterwards.

try this instead:

score -= ((sqrt (knight_mobility(i)) - 2) * nme);
No, the original code was perfectly fine. Look up "C operator precedence" in Google.
outAtime
Posts: 226
Joined: Sun Mar 08, 2009 3:08 pm
Location: Canada

Re: Mobility

Post by outAtime »

Thanks, looks like it's working.
I haven't added any of the suggested add ons/improvements yet.
I did add queen_mobility, and got rid of the sqrt() for now.
There are no negative scores.

Code: Select all

/* use piece offsets for mobility scores */

int n_offsets&#91;8&#93; = &#123; -10, 10, -14, 14, -23, 23, -25, 25 &#125;;
int b_offsets&#91;4&#93; = &#123; 11, -11, 13, -13 &#125;;
int r_offsets&#91;4&#93; = &#123; 12, -12, 1, -1 &#125;;
int q_offsets&#91;8&#93; = &#123; 13, -13, 11, -11, 12, -12, 1, -1 &#125;;

/* calculate mobitity scores */
int knight_mobility&#40;int squaren&#41;
&#123;
  int n;
  int g = 0;
  
  for &#40;n = 0; n < 8; n++)
  //n_sq = squaren + n_offsets&#91;n&#93;;
    if &#40;board&#91;squaren + n_offsets&#91;n&#93;&#93; == npiece&#41; // or == opponent
      g++;
  return g;
&#125; 

int bishop_mobility&#40;int squareb&#41;
&#123;
  int d;
  int s = 0;
  
  for &#40;d = 0; d < 4; d++)
  //b_sq = squareb + b_offsets&#91;d&#93;;
    if &#40;board&#91;squareb + b_offsets&#91;d&#93;&#93; == npiece&#41; // or == opponent
      s++;
  return s;
&#125; 

int rook_mobility&#40;int squarer&#41;
&#123;
  int f;
  int c = 0;
  
  for &#40;f = 0; f < 4; f++)
  //r_sq = squarer + r_offsets&#91;f&#93;;
    if &#40;board&#91;squarer + r_offsets&#91;f&#93;&#93; == npiece&#41; // or == opponent
      c++;
  return c;
&#125; 

int queen_mobility&#40;int squareq&#41;
&#123;
  int l;
  int m = 0;
  
  for &#40;l = 0; l < 8; l++)
  //r_sq = squarer + r_offsets&#91;f&#93;;
    if &#40;board&#91;squareq + q_offsets&#91;l&#93;&#93; == npiece&#41; // or == opponent
      m++;
  return m;
&#125; 
then simply...


Code: Select all

score += rook_mobility&#40;i&#41; * rme;
and the same formula for each piece. "rme" changes to "rmo" in the opening with a different value.

A short 10 game match at 3 0 went:

Code: Select all

-----------------NoMobilty &#91;010&#93;-----------------
NoMobility &#91;010&#93; - Mobility &#91;017&#93; &#58; 3.0/10 1-5-4 &#40;0000=1===0&#41;  30%  -147
-----------------Mobility &#91;017&#93;-----------------
Mobility &#91;017&#93; - NoMobilty &#91;010&#93; &#58; 7.0/10 5-1-4 &#40;1111=0===1&#41;  70%  +147

Longer tests later... Now I wish I had one of those clusters for some _mega_ tuning :) lol. Thanks Again.

-outAtime
outAtime
bob
Posts: 20943
Joined: Mon Feb 27, 2006 7:30 pm
Location: Birmingham, AL

Re: Mobility

Post by bob »

outAtime wrote:Thanks, looks like it's working.
I haven't added any of the suggested add ons/improvements yet.
I did add queen_mobility, and got rid of the sqrt() for now.
There are no negative scores.

Code: Select all

/* use piece offsets for mobility scores */

int n_offsets&#91;8&#93; = &#123; -10, 10, -14, 14, -23, 23, -25, 25 &#125;;
int b_offsets&#91;4&#93; = &#123; 11, -11, 13, -13 &#125;;
int r_offsets&#91;4&#93; = &#123; 12, -12, 1, -1 &#125;;
int q_offsets&#91;8&#93; = &#123; 13, -13, 11, -11, 12, -12, 1, -1 &#125;;

/* calculate mobitity scores */
int knight_mobility&#40;int squaren&#41;
&#123;
  int n;
  int g = 0;
  
  for &#40;n = 0; n < 8; n++)
  //n_sq = squaren + n_offsets&#91;n&#93;;
    if &#40;board&#91;squaren + n_offsets&#91;n&#93;&#93; == npiece&#41; // or == opponent
      g++;
  return g;
&#125; 

int bishop_mobility&#40;int squareb&#41;
&#123;
  int d;
  int s = 0;
  
  for &#40;d = 0; d < 4; d++)
  //b_sq = squareb + b_offsets&#91;d&#93;;
    if &#40;board&#91;squareb + b_offsets&#91;d&#93;&#93; == npiece&#41; // or == opponent
      s++;
  return s;
&#125; 

int rook_mobility&#40;int squarer&#41;
&#123;
  int f;
  int c = 0;
  
  for &#40;f = 0; f < 4; f++)
  //r_sq = squarer + r_offsets&#91;f&#93;;
    if &#40;board&#91;squarer + r_offsets&#91;f&#93;&#93; == npiece&#41; // or == opponent
      c++;
  return c;
&#125; 

int queen_mobility&#40;int squareq&#41;
&#123;
  int l;
  int m = 0;
  
  for &#40;l = 0; l < 8; l++)
  //r_sq = squarer + r_offsets&#91;f&#93;;
    if &#40;board&#91;squareq + q_offsets&#91;l&#93;&#93; == npiece&#41; // or == opponent
      m++;
  return m;
&#125; 
then simply...


Code: Select all

score += rook_mobility&#40;i&#41; * rme;
and the same formula for each piece. "rme" changes to "rmo" in the opening with a different value.

A short 10 game match at 3 0 went:

Code: Select all

-----------------NoMobilty &#91;010&#93;-----------------
NoMobility &#91;010&#93; - Mobility &#91;017&#93; &#58; 3.0/10 1-5-4 &#40;0000=1===0&#41;  30%  -147
-----------------Mobility &#91;017&#93;-----------------
Mobility &#91;017&#93; - NoMobilty &#91;010&#93; &#58; 7.0/10 5-1-4 &#40;1111=0===1&#41;  70%  +147

Longer tests later... Now I wish I had one of those clusters for some _mega_ tuning :) lol. Thanks Again.

-outAtime
Couple of things.

1. 10 games shows absolutely nothing but random noise. So don't draw _any_ conclusion.

2. How do you measure bishop mobility checking just 4 squares??? I'd expect 4 loop iterations to choose the 4 directions, but then a loop to take you down each ray to count the squares... what is given above looks wrong unless I am missing something important.