Soberango 0.00.0 (chess engine) realized.

User projects written in or related to FreeBASIC.
MrSwiss
Posts: 3124
Joined: Jun 02, 2013 9:27
Location: Switzerland

Re: Soberango 0.00.0 (chess engine) realized.

Postby MrSwiss » Sep 02, 2016 14:18

Luis Babboni wrote:I think I understadn now.... you compiled soberango have 190kb and my compiled have 370 kb, I´m right?
Yes, that is exactly the point of frisian.

Also, the advice given by frisian refer only to programming (in general) and not to any specific coding task (Chess-Engine).
Luis Babboni
Posts: 300
Joined: Mar 15, 2015 12:41

Re: Soberango 0.00.0 (chess engine) realized.

Postby Luis Babboni » Sep 02, 2016 15:01

MrSwiss wrote:
Luis Babboni wrote:I think I understadn now.... you compiled soberango have 190kb and my compiled have 370 kb, I´m right?
Yes, that is exactly the point of frisian.

Also, the advice given by frisian refer only to programming (in general) and not to any specific coding task (Chess-Engine).



OK, I must be more carefully and slower reading english. :-D

I must make some kind of list to know where to find those advices in the future when I´ll need to improve my programming!

Thanks MrSwiss!
frisian
Posts: 249
Joined: Oct 08, 2009 17:25

Re: Soberango 0.00.0 (chess engine) realized.

Postby frisian » Sep 02, 2016 21:38

Luis Babboni

Yes I was taking about Soberango, Numpty\NoMega has a .exe file just under 300 Kb and can processes about 2 to 3 times more nodes then your program and it still has some problems.

About debug.
The debug information is only needed when you are looking for bugs or weird behavior, it does not interfere with the working.
Also for testing you can compile with the -exx option, this adds checks for the array’s resulting in slowing the program.
Therefore when you place a program on the internet it should only be compiled with -s console or -s gui.

It will take some time to figure out how your program works, but I have seen somethings that need to change in order to gain more speed.
The idea of a chess program is very simple, find the best move. There are two way’s to do this.
1. Try to get as many ply’s you can in a given time and look at the value of the pieces, the move with the highest score is played.
2. Make a move and evaluate the board add points for strong positions and subtract points for bad positions.
3. A combination of the both methods.

For this speed is very important, thus using integer’s is the best thing, other types like floats (single, double) and strings should be avoided. So using rnd() in the move generation is as very bad thing. Getting a random number takes to much time and converting that number to an integer is also time consuming.
Playing random moves is a very bad idea, there is a change that you create a situation where your opponent can take pieces that have not enough protection and before you know it you lose the game, because you lost important pieces.
Also calling lot’s of SubRoutine’s is waist of time, especial routine’s that only called from one places.
Better incorporate SubRoutine’s into one. ‘MuevePeon.bas’ has several subroutine’s that should be made into one big subroutine.

DIM
From your program I can see that you have no idea what DIM does.
(small example) From: BOOTEO.BAS
'DIMENSIONAMIENTOS:
Dim Tablero(1 To 8, 1 To 8) As Integer
What DIM does is it claims 8*8*4 (size of integer) byte’s, and then clears the array by loading it with 0’s

Then later you have this
'Inicializa todo en 0, CargaFEN se encarga después de poner lo que debe valer:
For i=1 To 8:For j=1 To 8: Tablero(i,j)=0:Next: Next
You do something that already done, and also you a slower then FB.

If you DIM a variable it contents is loaded with 0.

in Sub Reseteo you clear some array's
'Inicializa todo en 0, CargaFEN se encarga después de poner lo que debe valer:

For i=1 To 8:For j=1 To 8: Tablero(i,j)=0:Next: Next

Since Tablero() is shared you simple do REDIM Tablero(1 to 8, 1 to 8).
What happens is Tablero() is removed and replaced by a new version that has it contents filled with 0’s.

To show how fast that is I have made a little program to demonstrate the principle.

Code: Select all

