package chess import ( "fmt" "math/rand" "strings" "testing" ) func (c *ChessJPZ) TestPrint() { for row := 0; row < c.Height; row++ { for col := 0; col < c.Width; col++ { idx := (c.Height-1-row)*c.Width + col piece := c.Buf[idx] if IsEmpty(piece) { fmt.Printf("|. %2d| ", idx) // 打印空格表示没有棋子 } else { fmt.Printf("|%s%2d| ", piece, idx) } } fmt.Println() } } func (c *ChessJPZ) TestPrintType() { fmt.Println("[]Piece{") for row := 0; row < c.Height; row++ { for col := 0; col < c.Width; col++ { idx := (c.Height-1-row)*c.Width + col piece := c.Buf[idx] if IsEmpty(piece) { fmt.Printf("\"\"") // 打印空格表示没有棋子 } else { fmt.Printf("%s", piece) } if col < c.Width-1 { fmt.Print(",") } } fmt.Println() } fmt.Println("}") } func (c *ChessJPZ) TestSet(buf []Piece, bufString []string, cambodianMove []bool) { var buf2 []Piece if len(buf) > 0 { buf2 = make([]Piece, len(buf)) for x := 0; x < c.Width; x++ { for y := 0; y < c.Height; y++ { buf2[(c.Height-1-y)*c.Width+x] = buf[y*c.Width+x] } } } else { buf2 = make([]Piece, len(bufString)) for x := 0; x < c.Width; x++ { for y := 0; y < c.Height; y++ { buf2[(c.Height-1-y)*c.Width+x] = Piece(bufString[y*c.Width+x]) } } } c.Buf = buf2 if len(cambodianMove) == 4 { for k, v := range cambodianMove { c.CambodianMove[k] = v } } } func Print() { c := &ChessJPZ{} c.Init() c.TestPrint() c.TestPrintType() } func RandChess() { // 生成随机数据 b := make([]Piece, len(pieceJPZ)) copy(b, pieceJPZ) // 随机删除棋子 for k, v := range b { if IsEmpty(v) || IsK(v) { continue } if rand.Intn(2) == 1 { b[k] = "" } } // 随机移动棋子 rand.Shuffle(len(b), func(i, j int) { b[i], b[j] = b[j], b[i] }) fmt.Println("[]Piece{") for row := 0; row < 8; row++ { for col := 0; col < 8; col++ { idx := (8-1-row)*8 + col piece := b[idx] if IsEmpty(piece) { fmt.Printf("\"\"") // 打印空格表示没有棋子 } else { fmt.Printf("%s", piece) } if col < 7 { fmt.Print(",") } } fmt.Println() } fmt.Println("}") } func TestNoTest(t *testing.T) { //Print() RandChess() } func TestChessJPZ_GetIndexes(t *testing.T) { // BR, BN, BS, BM, BK, BS, BN, BR, // "", "", "", "", "", "", "", "", // BP, BP, BP, BP, BP, BP, BP, BP, // "", "", "", "", "", "", "", "", // "", "", "", "", "", "", "", "", // WP, WP, WP, WP, WP, WP, WP, WP, // "", "", "", "", "", "", "", "", // WR, WN, WS, WK, WM, WS, WN, WR, data := map[Piece][]int{ WR: {0, 7}, WN: {1, 6}, WS: {2, 5}, WM: {4}, WK: {3}, WP: {16, 17, 18, 19, 20, 21, 22, 23}, BR: {56, 63}, BN: {57, 62}, BS: {58, 61}, BM: {59}, BK: {60}, BP: {40, 41, 42, 43, 44, 45, 46, 47}, } c := new(ChessJPZ) c.Init() //c.TestPrint() for k, target := range data { result := c.GetIndexes(k) if len(result) != len(target) { t.Fatalf("%s: target:%v, result:%v\n", k, target, result) } for _, r := range result { has := false for _, i := range target { if i == r { has = true break } } if !has { t.Fatalf("%s: target:%v, result:%v\n", k, target, result) } } } } func TestChessJPZ_GetMovePositions(t *testing.T) { type Test struct { Buf []Piece WMMoved bool BMMoved bool WKMoved bool BKMoved bool Index int Moves []*PositionPiece } // 测试数据 data := []Test{ { Buf: pieceJPZ, WMMoved: true, BMMoved: true, WKMoved: true, BKMoved: true, Index: 0, Moves: []*PositionPiece{ {Index: 8, P: ""}, }, }, { Buf: pieceJPZ, WMMoved: true, BMMoved: true, WKMoved: true, BKMoved: true, Index: 1, Moves: []*PositionPiece{ {Index: 11, P: ""}, }, }, { Buf: pieceJPZ, WMMoved: true, BMMoved: true, WKMoved: true, BKMoved: true, Index: 2, Moves: []*PositionPiece{{Index: 9}, {Index: 11}, {Index: 10}}, }, { Buf: pieceJPZ, WMMoved: true, BMMoved: true, WKMoved: true, BKMoved: true, Index: 3, Moves: []*PositionPiece{{Index: 10}, {Index: 11}, {Index: 12}, {Index: 9}, {Index: 13}}, }, { Buf: pieceJPZ, WMMoved: true, BMMoved: true, WKMoved: true, BKMoved: true, Index: 4, Moves: []*PositionPiece{{Index: 11}, {Index: 13}}, }, { Buf: pieceJPZ, WMMoved: true, BMMoved: true, WKMoved: true, BKMoved: true, Index: 5, Moves: []*PositionPiece{{Index: 12}, {Index: 14}, {Index: 13}}, }, { Buf: pieceJPZ, WMMoved: true, BMMoved: true, WKMoved: true, BKMoved: true, Index: 6, Moves: []*PositionPiece{{Index: 12}}, }, { Buf: pieceJPZ, WMMoved: true, BMMoved: true, WKMoved: true, BKMoved: true, Index: 7, Moves: []*PositionPiece{{Index: 15}}, }, { Buf: pieceJPZ, WMMoved: true, BMMoved: true, WKMoved: true, BKMoved: true, Index: 16, Moves: []*PositionPiece{{Index: 24}}, }, { Buf: pieceJPZ, WMMoved: true, BMMoved: true, WKMoved: true, BKMoved: true, Index: 17, Moves: []*PositionPiece{{Index: 25}}, }, { Buf: pieceJPZ, WMMoved: true, BMMoved: true, WKMoved: true, BKMoved: true, Index: 40, Moves: []*PositionPiece{{Index: 32}}, }, { Buf: pieceJPZ, WMMoved: true, BMMoved: true, WKMoved: true, BKMoved: true, Index: 41, Moves: []*PositionPiece{{Index: 33}}, }, { Buf: pieceJPZ, WMMoved: true, BMMoved: true, WKMoved: true, BKMoved: true, Index: 56, Moves: []*PositionPiece{{Index: 48}}, }, { Buf: pieceJPZ, WMMoved: true, BMMoved: true, WKMoved: true, BKMoved: true, Index: 57, Moves: []*PositionPiece{{Index: 51}}, }, { Buf: pieceJPZ, WMMoved: true, BMMoved: true, WKMoved: true, BKMoved: true, Index: 58, Moves: []*PositionPiece{{Index: 49}, {Index: 50}, {Index: 51}}, }, { Buf: pieceJPZ, WMMoved: true, BMMoved: true, WKMoved: true, BKMoved: true, Index: 59, Moves: []*PositionPiece{{Index: 50}, {Index: 52}}, }, { Buf: pieceJPZ, WMMoved: true, BMMoved: true, WKMoved: true, BKMoved: true, Index: 60, Moves: []*PositionPiece{{Index: 51}, {Index: 52}, {Index: 53}, {Index: 50}, {Index: 54}}, }, { Buf: pieceJPZ, WMMoved: true, BMMoved: true, WKMoved: true, BKMoved: true, Index: 61, Moves: []*PositionPiece{{Index: 52}, {Index: 54}, {Index: 53}}, }, { Buf: pieceJPZ, WMMoved: true, BMMoved: true, WKMoved: true, BKMoved: true, Index: 62, Moves: []*PositionPiece{{Index: 52}}, }, { Buf: pieceJPZ, WMMoved: true, BMMoved: true, WKMoved: true, BKMoved: true, Index: 63, Moves: []*PositionPiece{{Index: 55}}, }, { Buf: pieceJPZ, WMMoved: true, BMMoved: true, WKMoved: true, BKMoved: false, Index: 60, Moves: []*PositionPiece{{Index: 51}, {Index: 52}, {Index: 53}}, }, { Buf: pieceJPZ, WMMoved: true, BMMoved: true, BKMoved: true, WKMoved: false, Index: 3, Moves: []*PositionPiece{{Index: 10}, {Index: 11}, {Index: 12}}, }, { Buf: []Piece{ BR, BN, BS, BM, BK, BS, BN, BR, "", "", "", "", "", "", "", "", BP, BP, BP, BP, BP, BP, BP, BP, "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", WP, WP, WP, WP, "", WP, WP, WP, "", "", "", "", "", "", "", "", WR, WN, WS, WK, WM, WS, WN, WR, }, BMMoved: true, WKMoved: true, BKMoved: true, WMMoved: false, Index: 4, Moves: []*PositionPiece{{Index: 11}, {Index: 13}}, }, { Buf: []Piece{ BR, BN, BS, BM, BK, BS, BN, BR, "", "", "", "", "", "", "", "", BP, BP, BP, BP, BP, BP, BP, BP, "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", WP, WP, WP, WP, "", WP, WP, WP, "", "", "", "", "", "", "", "", WR, WN, WS, WK, WM, WS, WN, WR, }, WMMoved: true, Index: 4, Moves: []*PositionPiece{{Index: 11}, {Index: 13}, {Index: 20}}, }, { Buf: []Piece{ BR, BN, BS, BM, BK, BS, BN, BR, "", "", "", "", "", "", "", "", BP, BP, BP, "", BP, BP, BP, BP, "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", WP, WP, WP, WP, "", WP, WP, WP, "", "", "", "", "", "", "", "", WR, WN, WS, WK, WM, WS, WN, WR, }, WMMoved: true, WKMoved: true, BKMoved: true, BMMoved: false, Index: 59, Moves: []*PositionPiece{{Index: 50}, {Index: 52}}, }, { Buf: []Piece{ BR, BN, BS, BM, BK, BS, BN, BR, "", "", "", "", "", "", "", "", BP, BP, BP, "", BP, BP, BP, BP, "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", WP, WP, WP, WP, "", WP, WP, WP, "", "", "", "", "", "", "", "", WR, WN, WS, WK, WM, WS, WN, WR, }, BMMoved: true, Index: 59, Moves: []*PositionPiece{{Index: 50}, {Index: 52}, {Index: 43}}, }, } f := func(name string, moves []*PositionPiece) { b := strings.Builder{} for _, s := range moves { b.WriteString(fmt.Sprintf("%+v,", *s)) } fmt.Println(name, b.String()) } c := new(ChessJPZ) c.Init() //c.TestPrint() for _, v := range data { c.TestSet(v.Buf, nil, []bool{v.WKMoved, v.WMMoved, v.BMMoved, v.BKMoved}) moves := c.GetMovePositions(v.Index) if len(v.Moves) != len(moves) { c.TestPrint() fmt.Printf("Index:%v\n", v.Index) f("Target Moves:", v.Moves) f("Result Moves:", moves) t.Fail() } for _, m := range moves { has := false for _, v := range v.Moves { if v.Index == m.Index && v.P == m.P { has = true break } } if !has { c.TestPrint() fmt.Printf("Index:%v\n", v.Index) f("Target Moves:", v.Moves) f("Result Moves:", moves) t.Fail() } } } } func TestChessJPZ_GetMovePositions2(t *testing.T) { testChess := []Piece{ BR, "", BS, BM, BK, BN, "", "", "", "", "", "", "", "", "", WR, BP, "", WM, WN, "", WM, "", BP, "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", WP, "", BP, "", "", BP, "", WP, "", "", "", "", "", "", "", "", "", "", WS, WK, WM, "", "", "", } type Test struct { Buf []Piece WMMoved bool BMMoved bool WKMoved bool BKMoved bool Index int Moves []*PositionPiece } data := []Test{ { Buf: testChess, WMMoved: true, BMMoved: true, WKMoved: true, BKMoved: true, Index: 2, Moves: []*PositionPiece{{Index: 9}, {Index: 11}, {Index: 10}}, }, { Buf: testChess, WMMoved: true, BMMoved: true, WKMoved: true, BKMoved: true, Index: 3, Moves: []*PositionPiece{{Index: 10}, {Index: 13}}, }, { Buf: testChess, WMMoved: true, BMMoved: true, WKMoved: true, BKMoved: true, Index: 4, Moves: []*PositionPiece{{Index: 11}, {Index: 13}, {Index: 20}}, }, { Buf: testChess, Index: 2, Moves: []*PositionPiece{{Index: 9}, {Index: 11}, {Index: 10}}, }, { Buf: testChess, Index: 3, Moves: []*PositionPiece{{Index: 10}}, }, { Buf: testChess, Index: 4, Moves: []*PositionPiece{{Index: 11}, {Index: 13}}, }, { Buf: testChess, WMMoved: true, BMMoved: true, WKMoved: true, BKMoved: true, Index: 16, Moves: []*PositionPiece{{Index: 24}}, }, { Buf: testChess, WMMoved: true, BMMoved: true, WKMoved: true, BKMoved: true, Index: 18, Moves: []*PositionPiece{}, }, { Buf: testChess, WMMoved: true, BMMoved: true, WKMoved: true, BKMoved: true, Index: 21, Moves: []*PositionPiece{}, }, { Buf: testChess, WMMoved: true, BMMoved: true, WKMoved: true, BKMoved: true, Index: 23, Moves: []*PositionPiece{{Index: 31}}, }, { Buf: testChess, Index: 16, Moves: []*PositionPiece{{Index: 24}}, }, { Buf: testChess, Index: 18, Moves: []*PositionPiece{}, }, { Buf: testChess, Index: 21, Moves: []*PositionPiece{}, }, { Buf: testChess, Index: 23, Moves: []*PositionPiece{{Index: 31}}, }, { Buf: testChess, WMMoved: true, BMMoved: true, WKMoved: true, BKMoved: true, Index: 40, Moves: []*PositionPiece{}, }, { Buf: testChess, WMMoved: true, BMMoved: true, WKMoved: true, BKMoved: true, Index: 42, Moves: []*PositionPiece{{Index: 33}, {Index: 49}, {Index: 35}, {Index: 51}}, }, { Buf: testChess, WMMoved: true, BMMoved: true, WKMoved: true, BKMoved: true, Index: 43, Moves: []*PositionPiece{{Index: 53}, {Index: 37}, {Index: 49}, {Index: 33}, {Index: 60, P: BK}, {Index: 28}, {Index: 58, P: BS}, {Index: 26}}, }, { Buf: testChess, WMMoved: true, BMMoved: true, WKMoved: true, BKMoved: true, Index: 45, Moves: []*PositionPiece{{Index: 36}, {Index: 52}, {Index: 38}, {Index: 54}}, }, { Buf: testChess, WMMoved: true, BMMoved: true, WKMoved: true, BKMoved: true, Index: 47, Moves: []*PositionPiece{}, }, { Buf: testChess, Index: 40, Moves: []*PositionPiece{}, }, { Buf: testChess, Index: 42, Moves: []*PositionPiece{{Index: 33}, {Index: 49}, {Index: 35}, {Index: 51}}, }, { Buf: testChess, Index: 43, Moves: []*PositionPiece{{Index: 53}, {Index: 37}, {Index: 49}, {Index: 33}, {Index: 60, P: BK}, {Index: 28}, {Index: 58, P: BS}, {Index: 26}}, }, { Buf: testChess, Index: 45, Moves: []*PositionPiece{{Index: 36}, {Index: 52}, {Index: 38}, {Index: 54}}, }, { Buf: testChess, Index: 47, Moves: []*PositionPiece{}, }, { Buf: testChess, Index: 55, Moves: []*PositionPiece{{Index: 47, P: BP}, {Index: 63}, {Index: 54}, {Index: 53}, {Index: 52}, {Index: 51}, {Index: 50}, {Index: 49}, {Index: 48}}, }, { Buf: testChess, WMMoved: true, BMMoved: true, WKMoved: true, BKMoved: true, Index: 56, Moves: []*PositionPiece{}, }, { Buf: testChess, WMMoved: true, BMMoved: true, WKMoved: true, BKMoved: true, Index: 58, Moves: []*PositionPiece{}, }, { Buf: testChess, WMMoved: true, BMMoved: true, WKMoved: true, BKMoved: true, Index: 59, Moves: []*PositionPiece{}, }, { Buf: testChess, WMMoved: true, BMMoved: true, WKMoved: true, BKMoved: true, Index: 60, Moves: []*PositionPiece{}, }, { Buf: testChess, WMMoved: true, BMMoved: true, WKMoved: true, BKMoved: true, Index: 61, Moves: []*PositionPiece{}, }, { Buf: testChess, Index: 56, Moves: []*PositionPiece{}, }, { Buf: testChess, Index: 58, Moves: []*PositionPiece{}, }, { Buf: testChess, Index: 59, Moves: []*PositionPiece{}, }, { Buf: testChess, Index: 60, Moves: []*PositionPiece{}, }, { Buf: testChess, Index: 61, Moves: []*PositionPiece{}, }, } f := func(name string, moves []*PositionPiece) { b := strings.Builder{} for _, s := range moves { b.WriteString(fmt.Sprintf("%+v,", *s)) } fmt.Println(name, b.String()) } c := new(ChessJPZ) c.Init() //c.TestPrint() for _, v := range data { c.TestSet(v.Buf, nil, []bool{v.WKMoved, v.WMMoved, v.BMMoved, v.BKMoved}) moves := c.GetMovePositions(v.Index) if len(v.Moves) != len(moves) { c.TestPrint() fmt.Printf("Index:%v\n", v.Index) f("Target Moves:", v.Moves) f("Result Moves:", moves) t.Fatal() } for _, m := range moves { has := false for _, v := range v.Moves { if v.Index == m.Index && v.P == m.P { has = true break } } if !has { c.TestPrint() fmt.Printf("Index:%v\n", v.Index) f("Target Moves:", v.Moves) f("Result Moves:", moves) t.Fatal() } } } } func TestChessJPZ_GetMoveAllPositions(t *testing.T) { type Test struct { Buf []Piece WMMoved bool BMMoved bool WKMoved bool BKMoved bool WhiteMoves, BlackMoves [][2]*PositionPiece } data := []Test{ { Buf: []Piece{ "", "", "", "", BS, "", "", "", "", "", BM, "", "", "", BS, "", "", "", "", "", WK, "", "", "", "", "", BN, "", "", "", "", BR, "", WM, "", WR, WN, BP, "", "", "", "", BK, "", "", BP, "", WP, "", WR, "", "", "", "", "", "", WM, "", "", "", "", "", "", "", }, WhiteMoves: [][2]*PositionPiece{{{Index: 25, P: WM}, {Index: 34, P: BN}}, {{Index: 28, P: WN}, {Index: 34, P: BN}}}, BlackMoves: [][2]*PositionPiece{{{Index: 18, P: BK}, {Index: 27, P: WR}}}, }, } f := func(name string, moves [][2]*PositionPiece) { b := strings.Builder{} for _, s := range moves { b.WriteString(fmt.Sprintf("%+v,", *s[0])) b.WriteString(fmt.Sprintf("%+v,", *s[1])) } fmt.Println(name, b.String()) } c := new(ChessJPZ) c.Init() //c.TestPrint() for _, v := range data { c.TestSet(v.Buf, nil, []bool{v.WKMoved, v.WMMoved, v.BMMoved, v.BKMoved}) moves := c.GetMoveAllPositions(true) if len(v.WhiteMoves) != len(moves) { c.TestPrint() f("Target WhiteMoves:", v.WhiteMoves) f("Result WhiteMoves:", moves) t.Fatal() } for _, m := range moves { has := false for _, v := range v.WhiteMoves { if v[0].Index == m[0].Index && v[0].P == m[0].P && v[1].Index == m[1].Index && v[1].P == m[1].P { has = true break } } if !has { c.TestPrint() f("Target WhiteMoves:", v.WhiteMoves) f("Result WhiteMoves:", moves) t.Fatal() } } moves = c.GetMoveAllPositions(false) if len(v.BlackMoves) != len(moves) { c.TestPrint() f("Target BlackMoves:", v.BlackMoves) f("Result BlackMoves:", moves) t.Fatal() } for _, m := range moves { has := false for _, v := range v.BlackMoves { if v[0].Index == m[0].Index && v[0].P == m[0].P && v[1].Index == m[1].Index && v[1].P == m[1].P { has = true break } } if !has { c.TestPrint() f("Target BlackMoves:", v.BlackMoves) f("Result BlackMoves:", moves) t.Fatal() } } } } func TestChessJPZ_IsCheck(t *testing.T) { type Test struct { Buf []Piece WMMoved bool BMMoved bool WKMoved bool BKMoved bool Check [2]bool Checkmate [2]bool Stop [2]bool } data := []Test{ { Buf: []Piece{ BR, "", BS, BM, BK, BN, "", "", "", "", "", "", "", "", "", WR, BP, "", WM, WN, "", WM, "", BP, "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", WP, "", BP, "", "", BP, "", WP, "", "", "", "", "", "", "", "", "", "", WS, WK, WM, "", "", "", }, WMMoved: true, BMMoved: true, WKMoved: true, BKMoved: true, Check: [2]bool{true, false}, Checkmate: [2]bool{true, false}, Stop: [2]bool{false, true}, }, { Buf: []Piece{ BR, "", BS, BM, BK, BN, "", "", "", "", "", "", "", "", "", WR, BP, "", WM, WN, "", WM, "", BP, "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", WP, "", BP, "", "", BP, "", WP, "", "", "", "", "", "", "", "", "", "", WS, WK, WM, "", "", "", }, Check: [2]bool{true, false}, Checkmate: [2]bool{true, false}, Stop: [2]bool{false, true}, }, { Buf: []Piece{ "", "", "", "", BS, "", "", "", "", "", BM, "", "", "", BS, "", "", "", "", "", WK, "", "", "", "", "", BN, "", "", "", "", BR, "", WM, "", WR, WN, BP, "", "", "", "", BK, "", "", BP, "", WP, "", WR, "", "", "", "", "", "", WM, "", "", "", "", "", "", "", }, Check: [2]bool{true, true}, Checkmate: [2]bool{false, false}, Stop: [2]bool{false, false}, }, { Buf: []Piece{ "", "", "", "", BS, "", "", "", "", "", BM, "", "", "", BS, "", "", BK, "", "", WK, "", "", "", "", "", BP, "", "", "", "", BR, "", "", WP, "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", }, Check: [2]bool{false, false}, Checkmate: [2]bool{false, false}, Stop: [2]bool{true, false}, }, { Buf: []Piece{ "", "", "", "", WR, "", WR, "", "", "", BM, BR, "", BK, "", "", "", "", "", "", "", "", "", "", "", "", "", "", WN, "", WP, "", "", "", "", BP, "", "", "", "", "", "", BS, "", WP, "", WS, "", "", "", WS, "", WK, "", BM, "", "", "", "", "", WM, "", "", "", }, Check: [2]bool{true, false}, Checkmate: [2]bool{true, false}, Stop: [2]bool{false, true}, }, } c := new(ChessJPZ) c.Init() //c.TestPrint() for _, v := range data { c.TestSet(v.Buf, nil, []bool{v.WKMoved, v.WMMoved, v.BMMoved, v.BKMoved}) if v.Check[0] != c.IsCheck(true) || v.Check[1] != c.IsCheck(false) { c.TestPrint() fmt.Println("Target Check:", v.Check) fmt.Println("Result Check:", c.IsCheck(true), c.IsCheck(false)) t.Fatal() } if v.Checkmate[0] != c.IsCheckmate(true) || v.Checkmate[1] != c.IsCheckmate(false) { c.TestPrint() fmt.Println("Target Checkmate:", v.Checkmate) fmt.Println("Result Checkmate:", c.IsCheckmate(true), c.IsCheckmate(false)) t.Fatal() } if v.Stop[0] != c.IsStop(true) || v.Stop[1] != c.IsStop(false) { c.TestPrint() fmt.Println("Target Stop:", v.Stop) fmt.Println("Result Stop:", c.IsStop(true), c.IsStop(false)) t.Fatal() } } }