shufflecom-calculations 1.2.1 → 1.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,5 +1,5 @@
1
1
  import BigNumber from 'bignumber.js';
2
- import { Blackjack, BlackjackAction, InsuranceStatus, PerfectPairType, SettleBetVars, TwentyOnePlusThreeType } from './blackjack';
2
+ import { Blackjack, BlackjackAction, HandOutcome, InsuranceStatus, PerfectPairType, SettleBetVars, TwentyOnePlusThreeType } from './blackjack';
3
3
  import { CardGames, CardValue, Suits, suitsArr } from './cardGames';
4
4
 
5
5
  const getIndex = (value: CardValue) => CardGames.getCardIndexFromDetails({ suit: suitsArr[Math.floor(Math.random() * 4)], value });
@@ -232,21 +232,41 @@ describe('Blackjack', () => {
232
232
  });
233
233
 
234
234
  it('calculate main bet payout correctly, accounting for blackjacks after splitting', () => {
235
- const funcParams: Array<{ input: [number[], number[], boolean]; output: BigNumber }> = [
236
- { input: [[getIndex('4'), getIndex('5')], [getIndex('A'), getIndex('10')], false], output: new BigNumber(2.5) },
237
- { input: [[getIndex('9'), getIndex('10')], [getIndex('10'), getIndex('A')], false], output: new BigNumber(2.5) },
238
- { input: [[getIndex('9'), getIndex('10')], [getIndex('10'), getIndex('A')], true], output: new BigNumber(2) },
239
- { input: [[getIndex('10'), getIndex('A')], [], false], output: new BigNumber(0) },
240
- { input: [[getIndex('10'), getIndex('A')], [getIndex('J'), getIndex('A')], false], output: new BigNumber(1) },
241
- { input: [[getIndex('8'), getIndex('A')], [getIndex('J'), getIndex('10'), getIndex('9')], false], output: new BigNumber(0) },
242
- { input: [[getIndex('8'), getIndex('10'), getIndex('9')], [getIndex('J'), getIndex('2'), getIndex('5')], false], output: new BigNumber(2) },
243
- { input: [[getIndex('8'), getIndex('10')], [getIndex('J'), getIndex('2'), getIndex('5')], false], output: new BigNumber(0) },
244
- { input: [[getIndex('8'), getIndex('10')], [getIndex('J'), getIndex('3'), getIndex('5')], false], output: new BigNumber(1) },
245
- { input: [[getIndex('8'), getIndex('10')], [getIndex('J'), getIndex('4'), getIndex('5')], false], output: new BigNumber(2) },
235
+ const funcParams: Array<{ input: [number[], number[], boolean]; output: ReturnType<typeof Blackjack.getHandOutcome> }> = [
236
+ {
237
+ input: [[getIndex('4'), getIndex('5')], [getIndex('A'), getIndex('10')], false],
238
+ output: { multiplier: new BigNumber(2.5), outcome: HandOutcome.BLACKJACK },
239
+ },
240
+ {
241
+ input: [[getIndex('9'), getIndex('10')], [getIndex('10'), getIndex('A')], false],
242
+ output: { multiplier: new BigNumber(2.5), outcome: HandOutcome.BLACKJACK },
243
+ },
244
+ { input: [[getIndex('9'), getIndex('10')], [getIndex('10'), getIndex('A')], true], output: { multiplier: new BigNumber(2), outcome: HandOutcome.WIN } },
245
+ { input: [[getIndex('10'), getIndex('A')], [], false], output: { multiplier: new BigNumber(0), outcome: HandOutcome.LOSS } },
246
+ { input: [[getIndex('10'), getIndex('A')], [getIndex('J'), getIndex('A')], false], output: { multiplier: new BigNumber(1), outcome: HandOutcome.PUSH } },
247
+ {
248
+ input: [[getIndex('8'), getIndex('A')], [getIndex('J'), getIndex('10'), getIndex('9')], false],
249
+ output: { multiplier: new BigNumber(0), outcome: HandOutcome.LOSS },
250
+ },
251
+ {
252
+ input: [[getIndex('6'), getIndex('10'), getIndex('9')], [getIndex('J'), getIndex('2'), getIndex('5')], false],
253
+ output: { multiplier: new BigNumber(2), outcome: HandOutcome.WIN },
254
+ },
255
+ {
256
+ input: [[getIndex('8'), getIndex('10')], [getIndex('J'), getIndex('2'), getIndex('5')], false],
257
+ output: { multiplier: new BigNumber(0), outcome: HandOutcome.LOSS },
258
+ },
259
+ {
260
+ input: [[getIndex('8'), getIndex('10')], [getIndex('J'), getIndex('3'), getIndex('5')], false],
261
+ output: { multiplier: new BigNumber(1), outcome: HandOutcome.PUSH },
262
+ },
263
+ {
264
+ input: [[getIndex('8'), getIndex('10')], [getIndex('J'), getIndex('4'), getIndex('5')], false],
265
+ output: { multiplier: new BigNumber(2), outcome: HandOutcome.WIN },
266
+ },
246
267
  ];
247
268
  funcParams.forEach((param) => {
248
- const result = Blackjack.calcMainBetMultiplier(...param.input);
249
- expect(result).toEqual(param.output);
269
+ expect(Blackjack.getHandOutcome(...param.input)).toStrictEqual(param.output);
250
270
  });
251
271
 
252
272
  /**
@@ -546,7 +566,7 @@ describe('Blackjack', () => {
546
566
  });
547
567
 
548
568
  it('can calculate the total payout correctly', () => {
549
- const funcParams: Array<{ input: SettleBetVars; output: BigNumber }> = [
569
+ const funcParams: Array<{ input: SettleBetVars; output: ReturnType<typeof Blackjack.getGameOutcome> }> = [
550
570
  // Without sidebets
551
571
  // blackjack win
552
572
  {
@@ -554,14 +574,15 @@ describe('Blackjack', () => {
554
574
  mainPlayerHand: [getIndex('A'), getIndex('10')],
555
575
  splitPlayerHand: [],
556
576
  dealerHand: [getIndex('10'), getIndex('10')],
557
- mainHandBetAmount: new BigNumber(10),
558
- splitHandBetAmount: new BigNumber(0),
577
+ mainBetAmount: new BigNumber(10),
559
578
  twentyOnePlusThreeAmount: new BigNumber(0),
560
579
  perfectPairAmount: new BigNumber(0),
561
580
  boughtInsurance: false,
562
581
  hasSplit: false,
582
+ mainHandDoubleDown: false,
583
+ splitHandDoubleDown: false,
563
584
  },
564
- output: new BigNumber(25),
585
+ output: { payout: new BigNumber(25), multiplier: new BigNumber(2.5), mainHandOutcome: HandOutcome.BLACKJACK, splitHandOutcome: HandOutcome.NONE },
565
586
  },
566
587
  // blackjack push
567
588
  {
@@ -569,14 +590,15 @@ describe('Blackjack', () => {
569
590
  mainPlayerHand: [getIndex('A'), getIndex('10')],
570
591
  splitPlayerHand: [],
571
592
  dealerHand: [getIndex('10'), getIndex('A')],
572
- mainHandBetAmount: new BigNumber(10),
573
- splitHandBetAmount: new BigNumber(0),
593
+ mainBetAmount: new BigNumber(10),
574
594
  twentyOnePlusThreeAmount: new BigNumber(0),
575
595
  perfectPairAmount: new BigNumber(0),
576
596
  boughtInsurance: false,
577
597
  hasSplit: false,
598
+ mainHandDoubleDown: false,
599
+ splitHandDoubleDown: false,
578
600
  },
579
- output: new BigNumber(10),
601
+ output: { payout: new BigNumber(10), multiplier: new BigNumber(1), mainHandOutcome: HandOutcome.PUSH, splitHandOutcome: HandOutcome.NONE },
580
602
  },
581
603
  // blackjack lose
582
604
  {
@@ -584,14 +606,15 @@ describe('Blackjack', () => {
584
606
  mainPlayerHand: [getIndex('A'), getIndex('6')],
585
607
  splitPlayerHand: [],
586
608
  dealerHand: [getIndex('10'), getIndex('A')],
587
- mainHandBetAmount: new BigNumber(10),
588
- splitHandBetAmount: new BigNumber(0),
609
+ mainBetAmount: new BigNumber(10),
589
610
  twentyOnePlusThreeAmount: new BigNumber(0),
590
611
  perfectPairAmount: new BigNumber(0),
591
612
  boughtInsurance: false,
592
613
  hasSplit: false,
614
+ mainHandDoubleDown: false,
615
+ splitHandDoubleDown: false,
593
616
  },
594
- output: new BigNumber(0),
617
+ output: { payout: new BigNumber(0), multiplier: new BigNumber(0), mainHandOutcome: HandOutcome.LOSS, splitHandOutcome: HandOutcome.NONE },
595
618
  },
596
619
  // no blackjack win
597
620
  {
@@ -599,28 +622,30 @@ describe('Blackjack', () => {
599
622
  mainPlayerHand: [getIndex('A'), getIndex('6'), getIndex('4')],
600
623
  splitPlayerHand: [],
601
624
  dealerHand: [getIndex('10'), getIndex('4')],
602
- mainHandBetAmount: new BigNumber(10),
603
- splitHandBetAmount: new BigNumber(0),
625
+ mainBetAmount: new BigNumber(10),
604
626
  twentyOnePlusThreeAmount: new BigNumber(0),
605
627
  perfectPairAmount: new BigNumber(0),
606
628
  boughtInsurance: false,
607
629
  hasSplit: false,
630
+ mainHandDoubleDown: false,
631
+ splitHandDoubleDown: false,
608
632
  },
609
- output: new BigNumber(20),
633
+ output: { payout: new BigNumber(20), multiplier: new BigNumber(2), mainHandOutcome: HandOutcome.WIN, splitHandOutcome: HandOutcome.NONE },
610
634
  },
611
635
  {
612
636
  input: {
613
637
  mainPlayerHand: [getIndex('A'), getIndex('6'), getIndex('4')],
614
638
  splitPlayerHand: [],
615
639
  dealerHand: [getIndex('10'), getIndex('4'), getIndex('10')],
616
- mainHandBetAmount: new BigNumber(10),
617
- splitHandBetAmount: new BigNumber(0),
640
+ mainBetAmount: new BigNumber(10),
618
641
  twentyOnePlusThreeAmount: new BigNumber(0),
619
642
  perfectPairAmount: new BigNumber(0),
620
643
  boughtInsurance: false,
621
644
  hasSplit: false,
645
+ mainHandDoubleDown: false,
646
+ splitHandDoubleDown: false,
622
647
  },
623
- output: new BigNumber(20),
648
+ output: { payout: new BigNumber(20), multiplier: new BigNumber(2), mainHandOutcome: HandOutcome.WIN, splitHandOutcome: HandOutcome.NONE },
624
649
  },
625
650
  // no blackjack push
626
651
  {
@@ -628,28 +653,30 @@ describe('Blackjack', () => {
628
653
  mainPlayerHand: [getIndex('A'), getIndex('6')],
629
654
  splitPlayerHand: [],
630
655
  dealerHand: [getIndex('10'), getIndex('4'), getIndex('3')],
631
- mainHandBetAmount: new BigNumber(10),
632
- splitHandBetAmount: new BigNumber(0),
656
+ mainBetAmount: new BigNumber(10),
633
657
  twentyOnePlusThreeAmount: new BigNumber(0),
634
658
  perfectPairAmount: new BigNumber(0),
635
659
  boughtInsurance: false,
636
660
  hasSplit: false,
661
+ mainHandDoubleDown: false,
662
+ splitHandDoubleDown: false,
637
663
  },
638
- output: new BigNumber(10),
664
+ output: { payout: new BigNumber(10), multiplier: new BigNumber(1), mainHandOutcome: HandOutcome.PUSH, splitHandOutcome: HandOutcome.NONE },
639
665
  },
640
666
  {
641
667
  input: {
642
668
  mainPlayerHand: [getIndex('10'), getIndex('6'), getIndex('4')],
643
669
  splitPlayerHand: [],
644
670
  dealerHand: [getIndex('10'), getIndex('4'), getIndex('6')],
645
- mainHandBetAmount: new BigNumber(10),
646
- splitHandBetAmount: new BigNumber(0),
671
+ mainBetAmount: new BigNumber(10),
647
672
  twentyOnePlusThreeAmount: new BigNumber(0),
648
673
  perfectPairAmount: new BigNumber(0),
649
674
  boughtInsurance: false,
650
675
  hasSplit: false,
676
+ mainHandDoubleDown: false,
677
+ splitHandDoubleDown: false,
651
678
  },
652
- output: new BigNumber(10),
679
+ output: { payout: new BigNumber(10), multiplier: new BigNumber(1), mainHandOutcome: HandOutcome.PUSH, splitHandOutcome: HandOutcome.NONE },
653
680
  },
654
681
  // no blackjack lose
655
682
  {
@@ -657,28 +684,30 @@ describe('Blackjack', () => {
657
684
  mainPlayerHand: [getIndex('A'), getIndex('6')],
658
685
  splitPlayerHand: [],
659
686
  dealerHand: [getIndex('10'), getIndex('J')],
660
- mainHandBetAmount: new BigNumber(10),
661
- splitHandBetAmount: new BigNumber(0),
687
+ mainBetAmount: new BigNumber(10),
662
688
  twentyOnePlusThreeAmount: new BigNumber(0),
663
689
  perfectPairAmount: new BigNumber(0),
664
690
  boughtInsurance: false,
665
691
  hasSplit: false,
692
+ mainHandDoubleDown: false,
693
+ splitHandDoubleDown: false,
666
694
  },
667
- output: new BigNumber(0),
695
+ output: { payout: new BigNumber(0), multiplier: new BigNumber(0), mainHandOutcome: HandOutcome.LOSS, splitHandOutcome: HandOutcome.NONE },
668
696
  },
669
697
  {
670
698
  input: {
671
699
  mainPlayerHand: [getIndex('J'), getIndex('6'), getIndex('9')],
672
700
  splitPlayerHand: [],
673
701
  dealerHand: [getIndex('10'), getIndex('J')],
674
- mainHandBetAmount: new BigNumber(10),
675
- splitHandBetAmount: new BigNumber(0),
702
+ mainBetAmount: new BigNumber(10),
676
703
  twentyOnePlusThreeAmount: new BigNumber(0),
677
704
  perfectPairAmount: new BigNumber(0),
678
705
  boughtInsurance: false,
679
706
  hasSplit: false,
707
+ mainHandDoubleDown: false,
708
+ splitHandDoubleDown: false,
680
709
  },
681
- output: new BigNumber(0),
710
+ output: { payout: new BigNumber(0), multiplier: new BigNumber(0), mainHandOutcome: HandOutcome.LOSS, splitHandOutcome: HandOutcome.NONE },
682
711
  },
683
712
 
684
713
  {
@@ -689,14 +718,20 @@ describe('Blackjack', () => {
689
718
  ],
690
719
  splitPlayerHand: [],
691
720
  dealerHand: [CardGames.getCardIndexFromDetails({ suit: Suits.CLUBS, value: '10' }), getIndex('7')],
692
- mainHandBetAmount: new BigNumber(10),
693
- splitHandBetAmount: new BigNumber(0),
721
+ mainBetAmount: new BigNumber(10),
694
722
  twentyOnePlusThreeAmount: new BigNumber(10),
695
723
  perfectPairAmount: new BigNumber(20),
696
724
  boughtInsurance: false,
697
725
  hasSplit: false,
726
+ mainHandDoubleDown: false,
727
+ splitHandDoubleDown: false,
728
+ },
729
+ output: {
730
+ payout: new BigNumber(1550),
731
+ multiplier: new BigNumber(1550).dividedBy(40),
732
+ mainHandOutcome: HandOutcome.WIN,
733
+ splitHandOutcome: HandOutcome.NONE,
698
734
  },
699
- output: new BigNumber(1550), // 10 * 101 + 20 * 26 + 2 * 10
700
735
  },
701
736
  {
702
737
  input: {
@@ -706,14 +741,20 @@ describe('Blackjack', () => {
706
741
  CardGames.getCardIndexFromDetails({ suit: Suits.CLUBS, value: '10' }),
707
742
  CardGames.getCardIndexFromDetails({ suit: Suits.HEARTS, value: '10' }),
708
743
  ],
709
- mainHandBetAmount: new BigNumber(10),
710
- splitHandBetAmount: new BigNumber(0),
744
+ mainBetAmount: new BigNumber(10),
711
745
  twentyOnePlusThreeAmount: new BigNumber(0),
712
746
  perfectPairAmount: new BigNumber(10),
713
747
  boughtInsurance: false,
714
748
  hasSplit: false,
749
+ mainHandDoubleDown: false,
750
+ splitHandDoubleDown: false,
751
+ },
752
+ output: {
753
+ payout: new BigNumber(25),
754
+ multiplier: new BigNumber(25).dividedBy(20),
755
+ mainHandOutcome: HandOutcome.BLACKJACK,
756
+ splitHandOutcome: HandOutcome.NONE,
715
757
  },
716
- output: new BigNumber(25),
717
758
  },
718
759
  {
719
760
  input: {
@@ -723,14 +764,20 @@ describe('Blackjack', () => {
723
764
  ],
724
765
  splitPlayerHand: [],
725
766
  dealerHand: [CardGames.getCardIndexFromDetails({ suit: Suits.HEARTS, value: 'J' }), getIndex('A')],
726
- mainHandBetAmount: new BigNumber(10),
727
- splitHandBetAmount: new BigNumber(0),
767
+ mainBetAmount: new BigNumber(10),
728
768
  twentyOnePlusThreeAmount: new BigNumber(10),
729
769
  perfectPairAmount: new BigNumber(0),
730
770
  boughtInsurance: false,
731
771
  hasSplit: false,
772
+ mainHandDoubleDown: false,
773
+ splitHandDoubleDown: false,
774
+ },
775
+ output: {
776
+ payout: new BigNumber(60),
777
+ multiplier: new BigNumber(60).dividedBy(20),
778
+ mainHandOutcome: HandOutcome.LOSS,
779
+ splitHandOutcome: HandOutcome.NONE,
732
780
  },
733
- output: new BigNumber(60),
734
781
  },
735
782
 
736
783
  // With insurance
@@ -739,14 +786,20 @@ describe('Blackjack', () => {
739
786
  mainPlayerHand: [getIndex('A'), getIndex('10')],
740
787
  splitPlayerHand: [],
741
788
  dealerHand: [getIndex('A'), getIndex('3')],
742
- mainHandBetAmount: new BigNumber(10),
743
- splitHandBetAmount: new BigNumber(0),
789
+ mainBetAmount: new BigNumber(10),
744
790
  twentyOnePlusThreeAmount: new BigNumber(0),
745
791
  perfectPairAmount: new BigNumber(0),
746
792
  boughtInsurance: true,
747
793
  hasSplit: false,
794
+ mainHandDoubleDown: false,
795
+ splitHandDoubleDown: false,
796
+ },
797
+ output: {
798
+ payout: new BigNumber(25),
799
+ multiplier: new BigNumber(25).dividedBy(15),
800
+ mainHandOutcome: HandOutcome.BLACKJACK,
801
+ splitHandOutcome: HandOutcome.NONE,
748
802
  },
749
- output: new BigNumber(25),
750
803
  },
751
804
  // blackjack push
752
805
  {
@@ -754,14 +807,20 @@ describe('Blackjack', () => {
754
807
  mainPlayerHand: [getIndex('A'), getIndex('10')],
755
808
  splitPlayerHand: [],
756
809
  dealerHand: [getIndex('A'), getIndex('K')],
757
- mainHandBetAmount: new BigNumber(10),
758
- splitHandBetAmount: new BigNumber(0),
810
+ mainBetAmount: new BigNumber(10),
759
811
  twentyOnePlusThreeAmount: new BigNumber(0),
760
812
  perfectPairAmount: new BigNumber(0),
761
813
  boughtInsurance: true,
762
814
  hasSplit: false,
815
+ mainHandDoubleDown: false,
816
+ splitHandDoubleDown: false,
817
+ },
818
+ output: {
819
+ payout: new BigNumber(25),
820
+ multiplier: new BigNumber(25).dividedBy(15),
821
+ mainHandOutcome: HandOutcome.PUSH,
822
+ splitHandOutcome: HandOutcome.NONE,
763
823
  },
764
- output: new BigNumber(25),
765
824
  },
766
825
  // blackjack lose
767
826
  {
@@ -769,14 +828,15 @@ describe('Blackjack', () => {
769
828
  mainPlayerHand: [getIndex('A'), getIndex('6')],
770
829
  splitPlayerHand: [],
771
830
  dealerHand: [getIndex('A'), getIndex('J')],
772
- mainHandBetAmount: new BigNumber(10),
773
- splitHandBetAmount: new BigNumber(0),
831
+ mainBetAmount: new BigNumber(10),
774
832
  twentyOnePlusThreeAmount: new BigNumber(0),
775
833
  perfectPairAmount: new BigNumber(0),
776
834
  boughtInsurance: false,
777
835
  hasSplit: false,
836
+ mainHandDoubleDown: false,
837
+ splitHandDoubleDown: false,
778
838
  },
779
- output: new BigNumber(0),
839
+ output: { payout: new BigNumber(0), multiplier: new BigNumber(0), mainHandOutcome: HandOutcome.LOSS, splitHandOutcome: HandOutcome.NONE },
780
840
  },
781
841
 
782
842
  // With insurance and sidebets
@@ -788,14 +848,15 @@ describe('Blackjack', () => {
788
848
  ],
789
849
  splitPlayerHand: [],
790
850
  dealerHand: [getIndex('A'), getIndex('J')],
791
- mainHandBetAmount: new BigNumber(10),
792
- splitHandBetAmount: new BigNumber(0),
851
+ mainBetAmount: new BigNumber(10),
793
852
  twentyOnePlusThreeAmount: new BigNumber(0),
794
853
  perfectPairAmount: new BigNumber(0),
795
854
  boughtInsurance: true,
796
855
  hasSplit: false,
856
+ mainHandDoubleDown: false,
857
+ splitHandDoubleDown: false,
797
858
  },
798
- output: new BigNumber(15),
859
+ output: { payout: new BigNumber(15), multiplier: new BigNumber(1), mainHandOutcome: HandOutcome.LOSS, splitHandOutcome: HandOutcome.NONE },
799
860
  },
800
861
  {
801
862
  input: {
@@ -805,14 +866,20 @@ describe('Blackjack', () => {
805
866
  ],
806
867
  splitPlayerHand: [],
807
868
  dealerHand: [getIndex('A'), getIndex('9')],
808
- mainHandBetAmount: new BigNumber(10),
809
- splitHandBetAmount: new BigNumber(0),
869
+ mainBetAmount: new BigNumber(10),
810
870
  twentyOnePlusThreeAmount: new BigNumber(0),
811
871
  perfectPairAmount: new BigNumber(0),
812
872
  boughtInsurance: true,
813
873
  hasSplit: false,
874
+ mainHandDoubleDown: false,
875
+ splitHandDoubleDown: false,
876
+ },
877
+ output: {
878
+ payout: new BigNumber(10),
879
+ multiplier: new BigNumber(10).dividedBy(15),
880
+ mainHandOutcome: HandOutcome.PUSH,
881
+ splitHandOutcome: HandOutcome.NONE,
814
882
  },
815
- output: new BigNumber(10),
816
883
  },
817
884
 
818
885
  // Split bets without sidebets or insurance
@@ -828,14 +895,15 @@ describe('Blackjack', () => {
828
895
  CardGames.getCardIndexFromDetails({ suit: Suits.CLUBS, value: '7' }),
829
896
  ],
830
897
  dealerHand: [getIndex('6'), getIndex('10')],
831
- mainHandBetAmount: new BigNumber(10),
832
- splitHandBetAmount: new BigNumber(10),
898
+ mainBetAmount: new BigNumber(10),
833
899
  twentyOnePlusThreeAmount: new BigNumber(0),
834
900
  perfectPairAmount: new BigNumber(0),
835
901
  boughtInsurance: false,
836
902
  hasSplit: true,
903
+ mainHandDoubleDown: false,
904
+ splitHandDoubleDown: false,
837
905
  },
838
- output: new BigNumber(40),
906
+ output: { payout: new BigNumber(40), multiplier: new BigNumber(2), mainHandOutcome: HandOutcome.WIN, splitHandOutcome: HandOutcome.WIN },
839
907
  },
840
908
  // Split 1 win 1 push
841
909
  {
@@ -849,14 +917,15 @@ describe('Blackjack', () => {
849
917
  CardGames.getCardIndexFromDetails({ suit: Suits.CLUBS, value: '8' }),
850
918
  ],
851
919
  dealerHand: [getIndex('8'), getIndex('10')],
852
- mainHandBetAmount: new BigNumber(10),
853
- splitHandBetAmount: new BigNumber(10),
920
+ mainBetAmount: new BigNumber(10),
854
921
  twentyOnePlusThreeAmount: new BigNumber(0),
855
922
  perfectPairAmount: new BigNumber(0),
856
923
  boughtInsurance: false,
857
924
  hasSplit: true,
925
+ mainHandDoubleDown: false,
926
+ splitHandDoubleDown: false,
858
927
  },
859
- output: new BigNumber(30),
928
+ output: { payout: new BigNumber(30), multiplier: new BigNumber(1.5), mainHandOutcome: HandOutcome.WIN, splitHandOutcome: HandOutcome.PUSH },
860
929
  },
861
930
  // Split 1 win 1 lose
862
931
  {
@@ -870,14 +939,15 @@ describe('Blackjack', () => {
870
939
  CardGames.getCardIndexFromDetails({ suit: Suits.CLUBS, value: '5' }),
871
940
  ],
872
941
  dealerHand: [getIndex('8'), getIndex('10')],
873
- mainHandBetAmount: new BigNumber(10),
874
- splitHandBetAmount: new BigNumber(10),
942
+ mainBetAmount: new BigNumber(10),
875
943
  twentyOnePlusThreeAmount: new BigNumber(0),
876
944
  perfectPairAmount: new BigNumber(0),
877
945
  boughtInsurance: false,
878
946
  hasSplit: true,
947
+ mainHandDoubleDown: false,
948
+ splitHandDoubleDown: false,
879
949
  },
880
- output: new BigNumber(20),
950
+ output: { payout: new BigNumber(20), multiplier: new BigNumber(1), mainHandOutcome: HandOutcome.WIN, splitHandOutcome: HandOutcome.LOSS },
881
951
  },
882
952
  // Split 2 push
883
953
  {
@@ -891,14 +961,15 @@ describe('Blackjack', () => {
891
961
  CardGames.getCardIndexFromDetails({ suit: Suits.CLUBS, value: '10' }),
892
962
  ],
893
963
  dealerHand: [getIndex('10'), getIndex('10')],
894
- mainHandBetAmount: new BigNumber(10),
895
- splitHandBetAmount: new BigNumber(10),
964
+ mainBetAmount: new BigNumber(10),
896
965
  twentyOnePlusThreeAmount: new BigNumber(0),
897
966
  perfectPairAmount: new BigNumber(0),
898
967
  boughtInsurance: false,
899
968
  hasSplit: true,
969
+ mainHandDoubleDown: false,
970
+ splitHandDoubleDown: false,
900
971
  },
901
- output: new BigNumber(20),
972
+ output: { payout: new BigNumber(20), multiplier: new BigNumber(1), mainHandOutcome: HandOutcome.PUSH, splitHandOutcome: HandOutcome.PUSH },
902
973
  },
903
974
  // Split 1 push 1 lose
904
975
  {
@@ -912,14 +983,15 @@ describe('Blackjack', () => {
912
983
  CardGames.getCardIndexFromDetails({ suit: Suits.CLUBS, value: '5' }),
913
984
  ],
914
985
  dealerHand: [getIndex('10'), getIndex('7')],
915
- mainHandBetAmount: new BigNumber(10),
916
- splitHandBetAmount: new BigNumber(10),
986
+ mainBetAmount: new BigNumber(10),
917
987
  twentyOnePlusThreeAmount: new BigNumber(0),
918
988
  perfectPairAmount: new BigNumber(0),
919
989
  boughtInsurance: false,
920
990
  hasSplit: true,
991
+ mainHandDoubleDown: false,
992
+ splitHandDoubleDown: false,
921
993
  },
922
- output: new BigNumber(10),
994
+ output: { payout: new BigNumber(10), multiplier: new BigNumber(0.5), mainHandOutcome: HandOutcome.PUSH, splitHandOutcome: HandOutcome.LOSS },
923
995
  },
924
996
  // Split 2 lose
925
997
  {
@@ -933,14 +1005,15 @@ describe('Blackjack', () => {
933
1005
  CardGames.getCardIndexFromDetails({ suit: Suits.CLUBS, value: '8' }),
934
1006
  ],
935
1007
  dealerHand: [getIndex('10'), getIndex('10')],
936
- mainHandBetAmount: new BigNumber(10),
937
- splitHandBetAmount: new BigNumber(10),
1008
+ mainBetAmount: new BigNumber(10),
938
1009
  twentyOnePlusThreeAmount: new BigNumber(0),
939
1010
  perfectPairAmount: new BigNumber(0),
940
1011
  boughtInsurance: false,
941
1012
  hasSplit: true,
1013
+ mainHandDoubleDown: false,
1014
+ splitHandDoubleDown: false,
942
1015
  },
943
- output: new BigNumber(0),
1016
+ output: { payout: new BigNumber(0), multiplier: new BigNumber(0), mainHandOutcome: HandOutcome.LOSS, splitHandOutcome: HandOutcome.LOSS },
944
1017
  },
945
1018
 
946
1019
  // Split blackjacks
@@ -955,14 +1028,15 @@ describe('Blackjack', () => {
955
1028
  CardGames.getCardIndexFromDetails({ suit: Suits.CLUBS, value: 'A' }),
956
1029
  ],
957
1030
  dealerHand: [getIndex('10'), getIndex('10')],
958
- mainHandBetAmount: new BigNumber(10),
959
- splitHandBetAmount: new BigNumber(10),
1031
+ mainBetAmount: new BigNumber(10),
960
1032
  twentyOnePlusThreeAmount: new BigNumber(0),
961
1033
  perfectPairAmount: new BigNumber(0),
962
1034
  boughtInsurance: false,
963
1035
  hasSplit: true,
1036
+ mainHandDoubleDown: false,
1037
+ splitHandDoubleDown: false,
964
1038
  },
965
- output: new BigNumber(40),
1039
+ output: { payout: new BigNumber(40), multiplier: new BigNumber(2), mainHandOutcome: HandOutcome.WIN, splitHandOutcome: HandOutcome.WIN },
966
1040
  },
967
1041
 
968
1042
  // Split Aces
@@ -977,14 +1051,15 @@ describe('Blackjack', () => {
977
1051
  CardGames.getCardIndexFromDetails({ suit: Suits.CLUBS, value: '10' }),
978
1052
  ],
979
1053
  dealerHand: [getIndex('10'), getIndex('10')],
980
- mainHandBetAmount: new BigNumber(10),
981
- splitHandBetAmount: new BigNumber(10),
1054
+ mainBetAmount: new BigNumber(10),
982
1055
  twentyOnePlusThreeAmount: new BigNumber(0),
983
1056
  perfectPairAmount: new BigNumber(0),
984
1057
  boughtInsurance: false,
985
1058
  hasSplit: true,
1059
+ mainHandDoubleDown: false,
1060
+ splitHandDoubleDown: false,
986
1061
  },
987
- output: new BigNumber(20),
1062
+ output: { payout: new BigNumber(20), multiplier: new BigNumber(1), mainHandOutcome: HandOutcome.LOSS, splitHandOutcome: HandOutcome.WIN },
988
1063
  },
989
1064
 
990
1065
  // Split bets with double down and sidebets and insurance
@@ -1003,14 +1078,22 @@ describe('Blackjack', () => {
1003
1078
  CardGames.getCardIndexFromDetails({ suit: Suits.CLUBS, value: 'A' }),
1004
1079
  CardGames.getCardIndexFromDetails({ suit: Suits.DIAMONDS, value: '7' }),
1005
1080
  ],
1006
- mainHandBetAmount: new BigNumber(20),
1007
- splitHandBetAmount: new BigNumber(10),
1081
+ mainBetAmount: new BigNumber(10),
1008
1082
  twentyOnePlusThreeAmount: new BigNumber(10),
1009
1083
  perfectPairAmount: new BigNumber(10),
1010
1084
  boughtInsurance: true,
1011
1085
  hasSplit: true,
1086
+ mainHandDoubleDown: true,
1087
+ splitHandDoubleDown: false,
1088
+ },
1089
+ // total bet amount: 20 (main hand doubled) + 10 (split hand) + 5 (insurance) + 10 (21+3) + 10 (perfect pair)
1090
+ output: {
1091
+ payout: new BigNumber(380),
1092
+ multiplier: new BigNumber(380).dividedBy(55),
1093
+ mainHandOutcome: HandOutcome.WIN,
1094
+ splitHandOutcome: HandOutcome.WIN,
1012
1095
  },
1013
- output: new BigNumber(380), // win main (40) + win split (20) + perfect pair (10*26) + flush (10*6)
1096
+ // win main (40) + win split (20) + perfect pair (10*26) + flush (10*6)
1014
1097
  },
1015
1098
  {
1016
1099
  input: {
@@ -1027,19 +1110,278 @@ describe('Blackjack', () => {
1027
1110
  CardGames.getCardIndexFromDetails({ suit: Suits.CLUBS, value: 'A' }),
1028
1111
  CardGames.getCardIndexFromDetails({ suit: Suits.DIAMONDS, value: '9' }),
1029
1112
  ],
1030
- mainHandBetAmount: new BigNumber(10),
1031
- splitHandBetAmount: new BigNumber(20),
1113
+ mainBetAmount: new BigNumber(10),
1032
1114
  twentyOnePlusThreeAmount: new BigNumber(10),
1033
1115
  perfectPairAmount: new BigNumber(10),
1034
1116
  boughtInsurance: true,
1035
1117
  hasSplit: true,
1118
+ mainHandDoubleDown: false,
1119
+ splitHandDoubleDown: true,
1120
+ },
1121
+ // total bet amount: 20 (main hand doubled) + 10 (split hand) + 5 (insurance) + 10 (21+3) + 10 (perfect pair)
1122
+ output: {
1123
+ payout: new BigNumber(90),
1124
+ multiplier: new BigNumber(90).dividedBy(55),
1125
+ mainHandOutcome: HandOutcome.LOSS,
1126
+ splitHandOutcome: HandOutcome.PUSH,
1127
+ }, // push split (20) + mixed pair (7*10)
1128
+ },
1129
+ // double down on main bet only,
1130
+ {
1131
+ input: {
1132
+ mainPlayerHand: [
1133
+ CardGames.getCardIndexFromDetails({ suit: Suits.DIAMONDS, value: '10' }),
1134
+ CardGames.getCardIndexFromDetails({ suit: Suits.SPADES, value: '4' }),
1135
+ CardGames.getCardIndexFromDetails({ suit: Suits.SPADES, value: '4' }),
1136
+ ],
1137
+ splitPlayerHand: [],
1138
+ dealerHand: [
1139
+ CardGames.getCardIndexFromDetails({ suit: Suits.CLUBS, value: 'A' }),
1140
+ CardGames.getCardIndexFromDetails({ suit: Suits.DIAMONDS, value: '9' }),
1141
+ ],
1142
+ mainBetAmount: new BigNumber(10),
1143
+ twentyOnePlusThreeAmount: new BigNumber(0),
1144
+ perfectPairAmount: new BigNumber(0),
1145
+ boughtInsurance: false,
1146
+ hasSplit: false,
1147
+ mainHandDoubleDown: true,
1148
+ splitHandDoubleDown: false,
1149
+ },
1150
+ output: { payout: new BigNumber(0), multiplier: new BigNumber(0), mainHandOutcome: HandOutcome.LOSS, splitHandOutcome: HandOutcome.NONE },
1151
+ },
1152
+ {
1153
+ input: {
1154
+ mainPlayerHand: [
1155
+ CardGames.getCardIndexFromDetails({ suit: Suits.DIAMONDS, value: '10' }),
1156
+ CardGames.getCardIndexFromDetails({ suit: Suits.SPADES, value: '4' }),
1157
+ CardGames.getCardIndexFromDetails({ suit: Suits.SPADES, value: '7' }),
1158
+ ],
1159
+ splitPlayerHand: [],
1160
+ dealerHand: [
1161
+ CardGames.getCardIndexFromDetails({ suit: Suits.CLUBS, value: 'A' }),
1162
+ CardGames.getCardIndexFromDetails({ suit: Suits.DIAMONDS, value: '9' }),
1163
+ ],
1164
+ mainBetAmount: new BigNumber(10),
1165
+ twentyOnePlusThreeAmount: new BigNumber(0),
1166
+ perfectPairAmount: new BigNumber(0),
1167
+ boughtInsurance: false,
1168
+ hasSplit: false,
1169
+ mainHandDoubleDown: true,
1170
+ splitHandDoubleDown: false,
1171
+ },
1172
+ output: { payout: new BigNumber(40), multiplier: new BigNumber(2), mainHandOutcome: HandOutcome.WIN, splitHandOutcome: HandOutcome.NONE },
1173
+ },
1174
+
1175
+ // bets with 0 bet amount, check that they work properly with the multiplier
1176
+ {
1177
+ input: {
1178
+ mainPlayerHand: [
1179
+ CardGames.getCardIndexFromDetails({ suit: Suits.DIAMONDS, value: '10' }),
1180
+ CardGames.getCardIndexFromDetails({ suit: Suits.SPADES, value: '4' }),
1181
+ CardGames.getCardIndexFromDetails({ suit: Suits.SPADES, value: '7' }),
1182
+ ],
1183
+ splitPlayerHand: [],
1184
+ dealerHand: [
1185
+ CardGames.getCardIndexFromDetails({ suit: Suits.CLUBS, value: 'A' }),
1186
+ CardGames.getCardIndexFromDetails({ suit: Suits.DIAMONDS, value: '9' }),
1187
+ ],
1188
+ mainBetAmount: new BigNumber(0),
1189
+ twentyOnePlusThreeAmount: new BigNumber(0),
1190
+ perfectPairAmount: new BigNumber(0),
1191
+ boughtInsurance: false,
1192
+ hasSplit: false,
1193
+ mainHandDoubleDown: true,
1194
+ splitHandDoubleDown: false,
1195
+ },
1196
+ output: { payout: new BigNumber(0), multiplier: new BigNumber(2), mainHandOutcome: HandOutcome.WIN, splitHandOutcome: HandOutcome.NONE },
1197
+ },
1198
+ {
1199
+ input: {
1200
+ mainPlayerHand: [
1201
+ CardGames.getCardIndexFromDetails({ suit: Suits.DIAMONDS, value: '10' }),
1202
+ CardGames.getCardIndexFromDetails({ suit: Suits.SPADES, value: '4' }),
1203
+ CardGames.getCardIndexFromDetails({ suit: Suits.SPADES, value: '6' }),
1204
+ ],
1205
+ splitPlayerHand: [],
1206
+ dealerHand: [
1207
+ CardGames.getCardIndexFromDetails({ suit: Suits.CLUBS, value: 'A' }),
1208
+ CardGames.getCardIndexFromDetails({ suit: Suits.DIAMONDS, value: '9' }),
1209
+ ],
1210
+ mainBetAmount: new BigNumber(0),
1211
+ twentyOnePlusThreeAmount: new BigNumber(0),
1212
+ perfectPairAmount: new BigNumber(0),
1213
+ boughtInsurance: false,
1214
+ hasSplit: false,
1215
+ mainHandDoubleDown: true,
1216
+ splitHandDoubleDown: false,
1217
+ },
1218
+ output: { payout: new BigNumber(0), multiplier: new BigNumber(1), mainHandOutcome: HandOutcome.PUSH, splitHandOutcome: HandOutcome.NONE },
1219
+ },
1220
+ {
1221
+ input: {
1222
+ mainPlayerHand: [
1223
+ CardGames.getCardIndexFromDetails({ suit: Suits.DIAMONDS, value: '10' }),
1224
+ CardGames.getCardIndexFromDetails({ suit: Suits.SPADES, value: '4' }),
1225
+ CardGames.getCardIndexFromDetails({ suit: Suits.SPADES, value: '5' }),
1226
+ ],
1227
+ splitPlayerHand: [],
1228
+ dealerHand: [
1229
+ CardGames.getCardIndexFromDetails({ suit: Suits.CLUBS, value: 'A' }),
1230
+ CardGames.getCardIndexFromDetails({ suit: Suits.DIAMONDS, value: '9' }),
1231
+ ],
1232
+ mainBetAmount: new BigNumber(0),
1233
+ twentyOnePlusThreeAmount: new BigNumber(0),
1234
+ perfectPairAmount: new BigNumber(0),
1235
+ boughtInsurance: false,
1236
+ hasSplit: false,
1237
+ mainHandDoubleDown: true,
1238
+ splitHandDoubleDown: false,
1239
+ },
1240
+ output: { payout: new BigNumber(0), multiplier: new BigNumber(0), mainHandOutcome: HandOutcome.LOSS, splitHandOutcome: HandOutcome.NONE },
1241
+ },
1242
+
1243
+ {
1244
+ input: {
1245
+ mainPlayerHand: [
1246
+ CardGames.getCardIndexFromDetails({ suit: Suits.DIAMONDS, value: '10' }),
1247
+ CardGames.getCardIndexFromDetails({ suit: Suits.SPADES, value: '4' }),
1248
+ CardGames.getCardIndexFromDetails({ suit: Suits.SPADES, value: '7' }),
1249
+ ],
1250
+ splitPlayerHand: [
1251
+ CardGames.getCardIndexFromDetails({ suit: Suits.DIAMONDS, value: '10' }),
1252
+ CardGames.getCardIndexFromDetails({ suit: Suits.SPADES, value: '4' }),
1253
+ ],
1254
+ dealerHand: [
1255
+ CardGames.getCardIndexFromDetails({ suit: Suits.CLUBS, value: 'A' }),
1256
+ CardGames.getCardIndexFromDetails({ suit: Suits.DIAMONDS, value: '9' }),
1257
+ ],
1258
+ mainBetAmount: new BigNumber(0),
1259
+ twentyOnePlusThreeAmount: new BigNumber(0),
1260
+ perfectPairAmount: new BigNumber(0),
1261
+ boughtInsurance: false,
1262
+ hasSplit: true,
1263
+ mainHandDoubleDown: true,
1264
+ splitHandDoubleDown: false,
1265
+ },
1266
+ output: { payout: new BigNumber(0), multiplier: new BigNumber(4).dividedBy(3), mainHandOutcome: HandOutcome.WIN, splitHandOutcome: HandOutcome.LOSS },
1267
+ },
1268
+ {
1269
+ input: {
1270
+ mainPlayerHand: [
1271
+ CardGames.getCardIndexFromDetails({ suit: Suits.DIAMONDS, value: '10' }),
1272
+ CardGames.getCardIndexFromDetails({ suit: Suits.SPADES, value: '4' }),
1273
+ ],
1274
+ splitPlayerHand: [
1275
+ CardGames.getCardIndexFromDetails({ suit: Suits.DIAMONDS, value: '10' }),
1276
+ CardGames.getCardIndexFromDetails({ suit: Suits.SPADES, value: 'A' }),
1277
+ ],
1278
+ dealerHand: [
1279
+ CardGames.getCardIndexFromDetails({ suit: Suits.CLUBS, value: 'A' }),
1280
+ CardGames.getCardIndexFromDetails({ suit: Suits.DIAMONDS, value: '9' }),
1281
+ ],
1282
+ mainBetAmount: new BigNumber(0),
1283
+ twentyOnePlusThreeAmount: new BigNumber(0),
1284
+ perfectPairAmount: new BigNumber(0),
1285
+ boughtInsurance: false,
1286
+ hasSplit: true,
1287
+ mainHandDoubleDown: false,
1288
+ splitHandDoubleDown: true,
1289
+ },
1290
+ output: { payout: new BigNumber(0), multiplier: new BigNumber(4).dividedBy(3), mainHandOutcome: HandOutcome.LOSS, splitHandOutcome: HandOutcome.WIN },
1291
+ },
1292
+ {
1293
+ input: {
1294
+ mainPlayerHand: [
1295
+ CardGames.getCardIndexFromDetails({ suit: Suits.DIAMONDS, value: '10' }),
1296
+ CardGames.getCardIndexFromDetails({ suit: Suits.SPADES, value: '4' }),
1297
+ ],
1298
+ splitPlayerHand: [
1299
+ CardGames.getCardIndexFromDetails({ suit: Suits.DIAMONDS, value: '10' }),
1300
+ CardGames.getCardIndexFromDetails({ suit: Suits.SPADES, value: 'A' }),
1301
+ ],
1302
+ dealerHand: [
1303
+ CardGames.getCardIndexFromDetails({ suit: Suits.CLUBS, value: 'A' }),
1304
+ CardGames.getCardIndexFromDetails({ suit: Suits.DIAMONDS, value: '9' }),
1305
+ ],
1306
+ mainBetAmount: new BigNumber(0),
1307
+ twentyOnePlusThreeAmount: new BigNumber(0),
1308
+ perfectPairAmount: new BigNumber(0),
1309
+ boughtInsurance: true,
1310
+ hasSplit: true,
1311
+ mainHandDoubleDown: false,
1312
+ splitHandDoubleDown: true,
1313
+ },
1314
+ output: {
1315
+ payout: new BigNumber(0),
1316
+ multiplier: new BigNumber(4).dividedBy(3.5),
1317
+ mainHandOutcome: HandOutcome.LOSS,
1318
+ splitHandOutcome: HandOutcome.WIN,
1319
+ },
1320
+ },
1321
+ {
1322
+ input: {
1323
+ mainPlayerHand: [
1324
+ CardGames.getCardIndexFromDetails({ suit: Suits.DIAMONDS, value: '10' }),
1325
+ CardGames.getCardIndexFromDetails({ suit: Suits.SPADES, value: '4' }),
1326
+ ],
1327
+ splitPlayerHand: [
1328
+ CardGames.getCardIndexFromDetails({ suit: Suits.DIAMONDS, value: '10' }),
1329
+ CardGames.getCardIndexFromDetails({ suit: Suits.SPADES, value: 'A' }),
1330
+ ],
1331
+ dealerHand: [
1332
+ CardGames.getCardIndexFromDetails({ suit: Suits.CLUBS, value: 'A' }),
1333
+ CardGames.getCardIndexFromDetails({ suit: Suits.DIAMONDS, value: '9' }),
1334
+ ],
1335
+ mainBetAmount: new BigNumber(0),
1336
+ twentyOnePlusThreeAmount: new BigNumber(0),
1337
+ perfectPairAmount: new BigNumber(0),
1338
+ boughtInsurance: true,
1339
+ hasSplit: true,
1340
+ mainHandDoubleDown: false,
1341
+ splitHandDoubleDown: false,
1342
+ },
1343
+ output: {
1344
+ payout: new BigNumber(0),
1345
+ multiplier: new BigNumber(2).dividedBy(2.5),
1346
+ mainHandOutcome: HandOutcome.LOSS,
1347
+ splitHandOutcome: HandOutcome.WIN,
1348
+ },
1349
+ },
1350
+ {
1351
+ input: {
1352
+ mainPlayerHand: [
1353
+ CardGames.getCardIndexFromDetails({ suit: Suits.DIAMONDS, value: '10' }),
1354
+ CardGames.getCardIndexFromDetails({ suit: Suits.SPADES, value: '4' }),
1355
+ ],
1356
+ splitPlayerHand: [
1357
+ CardGames.getCardIndexFromDetails({ suit: Suits.DIAMONDS, value: '10' }),
1358
+ CardGames.getCardIndexFromDetails({ suit: Suits.SPADES, value: 'A' }),
1359
+ ],
1360
+ dealerHand: [
1361
+ CardGames.getCardIndexFromDetails({ suit: Suits.CLUBS, value: 'A' }),
1362
+ CardGames.getCardIndexFromDetails({ suit: Suits.DIAMONDS, value: '9' }),
1363
+ ],
1364
+ mainBetAmount: new BigNumber(0),
1365
+ twentyOnePlusThreeAmount: new BigNumber(0),
1366
+ perfectPairAmount: new BigNumber(0),
1367
+ boughtInsurance: true,
1368
+ hasSplit: true,
1369
+ mainHandDoubleDown: true,
1370
+ splitHandDoubleDown: true,
1371
+ },
1372
+ output: {
1373
+ payout: new BigNumber(0),
1374
+ multiplier: new BigNumber(4).dividedBy(4.5),
1375
+ mainHandOutcome: HandOutcome.LOSS,
1376
+ splitHandOutcome: HandOutcome.WIN,
1036
1377
  },
1037
- output: new BigNumber(90), // push split (20) + mixed pair (7*10)
1038
1378
  },
1039
1379
  ];
1040
1380
 
1041
1381
  funcParams.forEach((param) => {
1042
- expect(Blackjack.getPayout(param.input)).toEqual(param.output);
1382
+ const output = Blackjack.getGameOutcome(param.input);
1383
+ expect(output).toStrictEqual(param.output);
1384
+ expect(output.payout).toEqual(param.output.payout);
1043
1385
  });
1044
1386
  /**
1045
1387
  * ONLY 1 HAND(no splits)