'compile with -s console

#Define small 10
#Define big 10000000 ' 10 000 0000

dim as integer a, b, c
Dim As Byte array()
ReDim array(big, small)
Print

Dim As Double t1 = Timer
For a = 1 To small
    For b = 1 To big
        array(big, small) = 0
    Next
Next
t1 = Timer - t1
Print Using " small first then big: ##.######## ";t1

t1 = Timer
For a = 1 To big
    For b = 1 To small
        array(big, small) = 0
    Next
Next
t1 = Timer - t1
Print Using " big first then small: ##.######## ";t1

t1 = Timer
ReDim array(big, small) ' As byte
t1 = Timer - t1
Print Using "          redim array: ##.######## ";t1

Print : print

t1 = 12.34567
Print "               normal display";t1
Print Using " Hey look automatic round off ##.##"; t1
Print Using " Hey look automatic round off ##.###"; t1
Print Using " Hey look automatic round off ##.####" ; t1
Print Using " Hey look automatic round off ##.#####" ; t1

Print
Print "hit any key to stop"

Sleep

From HaceLog.bas
Print #1, " Tiempo(s)=";Using "###.## ";Int(Tiempo*100+0.5)/100
Can be replaced with.
Print #1, " Tiempo(s)=";Using "###.## ";Tiempo
Gives the same result.

Code: Select all

Sub AlfaBeta (ByVal p As Integer, ByRef AB As Integer)
   
   Dim par As Single   'Necesito que no sea entero para evaluar p/2
   par=p
      
   AB=1   'En principio la búsqueda debe seguir.
   
   If p>1 And Nodo(p-1,1)=1 And par/2=Int(par/2) Then   'si p es nodo par, mueve rival.
      If ColorSoberango=1 Then If Nodo(p,2)<=Nodo(p-1,2) Then AB=0   'si rival es negras corta si ve que la valuación es menor pues Soberango con blancas no la elegiría.
      If ColorSoberango=-1 Then If Nodo(p,2)>=Nodo(p-1,2) Then AB=0   'si rival es blancas corta si ve que la valuación es mayor pues Soberango con negras no la elegiría.
   EndIf
   
   If p>1 And Nodo(p-1,1)=1 And par/2<>Int(par/2) Then   'si p es nodo impar, mueve Soberango.
      If ColorSoberango=1 Then If Nodo(p,2)>=Nodo(p-1,2) Then AB=0   'si Soberango es blancas corta si ve que la valuación es mayor pues rival con negras no la elegiría.
      If ColorSoberango=-1 Then If Nodo(p,2)<=Nodo(p-1,2) Then AB=0   'si Soberango es negras corta si ve que la valuación es menor pues rival con blancas no la elegiría.
   EndIf
      
End Sub


AlfaBeta is called from to 2 places it would be better to replace the calls with the code itself it’s only a few lines. The code needs some alteration to fit in and to streamline the code.
par/2=Int(par/2) is not the best way to check if a variable is odd or even. Floating point division is slow and converting floaing point variables to a integer is not fast. The way to do this is p and 1 = 1 for odd and p and 1 = 0 for even. This method is much faster. Also the logic can be changed make it more streamlined.

If you don't understand the principals then leave it as it is, I will work some thing out when I have time.
Last edited by frisian on Sep 10, 2016 7:18, edited 1 time in total.
Luis Babboni
Posts: 300
Joined: Mar 15, 2015 12:41

Re: Soberango 0.00.0 (chess engine) realized.

Postby Luis Babboni » Sep 03, 2016 2:11

Thanks for your time frisian!!

I think all your comments are right, but some have more influence than others in the engine speed.

I think that as a good programmer you feel horrorized with things like this about fill with zeros in a loop an array!! :-D
I´ll change it in a future now you said. But has no importance in the engine speed cause it is something that is do just once in a game and even out of counted time.

On the other hand, things like this awful way to see if a number is odd or even or the great number of subroutines in MuevePeon.bas are of great importance in the engine speed cause are things the program do millions of times in each move!!

