trd69 commited on
Commit
2db64c5
·
verified ·
1 Parent(s): 38103a1

Update index.html

Browse files
Files changed (1) hide show
  1. index.html +428 -331
index.html CHANGED
@@ -1,3 +1,4 @@
 
1
  <!DOCTYPE html>
2
  <html lang="en">
3
  <head>
@@ -97,7 +98,6 @@
97
  margin-left: 10px;
98
  align-self: center;
99
  }
100
-
101
  .row-container {
102
  display: flex;
103
  align-items: center;
@@ -517,40 +517,12 @@
517
 
518
  // All cards placed - show final scores
519
  if (opponentCards === 13 && playerCards === 13) {
520
- const resultsContainer = document.getElementById('score-summary');
521
- const playerTopCombo = document.getElementById('player-top-combination').textContent;
522
- const playerMiddleCombo = document.getElementById('player-middle-combination').textContent;
523
- const playerBottomCombo = document.getElementById('player-bottom-combination').textContent;
524
-
525
- const opponentTopCombo = document.getElementById('opponent-top-combination').textContent;
526
- const opponentMiddleCombo = document.getElementById('opponent-middle-combination').textContent;
527
- const opponentBottomCombo = document.getElementById('opponent-bottom-combination').textContent;
528
-
529
- // Display results
530
- document.getElementById('final-player-top').textContent = `${playerTopCombo} (${document.getElementById('player-top-points').textContent} pts)`;
531
- document.getElementById('final-player-middle').textContent = `${playerMiddleCombo} (${document.getElementById('player-middle-points').textContent} pts)`;
532
- document.getElementById('final-player-bottom').textContent = `${playerBottomCombo} (${document.getElementById('player-bottom-points').textContent} pts)`;
533
-
534
- document.getElementById('final-opponent-top').textContent = `${opponentTopCombo} (${document.getElementById('opponent-top-points').textContent} pts)`;
535
- document.getElementById('final-opponent-middle').textContent = `${opponentMiddleCombo} (${document.getElementById('opponent-middle-points').textContent} pts)`;
536
- document.getElementById('final-opponent-bottom').textContent = `${opponentBottomCombo} (${document.getElementById('opponent-bottom-points').textContent} pts)`;
537
-
538
- // Calculate final score (simplified for demo)
539
- const playerScore =
540
- parseInt(document.getElementById('player-top-points').textContent) +
541
- parseInt(document.getElementById('player-middle-points').textContent) +
542
- parseInt(document.getElementById('player-bottom-points').textContent);
543
- const opponentScore =
544
- parseInt(document.getElementById('opponent-top-points').textContent) +
545
- parseInt(document.getElementById('opponent-middle-points').textContent) +
546
- parseInt(document.getElementById('opponent-bottom-points').textContent);
547
-
548
- document.getElementById('final-player-score').textContent = playerScore;
549
- document.getElementById('final-opponent-score').textContent = opponentScore;
550
-
551
- resultsContainer.classList.remove('hidden');
552
- calculateBtn.disabled = true;
553
- gameState.lastMoveValid = true;
554
  }
555
  else if (isValidState) {
556
  calculateBtn.disabled = false;
@@ -580,168 +552,410 @@
580
 
581
  // Update combination label for a specific row
582
  function updateRowCombination(prefix, size) {
583
- const cardIds = [];
584
- for (let i = 0; i < size; i++) {
585
- const cardId = gameState.slots[`${prefix}-${i}`];
586
- if (cardId !== null) {
587
- cardIds.push(gameState.cards.find(c => c.id == cardId));
588
- }
589
- }
590
-
591
- if (cardIds.length < size) {
592
- document.getElementById(`${prefix}-combination`).textContent = '-';
593
- document.getElementById(`${prefix}-points`).textContent = '0';
594
- return;
595
- }
596
-
597
- const combination = evaluateCombination(cardIds, prefix.split('-')[0]);
598
- document.getElementById(`${prefix}-combination`).textContent = combination.name;
599
- document.getElementById(`${prefix}-points`).textContent = combination.points;
600
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
601
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
602
  // Evaluate combination for a set of cards
603
- function evaluateCombination(cards, rowType) {
604
- // Sort cards by rank (high to low)
605
- cards.sort((a, b) => b.rank - a.rank);
606
-
607
- // For Chinese Poker different rows have different combinations:
608
- if (rowType === 'top') {
609
- // Top row: only simple 3-card combinations (no flushes/straights)
610
- return evaluateTopRow(cards);
611
- } else if (rowType === 'middle' || rowType === 'bottom') {
612
- // Middle/Bottom rows: standard 5-card poker hands
613
- return evaluateFiveCardHand(cards);
614
- } else {
615
- // For other rows (like opponent's) default to simple evaluation
616
- if (cards.length === 3) {
617
- return evaluateTopRow(cards);
618
- } else if (cards.length === 5) {
619
- return evaluateFiveCardHand(cards);
620
- }
621
- return { name: 'Unknown', points: 0 };
622
- }
623
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
624
 
625
- // Evaluate top row (3 cards)
626
- function evaluateTopRow(cards) {
627
- cards.sort((a, b) => b.rank - a.rank); // Sort descending
628
-
629
- const ranks = cards.map(c => c.rank);
630
-
631
- // Three of a kind (set)
632
- if (ranks[0] === ranks[1] && ranks[1] === ranks[2]) {
633
- return {
634
- name: `Three ${cards[0].value}'s`,
635
- points: cards[0].rank // Points equal to card rank (2=2, A=14)
636
- };
637
- }
638
-
639
- // Pair
640
- if (ranks[0] === ranks[1] || ranks[1] === ranks[2]) {
641
- const pairRank = ranks[0] === ranks[1] ? ranks[0] : ranks[1];
642
-
643
- return {
644
- name: `Pair of ${cards[0].value}'s`,
645
- points: Math.floor(pairRank / 2) // Simple point scale (2=1, A=7)
646
  };
 
647
  }
648
-
649
- // High card (single card)
650
- return {
651
- name: `High ${cards[0].value}`,
652
- points: 0
653
- };
654
- }
655
-
656
- // Evaluate 5-card hand (middle or bottom row)
657
- function evaluateFiveCardHand(cards) {
658
- // For now we'll implement basic poker hands
659
-
660
- // Check flush
661
- const isFlush = cards.every(c => c.suit === cards[0].suit);
662
-
663
- // Check straight
664
- let isStraight = true;
665
- for (let i = 1; i < cards.length; i++) {
666
- if (cards[i].rank !== cards[i-1].rank - 1) {
667
- isStraight = false;
668
- break;
669
- }
670
- }
671
-
672
- // Check wheel (A-2-3-4-5)
673
- const wheelRanks = [12, 0, 1, 2, 3];
674
- const currentRanks = cards.map(c => c.rank).sort((a,b) => a-b);
675
- let isWheel = true;
676
- for (let i = 0; i < wheelRanks.length; i++) {
677
- if (currentRanks[i] !== wheelRanks[i]) {
678
- isWheel = false;
679
- break;
680
- }
681
- }
682
- isStraight = isStraight || isWheel;
683
-
684
- // Check royal flush (10-J-Q-K-A of same suit)
685
- const isRoyal = isFlush &&
686
- (cards[0].rank === 14) && // Ace
687
- (cards[1].rank === 13) && // King
688
- (cards[2].rank === 12) && // Queen
689
- (cards[3].rank === 11) && // Jack
690
- (cards[4].rank === 10); // 10
691
-
692
- // Check straight flush and royal flush
693
- if (isStraight && isFlush) {
694
- if (isRoyal) {
695
- return { name: 'Royal Flush', points: 15 };
696
- }
697
- return { name: 'Straight Flush', points: 10 };
698
- }
699
-
700
- // Check four of a kind
701
- const rankCounts = {};
702
- cards.forEach(c => {
703
- rankCounts[c.rank] = (rankCounts[c.rank] || 0) + 1;
704
- });
705
- const counts = Object.values(rankCounts);
706
-
707
- if (counts.includes(4)) {
708
- return { name: 'Four of a Kind', points: 8 };
709
- }
710
-
711
- // Check full house
712
- if (counts.includes(3) && counts.includes(2)) {
713
- return { name: 'Full House', points: 6 };
714
- }
715
-
716
- // Check flush
717
- if (isFlush) {
718
- return { name: 'Flush', points: 4 };
719
- }
720
-
721
- // Check straight
722
- if (isStraight || isWheel) {
723
- return { name: 'Straight', points: 2 };
724
- }
725
-
726
- // Check three of a kind
727
- if (counts.includes(3)) {
728
- return { name: 'Three of a Kind', points: 0 };
729
- }
730
-
731
- // Check two pairs
732
- const pairCount = counts.filter(c => c === 2).length;
733
- if (pairCount === 2) {
734
- return { name: 'Two Pairs', points: 0 };
735
- }
736
-
737
- // Check pair
738
- if (pairCount === 1) {
739
- return { name: 'Pair', points: 0 };
740
- }
741
-
742
- // High card
743
- return { name: 'High Card', points: 0 };
744
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
745
 
746
  // Calculate best moves (simplified for demo)
747
  function calculateBestMoves() {
@@ -754,12 +968,7 @@
754
  v => v !== null && gameState.cardPositions[v]?.startsWith('opponent-')
755
  ).length;
756
 
757
- if (playerCards === 13 && opponentCards === 13) {
758
- // Show final scores
759
- showFinalScores();
760
- return;
761
- }
762
-
763
  const resultsContainer = document.getElementById('results');
764
  const resultsContent = document.getElementById('results-content');
765
 
@@ -825,140 +1034,30 @@
825
 
826
  // Show final scores when all cards are placed
827
  function showFinalScores() {
828
- // Display results
829
- const playerTopCombo = document.getElementById('player-top-combination').textContent;
830
- const playerMiddleCombo = document.getElementById('player-middle-combination').textContent;
831
- const playerBottomCombo = document.getElementById('player-bottom-combination').textContent;
832
-
833
- const opponentTopCombo = document.getElementById('opponent-top-combination').textContent;
834
- const opponentMiddleCombo = document.getElementById('opponent-middle-combination').textContent;
835
- const opponentBottomCombo = document.getElementById('opponent-bottom-combination').textContent;
 
 
 
 
836
 
837
- // Get points for each row
838
- const playerTopPoints = parseInt(document.getElementById('player-top-points').textContent);
839
- const playerMiddlePoints = parseInt(document.getElementById('player-middle-points').textContent);
840
- const playerBottomPoints = parseInt(document.getElementById('player-bottom-points').textContent);
841
-
842
- const opponentTopPoints = parseInt(document.getElementById('opponent-top-points').textContent);
843
- const opponentMiddlePoints = parseInt(document.getElementById('opponent-middle-points').textContent);
844
- const opponentBottomPoints = parseInt(document.getElementById('opponent-bottom-points').textContent);
845
-
846
- // Check for seniority violation (broken hand)
847
- let playerBrokenHand = false;
848
- let opponentBrokenHand = false;
849
-
850
- if (playerMiddlePoints > playerBottomPoints || playerTopPoints > playerMiddlePoints) {
851
- playerBrokenHand = true;
852
- alert("You have a broken hand! (Bottom must be strongest, middle stronger than top)");
853
- }
854
-
855
- if (opponentMiddlePoints > opponentBottomPoints || opponentTopPoints > opponentMiddlePoints) {
856
- opponentBrokenHand = true;
857
- alert("Opponent has a broken hand! (Bottom must be strongest, middle stronger than top)");
858
- }
859
 
860
- // Reset scores
861
- let playerScore = 0;
862
- let opponentScore = 0;
863
-
864
- // Apply breaking hand rule - if hand is broken, ALL points are zero including royalties
865
- if (playerBrokenHand || opponentBrokenHand) {
866
- playerScore = 0;
867
- opponentScore = 0;
868
- } else {
869
- let playerRowWins = 0;
870
- let opponentRowWins = 0;
871
-
872
- // Compare top rows (3 cards)
873
- if (playerTopPoints > opponentTopPoints) {
874
- playerScore += 1;
875
- playerRowWins += 1;
876
- } else if (playerTopPoints < opponentTopPoints) {
877
- opponentScore += 1;
878
- opponentRowWins += 1;
879
- }
880
-
881
- // Compare middle rows (5 cards)
882
- if (playerMiddlePoints > opponentMiddlePoints) {
883
- playerScore += 1;
884
- playerRowWins += 1;
885
- } else if (playerMiddlePoints < opponentMiddlePoints) {
886
- opponentScore += 1;
887
- opponentRowWins += 1;
888
- }
889
-
890
- // Compare bottom rows (5 cards)
891
- if (playerBottomPoints > opponentBottomPoints) {
892
- playerScore += 1;
893
- playerRowWins += 1;
894
- } else if (playerBottomPoints < opponentBottomPoints) {
895
- opponentScore += 1;
896
- opponentRowWins += 1;
897
- }
898
-
899
- // Scoop bonus: +3 for winning all 3 rows
900
- if (playerRowWins === 3) {
901
- playerScore += 3;
902
- } else if (opponentRowWins === 3) {
903
- opponentScore += 3;
904
- }
905
-
906
- // Add royalties as additional points (if no broken hand)
907
- const playerRoyalty = calculateRoyaltyPoints(playerTopCombo, 'top') +
908
- calculateRoyaltyPoints(playerMiddleCombo, 'middle') +
909
- calculateRoyaltyPoints(playerBottomCombo, 'bottom');
910
- playerScore += playerRoyalty;
911
-
912
- const opponentRoyalty = calculateRoyaltyPoints(opponentTopCombo, 'top') +
913
- calculateRoyaltyPoints(opponentMiddleCombo, 'middle') +
914
- calculateRoyaltyPoints(opponentBottomCombo, 'bottom');
915
- opponentScore += opponentRoyalty;
916
- }
917
-
918
- function calculateRoyaltyPoints(combo, rowType) {
919
- let points = 0;
920
- const comboStr = combo.toLowerCase();
921
-
922
- // Top row royalties
923
- if (rowType === 'top') {
924
- if (comboStr.includes('three')) points += 3;
925
- else if (comboStr.includes('pair')) points += 1;
926
- }
927
- // Middle row royalties
928
- else if (rowType === 'middle') {
929
- if (comboStr.includes('royal flush')) points += 15;
930
- else if (comboStr.includes('straight flush')) points += 10;
931
- else if (comboStr.includes('four of')) points += 8;
932
- else if (comboStr.includes('full house')) points += 4;
933
- }
934
- // Bottom row royalties
935
- else if (rowType === 'bottom') {
936
- if (comboStr.includes('royal flush')) points += 25;
937
- else if (comboStr.includes('straight flush')) points += 15;
938
- else if (comboStr.includes('four of')) points += 10;
939
- else if (comboStr.includes('full house')) points += 6;
940
- else if (comboStr.includes('flush')) points += 4;
941
- else if (comboStr.includes('straight')) points += 2;
942
- }
943
-
944
- return points;
945
- }
946
-
947
- // Display final scores
948
- document.getElementById('final-player-top').textContent = `${playerTopCombo} (${playerTopPoints} pts)`;
949
- document.getElementById('final-player-middle').textContent = `${playerMiddleCombo} (${playerMiddlePoints} pts)`;
950
- document.getElementById('final-player-bottom').textContent = `${playerBottomCombo} (${playerBottomPoints} pts)`;
951
-
952
- document.getElementById('final-opponent-top').textContent = `${opponentTopCombo} (${opponentTopPoints} pts)`;
953
- document.getElementById('final-opponent-middle').textContent = `${opponentMiddleCombo} (${opponentMiddlePoints} pts)`;
954
- document.getElementById('final-opponent-bottom').textContent = `${opponentBottomCombo} (${opponentBottomPoints} pts)`;
955
-
956
- document.getElementById('final-player-score').textContent = playerScore;
957
- document.getElementById('final-opponent-score').textContent = opponentScore;
958
-
959
- document.getElementById('score-summary').classList.remove('hidden');
960
- document.getElementById('results').classList.add('hidden');
961
- }
962
 
963
  // Reset all cards
964
  function resetAllCards() {
@@ -1022,5 +1121,3 @@
1022
  initGame();
1023
  });
1024
  </script>
1025
- <p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - 🧬 <a href="https://enzostvs-deepsite.hf.space?remix=trd69/cps" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body>
1026
- </html>
 
1
+
2
  <!DOCTYPE html>
3
  <html lang="en">
4
  <head>
 
98
  margin-left: 10px;
99
  align-self: center;
100
  }
 
101
  .row-container {
102
  display: flex;
103
  align-items: center;
 
517
 
518
  // All cards placed - show final scores
519
  if (opponentCards === 13 && playerCards === 13) {
520
+ // Вызываем функцию расчета итоговых очков
521
+ showFinalScores();
522
+ // Отображаем таблицу с очками
523
+ document.getElementById('score-summary').classList.remove('hidden');
524
+ calculateBtn.disabled = true;
525
+ gameState.lastMoveValid = true;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
526
  }
527
  else if (isValidState) {
528
  calculateBtn.disabled = false;
 
552
 
553
  // Update combination label for a specific row
554
  function updateRowCombination(prefix, size) {
555
+ const cardIds = [];
556
+ for (let i = 0; i < size; i++) {
557
+ const cardId = gameState.slots[`${prefix}-${i}`];
558
+ if (cardId !== null) {
559
+ cardIds.push(gameState.cards.find(c => c.id == cardId));
560
+ }
561
+ }
562
+
563
+ if (cardIds.length < size) {
564
+ document.getElementById(`${prefix}-combination`).textContent = '-';
565
+ document.getElementById(`${prefix}-points`).textContent = '0';
566
+ return null;
567
+ }
568
+
569
+ const result = evaluateCombinationWithCards(cardIds);
570
+ document.getElementById(`${prefix}-combination`).textContent = result.combination;
571
+
572
+ // Рассчитываем бонусы только для UI
573
+ const rowType = prefix.split('-')[1];
574
+ const royalty = calculateRoyalty(result, rowType);
575
+ document.getElementById(`${prefix}-points`).textContent = royalty;
576
+
577
+ return result;
578
+ }
579
+
580
+
581
+
582
+ function getCombinationRank(combination) {
583
+ const ranks = {
584
+ 'High Card': 0,
585
+ 'Pair': 1,
586
+ 'Two Pairs': 2,
587
+ 'Three of a Kind': 3,
588
+ 'Straight': 4,
589
+ 'Flush': 5,
590
+ 'Full House': 6,
591
+ 'Four of a Kind': 7,
592
+ 'Straight Flush': 8,
593
+ 'Royal Flush': 9
594
+ };
595
+ return ranks[combination] || 0;
596
+ }
597
+
598
+ // Get kicker strength (for comparing same combination types)
599
+ function getCombinationStrength(cards, combination) {
600
+ // Sort cards by rank (high to low)
601
+ const sortedCards = [...cards].sort((a, b) => b.rank - a.rank);
602
+
603
+ // For combinations with fixed kickers
604
+ switch(combination) {
605
+ case 'Pair':
606
+ // Find pair value
607
+ const pairValue = sortedCards.find(card =>
608
+ sortedCards.filter(c => c.rank === card.rank).length === 2
609
+ ).rank;
610
+ // Get kickers
611
+ const kickers = sortedCards
612
+ .filter(c => c.rank !== pairValue)
613
+ .map(c => c.rank)
614
+ .sort((a, b) => b - a);
615
+ return [pairValue, ...kickers];
616
+
617
+ case 'Two Pairs':
618
+ const values = sortedCards.map(c => c.rank);
619
+ const counts = {};
620
+ values.forEach(v => counts[v] = (counts[v] || 0) + 1);
621
+
622
+ const pairs = Object.entries(counts)
623
+ .filter(([_, count]) => count === 2)
624
+ .map(([rank]) => parseInt(rank))
625
+ .sort((a, b) => b - a);
626
+
627
+ const kicker = Object.entries(counts)
628
+ .filter(([_, count]) => count === 1)
629
+ .map(([rank]) => parseInt(rank))[0];
630
+
631
+ return [...pairs, kicker];
632
+
633
+ case 'Three of a Kind':
634
+ const setValue = sortedCards.find(card =>
635
+ sortedCards.filter(c => c.rank === card.rank).length === 3
636
+ ).rank;
637
+ return [setValue];
638
+
639
+ case 'Straight':
640
+ case 'Straight Flush':
641
+ // Handle wheel (A-2-3-4-5)
642
+ const isWheel = sortedCards.some(c => c.rank === 14) &&
643
+ sortedCards.some(c => c.rank === 2) &&
644
+ sortedCards.some(c => c.rank === 3) &&
645
+ sortedCards.some(c => c.rank === 4) &&
646
+ sortedCards.some(c => c.rank === 5);
647
+
648
+ return [isWheel ? 5 : sortedCards[0].rank];
649
+
650
+ case 'Flush':
651
+ case 'High Card':
652
+ return sortedCards.map(c => c.rank);
653
+
654
+ case 'Full House':
655
+ const setVal = sortedCards.find(card =>
656
+ sortedCards.filter(c => c.rank === card.rank).length === 3
657
+ ).rank;
658
+ const pairVal = sortedCards.find(card =>
659
+ card.rank !== setVal &&
660
+ sortedCards.filter(c => c.rank === card.rank).length === 2
661
+ ).rank;
662
+ return [setVal, pairVal];
663
 
664
+ case 'Four of a Kind':
665
+ const quadValue = sortedCards.find(card =>
666
+ sortedCards.filter(c => c.rank === card.rank).length === 4
667
+ ).rank;
668
+ const kickerValue = sortedCards.find(c => c.rank !== quadValue).rank;
669
+ return [quadValue, kickerValue];
670
+
671
+ case 'Royal Flush':
672
+ return [14]; // Always highest
673
+
674
+ default:
675
+ return [sortedCards[0].rank];
676
+ }
677
+ }
678
+
679
+
680
  // Evaluate combination for a set of cards
681
+ function evaluateCombinationWithCards(cards, rowType) {
682
+ if (cards.length === 0) return {
683
+ combination: 'None',
684
+ strength: [],
685
+ cards: []
686
+ };
687
+
688
+ // Sort cards by rank (high to low)
689
+ const sortedCards = [...cards].sort((a, b) => b.rank - a.rank);
690
+
691
+ // Check flush
692
+ const isFlush = sortedCards.every(c => c.suit === sortedCards[0].suit);
693
+
694
+ // Check straight
695
+ let isStraight = true;
696
+ for (let i = 1; i < sortedCards.length; i++) {
697
+ if (sortedCards[i].rank !== sortedCards[i-1].rank - 1) {
698
+ isStraight = false;
699
+ break;
700
+ }
701
+ }
702
+
703
+ // Check wheel (A-2-3-4-5)
704
+ function isWheel(cards) {
705
+ const hasAce = cards.some(c => c.rank === 14);
706
+ const ranks = cards.map(c => c.rank).sort((a, b) => a - b);
707
+ return hasAce &&
708
+ ranks.includes(2) &&
709
+ ranks.includes(3) &&
710
+ ranks.includes(4) &&
711
+ ranks.includes(5);
712
+ }
713
+
714
+ isStraight = isStraight || isWheel(sortedCards);
715
+
716
+ // Check royal flush (10-J-Q-K-A of same suit)
717
+ const isRoyal = isFlush &&
718
+ sortedCards[0].rank === 14 &&
719
+ sortedCards[1].rank === 13 &&
720
+ sortedCards[2].rank === 12 &&
721
+ sortedCards[3].rank === 11 &&
722
+ sortedCards[4].rank === 10;
723
+
724
+ // Check straight flush and royal flush
725
+ if (isStraight && isFlush && sortedCards.length >= 5) {
726
+ const combination = isRoyal ? 'Royal Flush' : 'Straight Flush';
727
+ return {
728
+ combination,
729
+ strength: getCombinationStrength(sortedCards, combination),
730
+ cards: sortedCards
731
+ };
732
+ }
733
+
734
+ // Check four of a kind
735
+ const rankCounts = {};
736
+ sortedCards.forEach(c => {
737
+ rankCounts[c.rank] = (rankCounts[c.rank] || 0) + 1;
738
+ });
739
+
740
+ const counts = Object.values(rankCounts);
741
+ if (counts.includes(4)) {
742
+ return {
743
+ combination: 'Four of a Kind',
744
+ strength: getCombinationStrength(sortedCards, 'Four of a Kind'),
745
+ cards: sortedCards
746
+ };
747
+ }
748
+
749
+ // Check full house
750
+ if (counts.includes(3) && counts.includes(2) && sortedCards.length >= 5) {
751
+ return {
752
+ combination: 'Full House',
753
+ strength: getCombinationStrength(sortedCards, 'Full House'),
754
+ cards: sortedCards
755
+ };
756
+ }
757
+
758
+ // Check flush (only for 5+ cards)
759
+ if (isFlush && sortedCards.length >= 5) {
760
+ return {
761
+ combination: 'Flush',
762
+ strength: getCombinationStrength(sortedCards, 'Flush'),
763
+ cards: sortedCards
764
+ };
765
+ }
766
+
767
+ // Check straight (only for 5+ cards)
768
+ if (isStraight && sortedCards.length >= 5) {
769
+ return {
770
+ combination: 'Straight',
771
+ strength: getCombinationStrength(sortedCards, 'Straight'),
772
+ cards: sortedCards
773
+ };
774
+ }
775
+
776
+ // Check three of a kind
777
+ if (counts.includes(3)) {
778
+ return {
779
+ combination: 'Three of a Kind',
780
+ strength: getCombinationStrength(sortedCards, 'Three of a Kind'),
781
+ cards: sortedCards
782
+ };
783
+ }
784
+
785
+ // Check two pairs
786
+ const pairCount = counts.filter(c => c === 2).length;
787
+ if (pairCount === 2) {
788
+ return {
789
+ combination: 'Two Pairs',
790
+ strength: getCombinationStrength(sortedCards, 'Two Pairs'),
791
+ cards: sortedCards
792
+ };
793
+ }
794
+
795
+ // Check pair
796
+ if (pairCount === 1) {
797
+ return {
798
+ combination: 'Pair',
799
+ strength: getCombinationStrength(sortedCards, 'Pair'),
800
+ cards: sortedCards
801
+ };
802
+ }
803
+
804
+ // High card
805
+ return {
806
+ combination: `High ${sortedCards[0].value}`,
807
+ strength: getCombinationStrength(sortedCards, 'High Card'),
808
+ cards: sortedCards
809
+ };
810
+ }
811
+
812
+ function compareCombinations(comb1, comb2) {
813
+ // Compare combination ranks
814
+ const rank1 = getCombinationRank(comb1.combination);
815
+ const rank2 = getCombinationRank(comb2.combination);
816
+
817
+ if (rank1 !== rank2) {
818
+ return rank1 > rank2 ? 1 : -1;
819
+ }
820
+
821
+ // Same rank - compare strengths and kickers
822
+ const strength1 = comb1.strength;
823
+ const strength2 = comb2.strength;
824
+
825
+ for (let i = 0; i < Math.min(strength1.length, strength2.length); i++) {
826
+ if (strength1[i] !== strength2[i]) {
827
+ return strength1[i] > strength2[i] ? 1 : -1;
828
+ }
829
+ }
830
+
831
+ // All kickers match
832
+ return 0;
833
+ }
834
+
835
+ // =====================
836
+ // Scoring Module (Updated)
837
+ // =====================
838
+
839
+ // Check for dead hand (invalid hand structure)
840
+ function isDeadHand(rows) {
841
+ const { top, middle, bottom } = rows;
842
+ return !(compareCombinations(top, middle) <= 0 &&
843
+ compareCombinations(middle, bottom) <= 0);
844
+ }
845
+
846
+ // Calculate royalty points for a row
847
+ function calculateRoyalty(row, rowType) {
848
+ const combination = row.combination;
849
+
850
+ if (rowType === 'bottom') {
851
+ switch(combination) {
852
+ case 'Straight': return 2;
853
+ case 'Flush': return 4;
854
+ case 'Full House': return 6;
855
+ case 'Four of a Kind': return 8;
856
+ case 'Straight Flush': return 10;
857
+ case 'Royal Flush': return 15;
858
+ default: return 0;
859
+ }
860
+ }
861
+
862
+ if (rowType === 'middle') {
863
+ switch(combination) {
864
+ case 'Three of a Kind': return 2;
865
+ case 'Straight': return 4;
866
+ case 'Flush': return 8;
867
+ case 'Full House': return 12;
868
+ case 'Four of a Kind': return 16;
869
+ case 'Straight Flush': return 20;
870
+ case 'Royal Flush': return 30;
871
+ default: return 0;
872
+ }
873
+ }
874
+
875
+ if (rowType === 'top') {
876
+ if (combination === 'Three of a Kind') {
877
+ const value = row.cards[0].value;
878
+ const rankMap = {
879
+ '2': 10, '3': 11, '4': 12, '5': 13, '6': 14,
880
+ '7': 15, '8': 16, '9': 17, 'T': 18, 'J': 19,
881
+ 'Q': 20, 'K': 21, 'A': 22
882
+ };
883
+ return rankMap[value] || 0;
884
+ }
885
+
886
+ if (combination === 'Pair') {
887
+ // Find pair value
888
+ const values = row.cards.map(c => c.value);
889
+ const valueCounts = {};
890
+ values.forEach(v => valueCounts[v] = (valueCounts[v] || 0) + 1);
891
 
892
+ for (const [value, count] of Object.entries(valueCounts)) {
893
+ if (count === 2) {
894
+ const rankMap = {
895
+ '6': 1, '7': 2, '8': 3, '9': 4, 'T': 5,
896
+ 'J': 6, 'Q': 7, 'K': 8, 'A': 9
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
897
  };
898
+ return rankMap[value] || 0;
899
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
900
  }
901
+ }
902
+ }
903
+
904
+ return 0;
905
+ }
906
+
907
+ function calculateRoyalties(rows) {
908
+ return calculateRoyalty(rows.top, 'top') +
909
+ calculateRoyalty(rows.middle, 'middle') +
910
+ calculateRoyalty(rows.bottom, 'bottom');
911
+ }
912
+ function calculateScores(playerRows, opponentRows) {
913
+ // Dead hand penalties
914
+ const playerDead = isDeadHand(playerRows);
915
+ const opponentDead = isDeadHand(opponentRows);
916
+
917
+ if (playerDead && opponentDead) return { player: 0, opponent: 0 };
918
+ if (playerDead) return { player: 0, opponent: 6 + calculateRoyalties(opponentRows) };
919
+ if (opponentDead) return { player: 6 + calculateRoyalties(playerRows), opponent: 0 };
920
+
921
+ // Compare rows
922
+ const topResult = compareCombinations(playerRows.top, opponentRows.top);
923
+ const middleResult = compareCombinations(playerRows.middle, opponentRows.middle);
924
+ const bottomResult = compareCombinations(playerRows.bottom, opponentRows.bottom);
925
+
926
+ // Calculate row wins
927
+ let playerRowWins = 0;
928
+ let opponentRowWins = 0;
929
+
930
+ if (topResult > 0) playerRowWins++;
931
+ else if (topResult < 0) opponentRowWins++;
932
+
933
+ if (middleResult > 0) playerRowWins++;
934
+ else if (middleResult < 0) opponentRowWins++;
935
+
936
+ if (bottomResult > 0) playerRowWins++;
937
+ else if (bottomResult < 0) opponentRowWins++;
938
+
939
+ // Scoop bonus
940
+ let playerScore = playerRowWins;
941
+ let opponentScore = opponentRowWins;
942
+
943
+ if (playerRowWins === 3) playerScore += 3;
944
+ else if (opponentRowWins === 3) opponentScore += 3;
945
+
946
+ // Add royalties
947
+ playerScore += calculateRoyalties(playerRows);
948
+ opponentScore += calculateRoyalties(opponentRows);
949
+
950
+ return {
951
+ player: playerScore,
952
+ opponent: opponentScore,
953
+ details: {
954
+ player: { rowWins: playerRowWins, royalties: calculateRoyalties(playerRows) },
955
+ opponent: { rowWins: opponentRowWins, royalties: calculateRoyalties(opponentRows) }
956
+ }
957
+ };
958
+ }
959
 
960
  // Calculate best moves (simplified for demo)
961
  function calculateBestMoves() {
 
968
  v => v !== null && gameState.cardPositions[v]?.startsWith('opponent-')
969
  ).length;
970
 
971
+
 
 
 
 
 
972
  const resultsContainer = document.getElementById('results');
973
  const resultsContent = document.getElementById('results-content');
974
 
 
1034
 
1035
  // Show final scores when all cards are placed
1036
  function showFinalScores() {
1037
+ // Получаем данные рядов
1038
+ const playerRows = {
1039
+ top: updateRowCombination('player-top', 3),
1040
+ middle: updateRowCombination('player-middle', 5),
1041
+ bottom: updateRowCombination('player-bottom', 5)
1042
+ };
1043
+
1044
+ const opponentRows = {
1045
+ top: updateRowCombination('opponent-top', 3),
1046
+ middle: updateRowCombination('opponent-middle', 5),
1047
+ bottom: updateRowCombination('opponent-bottom', 5)
1048
+ };
1049
 
1050
+ // Вычисляем очки
1051
+ const scores = calculateScores(playerRows, opponentRows);
1052
+
1053
+ // Только отображение результатов
1054
+ document.getElementById('final-player-score').textContent = scores.player;
1055
+ document.getElementById('final-opponent-score').textContent = scores.opponent;
1056
+ document.getElementById('final-player-top').textContent = scores.details.player.royalties;
1057
+ document.getElementById('final-opponent-top').textContent = scores.details.opponent.royalties;
1058
+ document.getElementById('score-summary').classList.remove('hidden');
1059
+ }
 
 
 
 
 
 
 
 
 
 
 
 
1060
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1061
 
1062
  // Reset all cards
1063
  function resetAllCards() {
 
1121
  initGame();
1122
  });
1123
  </script>