Problem with Negamax

Discussion of chess software programming and technical issues.

Moderators: hgm, Rebel, chrisw

universecoder
Posts: 53
Joined: Mon Sep 19, 2016 6:51 am

Problem with Negamax

Post by universecoder »

Hello, I made quite a few additions to my chess engine over the past few days.

Here is the code(Working copy) : https://github.com/universecoder/Horus-Chess-Engine

To test negamax, I made a few changes to the code. However, it is crashing.

Here is the code:
https://github.com/universecoder/Horus- ... /tree/test

Where have I gone wrong? Note that the eval function and all are just temporary right now.

Edit: The function chessboard::negamax() in the file think.cpp.
universecoder
Posts: 53
Joined: Mon Sep 19, 2016 6:51 am

Re: Problem with Negamax

Post by universecoder »

I solved it.
CheckersGuy
Posts: 273
Joined: Wed Aug 24, 2016 9:49 pm

Re: Problem with Negamax

Post by CheckersGuy »

I solved it.
Happy that your solved your problems. Just one thing to add.

Code: Select all

Move chessboard::findMove() { 
45 	 
46 	vector<Move> moveList; 
47 	generateAllMoves&#40;moveList&#41;; 
48 	 
49 	Move bestMove; 
50 	int maxScore = -INT_MAX; 
51 
 
52 	for&#40;vector<Move>&#58;&#58;iterator it = moveList.begin&#40;); it!= moveList.end&#40;); it++) &#123; 
53 		 
54 		Move move = *it; 
55 		 
56 		playMove&#40;move&#41;; 
57 		int score = negamax&#40;1&#41;; 
58 		undoMove&#40;move&#41;; 
59 		 
60 		if ( score >= maxScore ) &#123; 
61 			bestMove = move; 
62 		&#125; 
63 	&#125; 
64 	 
65 	return bestMove; 
66 &#125; 
Did you intend to only do a 2 ply search ? ()

Code: Select all

int score = negamax&#40;1&#41;; 
universecoder
Posts: 53
Joined: Mon Sep 19, 2016 6:51 am

Re: Problem with Negamax

Post by universecoder »

Haha:) I know, I told you it was just temporary ( since I wanted to know why it was segfaulting).
Sven
Posts: 4052
Joined: Thu May 15, 2008 9:57 pm
Location: Berlin, Germany
Full name: Sven Schüle

Re: Problem with Negamax

Post by Sven »

universecoder wrote:Haha:) I know, I told you it was just temporary ( since I wanted to know why it was segfaulting).
Even if your staticEval() is temporary, please do not forget to fix it, currently it will only count the material of the moving side and ignores the opponent.

Also findMove() should be fixed (three errors). Instead of

Code: Select all

playMove&#40;move&#41;;
int score = negamax&#40;4&#41;;
undoMove&#40;move&#41;;

if ( score >= maxScore ) &#123;
    bestMove = move;
&#125;
it should be

Code: Select all

playMove&#40;move&#41;;
int score = -negamax&#40;4&#41;;
undoMove&#40;move&#41;;

if ( score > maxScore ) &#123;
    maxScore = score;
    bestMove = move;
&#125;
universecoder
Posts: 53
Joined: Mon Sep 19, 2016 6:51 am

Re: Problem with Negamax

Post by universecoder »

Yes, ok. I corrected it. I wrote this all in a hurry 'cause I wanted to test the GUI.
universecoder
Posts: 53
Joined: Mon Sep 19, 2016 6:51 am

Re: Problem with Negamax

Post by universecoder »

I am finding it really difficult to communicate with xboard, is there any sample code available?
Sven
Posts: 4052
Joined: Thu May 15, 2008 9:57 pm
Location: Berlin, Germany
Full name: Sven Schüle

Re: Problem with Negamax

Post by Sven »

universecoder wrote:I am finding it really difficult to communicate with xboard, is there any sample code available?
There are lots of open source engines, some of them use UCI and others xboard/WinBoard (CECP).

In the beginning it is usually sufficient to implement the following elements of CECP:

1) Send "feature done=0" at engine startup, and configure standard input to "not buffered". Then do any kind of initialization of the engine itself.

2) Maintain information about color of engine, force mode set or not, and engine clock.

3) Provide a command loop basically working like this:

Code: Select all

read next command from stdin
while &#40;not EOF and not quit&#41; &#123;
    process command
    if &#40;engine color == active color of board&#41; &#123;
        start engine clock
        calculate engine move
        make engine move on board
        send engine move
        if &#40;end of game reached&#41; &#123;
            send RESULT &#123;reason&#125; &#40;where RESULT is one of 1-0, 0-1, 1/2-1/2&#41;
            set engine color to "none" &#40;and/or enter force mode&#41;
        &#125;
        stop engine clock
    &#125;
    read next command from stdin
&#125;
4) When processing a command, understand these commands from GUI (or console, or standard input in general) to engine, and take appropriate actions:

quit
xboard (reply with "\n")
protover 2 (reply with "feature ping=1 setboard=1 usermove=1 colors=0 sigint=0 sigterm=0 debug=1 variants="normal" myname="ENGINE_NAME" done=1\n"
new
force (enter force mode)
ping NUMBER (reply with "pong NUMBER\n")
usermove MOVE (make MOVE on the board and check for end-of-game the same way as shown above)
go (set engine color to active color of board)
setboard FEN
level MPS TIME INC
time TIME_LEFT
Last edited by Sven on Sun Oct 09, 2016 3:49 pm, edited 2 times in total.
Sven
Posts: 4052
Joined: Thu May 15, 2008 9:57 pm
Location: Berlin, Germany
Full name: Sven Schüle

Re: Problem with Negamax

Post by Sven »

universecoder wrote:Yes, ok. I corrected it. I wrote this all in a hurry 'cause I wanted to test the GUI.
Your current GitHub version still only evaluates for the moving side (you need to evaluate everything for White and for Black, and then subtract one from the other depending on current side to move), and findMove() still misses to negate the result from the call to negamax() which has the viewpoint of the opponent.
Sven
Posts: 4052
Joined: Thu May 15, 2008 9:57 pm
Location: Berlin, Germany
Full name: Sven Schüle

Re: Problem with Negamax

Post by Sven »

Sven Schüle wrote:
universecoder wrote:I am finding it really difficult to communicate with xboard, is there any sample code available?
[...]
usermove MOVE (make MOVE on the board and check for end-of-game the same way as shown above)
Of course I did not mention any kind of error handling. In case of a user move (opponent move) you need to check the move for legality first (after checking the move string itself for validity, e.g. "hello", "e2e4567" and "e9k4" aren't valid move strings. I do this by generating all legal moves and matching the from-to-promotionPiece triple that I have extracted from the move string against the move string. If there is no matching legal move then the user move is rejected with an error message (CECP protocol describes a standard style for it), otherwise you have found a valid move data structure including information like en passant or castling, and can make that move on the board.