About the randomize is more near the redim case, I did it just once per move, nothing compared with the millions per move of other stuff.

As I said upon, I will changed the just made code with more care in the optimization of time just after I´ll end to understand the basics chess programming ideas*, but from now on I think I could do the things better thanks to your comments and in the future when I´ll rewrite the code I´ll come back to here to see your suggestions!
*: in my plan, versions 0.xx.x are experimental or to learn. I took several months in 2015 thinking too much in details without do nothing. This year I decided to make things that work no matter how primitively programmed are. (This not means I´ll do things bad on purpose, so any suggestion is welcome, just I beg your pardon if after you use your time to make suggestions, I do not implemented them yet.) ;-)

Note 1: some subroutines are too much just to see them more easy, I did not know that uses more time. I think I´ll think in it more from now on comparing speed with clearity.

Note 2: I do not understand, you say that if I compile the code in other way the program will work faster? I will test it tomorrow if you say it could be.

Thanks again!! :-)
Last edited by Luis Babboni on Sep 03, 2016 2:51, edited 1 time in total.
Luis Babboni
Posts: 300
Joined: Mar 15, 2015 12:41

Re: Soberango 0.00.0 (chess engine) realized.

Postby Luis Babboni » Sep 03, 2016 2:40

More about the random I use to make it more clear.
I need to make all possible moves for each piece.
The random is just used at the begining of each move (each move, not each ply of the search), to determine the order of the pieces and the order of the moves of each piece I will examine.
This helps the engine to not make always the same move in the same position as other weak engines do. I mean, there are moves better than others, but if there are more than one move that have the better score, this random makes that sometimes choice one of those moves and sometimes other cause at same score, the program always do the move found first.
Not sure if this increases or not the force of the engine (I think yes), but I asure do not as bored games as if there is no random.
May be in the future with more refined evaluation function when moves with same score will be rare, I´ll could turn this random off to gain a little time.
frisian
Posts: 249
Joined: Oct 08, 2009 17:25

Re: Soberango 0.00.0 (chess engine) realized.

Postby frisian » Sep 08, 2016 18:03

Luis Babboni

First something I noticed seeing Soberango play.
When Soberango’s Queen is take and his opponent manage to hold his Queen, the value that Soberango gives to it own moves is wrong. Soberango had already lost some pieces and it start rating it moves with + (positive) but it should be rating it move with (negative) because it lost it Queen and other pieces. Since it takes the move with the highest value it was giving away pieces resulting in losing the game.
This behavior does not occur when the opponent has lost it Queen.

About random moves.
Some computes chess programs have a feature called “blunder chess” where the program choices not the best move, but some lesser move to simulate a human that makes a not so good move. Mostly it used to make it a little easier for a human to win from a chess program. But when playing an other chess program you need to go for the best move.

Only when you have more than one move with the same score you can make a random choice.

The other place where you can have a random choice is with your opening move when you have an opening book. Best to stick to d2d4 or e2e4 and try to clear f1 and g1 to give yourself the possibility to Castle and bring the rook on h1 into play.

Made the code in AlfaBeta.bas into a macro there are no changes needed in MainGenerador.bas. The macro is a piece code that is inserted in the listing at compile time, removing the need for a sub routine call. I changed the If Then flow for faster processing.

Code: Select all

'Sub AlfaBeta(ByVal p As Integer, ByRef AB As Integer)
   
'   Dim par As Single                             'Necesito que no sea entero para evaluar p/2
'   par = p
   
'   AB = 1                                        'En principio la búsqueda debe seguir.
   
'   If p > 1 And Nodo(p - 1, 1) = 1 And par / 2 = Int(par / 2) Then 'si p es nodo par, mueve rival.
'      If ColorSoberango = 1 Then If Nodo(p, 2) <= Nodo(p - 1, 2) Then AB = 0 'si rival es negras corta si ve que la valuación es menor pues Soberango con blancas no la elegiría.
'      If ColorSoberango = - 1 Then If Nodo(p, 2) >= Nodo(p - 1, 2) Then AB = 0 'si rival es blancas corta si ve que la valuación es mayor pues Soberango con negras no la elegiría.
'   End If
   
