StefanSalewski / salewski-chess

The Salewski Chess Engine
MIT License
20 stars 1 forks source link

invalid move #4

Open tissatussa opened 5 months ago

tissatussa commented 5 months ago

This just happened while playing a game with your engine : I played White and i wanted to move Bg2xh1 but salewski-chess refused : "invalid move".

salewski-chess-invalid-move

Indeed the square h1 above is not yellow ..

btw. I know you rewrote this engine into "rust-chess" at https://github.com/StefanSalewski/rust-chess. Maybe this version of the engine does not have this bug, i didn't try ..

tissatussa commented 5 months ago

here's the game :

[Event "human vs engine"] [Site "Holland"] [Date "2024.04.10"] [Round "?"] [White "Roelof Berkepeis"] [Black "salewski-chess"] [Result "*"]

1.d4 d5 2.h3 Qd6 3.Nf3 Bf5 4.Nbd2 Nc6 5.a3 e5 6.dxe5 Nxe5 7.Nd4 Qf6 8.Nxf5 Qxf5 9.g4 Qe6 10.f4 Nc6 11.Bg2 h5 12.f5 Qe5 13.Nf1 hxg4 14.hxg4 Rxh1 *

StefanSalewski commented 5 months ago

Thanks for reporting, I will investigate that issue soon.

Generally, I would recommend to use my Rust port instead, see https://github.com/StefanSalewski/rust-chess. I have not written a single line of Nim in the last twelve months any more, and I don't think I will use Nim again. I think Rust can replace Nim for most areas, Rust's general activity seems to be 100 times larger, and the community has many smart and friendly people. I am currently reading the book "Programming Rust" by Mr. Jim Blandy. It is quite good and explains the language in much detail. I hope that Rust will get the Xilem GUI by end of this year, then we would finally have a high quality open source GUI library.

I will try to reproduce your issue with the Rust version, and let you know how you can fix it for the Nim version if you really want. Note that there may exist at least one more tiny issue in the Nim version, see https://github.com/StefanSalewski/rust-chess/issues/2

StefanSalewski commented 5 months ago

It is really a funny issue. After thinking a few minutes, I have still no idea what might be wrong.

tissatussa commented 5 months ago

OK, that's clear. i didn't manage to compile the rust-chess engine on my Linux .. something with gtk4 / gdk4 and/or an environment variable .. maybe i should create an Issue for this at that concerning GitHub project.

tissatussa commented 5 months ago

It is really a funny issue. After thinking a few minutes, I have still no idea what might be wrong.

can you reporduce the error ? I can ..

StefanSalewski commented 5 months ago

Will test tomorrow. Compiling the Rust version should be easy, as most Linux users have Rust available. GTK4 issue might be https://users.rust-lang.org/t/gtk4-example-graphics-code-please/109136/3

Maybe you can fix that yourself after cloning. I will try to make GTK version request more robust by fixing the Cargo.toml file soon.

tissatussa commented 5 months ago

...I will try to make GTK version request more robust by fixing the Cargo.toml file soon...

Nice .. and often i have problems with the (minimal) rust version, eg. Nightly is needed .. i discovered how to install & switch between versions but this can be made clear in the README ? I might give a full report later : what i tried and the messages i get in terminal while compiling ..

StefanSalewski commented 5 months ago

eg. Nightly is needed

Please tell me all your Rust issues. I think Nightly should not be needed, maybe gtk-rs is using a Nightly feature. As I am still a Rust beginner, I might have done something wrong.

tissatussa commented 5 months ago

Please tell me all your Rust issues...

OK, tomorrow i will try to compile the rust-chess engine again and send my terminal output etc. .. but i guess it's best to open an Issue for that at the concerning GitHub project.

StefanSalewski commented 5 months ago

open an Issue for that at the concerning GitHub project.

Yes, that would be good. I can then ask at the Rust forum for help to make it work for all Rust and GTK versions.

StefanSalewski commented 5 months ago

Yes, I can reproduce the issue with my rust-chess. The manual setup for your position is

pub fn new_game() -> Game {

    ....

    if true {
        set_board(&mut g, VOID_ID, BB, B1);
        set_board(&mut g, W_KNIGHT, BF, B1);
        set_board(&mut g, VOID_ID, BG, B1);
        set_board(&mut g, B_ROOK, BH, B1);
        set_board(&mut g, VOID_ID, BA, B2);
        set_board(&mut g, VOID_ID, BD, B2);
        set_board(&mut g, VOID_ID, BF, B2);
        set_board(&mut g, W_BISHOP, BG, B2);
        set_board(&mut g, VOID_ID, BH, B2);
        set_board(&mut g, W_PAWN, BA, B3);
        set_board(&mut g, W_PAWN, BG, B4);
        set_board(&mut g, B_PAWN, BD, B5);
        set_board(&mut g, B_QUEEN, BE, B5);
        set_board(&mut g, W_PAWN, BF, B5);
        set_board(&mut g, B_KNIGHT, BC, B6);
        set_board(&mut g, VOID_ID, BD, B7);
        set_board(&mut g, VOID_ID, BE, B7);
        set_board(&mut g, VOID_ID, BH, B7);
        set_board(&mut g, VOID_ID, BB, B8);
        set_board(&mut g, VOID_ID, BC, B8);
        set_board(&mut g, VOID_ID, BD, B8);
        set_board(&mut g, VOID_ID, BH, B8);
    }
    g
}

