...

Source file src/code.rocketnine.space/tslocum/joker-cribbage/score_test.go

Documentation: code.rocketnine.space/tslocum/joker-cribbage

     1  package cribbage
     2  
     3  import (
     4  	"testing"
     5  
     6  	. "code.rocketnine.space/tslocum/joker"
     7  )
     8  
     9  var (
    10  	testHandA = Cards{
    11  		Card{Face2, SuitSpades},
    12  		Card{Face3, SuitSpades},
    13  		Card{Face4, SuitSpades},
    14  		Card{Face5, SuitSpades}}
    15  	testHandB = Cards{
    16  		Card{FaceJack, SuitHearts},
    17  		Card{Face5, SuitDiamonds},
    18  		Card{Face5, SuitClubs},
    19  		Card{Face5, SuitSpades}}
    20  	testHandC = Cards{
    21  		Card{Face3, SuitHearts},
    22  		Card{Face3, SuitDiamonds},
    23  		Card{Face3, SuitClubs},
    24  		Card{Face3, SuitSpades}}
    25  	testHandD = Cards{
    26  		Card{Face5, SuitHearts},
    27  		Card{Face5, SuitDiamonds},
    28  		Card{Face5, SuitClubs},
    29  		Card{Face5, SuitSpades}}
    30  	testHandE = Cards{
    31  		Card{Face7, SuitHearts},
    32  		Card{Face8, SuitHearts},
    33  		Card{Face9, SuitHearts},
    34  		Card{Face10, SuitHearts}}
    35  	testHandF = Cards{
    36  		Card{Face3, SuitHearts},
    37  		Card{Face6, SuitHearts},
    38  		Card{Face5, SuitHearts},
    39  		Card{Face4, SuitHearts}}
    40  	testHandG = Cards{
    41  		Card{Face6, SuitHearts},
    42  		Card{Face5, SuitHearts},
    43  		Card{Face4, SuitHearts}}
    44  	testHandH = Cards{
    45  		Card{FaceAce, SuitHearts},
    46  		Card{Face3, SuitHearts},
    47  		Card{Face2, SuitHearts},
    48  		Card{Face4, SuitHearts}}
    49  	testHandI = Cards{
    50  		Card{FaceAce, SuitHearts},
    51  		Card{Face3, SuitHearts},
    52  		Card{FaceAce, SuitClubs},
    53  		Card{Face2, SuitHearts},
    54  		Card{Face4, SuitHearts},
    55  		Card{Face7, SuitHearts}}
    56  	testHandJ = Cards{
    57  		Card{Face7, SuitHearts},
    58  		Card{Face3, SuitHearts},
    59  		Card{Face2, SuitHearts},
    60  		Card{Face4, SuitHearts}}
    61  	testHandK = Cards{
    62  		Card{Face5, SuitHearts},
    63  		Card{Face5, SuitDiamonds},
    64  		Card{Face5, SuitClubs},
    65  		Card{FaceJack, SuitSpades}}
    66  	testHandL = Cards{
    67  		Card{Face2, SuitHearts},
    68  		Card{Face2, SuitDiamonds},
    69  		Card{Face7, SuitClubs},
    70  		Card{Face7, SuitSpades}}
    71  	testHandM = Cards{
    72  		Card{Face5, SuitHearts},
    73  		Card{Face5, SuitDiamonds},
    74  		Card{Face5, SuitClubs},
    75  		Card{FaceKing, SuitSpades}}
    76  )
    77  
    78  type expectedPegScore struct {
    79  	Hand Cards
    80  
    81  	Result []ScoreResult
    82  }
    83  
    84  var expectedPegScores = []expectedPegScore{
    85  	{testHandA, []ScoreResult{
    86  		{Type: ScoreRun, Points: 4, Cards: Cards{
    87  			Card{Face2, SuitSpades},
    88  			Card{Face3, SuitSpades},
    89  			Card{Face4, SuitSpades},
    90  			Card{Face5, SuitSpades}}}}},
    91  	{testHandB, []ScoreResult{
    92  		{Type: ScorePair, Points: 6, Cards: Cards{
    93  			Card{Face5, SuitDiamonds},
    94  			Card{Face5, SuitClubs},
    95  			Card{Face5, SuitSpades}}}}},
    96  	{testHandC, []ScoreResult{
    97  		{Type: ScorePair, Points: 12, Cards: Cards{
    98  			Card{Face3, SuitHearts},
    99  			Card{Face3, SuitDiamonds},
   100  			Card{Face3, SuitClubs},
   101  			Card{Face3, SuitSpades}}}}},
   102  	{testHandF, []ScoreResult{
   103  		{Type: ScoreRun, Points: 4, Cards: Cards{
   104  			Card{Face3, SuitHearts},
   105  			Card{Face4, SuitHearts},
   106  			Card{Face5, SuitHearts},
   107  			Card{Face6, SuitHearts}}}}},
   108  	{testHandG, []ScoreResult{
   109  		{Type: Score15, Points: 2, Cards: Cards{
   110  			Card{Face4, SuitHearts},
   111  			Card{Face5, SuitHearts},
   112  			Card{Face6, SuitHearts}}},
   113  		{Type: ScoreRun, Points: 3, Cards: Cards{
   114  			Card{Face4, SuitHearts},
   115  			Card{Face5, SuitHearts},
   116  			Card{Face6, SuitHearts}}}}},
   117  	{testHandH, []ScoreResult{
   118  		{Type: ScoreRun, Points: 4, Cards: Cards{
   119  			Card{FaceAce, SuitHearts},
   120  			Card{Face2, SuitHearts},
   121  			Card{Face3, SuitHearts},
   122  			Card{Face4, SuitHearts}}}}},
   123  	{testHandI, []ScoreResult{}},
   124  	{testHandJ, []ScoreResult{
   125  		{Type: ScoreRun, Points: 3}}},
   126  	{testHandK, []ScoreResult{}},
   127  	{testHandL, []ScoreResult{
   128  		{Type: ScorePair, Points: 2, Cards: Cards{
   129  			Card{Face7, SuitClubs},
   130  			Card{Face7, SuitSpades}}}}},
   131  	{testHandM, []ScoreResult{}},
   132  }
   133  
   134  type expectedShowScore struct {
   135  	Starter Card
   136  	Hand    Cards
   137  
   138  	HandResult []ScoreResult
   139  	CribResult []ScoreResult
   140  }
   141  
   142  var expectedShowScores = []expectedShowScore{
   143  	{Card{FaceAce, SuitSpades},
   144  		testHandA, []ScoreResult{
   145  			{Type: Score15, Points: 2, Cards: Cards{
   146  				Card{FaceAce, SuitSpades},
   147  				Card{Face2, SuitSpades},
   148  				Card{Face3, SuitSpades},
   149  				Card{Face4, SuitSpades},
   150  				Card{Face5, SuitSpades}}},
   151  			{Type: ScoreRun, Points: 5, Cards: Cards{
   152  				Card{FaceAce, SuitSpades},
   153  				Card{Face2, SuitSpades},
   154  				Card{Face3, SuitSpades},
   155  				Card{Face4, SuitSpades},
   156  				Card{Face5, SuitSpades}}},
   157  			{Type: ScoreFlush, Points: 5, Cards: Cards{
   158  				Card{FaceAce, SuitSpades},
   159  				Card{Face2, SuitSpades},
   160  				Card{Face3, SuitSpades},
   161  				Card{Face4, SuitSpades},
   162  				Card{Face5, SuitSpades}}},
   163  		}, []ScoreResult{
   164  			{Type: Score15, Points: 2, Cards: Cards{
   165  				Card{FaceAce, SuitSpades},
   166  				Card{Face2, SuitSpades},
   167  				Card{Face3, SuitSpades},
   168  				Card{Face4, SuitSpades},
   169  				Card{Face5, SuitSpades}}},
   170  			{Type: ScoreRun, Points: 5, Cards: Cards{
   171  				Card{FaceAce, SuitSpades},
   172  				Card{Face2, SuitSpades},
   173  				Card{Face3, SuitSpades},
   174  				Card{Face4, SuitSpades},
   175  				Card{Face5, SuitSpades}}},
   176  			{Type: ScoreFlush, Points: 5, Cards: Cards{
   177  				Card{FaceAce, SuitSpades},
   178  				Card{Face2, SuitSpades},
   179  				Card{Face3, SuitSpades},
   180  				Card{Face4, SuitSpades},
   181  				Card{Face5, SuitSpades}}},
   182  		}},
   183  
   184  	{Card{FaceKing, SuitClubs},
   185  		testHandA, []ScoreResult{
   186  			{Type: Score15, Points: 2, Cards: Cards{
   187  				Card{Face5, SuitSpades},
   188  				Card{FaceKing, SuitClubs}}},
   189  			{Type: Score15, Points: 2, Cards: Cards{
   190  				Card{Face2, SuitSpades},
   191  				Card{Face3, SuitSpades},
   192  				Card{FaceKing, SuitClubs}}},
   193  			{Type: ScoreRun, Points: 4, Cards: Cards{
   194  				Card{Face2, SuitSpades},
   195  				Card{Face3, SuitSpades},
   196  				Card{Face4, SuitSpades},
   197  				Card{Face5, SuitSpades}}},
   198  			{Type: ScoreFlush, Points: 4, Cards: Cards{
   199  				Card{Face2, SuitSpades},
   200  				Card{Face3, SuitSpades},
   201  				Card{Face4, SuitSpades},
   202  				Card{Face5, SuitSpades}}},
   203  		}, []ScoreResult{
   204  			{Type: Score15, Points: 2, Cards: Cards{
   205  				Card{Face5, SuitSpades},
   206  				Card{FaceKing, SuitClubs}}},
   207  			{Type: Score15, Points: 2, Cards: Cards{
   208  				Card{Face2, SuitSpades},
   209  				Card{Face3, SuitSpades},
   210  				Card{FaceKing, SuitClubs}}},
   211  			{Type: ScoreRun, Points: 4, Cards: Cards{
   212  				Card{Face2, SuitSpades},
   213  				Card{Face3, SuitSpades},
   214  				Card{Face4, SuitSpades},
   215  				Card{Face5, SuitSpades}}},
   216  		}},
   217  
   218  	{Card{Face8, SuitClubs},
   219  		testHandE, []ScoreResult{
   220  			{Type: Score15, Points: 2, Cards: Cards{
   221  				Card{Face7, SuitHearts},
   222  				Card{Face8, SuitHearts}}},
   223  			{Type: Score15, Points: 2, Cards: Cards{
   224  				Card{Face7, SuitHearts},
   225  				Card{Face8, SuitClubs}}},
   226  			{Type: ScorePair, Points: 2, Cards: Cards{
   227  				Card{Face8, SuitHearts},
   228  				Card{Face8, SuitClubs}}},
   229  			{Type: ScoreRun, Points: 4, Cards: Cards{
   230  				Card{Face7, SuitHearts},
   231  				Card{Face8, SuitHearts},
   232  				Card{Face9, SuitHearts},
   233  				Card{Face10, SuitHearts}}},
   234  			{Type: ScoreRun, Points: 4, Cards: Cards{
   235  				Card{Face7, SuitHearts},
   236  				Card{Face8, SuitClubs},
   237  				Card{Face9, SuitHearts},
   238  				Card{Face10, SuitHearts}}},
   239  			{Type: ScoreFlush, Points: 4, Cards: Cards{
   240  				Card{Face7, SuitHearts},
   241  				Card{Face8, SuitHearts},
   242  				Card{Face9, SuitHearts},
   243  				Card{Face10, SuitHearts}}},
   244  		}, []ScoreResult{
   245  			{Type: Score15, Points: 2, Cards: Cards{
   246  				Card{Face7, SuitHearts},
   247  				Card{Face8, SuitHearts}}},
   248  			{Type: Score15, Points: 2, Cards: Cards{
   249  				Card{Face7, SuitHearts},
   250  				Card{Face8, SuitClubs}}},
   251  			{Type: ScorePair, Points: 2, Cards: Cards{
   252  				Card{Face8, SuitHearts},
   253  				Card{Face8, SuitClubs}}},
   254  			{Type: ScoreRun, Points: 4, Cards: Cards{
   255  				Card{Face7, SuitHearts},
   256  				Card{Face8, SuitHearts},
   257  				Card{Face9, SuitHearts},
   258  				Card{Face10, SuitHearts}}},
   259  			{Type: ScoreRun, Points: 4, Cards: Cards{
   260  				Card{Face7, SuitHearts},
   261  				Card{Face8, SuitClubs},
   262  				Card{Face9, SuitHearts},
   263  				Card{Face10, SuitHearts}}},
   264  		}},
   265  
   266  	{Card{Face5, SuitSpades},
   267  		testHandK, []ScoreResult{
   268  			{Type: Score15, Points: 2, Cards: Cards{
   269  				Card{Face5, SuitHearts},
   270  				Card{FaceJack, SuitSpades}}},
   271  			{Type: Score15, Points: 2, Cards: Cards{
   272  				Card{Face5, SuitDiamonds},
   273  				Card{FaceJack, SuitSpades}}},
   274  			{Type: Score15, Points: 2, Cards: Cards{
   275  				Card{Face5, SuitClubs},
   276  				Card{FaceJack, SuitSpades}}},
   277  			{Type: Score15, Points: 2, Cards: Cards{
   278  				Card{Face5, SuitSpades},
   279  				Card{FaceJack, SuitSpades}}},
   280  			{Type: Score15, Points: 2, Cards: Cards{
   281  				Card{Face5, SuitHearts},
   282  				Card{Face5, SuitDiamonds},
   283  				Card{Face5, SuitClubs}}},
   284  			{Type: Score15, Points: 2, Cards: Cards{
   285  				Card{Face5, SuitHearts},
   286  				Card{Face5, SuitDiamonds},
   287  				Card{Face5, SuitSpades}}},
   288  			{Type: Score15, Points: 2, Cards: Cards{
   289  				Card{Face5, SuitHearts},
   290  				Card{Face5, SuitClubs},
   291  				Card{Face5, SuitSpades}}},
   292  			{Type: Score15, Points: 2, Cards: Cards{
   293  				Card{Face5, SuitDiamonds},
   294  				Card{Face5, SuitClubs},
   295  				Card{Face5, SuitSpades}}},
   296  			{Type: ScorePair, Points: 12, Cards: Cards{
   297  				Card{Face5, SuitHearts},
   298  				Card{Face5, SuitDiamonds},
   299  				Card{Face5, SuitClubs},
   300  				Card{Face5, SuitSpades}}},
   301  			{Type: ScoreNobs, Points: 1, Cards: Cards{
   302  				Card{FaceJack, SuitSpades}}},
   303  		}, []ScoreResult{
   304  			{Type: Score15, Points: 2, Cards: Cards{
   305  				Card{Face5, SuitHearts},
   306  				Card{FaceJack, SuitSpades}}},
   307  			{Type: Score15, Points: 2, Cards: Cards{
   308  				Card{Face5, SuitDiamonds},
   309  				Card{FaceJack, SuitSpades}}},
   310  			{Type: Score15, Points: 2, Cards: Cards{
   311  				Card{Face5, SuitClubs},
   312  				Card{FaceJack, SuitSpades}}},
   313  			{Type: Score15, Points: 2, Cards: Cards{
   314  				Card{Face5, SuitSpades},
   315  				Card{FaceJack, SuitSpades}}},
   316  			{Type: Score15, Points: 2, Cards: Cards{
   317  				Card{Face5, SuitHearts},
   318  				Card{Face5, SuitDiamonds},
   319  				Card{Face5, SuitClubs}}},
   320  			{Type: Score15, Points: 2, Cards: Cards{
   321  				Card{Face5, SuitHearts},
   322  				Card{Face5, SuitDiamonds},
   323  				Card{Face5, SuitSpades}}},
   324  			{Type: Score15, Points: 2, Cards: Cards{
   325  				Card{Face5, SuitHearts},
   326  				Card{Face5, SuitClubs},
   327  				Card{Face5, SuitSpades}}},
   328  			{Type: Score15, Points: 2, Cards: Cards{
   329  				Card{Face5, SuitDiamonds},
   330  				Card{Face5, SuitClubs},
   331  				Card{Face5, SuitSpades}}},
   332  			{Type: ScorePair, Points: 12, Cards: Cards{
   333  				Card{Face5, SuitHearts},
   334  				Card{Face5, SuitDiamonds},
   335  				Card{Face5, SuitClubs},
   336  				Card{Face5, SuitSpades}}},
   337  			{Type: ScoreNobs, Points: 1, Cards: Cards{
   338  				Card{FaceJack, SuitSpades}}},
   339  		}},
   340  
   341  	{Card{Face5, SuitSpades},
   342  		testHandM, []ScoreResult{
   343  			{Type: Score15, Points: 2, Cards: Cards{
   344  				Card{Face5, SuitHearts},
   345  				Card{FaceKing, SuitSpades}}},
   346  			{Type: Score15, Points: 2, Cards: Cards{
   347  				Card{Face5, SuitDiamonds},
   348  				Card{FaceKing, SuitSpades}}},
   349  			{Type: Score15, Points: 2, Cards: Cards{
   350  				Card{Face5, SuitClubs},
   351  				Card{FaceKing, SuitSpades}}},
   352  			{Type: Score15, Points: 2, Cards: Cards{
   353  				Card{Face5, SuitSpades},
   354  				Card{FaceKing, SuitSpades}}},
   355  			{Type: Score15, Points: 2, Cards: Cards{
   356  				Card{Face5, SuitHearts},
   357  				Card{Face5, SuitDiamonds},
   358  				Card{Face5, SuitClubs}}},
   359  			{Type: Score15, Points: 2, Cards: Cards{
   360  				Card{Face5, SuitHearts},
   361  				Card{Face5, SuitDiamonds},
   362  				Card{Face5, SuitSpades}}},
   363  			{Type: Score15, Points: 2, Cards: Cards{
   364  				Card{Face5, SuitHearts},
   365  				Card{Face5, SuitClubs},
   366  				Card{Face5, SuitSpades}}},
   367  			{Type: Score15, Points: 2, Cards: Cards{
   368  				Card{Face5, SuitDiamonds},
   369  				Card{Face5, SuitClubs},
   370  				Card{Face5, SuitSpades}}},
   371  			{Type: ScorePair, Points: 12, Cards: Cards{
   372  				Card{Face5, SuitHearts},
   373  				Card{Face5, SuitDiamonds},
   374  				Card{Face5, SuitClubs},
   375  				Card{Face5, SuitSpades}}},
   376  		}, []ScoreResult{
   377  			{Type: Score15, Points: 2, Cards: Cards{
   378  				Card{Face5, SuitHearts},
   379  				Card{FaceKing, SuitSpades}}},
   380  			{Type: Score15, Points: 2, Cards: Cards{
   381  				Card{Face5, SuitDiamonds},
   382  				Card{FaceKing, SuitSpades}}},
   383  			{Type: Score15, Points: 2, Cards: Cards{
   384  				Card{Face5, SuitClubs},
   385  				Card{FaceKing, SuitSpades}}},
   386  			{Type: Score15, Points: 2, Cards: Cards{
   387  				Card{Face5, SuitSpades},
   388  				Card{FaceKing, SuitSpades}}},
   389  			{Type: Score15, Points: 2, Cards: Cards{
   390  				Card{Face5, SuitHearts},
   391  				Card{Face5, SuitDiamonds},
   392  				Card{Face5, SuitClubs}}},
   393  			{Type: Score15, Points: 2, Cards: Cards{
   394  				Card{Face5, SuitHearts},
   395  				Card{Face5, SuitDiamonds},
   396  				Card{Face5, SuitSpades}}},
   397  			{Type: Score15, Points: 2, Cards: Cards{
   398  				Card{Face5, SuitHearts},
   399  				Card{Face5, SuitClubs},
   400  				Card{Face5, SuitSpades}}},
   401  			{Type: Score15, Points: 2, Cards: Cards{
   402  				Card{Face5, SuitDiamonds},
   403  				Card{Face5, SuitClubs},
   404  				Card{Face5, SuitSpades}}},
   405  			{Type: ScorePair, Points: 12, Cards: Cards{
   406  				Card{Face5, SuitHearts},
   407  				Card{Face5, SuitDiamonds},
   408  				Card{Face5, SuitClubs},
   409  				Card{Face5, SuitSpades}}},
   410  		}},
   411  }
   412  
   413  func TestScorePeg(t *testing.T) {
   414  	t.Parallel()
   415  
   416  	for i, expected := range expectedPegScores {
   417  		if Sum(expected.Hand) > 31 {
   418  			t.Errorf("case %d: invalid peg hand sum: got %d, want <=31: %s", i, Sum(expected.Hand), expected.Hand)
   419  		}
   420  
   421  		pegPoints, pegResult := Score(Peg, expected.Hand, Card{})
   422  
   423  		if !resultsEqual(pegResult, expected.Result) {
   424  			t.Fatalf("case %d: incorrect peg result: got %s, want %s: %s", i, pegResult, expected.Result, expected.Hand)
   425  		}
   426  
   427  		var expectedPoints int
   428  		for _, r := range expected.Result {
   429  			expectedPoints += r.Points
   430  		}
   431  		if pegPoints != expectedPoints {
   432  			t.Fatalf("case %d: incorrect peg score: got %d, want %d: %s", i, pegPoints, expectedPoints, expected.Hand)
   433  		}
   434  	}
   435  }
   436  
   437  func TestScoreShowHand(t *testing.T) {
   438  	t.Parallel()
   439  
   440  	var expectedPoints int
   441  	for i, expected := range expectedShowScores {
   442  		handPoints, handResult := Score(ShowHand, expected.Hand, expected.Starter)
   443  
   444  		if !resultsEqual(handResult, expected.HandResult) {
   445  			t.Fatalf("case %d: incorrect hand result: got %s, want %s: %s - %s", i, handResult, expected.HandResult, expected.Starter, expected.Hand)
   446  		}
   447  
   448  		expectedPoints = 0
   449  		for _, r := range expected.HandResult {
   450  			expectedPoints += r.Points
   451  		}
   452  		if handPoints != expectedPoints {
   453  			t.Fatalf("case %d: incorrect hand score: got %d, want %d: %s - %s", i, handPoints, expectedPoints, expected.Starter, expected.Hand)
   454  		}
   455  	}
   456  }
   457  
   458  func TestScoreShowCrib(t *testing.T) {
   459  	t.Parallel()
   460  
   461  	var expectedPoints int
   462  	for i, expected := range expectedShowScores {
   463  		cribPoints, cribResult := Score(ShowCrib, expected.Hand, expected.Starter)
   464  
   465  		if !resultsEqual(cribResult, expected.CribResult) {
   466  			t.Fatalf("case %d: incorrect crib result: got %s, want %s: %s - %s", i, cribResult, expected.CribResult, expected.Starter, expected.Hand)
   467  		}
   468  
   469  		expectedPoints = 0
   470  		for _, r := range expected.CribResult {
   471  			expectedPoints += r.Points
   472  		}
   473  		if cribPoints != expectedPoints {
   474  			t.Fatalf("case %d: incorrect crib score: got %d, want %d: %s - %s", i, cribPoints, expectedPoints, expected.Starter, expected.Hand)
   475  		}
   476  	}
   477  }
   478  
   479  func BenchmarkScorePeg(b *testing.B) {
   480  	var (
   481  		score   int
   482  		results ScoreResults
   483  	)
   484  	b.ResetTimer()
   485  	for i := 0; i < b.N; i++ {
   486  		for _, expected := range expectedPegScores {
   487  			score, results = Score(Peg, expected.Hand, Card{})
   488  		}
   489  	}
   490  	_, _ = score, results
   491  }
   492  
   493  func BenchmarkScoreShowHand(b *testing.B) {
   494  	var (
   495  		score   int
   496  		results ScoreResults
   497  	)
   498  	b.ResetTimer()
   499  	for i := 0; i < b.N; i++ {
   500  		for _, expected := range expectedShowScores {
   501  			score, results = Score(ShowHand, expected.Hand, expected.Starter)
   502  		}
   503  	}
   504  	_, _ = score, results
   505  }
   506  
   507  func BenchmarkScoreShowCrib(b *testing.B) {
   508  	var (
   509  		score   int
   510  		results ScoreResults
   511  	)
   512  	b.ResetTimer()
   513  	for i := 0; i < b.N; i++ {
   514  		for _, expected := range expectedShowScores {
   515  			score, results = Score(ShowCrib, expected.Hand, expected.Starter)
   516  		}
   517  	}
   518  	_, _ = score, results
   519  }
   520  
   521  func resultsEqual(a []ScoreResult, b []ScoreResult) bool {
   522  	if len(a) != len(b) {
   523  		return false
   524  	}
   525  
   526  	for i := range a {
   527  		if a[i].Type != b[i].Type {
   528  			return false
   529  		} else if a[i].Points != b[i].Points {
   530  			return false
   531  		} else if len(a[i].Cards) != len(b[i].Cards) {
   532  			return false
   533  		}
   534  
   535  		for j := range a[i].Cards {
   536  			if !a[i].Cards[j].Equal(b[i].Cards[j]) {
   537  				return false
   538  			}
   539  		}
   540  	}
   541  
   542  	return true
   543  }
   544  

View as plain text