'   If p > 1 And Nodo(p - 1, 1) = 1 And par / 2 <> Int(par / 2) Then 'si p es nodo impar, mueve Soberango.
'      If ColorSoberango = 1 Then If Nodo(p, 2) >= Nodo(p - 1, 2) Then AB = 0 'si Soberango es blancas corta si ve que la valuación es mayor pues rival con negras no la elegiría.
'      If ColorSoberango = - 1 Then If Nodo(p, 2) <= Nodo(p - 1, 2) Then AB = 0 'si Soberango es negras corta si ve que la valuación es menor pues rival con blancas no la elegiría.
'   End If
   
'End Sub

#macro AlfaBeta(p, AB)
   
   AB = 1
   
   if p > 1 andalso Nodo(p-1, 1) = 1 then
      if (p and 1) = 0 then                      ' p = even
         if ColorSoberango = 1 then
            if Nodo(p, 2) <= Nodo(p-1, 2) then AB = 0
         else
            ' ColorSoberango = -1
            if Nodo(p, 2) >= Nodo(p-1, 2) then AB = 0
         end if
      else
         ' p = odd
         if ColorSoberango = 1 then
            if Nodo(p, 2) >= Nodo(p-1, 2) Then AB = 0
         else
            ' ColorSoberango = -1
            if Nodo(p, 2) <= Nodo(p-1, 2) Then AB = 0
         end if
      end if
   end if
   
#endmacro

In the first line if p > 1 andalso Nodo(p-1, 1) = 1 then, andalso checks p > 1 first, if this is true it test Nodo(p-1, 1) = 1 if it's true or false, if it’s (p > 1) false then the status of Nodo(p-1, 1) = 1 does not matter, it leaves the If Then construction. And test both conditions and then decide what it needs to do, but if the first is false the rest is a waist of time.
The trick is to find out which condition fails the most times, it should be placed first in order to make the most gain from it.

The second test is to see if p is odd or even since p can only one of two things, if p is not even then it must be odd.
The same applies for ColorSoberango it’s either 1 of -1.

In CargaFEN.bas you have the line If hmC = 5 Then hmS3 = Char :hmV = 1000*Val(hmS1) + 100*Val(hmS2) + 10*Val(hmS3) + Val(hmS4) do you spot the error. hmS3 = Char should be hmS4 = Char

Code: Select all

'Halfmove:
      If espacios = 5 Then '  if Char = "-" or "" or " " then val(Char) = 0
         hmV = hmV * 10 + val(Char)
         ' If quienmueve = 1 Then hmV = hmV * 2 -1  '  }
         ' If quienmueve = -1 Then hmV = hmV * 2    '  }= outside Do Loop
         ' Halfmove = hmV                           '  }
         'Para debug:
         'Print "Halfmove de FEN:";Halfmove
      End If

The quienmueve stuff needs to moved outside the Do Loop or else it will change hmV.

Code outside the loop.

Code: Select all

if hmV <> 0 then halfmove = hmv * 2 else halfmove = 1 ' if halfmove field is empty then make halfmove = 1
                                                        ' to avoid a negative halfmove
    if quienmueve = 1 then halfmove = halfmove – 1

It should not be to hard for you to change the code under '50 movidas:.
Luis Babboni
Posts: 300
Joined: Mar 15, 2015 12:41

Re: Soberango 0.00.0 (chess engine) realized.

Postby Luis Babboni » Sep 09, 2016 12:14

Thanks frisian agian for your time!

I´m must going in 5 minutes so just first comments to your comment.

I´m not understand right your first comment about queen and wrong evaluations.
Could be this related what use to happens to Soberango cause the horizon effect that when it is near to lost a major piece start to give free to the oponent less value pieces just to move the lost of the greater far away its horizon or it is another think?
I must read you comment again.

