Skip to content Search Apps Documentation Source Content File Folder Download Copy Actions State String Boolean Number Struct Map Slice Pointer Function Closure Reference Nil Package Type Interface Unknown

Community realm. Read the code first. Community realm, deployed by its author. Read the code before you interact or send coins.

fastpath_test.gno

1.62 Kb · 62 lines
 1package minichess
 2
 3import "testing"
 4
 5// fastPerft walks the tree the way the search does (in-place make/unmake
 6// with the cheap legality and check filters) and cross-checks the filters
 7// against full attack tests at every node.
 8func fastPerft(t *testing.T, e *engine, depth, ply int, inCheck bool) int {
 9	if depth == 0 {
10		return 1
11	}
12	pb := e.buf(ply)
13	e.gen(pb, false)
14	n := 0
15	for i := 0; i < pb.nc+pb.nq; i++ {
16		m := 0
17		if i < pb.nc {
18			m = pb.caps[i]
19		} else {
20			m = pb.quiets[i-pb.nc]
21		}
22		u := e.make(m)
23		fast := e.moveIsLegal(m, u, inCheck)
24		full := !e.attacked(e.kings[1-e.turn], e.turn)
25		if fast != full {
26			t.Fatalf("moveIsLegal mismatch for %s", decode(m))
27		}
28		if full {
29			gc := e.givesCheck(m, u)
30			if gc != e.inCheck() {
31				t.Fatalf("givesCheck mismatch for %s", decode(m))
32			}
33			n += fastPerft(t, e, depth-1, ply+1, gc)
34		}
35		e.unmake(m, u)
36	}
37	return n
38}
39
40func TestFastPathPerft(t *testing.T) {
41	cases := []struct {
42		fen   string
43		depth int
44		want  int
45	}{
46		{"r3k2r/p1ppqpb1/bn2pnp1/3PN3/1p2P3/2N2Q1p/PPPBBPPP/R3K2R w KQkq - 0 1", 2, 2039},
47		{"8/2p5/3p4/KP5r/1R3p1k/8/4P1P1/8 w - - 0 1", 3, 2812},
48		{"r3k2r/Pppp1ppp/1b3nbN/nP6/BBP1P3/q4N2/Pp1P2PP/R2Q1RK1 w kq - 0 1", 3, 9467},
49		{"rnbq1k1r/pp1Pbppp/2p5/8/2B5/8/PPP1NnPP/RNBQK2R w KQ - 1 8", 2, 1486},
50	}
51	for _, c := range cases {
52		p := mustFEN(t, c.fen)
53		e := newEngine(&p)
54		before := p.FEN()
55		if got := fastPerft(t, e, c.depth, 0, e.inCheck()); got != c.want {
56			t.Fatalf("%s: got %d want %d", c.fen, got, c.want)
57		}
58		if after := e.position(p.Fullmove).FEN(); after != before {
59			t.Fatalf("make/unmake did not restore: %s vs %s", after, before)
60		}
61	}
62}