bonk-challanges 0.2.2 → 0.4.0

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.
Files changed (2) hide show
  1. package/index.js +578 -28
  2. package/package.json +1 -1
package/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  const React = require('react');
2
- const { PanResponder, Pressable, StyleSheet, Text, TextInput, View } = require('react-native');
2
+ const { Animated, PanResponder, Pressable, StyleSheet, Text, TextInput, View } = require('react-native');
3
3
 
4
4
  function randomInt(min, max) {
5
5
  return Math.floor(Math.random() * (max - min + 1)) + min;
@@ -58,6 +58,37 @@ function createMathProblem(difficulty = 'intermediate') {
58
58
  label: 'Answer',
59
59
  };
60
60
  }
61
+ if (difficulty === 'marc') {
62
+ const kind = randomInt(0, 2);
63
+ if (kind === 0) {
64
+ const slope = randomInt(-5, 5) * 2;
65
+ const intercept = randomInt(-8, 8);
66
+ const upper = randomInt(2, 8);
67
+ const answer = (slope / 2) * upper * upper + intercept * upper;
68
+ return {
69
+ text: `Integral from 0 to ${upper} of (${slope}x ${intercept >= 0 ? '+' : '-'} ${Math.abs(intercept)}) dx = ?`,
70
+ answer: String(answer),
71
+ label: 'Answer',
72
+ };
73
+ }
74
+ if (kind === 1) {
75
+ const matrix = Array.from({ length: 3 }, () => Array.from({ length: 3 }, () => randomInt(-4, 5)));
76
+ return {
77
+ text: `det(\n${formatMatrix(matrix)}\n) = ?`,
78
+ answer: String(determinant3(matrix)),
79
+ label: 'det',
80
+ monospace: true,
81
+ };
82
+ }
83
+ const a = [randomInt(-5, 5), randomInt(-5, 5), randomInt(-5, 5)];
84
+ const b = [randomInt(-5, 5), randomInt(-5, 5), randomInt(-5, 5)];
85
+ return {
86
+ text: `a x b\n\na = ${formatVerticalVector(a)}\nb = ${formatVerticalVector(b)}\n\nAnswer as x,y,z`,
87
+ answer: formatVector(crossProduct(a, b)),
88
+ label: 'x,y,z',
89
+ monospace: true,
90
+ };
91
+ }
61
92
  const x = randomInt(-12, 12);
62
93
  const a = randomInt(2, 10);
63
94
  const b = randomInt(-24, 24);
@@ -72,6 +103,33 @@ function createMathProblem(difficulty = 'intermediate') {
72
103
  return { text: `${a}x - ${b} = ${a * x - b}`, answer: String(x), label: 'x' };
73
104
  }
74
105
 