For the Rust version, there is even one more issue: f5e6 is allowed (yellow). That might be related to a wrong en passant move. With the above setup, it should be easy to find and fix the issues, I will continue tomorrow.

StefanSalewski commented 5 months ago

You really found an interesting bug. I think it is related to

fn init_bishop(g: &mut Game) {
...
g.bishop_path[src as usize][i].pos =
                    if pos == src { -dst as i8 } else { dst as i8 };

Here I temporary made dst negative to use it as a marker, and later made it positive again. Unfortunately, for positions 0..63, this fails for position 0, which is the lower right square, to which you can't move. This is a true engine bug, so it has an effect in playing. And the same issue can occur for rook moves. I have to see how I can best fix it.

Have you made progress installing the Rust version? I think I will try to relax the GTK requirements, and check why Nightly might be required.

tissatussa commented 5 months ago

as you see i created a new Issue at the rust-chess project concerning my compile error .. i solved it but the rust engine doesn't play the same : i can not reproduce the supplied game, the rust-chess engine plays 1...e6 after 1.d4, not 1...d5

StefanSalewski commented 5 months ago

Yes, I suppose that the Rust version plays better chess. My feeling is, that Rust is a bit faster, so it does a deeper search for the same time requests. But actually I can not directly compare Nim and Rust here, as I had to re-arrange the code for Rust, e.g. Rust does not like global variables, so now all functions takes the board instance as a first parameter. But of course Nim is very fast too. Additionally, the Rust version got some improvements: I do a depth increase if the search tree contains two or more queen movements, and for a few other interesting variants also. I think you told me that the engine exposed the queen too early, and I had observed that too. A depth increase for multiple queen movements should be a smart fix, and that depth increment was already possible in the code, but was deactivated. You can play with it in engine.rs if you search in the code for "SELECT_EXTEND".

StefanSalewski commented 5 months ago

You really found an interesting bug.

I think the following modification should fix it:

fn init_bishop(g: &mut Game) {
    for src in POS_RANGE {
        let mut i = 0;
        for d in BISHOP_DIRS {
            let mut pos = src;
            loop {
                let dst = pos + d as i8;
                if !move_is_valid(pos, dst) {
                    break;
                }
                //g.bishop_path[src as usize][i].pos =
                //    if pos == src { -dst as i8 } else { dst as i8 };
                g.bishop_path[src as usize][i].pos = dst as i8;
                if pos == src {
                    g.bishop_path[src as usize][i].nxt_dir_idx = -1; // temporary marker; default content is zero.
                }
                i += 1;
                pos = dst;
            }
        }
        let mut nxt_dir_start = i;
        g.bishop_path[src as usize][i].pos = -1;
        g.freedom[(ARRAY_BASE_6 + W_BISHOP) as usize][src as usize] = ((i as i32 - 10) * 4) as i64; // range -12..12 // abs val is big enough, so exchange of a
        g.freedom[(ARRAY_BASE_6 + W_QUEEN) as usize][src as usize] = ((i as i32 - 10) * 4) as i64; // range -12..12 // pawn for very good position may occur
        g.freedom[(ARRAY_BASE_6 + B_BISHOP) as usize][src as usize] = ((i as i32 - 10) * 4) as i64;
        g.freedom[(ARRAY_BASE_6 + B_QUEEN) as usize][src as usize] = ((i as i32 - 10) * 4) as i64;
        while i > 0 {
            i -= 1;
            let h = g.bishop_path[src as usize][i].nxt_dir_idx == -1;
            g.bishop_path[src as usize][i].nxt_dir_idx = nxt_dir_start as i64;
            if h {
                nxt_dir_start = i;
                //g.bishop_path[src as usize][i].pos *= -1;
            }
        }
    }
}

Here we use the field nxt_dir_idx as temporary marker, to avoid the sign inversion. Seems to work. Tomorrow I will apply the same fix to init_rook() and then investigate why for your setup an en passant move was possible for white. Maybe that is a bug only in the Rust version?

tissatussa commented 5 months ago

so you discovered that other bug concerning ep. .. i will await a next version of the rust-chess engine (the above modification is for the Rust version).

visanalexandru commented 5 months ago

Hey, @StefanSalewski, you should look into Perft. It's really useful for finding bugs in your engine.