github.com/gorgonia/agogo@v0.1.1/game/wq/wq_test.go (about)

     1  package 围碁
     2  
     3  import (
     4  	"fmt"
     5  	"testing"
     6  
     7  	"github.com/gorgonia/agogo/game"
     8  )
     9  
    10  func sqrt(a int) int {
    11  	if a == 0 || a == 1 {
    12  		return a
    13  	}
    14  	start := 1
    15  	end := a / 2
    16  	var retVal int
    17  	for start <= end {
    18  		mid := (start + end) / 2
    19  		sq := mid * mid
    20  		if sq == a {
    21  			return mid
    22  		}
    23  		if sq < a {
    24  			start = mid + 1
    25  			retVal = mid
    26  		} else {
    27  			end = mid - 1
    28  		}
    29  	}
    30  	return retVal
    31  }
    32  
    33  var applyTests = []struct {
    34  	board      []game.Colour
    35  	move       game.PlayerMove
    36  	board2     []game.Colour // nil if invalid
    37  	taken      byte
    38  	whiteScore float32
    39  	blackScore float32
    40  	willErr    bool
    41  }{
    42  	// placing on an empty
    43  	{
    44  		board: []game.Colour{
    45  			None, None, None,
    46  			None, None, None,
    47  			None, None, None,
    48  		},
    49  		move: game.PlayerMove{game.Player(Black), game.Single(4)}, // {1, 1}
    50  		board2: []game.Colour{
    51  			None, None, None,
    52  			None, Black, None,
    53  			None, None, None,
    54  		},
    55  		taken:      0,
    56  		blackScore: 3, // TODO: CHECK
    57  		willErr:    false,
    58  	},
    59  
    60  	// basic capture
    61  	// · O ·
    62  	// O X O
    63  	// · · ·
    64  	//
    65  	// becomes:
    66  	//
    67  	// · O ·
    68  	// O · O
    69  	// · O ·
    70  	{
    71  		board: []game.Colour{
    72  			None, White, None,
    73  			White, Black, White,
    74  			None, None, None,
    75  		},
    76  		move: game.PlayerMove{game.Player(White), game.Single(7)}, // {2, 1}
    77  		board2: []game.Colour{
    78  			None, White, None,
    79  			White, None, White,
    80  			None, White, None,
    81  		},
    82  		taken:      1,
    83  		whiteScore: 6, // TODO: CHECK
    84  		willErr:    false,
    85  	},
    86  
    87  	// group capture
    88  	// Note the extra column on the right is because we use sqrt to determine board size
    89  	// · O · ·
    90  	// O X O ·
    91  	// O X O ·
    92  	// · · · ·
    93  	//
    94  	// becomes:
    95  	//
    96  	// · O · ·
    97  	// O · O ·
    98  	// O · O ·
    99  	// · O · ·
   100  	{
   101  		board: []game.Colour{
   102  			None, White, None, None,
   103  			White, Black, White, None,
   104  			White, Black, White, None,
   105  			None, None, None, None,
   106  		},
   107  		move: game.PlayerMove{game.Player(White), game.Single(13)}, // {3, 1}
   108  		board2: []game.Colour{
   109  			None, White, None, None,
   110  			White, None, White, None,
   111  			White, None, White, None,
   112  			None, White, None, None,
   113  		},
   114  		taken:      2,
   115  		whiteScore: 9, // TODO: CHECK
   116  		willErr:    false,
   117  	},
   118  
   119  	// edge case (literally AT THE EDGE)
   120  	// · · · ·
   121  	// · · · ·
   122  	// · X X ·
   123  	// X O O ·
   124  	//
   125  	// becomes:
   126  	//
   127  	// · · · ·
   128  	// · · · ·
   129  	// · X X ·
   130  	// X · · X
   131  	{
   132  		board: []game.Colour{
   133  			None, None, None, None,
   134  			None, None, None, None,
   135  			None, Black, Black, None,
   136  			Black, White, White, None,
   137  		},
   138  		move: game.PlayerMove{game.Player(Black), game.Single(15)}, // {3, 3}
   139  		board2: []game.Colour{
   140  			None, None, None, None,
   141  			None, None, None, None,
   142  			None, Black, Black, None,
   143  			Black, None, None, Black,
   144  		},
   145  		taken:      2,
   146  		blackScore: 4, // TODO: CHECK -  this should just be 2 unless my understanding of Go (the game) is wrong
   147  		willErr:    false,
   148  	},
   149  
   150  	// Suicide
   151  	// · X ·
   152  	// X · X
   153  	// · X ·
   154  	//
   155  	// Disallowed:
   156  	// · X ·
   157  	// X O X
   158  	// · X ·
   159  	{
   160  		board: []game.Colour{
   161  			None, White, None,
   162  			White, None, White,
   163  			None, White, None,
   164  		},
   165  		move:    game.PlayerMove{game.Player(Black), game.Single(4)}, // {1, 1}
   166  		board2:  nil,
   167  		taken:   0,
   168  		willErr: true,
   169  	},
   170  
   171  	// impossible move
   172  	{
   173  		board: []game.Colour{
   174  			None, None, None,
   175  			None, None, None,
   176  			None, None, None,
   177  		},
   178  		move:    game.PlayerMove{game.Player(Black), game.Single(15)}, // {3, 3}
   179  		board2:  nil,
   180  		taken:   0,
   181  		willErr: true,
   182  	},
   183  
   184  	// impossible colour
   185  	{
   186  		board: []game.Colour{
   187  			None, None, None,
   188  			None, None, None,
   189  			None, None, None,
   190  		},
   191  		move:    game.PlayerMove{game.Player(None), game.Single(15)}, // {3, 3}
   192  		board2:  nil,
   193  		taken:   0,
   194  		willErr: true,
   195  	},
   196  }
   197  
   198  func TestBoard_Apply(t *testing.T) {
   199  	for testID, at := range applyTests {
   200  		size := sqrt(len(at.board))
   201  		board := newBoard(size)
   202  		data := board.data
   203  		copy(data, at.board)
   204  
   205  		taken, err := board.Apply(at.move)
   206  
   207  		switch {
   208  		case at.willErr && err == nil:
   209  			t.Errorf("Expected an error for \n%s", board)
   210  			continue
   211  		case at.willErr && err != nil:
   212  			// expected an error
   213  			continue
   214  		case !at.willErr && err != nil:
   215  			t.Errorf("err %v", err)
   216  			continue
   217  		}
   218  
   219  		if taken != at.taken {
   220  			t.Errorf("Test %d: Expected %d to be taken. Got %d instead", testID, at.taken, taken)
   221  		}
   222  
   223  		for i, v := range data {
   224  			if v != at.board2[i] {
   225  				t.Errorf("Board failure:\n%s", board)
   226  			}
   227  		}
   228  
   229  		whiteScore := board.Score(WhiteP)
   230  		blackScore := board.Score(BlackP)
   231  		if whiteScore != at.whiteScore {
   232  			t.Errorf("Expected White Score %v. Got %v. Board\n%s", at.whiteScore, whiteScore, board)
   233  		}
   234  		if blackScore != at.blackScore {
   235  			t.Errorf("Expected Black Score %v. Got %v. Board\n%s", at.blackScore, blackScore, board)
   236  		}
   237  	}
   238  }
   239  
   240  func TestCloneEq(t *testing.T) {
   241  	board := newBoard(3)
   242  	if !board.Eq(board) {
   243  		t.Fatal("Failed basic equality")
   244  	}
   245  	// clone a clean board for later
   246  	board3 := board.Clone()
   247  	board.Apply(game.PlayerMove{game.Player(Black), game.Single(2)})
   248  	board.Apply(game.PlayerMove{game.Player(White), game.Single(4)})
   249  
   250  	board2 := board.Clone()
   251  	if board2 == board {
   252  		t.Errorf("Cloning should not yield the same address")
   253  	}
   254  	if &board.data[0] == &board2.data[0] {
   255  		t.Errorf("Cloning should not yield the same underlying backing")
   256  	}
   257  	if !board.Eq(board2) {
   258  		t.Fatal("Cloning failed")
   259  	}
   260  
   261  	board.Reset()
   262  	if !board.Eq(board3) {
   263  		t.Fatalf("Reset board should be the same as newBoard\n%s\n%s", board, board3)
   264  	}
   265  }
   266  
   267  func TestBoard_Format(t *testing.T) {
   268  	b := newBoard(7)
   269  	b.it[1][1] = White
   270  	b.it[3][3] = Black
   271  	b.it[1][5] = White
   272  	b.it[5][5] = Black
   273  	s := fmt.Sprintf("%s", b)
   274  	t.Logf("\n%v", s)
   275  }