106
+ function determinant3(matrix) {
107
+ const [[a, b, c], [d, e, f], [g, h, i]] = matrix;
108
+ return a * (e * i - f * h) - b * (d * i - f * g) + c * (d * h - e * g);
109
+ }
110
+
111
+ function crossProduct(a, b) {
112
+ return [
113
+ a[1] * b[2] - a[2] * b[1],
114
+ a[2] * b[0] - a[0] * b[2],
115
+ a[0] * b[1] - a[1] * b[0],
116
+ ];
117
+ }
118
+
119
+ function formatVector(vector) {
120
+ return vector.join(',');
121
+ }
122
+
123
+ function formatMatrix(matrix) {
124
+ const width = Math.max(...matrix.flat().map((value) => String(value).length));
125
+ return matrix.map((row) => `[ ${row.map((value) => String(value).padStart(width, ' ')).join(' ')} ]`).join('\n');
126
+ }
127
+
128
+ function formatVerticalVector(vector) {
129
+ const width = Math.max(...vector.map((value) => String(value).length));
130
+ return `[ ${vector.map((value) => String(value).padStart(width, ' ')).join(' ')} ]`;
131
+ }
132
+
75
133
  function formatComplex(real, imag) {
76
134
  if (imag === 0) return String(real);
77
135
  if (real === 0) {
@@ -90,6 +148,7 @@ function normalizeAnswer(value) {
90
148
  .toLowerCase()
91
149
  .replace(/\s+/g, '')
92
150
  .replace(/−/g, '-')
151
+ .replace(/[()[\]]/g, '')
93
152
  .replace(/\*/g, '')
94
153
  .replace(/\+-/g, '-');
95
154
  }
@@ -165,6 +224,129 @@ function swipeTargetFromGesture(index, dx, dy, tileCount) {
165
224
  return null;
166
225
  }
167
226
 
227
+ function createDeck() {
228
+ const suits = ['S', 'H', 'D', 'C'];
229
+ const ranks = ['A', '2', '3', '4', '5', '6', '7', '8', '9', '10', 'J', 'Q', 'K'];
230
+ const deck = [];
231
+ suits.forEach((suit) => ranks.forEach((rank) => deck.push({ rank, suit, id: `${rank}${suit}` })));
232
+ for (let i = deck.length - 1; i > 0; i -= 1) {
233
+ const j = randomInt(0, i);
234
+ const tmp = deck[i];
235
+ deck[i] = deck[j];
236
+ deck[j] = tmp;
237
+ }
238
+ return deck;
239
+ }
240
+
241
+ function drawCard(deck) {
242
+ return deck.pop();
243
+ }
244
+
245
+ function cardLabel(card) {
246
+ return `${card.rank}${suitSymbol(card.suit)}`;
247
+ }
248
+
249
+ function suitSymbol(suit) {
250
+ if (suit === 'S') return '♠';
251
+ if (suit === 'H') return '♥';
252
+ if (suit === 'D') return '♦';
253
+ return '♣';
254
+ }
255
+
256
+ function isRedSuit(suit) {
257
+ return suit === 'H' || suit === 'D';
258
+ }
259
+
260
+ function handValue(cards) {
261
+ let total = 0;
262
+ let aces = 0;
263
+ cards.forEach((card) => {
264
+ if (card.rank === 'A') {
265
+ aces += 1;
266
+ total += 11;
267
+ } else if (['K', 'Q', 'J'].includes(card.rank)) {
268
+ total += 10;
269
+ } else {
270
+ total += Number(card.rank);
271
+ }
272
+ });
273
+ while (total > 21 && aces > 0) {
274
+ total -= 10;
275
+ aces -= 1;
276
+ }
277
+ return total;
278
+ }
279
+
280
+ function canSplitHand(hand) {
281
+ return hand.cards.length === 2 && hand.cards[0].rank === hand.cards[1].rank;
282
+ }
283
+
284
+ function createBlackjackRound(rounds = 0, message = 'Beat the dealer to pass.') {
285
+ const deck = createDeck();
286
+ const playerCards = [drawCard(deck), drawCard(deck)];
287
+ const dealerCards = [drawCard(deck), drawCard(deck)];
288
+ return {
289
+ deck,
290
+ dealerCards,
291
+ hands: [{ cards: playerCards, bet: 1, done: false }],
292
+ activeIndex: 0,
293
+ rounds,
294
+ message,
295
+ finished: false,
296
+ startedAt: Date.now(),
297
+ };
298
+ }
299
+
300
+ function activeBlackjackHand(game) {
301
+ return game.hands[game.activeIndex];
302
+ }
303
+
304
+ function nextBlackjackHandOrResolve(game) {
305
+ const nextIndex = game.hands.findIndex((hand, index) => index > game.activeIndex && !hand.done);
306
+ if (nextIndex >= 0) return { ...game, activeIndex: nextIndex };
307
+ return resolveBlackjackRound(game);
308
+ }
309
+
310
+ function dealerPlay(deck, dealerCards) {
311
+ const nextDeck = [...deck];
312
+ const nextDealer = [...dealerCards];
313
+ while (handValue(nextDealer) < 17) {
314
+ nextDealer.push(drawCard(nextDeck));
315
+ }
316
+ return { deck: nextDeck, dealerCards: nextDealer };
317
+ }
318
+
319
+ function resolveBlackjackRound(game) {
320
+ const { deck, dealerCards } = dealerPlay(game.deck, game.dealerCards);
321
+ const dealerTotal = handValue(dealerCards);
322
+ let won = false;
323
+ const resultLines = game.hands.map((hand, index) => {
324
+ const total = handValue(hand.cards);
325
+ let result = 'Push';
326
+ if (total > 21) result = 'Bust';
327
+ else if (dealerTotal > 21 || total > dealerTotal) {
328
+ result = 'Win';
329
+ won = true;
330
+ } else if (total < dealerTotal) result = 'Lose';
331
+ return `Hand ${index + 1}: ${result} (${total})`;
332
+ });
333
+ if (won) {
334
+ return {
335
+ ...game,
336
+ deck,
337
+ dealerCards,
338
+ message: `You won. ${resultLines.join(' ')}`,
339
+ finished: true,
340
+ };
341
+ }
342
+ return createBlackjackRound(game.rounds + 1, `No win yet. ${resultLines.join(' ')} New deal.`);
343
+ }
344
+
345
+ function updateBlackjackHand(game, updater) {
346
+ const hands = game.hands.map((hand, index) => (index === game.activeIndex ? updater(hand) : hand));
347
+ return { ...game, hands };
348
+ }
349
+
168
350
  function useMathChallenge(difficulty) {
169
351
  const [problem, setProblem] = React.useState(() => createMathProblem(difficulty));
170
352
  const [message, setMessage] = React.useState('');
@@ -209,12 +391,23 @@ function MathChallenge({ colors, stylesConfig, onSolved, difficulty = 'intermedi
209
391
  setInput('');
210
392
  }, [problem.text]);
211
393
 
212
- const pad = ['-', '+', 'i', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'C', '0', 'OK'];
394
+ const padRows = [['-', '+', 'i'], ['1', '2', '3'], ['4', '5', '6'], ['7', '8', '9'], [',', 'C', '0', 'OK']];
213
395
 
214
396
  return React.createElement(
215
397
  View,
216
398
  { style: [styles.block, stylesConfig?.block] },
217
- React.createElement(Text, { style: [styles.prompt, { color: colors.text }, stylesConfig?.prompt] }, problem.text),
399
+ React.createElement(
400
+ Text,
401
+ {
402
+ style: [
403
+ styles.prompt,
404
+ problem.monospace ? styles.monospacePrompt : null,
405
+ { color: colors.text },
406
+ stylesConfig?.prompt,
407
+ ],
408
+ },
409
+ problem.text
410
+ ),
218
411
  React.createElement(
219
412
  TextInput,
220
413
  {
@@ -233,33 +426,42 @@ function MathChallenge({ colors, stylesConfig, onSolved, difficulty = 'intermedi
233
426
  React.createElement(
234
427
  View,
235
428
  { style: styles.padGrid },
236
- pad.map((k) =>
429
+ padRows.map((row) =>
237
430
  React.createElement(
238
- Pressable,
431
+ View,
239
432
  {
240
- key: k,
241
- onPress: () => {
242
- if (k === 'C') {
243
- setInput('');
244
- return;
245
- }
246
- if (k === 'OK') {
247
- submit(input, onSolved);
248
- return;
249
- }
250
- if (input.length >= 12) return;
251
- setInput((v) => `${v}${k}`);
252
- },
253
- style: ({ pressed }) => [
254
- styles.key,
433
+ key: row.join(''),
434
+ style: styles.padRow,
435
+ },
436
+ row.map((k) =>
437
+ React.createElement(
438
+ Pressable,
255
439
  {
256
- borderColor: colors.border,
257
- backgroundColor: pressed ? colors.primaryPressed : colors.cardMuted,
440
+ key: k,
441
+ onPress: () => {
442
+ if (k === 'C') {
443
+ setInput('');
444
+ return;
445
+ }
446
+ if (k === 'OK') {
447
+ submit(input, onSolved);
448
+ return;
449
+ }
450
+ if (input.length >= 18) return;
451
+ setInput((v) => `${v}${k}`);
452
+ },
453
+ style: ({ pressed }) => [
454
+ styles.key,
455
+ {
456
+ borderColor: colors.border,
457
+ backgroundColor: pressed ? colors.primaryPressed : colors.cardMuted,
458
+ },
459
+ stylesConfig?.key,
460
+ ],
258
461
  },
259
- stylesConfig?.key,
260
- ],
261
- },
262
- React.createElement(Text, { style: [styles.keyText, { color: colors.text }, stylesConfig?.keyText] }, k)
462
+ React.createElement(Text, { style: [styles.keyText, { color: colors.text }, stylesConfig?.keyText] }, k)
463
+ )
464
+ )
263
465
  )
264
466
  )
265
467
  )
@@ -354,10 +556,255 @@ function TileChallenge({ colors, stylesConfig, onSolved, tileCount = 8 }) {
354
556
  );
355
557
  }
356
558
 
559
+ function BlackjackChallenge({ colors, stylesConfig, onSolved }) {
560
+ const [game, setGame] = React.useState(() => createBlackjackRound());
561
+ const activeHand = activeBlackjackHand(game);
562
+ const dealerShownCards = game.finished ? game.dealerCards : [game.dealerCards[0]];
563
+ const canAct = Boolean(activeHand) && !game.finished;
564
+ const canDouble = canAct && activeHand.cards.length === 2;
565
+ const canSplit = canAct && game.hands.length < 4 && canSplitHand(activeHand);
566
+
567
+ const completeIfWon = React.useCallback(
568
+ (nextGame) => {
569
+ setGame(nextGame);
570
+ if (nextGame.finished) {
571
+ onSolved({
572
+ type: 'blackjack',
573
+ attempts: nextGame.rounds + 1,
574
+ durationMs: Date.now() - nextGame.startedAt,
575
+ });
576
+ }
577
+ },
578
+ [onSolved]
579
+ );
580
+
581
+ const hit = React.useCallback(() => {
582
+ if (!canAct) return;
583
+ const deck = [...game.deck];
584
+ let next = updateBlackjackHand({ ...game, deck }, (hand) => ({
585
+ ...hand,
586
+ cards: [...hand.cards, drawCard(deck)],
587
+ }));
588
+ next = { ...next, deck };
589
+ if (handValue(activeBlackjackHand(next).cards) > 21) {
590
+ next = updateBlackjackHand(next, (hand) => ({ ...hand, done: true }));
591
+ next = nextBlackjackHandOrResolve(next);
592
+ }
593
+ completeIfWon(next);
594
+ }, [canAct, completeIfWon, game]);
595
+
596
+ const stand = React.useCallback(() => {
597
+ if (!canAct) return;
598
+ let next = updateBlackjackHand(game, (hand) => ({ ...hand, done: true }));
599
+ next = nextBlackjackHandOrResolve(next);
600
+ completeIfWon(next);
601
+ }, [canAct, completeIfWon, game]);
602
+
603
+ const doubleDown = React.useCallback(() => {
604
+ if (!canDouble) return;
605
+ const deck = [...game.deck];
606
+ let next = updateBlackjackHand({ ...game, deck }, (hand) => ({
607
+ ...hand,
608
+ bet: hand.bet * 2,
609
+ cards: [...hand.cards, drawCard(deck)],
610
+ done: true,
611
+ }));
612
+ next = nextBlackjackHandOrResolve({ ...next, deck });
613
+ completeIfWon(next);
614
+ }, [canDouble, completeIfWon, game]);
615
+
616
+ const split = React.useCallback(() => {
617
+ if (!canSplit) return;
618
+ const deck = [...game.deck];
619
+ const hands = [...game.hands];
620
+ const [first, second] = activeHand.cards;
621
+ hands.splice(
622
+ game.activeIndex,
623
+ 1,
624
+ { cards: [first, drawCard(deck)], bet: activeHand.bet, done: false },
625
+ { cards: [second, drawCard(deck)], bet: activeHand.bet, done: false }
626
+ );
627
+ setGame({ ...game, deck, hands });
628
+ }, [activeHand, canSplit, game]);
629
+
630
+ const renderHand = (hand, index) =>
631
+ React.createElement(
632
+ View,
633
+ {
634
+ key: index,
635
+ style: [
636
+ styles.blackjackHand,
637
+ {
638
+ borderColor: index === game.activeIndex && !game.finished ? colors.primary : colors.border,
639
+ backgroundColor: colors.cardMuted,
640
+ },
641
+ ],
642
+ },
643
+ React.createElement(
644
+ Text,
645
+ { style: [styles.blackjackLabel, { color: colors.subtleText }] },
646
+ `Hand ${index + 1}${hand.bet > 1 ? ' x2' : ''}`
647
+ ),
648
+ React.createElement(
649
+ View,
650
+ { style: styles.cardRow },
651
+ hand.cards.map((card, cardIndex) =>
652
+ React.createElement(AnimatedCard, {
653
+ key: `${game.rounds}-${index}-${card.id}-${cardIndex}-${hand.cards.length}`,
654
+ card,
655
+ delay: 120 + index * 120 + cardIndex * 95,
656
+ })
657
+ )
658
+ ),
659
+ React.createElement(
660
+ Text,
661
+ { style: [styles.blackjackValue, { color: handValue(hand.cards) > 21 ? '#D65A5A' : colors.subtleText }] },
662
+ `Value: ${handValue(hand.cards)}${hand.done ? ' Done' : ''}`
663
+ )
664
+ );
665
+
666
+ return React.createElement(
667
+ View,
668
+ { style: [styles.block, stylesConfig?.block] },
669
+ React.createElement(Text, { style: [styles.prompt, { color: colors.text }, stylesConfig?.prompt] }, 'Blackjack: beat the dealer'),
670
+ React.createElement(
671
+ View,
672
+ { style: [styles.blackjackDealer, { borderColor: colors.border, backgroundColor: colors.cardMuted }] },
673
+ React.createElement(Text, { style: [styles.blackjackLabel, { color: colors.subtleText }] }, 'Dealer'),
674
+ React.createElement(
675
+ View,
676
+ { style: styles.cardRow },
677
+ dealerShownCards.map((card, index) =>
678
+ React.createElement(AnimatedCard, {
679
+ key: `${game.rounds}-dealer-${card.id}-${index}-${game.finished ? 'show' : 'peek'}`,
680
+ card,
681
+ delay: index * 95,
682
+ })
683
+ ).concat(
684
+ game.finished
685
+ ? []
686
+ : [
687
+ React.createElement(AnimatedCard, {
688
+ key: `${game.rounds}-dealer-hidden`,
689
+ hidden: true,
690
+ delay: 95,
691
+ }),
692
+ ]
693
+ )
694
+ ),
695
+ React.createElement(
696
+ Text,
697
+ { style: [styles.blackjackValue, { color: colors.subtleText }] },
698
+ game.finished ? `Value: ${handValue(game.dealerCards)}` : `Showing: ${handValue(dealerShownCards)}`
699
+ )
700
+ ),
701
+ React.createElement(View, { style: styles.blackjackHands }, game.hands.map(renderHand)),
702
+ React.createElement(Text, { style: [styles.feedback, { color: colors.subtleText }, stylesConfig?.feedback] }, game.message),
703
+ React.createElement(
704
+ View,
705
+ { style: styles.blackjackActions },
706
+ React.createElement(BlackjackAction, { label: 'Hit', colors, disabled: !canAct, onPress: hit }),
707
+ React.createElement(BlackjackAction, { label: 'Stand', colors, disabled: !canAct, onPress: stand }),
708
+ React.createElement(BlackjackAction, { label: 'Double', colors, disabled: !canDouble, onPress: doubleDown }),
709
+ React.createElement(BlackjackAction, { label: 'Split', colors, disabled: !canSplit, onPress: split })
710
+ )
711
+ );
712
+ }
713
+
714
+ function BlackjackAction({ label, colors, disabled, onPress }) {
715
+ return React.createElement(
716
+ Pressable,
717
+ {
718
+ disabled,
719
+ onPress,
720
+ style: ({ pressed }) => [
721
+ styles.blackjackAction,
722
+ {
723
+ borderColor: colors.border,
724
+ backgroundColor: pressed ? colors.primaryPressed : colors.cardMuted,
725
+ opacity: disabled ? 0.45 : 1,
726
+ },
727
+ ],
728
+ },
729
+ React.createElement(Text, { style: [styles.blackjackActionText, { color: colors.text }] }, label)
730
+ );
731
+ }
732
+
733
+ function AnimatedCard({ card, hidden = false, delay = 0 }) {
734
+ const progress = React.useRef(new Animated.Value(0)).current;
735
+
736
+ React.useEffect(() => {
737
+ progress.setValue(0);
738
+ Animated.spring(progress, {
739
+ toValue: 1,
740
+ delay,
741
+ speed: 14,
742
+ bounciness: 8,
743
+ useNativeDriver: true,
744
+ }).start();
745
+ }, [delay, progress]);
746
+
747
+ return React.createElement(
748
+ Animated.View,
749
+ {
750
+ style: [
751
+ styles.playingCardAnim,
752
+ {
753
+ opacity: progress,
754
+ transform: [
755
+ {
756
+ translateY: progress.interpolate({
757
+ inputRange: [0, 1],
758
+ outputRange: [-26, 0],
759
+ }),
760
+ },
761
+ {
762
+ translateX: progress.interpolate({
763
+ inputRange: [0, 1],
764
+ outputRange: [22, 0],
765
+ }),
766
+ },
767
+ {
768
+ rotate: progress.interpolate({
769
+ inputRange: [0, 1],
770
+ outputRange: ['-7deg', '0deg'],
771
+ }),
772
+ },
773
+ ],
774
+ },
775
+ ],
776
+ },
777
+ React.createElement(PlayingCard, { card, hidden })
778
+ );
779
+ }
780
+
781
+ function PlayingCard({ card, hidden = false }) {
782
+ if (hidden) {
783
+ return React.createElement(
784
+ View,
785
+ { style: [styles.playingCard, styles.playingCardBack] },
786
+ React.createElement(Text, { style: styles.cardBackMark }, 'BONK')
787
+ );
788
+ }
789
+ const red = isRedSuit(card.suit);
790
+ const color = red ? '#D65A5A' : '#1F2328';
791
+ const symbol = suitSymbol(card.suit);
792
+ return React.createElement(
793
+ View,
794
+ { style: styles.playingCard },
795
+ React.createElement(Text, { style: [styles.cardCorner, { color }] }, card.rank),
796
+ React.createElement(Text, { style: [styles.cardSuit, { color }] }, symbol),
797
+ React.createElement(Text, { style: [styles.cardCornerBottom, { color }] }, card.rank)
798
+ );
799
+ }
800
+
357
801
  function BonkChallengeRunner({ type, tileCount = 8, difficulty = 'intermediate', colors, stylesConfig, onSolved }) {
358
802
  if (type === 'tile') {
359
803
  return React.createElement(TileChallenge, { colors, stylesConfig, onSolved, tileCount });
360
804
  }
805
+ if (type === 'blackjack') {
806
+ return React.createElement(BlackjackChallenge, { colors, stylesConfig, onSolved });
807
+ }
361
808
  return React.createElement(MathChallenge, { colors, stylesConfig, onSolved, difficulty });
362
809
  }
363
810
 
@@ -369,6 +816,11 @@ const styles = StyleSheet.create({
369
816
  fontSize: 20,
370
817
  fontWeight: '700',
371
818
  },
819
+ monospacePrompt: {
820
+ fontFamily: 'Courier',
821
+ fontSize: 18,
822
+ lineHeight: 24,
823
+ },
372
824
  answer: {
373
825
  fontSize: 15,
374
826
  fontWeight: '600',
@@ -387,12 +839,14 @@ const styles = StyleSheet.create({
387
839
  },
388
840
  padGrid: {
389
841
  marginTop: 2,
842
+ gap: 8,
843
+ },
844
+ padRow: {
390
845
  flexDirection: 'row',
391
- flexWrap: 'wrap',
392
846
  gap: 8,
393
847
  },
394
848
  key: {
395
- width: '30%',
849
+ flex: 1,
396
850
  borderRadius: 10,
397
851
  borderWidth: 1,
398
852
  alignItems: 'center',
@@ -403,6 +857,102 @@ const styles = StyleSheet.create({
403
857
  fontSize: 17,
404
858
  fontWeight: '700',
405
859
  },
860
+ blackjackDealer: {
861
+ borderWidth: 1,
862
+ borderRadius: 10,
863
+ padding: 12,
864
+ gap: 8,
865
+ },
866
+ blackjackHands: {
867
+ gap: 8,
868
+ },
869
+ blackjackHand: {
870
+ borderWidth: 1,
871
+ borderRadius: 10,
872
+ padding: 12,
873
+ gap: 8,
874
+ },
875
+ blackjackLabel: {
876
+ fontSize: 12,
877
+ fontWeight: '800',
878
+ letterSpacing: 0.6,
879
+ },
880
+ blackjackValue: {
881
+ fontSize: 13,
882
+ fontWeight: '700',
883
+ },
884
+ cardRow: {
885
+ flexDirection: 'row',
886
+ flexWrap: 'wrap',
887
+ gap: 8,
888
+ },
889
+ playingCardAnim: {
890
+ width: 54,
891
+ height: 76,
892
+ },
893
+ playingCard: {
894
+ width: 54,
895
+ height: 76,
896
+ borderRadius: 8,
897
+ backgroundColor: '#F8FAFC',
898
+ borderWidth: 1,
899
+ borderColor: '#D6DEE8',
900
+ padding: 5,
901
+ justifyContent: 'space-between',
902
+ shadowColor: '#000',
903
+ shadowOpacity: 0.18,
904
+ shadowRadius: 4,
905
+ shadowOffset: { width: 0, height: 2 },
906
+ elevation: 2,
907
+ },
908
+ playingCardBack: {
909
+ backgroundColor: '#E9A866',
910
+ borderColor: '#F2C083',
911
+ alignItems: 'center',
912
+ justifyContent: 'center',
913
+ },
914
+ cardBackMark: {
915
+ color: '#1F2328',
916
+ fontSize: 10,
917
+ fontWeight: '900',
918
+ letterSpacing: 0.8,
919
+ },
920
+ cardCorner: {
921
+ fontSize: 14,
922
+ fontWeight: '900',
923
+ lineHeight: 15,
924
+ },
925
+ cardSuit: {
926
+ alignSelf: 'center',
927
+ fontSize: 28,
928
+ fontWeight: '900',
929
+ lineHeight: 30,
930
+ },
931
+ cardCornerBottom: {
932
+ alignSelf: 'flex-end',
933
+ fontSize: 14,
934
+ fontWeight: '900',
935
+ lineHeight: 15,
936
+ transform: [{ rotate: '180deg' }],
937
+ },
938
+ blackjackActions: {
939
+ flexDirection: 'row',
940
+ flexWrap: 'wrap',
941
+ gap: 8,
942
+ },
943
+ blackjackAction: {
944
+ flexGrow: 1,
945
+ flexBasis: '45%',
946
+ minHeight: 42,
947
+ borderRadius: 10,
948
+ borderWidth: 1,
949
+ alignItems: 'center',
950
+ justifyContent: 'center',
951
+ },
952
+ blackjackActionText: {
953
+ fontSize: 15,
954
+ fontWeight: '800',
955
+ },
406
956
  tileGrid: {
407
957
  marginTop: 6,
408
958
  flexDirection: 'row',
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bonk-challanges",
3
- "version": "0.2.2",
3
+ "version": "0.4.0",
4
4
  "main": "index.js",
5
5
  "license": "MIT",
6
6
  "peerDependencies": {