What soberango do is in fact use random just with moves of equal value.

Good point this about use random only in openings!

I must read again the rest about macros.
Edit: I could not find even the word macro in FB Help!!

I´ll came back in few hours or less!
Last edited by Luis Babboni on Sep 09, 2016 14:09, edited 1 time in total.
Luis Babboni
Posts: 300
Joined: Mar 15, 2015 12:41

Re: Soberango 0.00.0 (chess engine) realized.

Postby Luis Babboni » Sep 09, 2016 12:42

frisian wrote:...
First something I noticed seeing Soberango play.
When Soberango’s Queen is take and his opponent manage to hold his Queen, the value that Soberango gives to it own moves is wrong. Soberango had already lost some pieces and it start rating it moves with + (positive) but it should be rating it move with (negative) because it lost it Queen and other pieces. Since it takes the move with the highest value it was giving away pieces resulting in losing the game.
This behavior does not occur when the opponent has lost it Queen.
...


Will be not easy to find this situation.
I just started a 50 games match against itself recording output to try to find it.
Luis Babboni
Posts: 300
Joined: Mar 15, 2015 12:41

Re: Soberango 0.00.0 (chess engine) realized.

Postby Luis Babboni » Sep 09, 2016 12:46

frisian wrote:...
About random moves.
Some computes chess programs have a feature called “blunder chess” where the program choices not the best move, but some lesser move to simulate a human that makes a not so good move. Mostly it used to make it a little easier for a human to win from a chess program.
...

Not have the option to be weaker on purpose.

frisian wrote:...
But when playing an other chess program you need to go for the best move.

Only when you have more than one move with the same score you can make a random choice.
...

Is exactly like this actually just with another approach.

frisian wrote:...
The other place where you can have a random choice is with your opening move when you have an opening book. Best to stick to d2d4 or e2e4 and try to clear f1 and g1 to give yourself the possibility to Castle and bring the rook on h1 into play.
...

Good idea but for still not have its own opening book.
Luis Babboni
Posts: 300
Joined: Mar 15, 2015 12:41

Re: Soberango 0.00.0 (chess engine) realized.

Postby Luis Babboni » Sep 09, 2016 12:59

frisian wrote:...
In CargaFEN.bas you have the line If hmC = 5 Then hmS3 = Char :hmV = 1000*Val(hmS1) + 100*Val(hmS2) + 10*Val(hmS3) + Val(hmS4) do you spot the error. hmS3 = Char should be hmS4 = Char
...


Nice find!

I think you need to read the core too carefully to find it!!
Thanks.

This part fortunatelly is not used yet cause it is prepared for future option to start not from the begining.
I mean, in the begining the halfmove are not as big to need to enter this part of code.

Fixed!
Luis Babboni
Posts: 300
Joined: Mar 15, 2015 12:41

Re: Soberango 0.00.0 (chess engine) realized.

Postby Luis Babboni » Sep 09, 2016 13:05

frisian wrote:...
Made the code in AlfaBeta.bas into a macro there are no changes needed in MainGenerador.bas. The macro is a piece code that is inserted in the listing at compile time, removing the need for a sub routine call.
...


Is something like the #Include...?
Luis Babboni
Posts: 300
Joined: Mar 15, 2015 12:41

Re: Soberango 0.00.0 (chess engine) realized.

Postby Luis Babboni » Sep 09, 2016 13:16

frisian wrote:...

Code: Select all

'Halfmove:
      If espacios = 5 Then '  if Char = "-" or "" or " " then val(Char) = 0
         hmV = hmV * 10 + val(Char)
         ' If quienmueve = 1 Then hmV = hmV * 2 -1  '  }
         ' If quienmueve = -1 Then hmV = hmV * 2    '  }= outside Do Loop
         ' Halfmove = hmV                           '  }
         'Para debug:
         'Print "Halfmove de FEN:";Halfmove
      End If

The quienmueve stuff needs to moved outside the Do Loop or else it will change hmV.

