...

Source file src/code.rocketnine.space/tslocum/tabula/board_test.go

Documentation: code.rocketnine.space/tslocum/tabula

     1  package tabula
     2  
     3  import (
     4  	"fmt"
     5  	"testing"
     6  )
     7  
     8  func TestMoveBackgammon(t *testing.T) {
     9  	b := NewBoard(VariantBackgammon)
    10  	b[SpaceRoll1] = 1
    11  	b[SpaceRoll2] = 2
    12  	got, expected := b[24], int8(2)
    13  	if got != expected {
    14  		t.Errorf("unexpected space %d value: expected %d: got %d", 24, expected, got)
    15  	}
    16  	got, expected = b[22], 0
    17  	if got != expected {
    18  		t.Errorf("unexpected space %d value: expected %d: got %d", 22, expected, got)
    19  	}
    20  	bc := b.Move(24, 23, 1)
    21  	got, expected = b[24], int8(2)
    22  	if got != expected {
    23  		t.Errorf("unexpected space %d value: expected %d: got %d", 24, expected, got)
    24  	}
    25  	got, expected = bc[23], int8(1)
    26  	if got != expected {
    27  		t.Errorf("unexpected space %d value: expected %d: got %d", 23, expected, got)
    28  	}
    29  	got, expected = bc[24], 1
    30  	if got != expected {
    31  		t.Errorf("unexpected space %d value: expected %d: got %d", 24, expected, got)
    32  	}
    33  	got, expected = bc[22], 0
    34  	if got != expected {
    35  		t.Errorf("unexpected space %d value: expected %d: got %d", 22, expected, got)
    36  	}
    37  }
    38  
    39  func TestMoveTabula(t *testing.T) {
    40  	{
    41  		b := NewBoard(VariantTabula)
    42  		b[SpaceRoll1] = 1
    43  		b[SpaceRoll2] = 2
    44  
    45  		bc := b.Move(SpaceHomePlayer, 23, 1)
    46  		got, expected := bc[SpaceHomePlayer], int8(14)
    47  		if got != expected {
    48  			t.Errorf("unexpected space %d value: expected %d: got %d", SpaceHomePlayer, expected, got)
    49  		}
    50  		got, expected = bc[23], int8(1)
    51  		if got != expected {
    52  			t.Errorf("unexpected space %d value: expected %d: got %d", 23, expected, got)
    53  		}
    54  		bc = bc.Move(SpaceHomePlayer, 22, 1)
    55  		got, expected = bc[SpaceHomePlayer], int8(13)
    56  		if got != expected {
    57  			t.Errorf("unexpected space %d value: expected %d: got %d", SpaceHomePlayer, expected, got)
    58  		}
    59  		got, expected = bc[22], int8(1)
    60  		if got != expected {
    61  			t.Errorf("unexpected space %d value: expected %d: got %d", 22, expected, got)
    62  		}
    63  	}
    64  
    65  	{
    66  		b := Board{0, 1, 2, 3, 4, 4, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -15, 0, 0, 0, 0, 1, 0, 2}
    67  		b[SpaceRoll1] = 1
    68  		b[SpaceRoll2] = 2
    69  
    70  		bc := b.UseRoll(1, 2, 1).Move(1, 2, 1)
    71  		got, expected := bc[1], int8(0)
    72  		if got != expected {
    73  			t.Errorf("unexpected space %d value: expected %d: got %d", 1, expected, got)
    74  		}
    75  		got, expected = bc[2], int8(3)
    76  		if got != expected {
    77  			t.Errorf("unexpected space %d value: expected %d: got %d", 2, expected, got)
    78  		}
    79  
    80  		if !bc.HaveRoll(5, 7, 1) {
    81  			t.Errorf("unexpected have roll value: expected %v: got %v", false, true)
    82  		}
    83  
    84  		if bc.HaveRoll(12, 13, 1) {
    85  			t.Errorf("unexpected have roll value: expected %v: got %v", false, true)
    86  		}
    87  
    88  		if !bc.HaveRoll(12, 14, 1) {
    89  			t.Errorf("unexpected have roll value: expected %v: got %v", true, true)
    90  		}
    91  	}
    92  
    93  	{
    94  		b := Board{1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -15, 0, 0, 0, 0, 0, 0, 2}
    95  		b[SpaceRoll1] = 1
    96  		b[SpaceRoll2] = 2
    97  
    98  		if b.HaveRoll(12, 13, 1) {
    99  			t.Errorf("unexpected have roll value: expected %v: got %v", false, true)
   100  		}
   101  
   102  		bc := b.UseRoll(0, 1, 1).Move(0, 1, 1)
   103  		got, expected := bc[0], int8(0)
   104  		if got != expected {
   105  			t.Errorf("unexpected space %d value: expected %d: got %d", 0, expected, got)
   106  		}
   107  		got, expected = bc[1], int8(1)
   108  		if got != expected {
   109  			t.Errorf("unexpected space %d value: expected %d: got %d", 1, expected, got)
   110  		}
   111  
   112  		if bc.HaveRoll(12, 13, 1) {
   113  			t.Errorf("unexpected have roll value: expected %v: got %v", false, false)
   114  		}
   115  
   116  		if !bc.HaveRoll(12, 14, 1) {
   117  			t.Errorf("unexpected have roll value: expected %v: got %v", true, false)
   118  		}
   119  	}
   120  
   121  	{
   122  		b := Board{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -15, 0, 0, 0, 0, 0, 0, 1, 0, 2}
   123  		b[SpaceRoll1] = 1
   124  		b[SpaceRoll2] = 2
   125  
   126  		if !b.HaveRoll(12, 14, 1) {
   127  			t.Errorf("unexpected have roll value: expected %v: got %v", true, false)
   128  		}
   129  
   130  		if b.MayBearOff(1) {
   131  			t.Errorf("unexpected bear off value: expected %v: got %v", false, true)
   132  		}
   133  
   134  		b = b.Move(12, 14, 1).UseRoll(12, 14, 1)
   135  		got, expected := b[12], int8(0)
   136  		if got != expected {
   137  			t.Errorf("unexpected space %d value: expected %d: got %d", 12, expected, got)
   138  		}
   139  		got, expected = b[14], int8(1)
   140  		if got != expected {
   141  			t.Errorf("unexpected space %d value: expected %d: got %d", 14, expected, got)
   142  		}
   143  
   144  		if !b.MayBearOff(1) {
   145  			t.Errorf("unexpected bear off value: expected %v: got %v", true, false)
   146  		}
   147  
   148  		if !b.HaveRoll(14, 15, 1) {
   149  			t.Errorf("unexpected have roll value: expected %v: got %v", true, false)
   150  		}
   151  
   152  		if b.HaveRoll(14, 16, 1) {
   153  			t.Errorf("unexpected have roll value: expected %v: got %v", false, true)
   154  		}
   155  	}
   156  
   157  	{
   158  		b := Board{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, -15, 0, 0, 0, 0, 0, 0, 1, 0, 2}
   159  		b[SpaceRoll1] = 1
   160  		b[SpaceRoll2] = 2
   161  
   162  		if !b.HaveRoll(12, 14, 1) {
   163  			t.Errorf("unexpected have roll value: expected %v: got %v", true, false)
   164  		}
   165  
   166  		if b.MayBearOff(1) {
   167  			t.Errorf("unexpected bear off value: expected %v: got %v", false, true)
   168  		}
   169  
   170  		if b.HaveRoll(24, 0, 1) {
   171  			t.Errorf("unexpected have roll value: expected %v: got %v", false, true)
   172  		}
   173  
   174  		b = b.UseRoll(12, 14, 1).Move(12, 14, 1)
   175  		got, expected := b[12], int8(0)
   176  		if got != expected {
   177  			t.Errorf("unexpected space %d value: expected %d: got %d", 12, expected, got)
   178  		}
   179  		got, expected = b[14], int8(1)
   180  		if got != expected {
   181  			t.Errorf("unexpected space %d value: expected %d: got %d", 14, expected, got)
   182  		}
   183  
   184  		if !b.MayBearOff(1) {
   185  			t.Errorf("unexpected bear off value: expected %v: got %v", true, false)
   186  		}
   187  
   188  		if !b.HaveRoll(24, 0, 1) {
   189  			t.Errorf("unexpected have roll value: expected %v: got %v", true, false)
   190  		}
   191  	}
   192  }
   193  
   194  func TestPastBackgammon(t *testing.T) {
   195  	b := NewBoard(VariantBackgammon)
   196  	got, expected := b.Past(), false
   197  	if got != expected {
   198  		t.Errorf("unexpected past value: expected %v: got %v", expected, got)
   199  	}
   200  
   201  	b = Board{0, 1, 3, -1, 0, -1, 0, -2, 0, 0, -1, 0, -3, 3, 0, 0, 0, -2, 0, -5, 4, 0, 2, 2, 0, 0, 0, 0, 5, 5, 5, 5, 1, 1, 0}
   202  	got, expected = b.Past(), false
   203  	if got != expected {
   204  		t.Errorf("unexpected past value: expected %v: got %v", expected, got)
   205  	}
   206  
   207  	b = Board{0, -1, 1, -2, -1, 2, 4, 0, 0, 0, 0, 0, -1, 2, -1, 0, 0, -1, 3, -3, 0, 3, -1, -3, -1, 0, 0, 0, 4, 3, 0, 0, 1, 1, 0}
   208  	got, expected = b.Past(), false
   209  	if got != expected {
   210  		t.Errorf("unexpected past value: expected %v: got %v", expected, got)
   211  	}
   212  
   213  	b = Board{7, 2, 2, 4, 0, -2, 0, 0, -1, 0, -1, 0, 0, 0, 0, 0, -1, -1, 0, -4, 0, -2, -1, -1, -1, 0, 0, 0, 6, 2, 0, 0, 1, 1, 0}
   214  	got, expected = b.Past(), true
   215  	if got != expected {
   216  		t.Errorf("unexpected past value: expected %v: got %v", expected, got)
   217  	}
   218  }
   219  
   220  func TestPastAcey(t *testing.T) {
   221  	b := NewBoard(VariantAceyDeucey)
   222  	got, expected := b.Past(), false
   223  	if got != expected {
   224  		t.Errorf("unexpected past value: expected %v: got %v", expected, got)
   225  	}
   226  
   227  	b = Board{0, 1, 3, -1, 0, -1, 0, -2, 0, 0, -1, 0, -3, 3, 0, 0, 0, -2, 0, -5, 4, 0, 2, 2, 0, 0, 0, 0, 5, 5, 5, 5, 1, 1, 1}
   228  	got, expected = b.Past(), false
   229  	if got != expected {
   230  		t.Errorf("unexpected past value: expected %v: got %v", expected, got)
   231  	}
   232  
   233  	b = Board{0, -1, 1, -2, -1, 2, 4, 0, 0, 0, 0, 0, -1, 2, -1, 0, 0, -1, 3, -3, 0, 3, -1, -3, -1, 0, 0, 0, 4, 3, 0, 0, 1, 1, 1}
   234  	got, expected = b.Past(), false
   235  	if got != expected {
   236  		t.Errorf("unexpected past value: expected %v: got %v", expected, got)
   237  	}
   238  
   239  	b = Board{7, 2, 2, 4, 0, -2, 0, 0, -1, 0, -1, 0, 0, 0, 0, 0, -1, -1, 0, -4, 0, -2, -1, -1, -1, 0, 0, 0, 6, 2, 0, 0, 0, 1, 1}
   240  	got, expected = b.Past(), false
   241  	if got != expected {
   242  		t.Errorf("unexpected past value: expected %v: got %v", expected, got)
   243  	}
   244  
   245  	b = Board{7, 2, 2, 4, 0, -2, 0, 0, -1, 0, -1, 0, 0, 0, 0, 0, -1, -1, 0, -4, 0, -2, -1, -1, -1, 0, 0, 0, 6, 2, 0, 0, 1, 1, 1}
   246  	got, expected = b.Past(), true
   247  	if got != expected {
   248  		t.Errorf("unexpected past value: expected %v: got %v", expected, got)
   249  	}
   250  }
   251  
   252  func TestPastTabula(t *testing.T) {
   253  	b := NewBoard(VariantTabula)
   254  	got, expected := b.Past(), false
   255  	if got != expected {
   256  		t.Errorf("unexpected past value: expected %v: got %v", expected, got)
   257  	}
   258  
   259  	b = Board{0, 1, 3, -1, 0, -1, 0, -2, 0, 0, -1, 0, -3, 3, 0, 0, 0, -2, 0, -5, 4, 0, 2, 2, 0, 0, 0, 0, 5, 5, 5, 5, 1, 1, 2}
   260  	got, expected = b.Past(), false
   261  	if got != expected {
   262  		t.Errorf("unexpected past value: expected %v: got %v", expected, got)
   263  	}
   264  
   265  	b = Board{0, -1, 1, -2, -1, 2, 4, 0, 0, 0, 0, 0, -1, 2, -1, 0, 0, -1, 3, -3, 0, 3, -1, -3, -1, 0, 0, 0, 4, 3, 0, 0, 1, 1, 2}
   266  	got, expected = b.Past(), false
   267  	if got != expected {
   268  		t.Errorf("unexpected past value: expected %v: got %v", expected, got)
   269  	}
   270  
   271  	b = Board{7, 2, 2, 4, 0, -2, 0, 0, -1, 0, -1, 0, 0, 0, 0, 0, -1, -1, 0, -4, 0, -2, -1, -1, -1, 0, 0, 0, 6, 2, 0, 0, 1, 1, 2}
   272  	got, expected = b.Past(), false
   273  	if got != expected {
   274  		t.Errorf("unexpected past value: expected %v: got %v", expected, got)
   275  	}
   276  }
   277  
   278  func TestBlots(t *testing.T) {
   279  	b := NewBoard(VariantBackgammon)
   280  	got, expected := b.Blots(1), 0
   281  	if got != expected {
   282  		t.Errorf("unexpected blots value: expected %v: got %v", expected, got)
   283  	}
   284  	got, expected = b.Blots(2), 0
   285  	if got != expected {
   286  		t.Errorf("unexpected blots value: expected %v: got %v", expected, got)
   287  	}
   288  
   289  	b = b.Move(24, 23, 1)
   290  
   291  	got, expected = b.Blots(1), 19
   292  	if got != expected {
   293  		t.Errorf("unexpected blots value: expected %v: got %v", expected, got)
   294  	}
   295  	got, expected = b.Blots(2), 0
   296  	if got != expected {
   297  		t.Errorf("unexpected blots value: expected %v: got %v", expected, got)
   298  	}
   299  
   300  	b = b.Move(1, 2, 2)
   301  
   302  	got, expected = b.Blots(1), 19
   303  	if got != expected {
   304  		t.Errorf("unexpected blots value: expected %v: got %v", expected, got)
   305  	}
   306  	got, expected = b.Blots(2), 19
   307  	if got != expected {
   308  		t.Errorf("unexpected blots value: expected %v: got %v", expected, got)
   309  	}
   310  }
   311  
   312  func TestHitScore(t *testing.T) {
   313  	b := Board{0, 0, -2, -2, -2, 4, 0, -1, 0, 0, -2, 4, 0, -2, -1, 0, -2, 4, 0, 2, 0, 0, 0, 0, -1, 0, 1, 0, 4, 1, 0, 0, 1, 1, 1}
   314  	available, _ := b.Available(1)
   315  	analysis := make([]*Analysis, 0, AnalysisBufferSize)
   316  	b.Analyze(available, &analysis)
   317  
   318  	var reached bool
   319  	minHitScore := 200
   320  	for _, a := range analysis {
   321  		if a.hitScore >= minHitScore {
   322  			reached = true
   323  			break
   324  		}
   325  	}
   326  	if !reached {
   327  		t.Errorf("unexpected hit score for analysis: expected hit score of at least %d", minHitScore)
   328  	}
   329  }
   330  
   331  func TestAnalyze(t *testing.T) {
   332  	b := NewBoard(VariantBackgammon)
   333  	b = b.Move(24, 23, 1)
   334  	b = b.Move(1, 2, 2)
   335  	b[SpaceRoll1], b[SpaceRoll2] = 1, 2
   336  
   337  	available, _ := b.Available(1)
   338  	analysis := make([]*Analysis, 0, AnalysisBufferSize)
   339  	b.Analyze(available, &analysis)
   340  	var blots int
   341  	for _, r := range analysis {
   342  		blots += r.Blots
   343  	}
   344  	if blots <= 0 {
   345  		t.Errorf("expected >0 blots in results, got %d", blots)
   346  	}
   347  
   348  	type testCase struct {
   349  		roll1, roll2, roll3, roll4 int8
   350  	}
   351  	cases := []*testCase{
   352  		{1, 1, 1, 1},
   353  		{2, 2, 2, 2},
   354  		{3, 3, 3, 3},
   355  		{4, 4, 4, 4},
   356  		{5, 5, 5, 5},
   357  		{6, 6, 6, 6},
   358  		{1, 2, 0, 0},
   359  		{2, 3, 0, 0},
   360  		{3, 4, 0, 0},
   361  		{4, 5, 0, 0},
   362  		{5, 6, 0, 0},
   363  	}
   364  	for _, c := range cases {
   365  		t.Run(fmt.Sprintf("%d-%d", c.roll1, c.roll2), func(t *testing.T) {
   366  			board := NewBoard(VariantBackgammon)
   367  			board[SpaceRoll1] = c.roll1
   368  			board[SpaceRoll2] = c.roll2
   369  			board[SpaceRoll3] = c.roll3
   370  			board[SpaceRoll4] = c.roll4
   371  			available, _ := board.Available(1)
   372  
   373  			board.Analyze(available, &analysis)
   374  		})
   375  	}
   376  }
   377  
   378  func BenchmarkAvailable(b *testing.B) {
   379  	type testCase struct {
   380  		roll1, roll2, roll3, roll4 int8
   381  	}
   382  	cases := []*testCase{
   383  		{1, 1, 1, 1},
   384  		{2, 2, 2, 2},
   385  		{3, 3, 3, 3},
   386  		{4, 4, 4, 4},
   387  		{5, 5, 5, 5},
   388  		{6, 6, 6, 6},
   389  		{1, 2, 0, 0},
   390  		{2, 3, 0, 0},
   391  		{3, 4, 0, 0},
   392  		{4, 5, 0, 0},
   393  		{5, 6, 0, 0},
   394  	}
   395  	for _, c := range cases {
   396  		b.Run(fmt.Sprintf("%d-%d", c.roll1, c.roll2), func(b *testing.B) {
   397  			board := NewBoard(VariantBackgammon)
   398  			board[SpaceRoll1] = c.roll1
   399  			board[SpaceRoll2] = c.roll2
   400  			board[SpaceRoll3] = c.roll3
   401  			board[SpaceRoll4] = c.roll4
   402  
   403  			var available [][4][2]int8
   404  			b.ResetTimer()
   405  			for i := 0; i < b.N; i++ {
   406  				available, _ = board.Available(1)
   407  			}
   408  
   409  			_ = available
   410  		})
   411  	}
   412  }
   413  
   414  func BenchmarkAnalyze(b *testing.B) {
   415  	type testCase struct {
   416  		roll1, roll2, roll3, roll4 int8
   417  	}
   418  	cases := []*testCase{
   419  		{1, 1, 1, 1},
   420  		{2, 2, 2, 2},
   421  		{3, 3, 3, 3},
   422  		{4, 4, 4, 4},
   423  		{5, 5, 5, 5},
   424  		{6, 6, 6, 6},
   425  		{1, 2, 0, 0},
   426  		{2, 3, 0, 0},
   427  		{3, 4, 0, 0},
   428  		{4, 5, 0, 0},
   429  		{5, 6, 0, 0},
   430  	}
   431  	for _, c := range cases {
   432  		b.Run(fmt.Sprintf("%d-%d", c.roll1, c.roll2), func(b *testing.B) {
   433  			board := NewBoard(VariantBackgammon)
   434  			board[SpaceRoll1] = c.roll1
   435  			board[SpaceRoll2] = c.roll2
   436  			board[SpaceRoll3] = c.roll3
   437  			board[SpaceRoll4] = c.roll4
   438  			available, _ := board.Available(1)
   439  			analysis := make([]*Analysis, 0, AnalysisBufferSize)
   440  
   441  			b.ResetTimer()
   442  			for i := 0; i < b.N; i++ {
   443  				board.Analyze(available, &analysis)
   444  			}
   445  
   446  			_ = analysis
   447  		})
   448  	}
   449  }
   450  
   451  func BenchmarkChooseDoubles(b *testing.B) {
   452  	board := Board{0, -2, -2, -3, -1, -2, -3, 0, -2, 0, 0, 0, 0, 0, 0, 0, 2, 4, 0, 2, 2, 5, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 1, 1, 1}
   453  	analysis := make([]*Analysis, 0, AnalysisBufferSize)
   454  
   455  	var doubles int
   456  	b.ResetTimer()
   457  	for i := 0; i < b.N; i++ {
   458  		doubles = board.ChooseDoubles(&analysis)
   459  	}
   460  	_ = doubles
   461  }
   462  
   463  func BenchmarkMayBearOff(b *testing.B) {
   464  	board := NewBoard(VariantBackgammon)
   465  
   466  	var allowed bool
   467  	b.ResetTimer()
   468  	for i := 0; i < b.N; i++ {
   469  		allowed = board.MayBearOff(1)
   470  	}
   471  
   472  	_ = allowed
   473  }
   474  

View as plain text