Code outside the loop.

Code: Select all

if hmV <> 0 then halfmove = hmv * 2 else halfmove = 1 ' if halfmove field is empty then make halfmove = 1
                                                        ' to avoid a negative halfmove
    if quienmueve = 1 then halfmove = halfmove – 1

...

Not sure but seems to me that may be is not the nicer way to code it but it works.
First: The idea is that I do not know in advance how many places the number to be read will have, so I calculate the value and if the number have no more places, then I got the value. If I find that the number have even more places, I recalculate the value deleting the previous value never needed.
Second: the first hmv is not the hmv I want to have. in FEN the corresponding number is in fact the move, not halfmove. so may be would be more claer if first I use "mv" instead of "hmv" and just "hmv" after the quienmueve stuff.

This part of the code not need to be fast cause is used just before start each game.

frisian wrote:...
It should not be to hard for you to change the code under '50 movidas:.


I not understand what you are referring with this. :-/
Luis Babboni
Posts: 300
Joined: Mar 15, 2015 12:41

Re: Soberango 0.00.0 (chess engine) realized.

Postby Luis Babboni » Sep 09, 2016 14:32

frisian wrote:...
In the first line if p > 1 andalso Nodo(p-1, 1) = 1 then, andalso checks p > 1 first, if this is true it test Nodo(p-1, 1) = 1 if it's true or false, if it’s (p > 1) false then the status of Nodo(p-1, 1) = 1 does not matter, it leaves the If Then construction. And test both conditions and then decide what it needs to do, but if the first is false the rest is a waist of time.
The trick is to find out which condition fails the most times, it should be placed first in order to make the most gain from it.

The second test is to see if p is odd or even since p can only one of two things, if p is not even then it must be odd.
The same applies for ColorSoberango it’s either 1 of -1.
...



Yes, you are too right, very awfull and not efficient way to do it.
I think that may be in that moment I was thinking in add clearity in the reading and just if works then optimize it.... but now looks as a very fool code! :-(

Thnaks for your time!
Luis Babboni
Posts: 300
Joined: Mar 15, 2015 12:41

Re: Soberango 0.00.0 (chess engine) realized.

Postby Luis Babboni » Sep 09, 2016 14:43

frisian wrote:...
First something I noticed seeing Soberango play.
When Soberango’s Queen is take and his opponent manage to hold his Queen, the value that Soberango gives to it own moves is wrong. Soberango had already lost some pieces and it start rating it moves with + (positive) but it should be rating it move with (negative) because it lost it Queen and other pieces. Since it takes the move with the highest value it was giving away pieces resulting in losing the game.
This behavior does not occur when the opponent has lost it Queen.
...


Sorry if I´m asking a fool question:
You be sure if is not just cause Soberango scores are always from white side no matter the side Soberango is playing?
frisian
Posts: 249
Joined: Oct 08, 2009 17:25

Re: Soberango 0.00.0 (chess engine) realized.

Postby frisian » Sep 10, 2016 8:27

Luis Babboni wrote:I must read again the rest about macros.
Edit: I could not find even the word macro in FB Help!!

For searching under index you must use the hole keyword #macro in other words as it's used in the program listing.

Code: Select all

'Halfmove:
      If espacios = 5 Then
         hmV = hmV * 10 + val(Char)
      End If

Comments are removed for a better view of the code.
This piece of code does not need to know what the size is, it works on numbers from 0 to 1000000000. Sweet and simple.
The more code you have the greater chance you have on errors. Keep It Simple, Stupid.

Luis Babboni wrote:Sorry if I´m asking a fool question:
You be sure if is not just cause Soberango scores are always from white side no matter the side Soberango is playing

If that's the case you have a problem, all chess programs rate good position and/or more pieces then there opponent with a positive number. And bad position and/or less pieces with a negative number regardless off the color they are playing with. The working of Xboard and Arena is based on that principle.

Return to “Projects”

Who is online

Users browsing this forum: No registered users and 5 guests