User prompt
The game is not detecting pairs well
User prompt
Please fix the bug: 'TypeError: self.getCardLabel is not a function' in or related to this line: 'self.rankText = new Text2(self.getCardLabel(), {' Line Number: 90
Code edit (1 edits merged)
Please save this source code
User prompt
Ultimate Video Poker Challenge
Initial prompt
We are making a video-poker game. In this kind of game the player is initially drawn 5 cards and he can select any of the cards dealt to keep, the other cards being rerolled. His score is based on the final hand he obtains after the reroll based on the classic poker hand ranking (with exact values of each hand I will come back later). This is the hand ranking in order from best to worst: Royal Flush: Ace, King, Queen, Jack, Ten, all of the same suit; Straight Flush: Five cards in sequence, all of the same suit; Four of a Kind: Four cards of the same rank; Full House: Three of a kind combined with a pair; Flush: Five cards of the same suit, not in sequence; Straight: Five cards in sequence, not all of the same suit; Three of a Kind: Three cards of the same rank; Two Pair: Two different pairs; One Pair: Two cards of the same rank; High Card: When no other hand is made, the highest card plays
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); var storage = LK.import("@upit/storage.v1"); /**** * Classes ****/ var Button = Container.expand(function (text, width, height, color) { var self = Container.call(this); self.buttonShape = self.attachAsset('button', { anchorX: 0.5, anchorY: 0.5, width: width || 300, height: height || 100, tint: color || 0x2ecc71 }); self.buttonText = new Text2(text, { size: 40, fill: 0xFFFFFF }); self.buttonText.anchor.set(0.5); self.addChild(self.buttonText); self.disable = function () { self.buttonShape.tint = 0x95a5a6; self.interactive = false; }; self.enable = function () { self.buttonShape.tint = color || 0x2ecc71; self.interactive = true; }; // Event handlers self.down = function (x, y, obj) { tween(self, { scaleX: 0.95, scaleY: 0.95 }, { duration: 100 }); }; self.up = function (x, y, obj) { tween(self, { scaleX: 1, scaleY: 1 }, { duration: 100 }); if (self.onPress) { self.onPress(); } }; return self; }); var Card = Container.expand(function (suit, rank) { var self = Container.call(this); self.suit = suit; self.rank = rank; self.isHeld = false; // Get suit symbol self.getSuitSymbol = function () { if (self.suit === 'hearts') { return '♥'; } if (self.suit === 'diamonds') { return '♦'; } if (self.suit === 'clubs') { return '♣'; } if (self.suit === 'spades') { return '♠'; } return ''; }; // Get card color self.getCardColor = function () { if (self.suit === 'hearts' || self.suit === 'diamonds') { return "#ff0000"; } return "#000000"; }; // Get card label self.getCardLabel = function () { return self.rank + self.getSuitSymbol(); }; // Front and back of card self.cardFront = self.attachAsset('cardFront', { anchorX: 0.5, anchorY: 0.5 }); self.cardBack = self.attachAsset('cardBack', { anchorX: 0.5, anchorY: 0.5 }); self.cardBack.visible = false; // Hold indicator self.holdIndicator = self.attachAsset('holdIndicator', { anchorX: 0.5, anchorY: 0.5, y: 85 }); self.holdIndicator.visible = false; // Card text (suit and rank) self.rankText = new Text2(self.getCardLabel(), { size: 40, fill: self.getCardColor() }); self.rankText.anchor.set(0.5); self.rankText.y = -65; self.addChild(self.rankText); // Suit symbol in the center self.suitText = new Text2(self.getSuitSymbol(), { size: 80, fill: self.getCardColor() }); self.suitText.anchor.set(0.5); self.addChild(self.suitText); // Hold text self.holdText = new Text2("HOLD", { size: 24, fill: 0x000000 }); self.holdText.anchor.set(0.5); self.holdText.y = 85; self.addChild(self.holdText); self.holdText.visible = false; // Toggle hold state self.toggleHold = function () { self.isHeld = !self.isHeld; self.holdIndicator.visible = self.isHeld; self.holdText.visible = self.isHeld; }; // Get card value for hand evaluations (1-13) self.getValue = function () { if (self.rank === 'A') { return 14; } if (self.rank === 'K') { return 13; } if (self.rank === 'Q') { return 12; } if (self.rank === 'J') { return 11; } return parseInt(self.rank); }; // Event handlers self.down = function (x, y, obj) { // Scale down slightly on press tween(self, { scaleX: 0.95, scaleY: 0.95 }, { duration: 100 }); }; self.up = function (x, y, obj) { // Scale back to normal tween(self, { scaleX: 1, scaleY: 1 }, { duration: 100 }); self.toggleHold(); }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x2c6e31 }); /**** * Game Code ****/ // Constants var CARD_SPACING = 180; var CARDS_PER_HAND = 5; var CARD_START_Y = 700; var DECK_POSITION_X = 300; var DECK_POSITION_Y = 300; // Game states var STATE_DEAL = "deal"; var STATE_PLAYER_TURN = "playerTurn"; var STATE_FINAL = "final"; // Game variables var deck = []; var playerHand = []; var gameState = STATE_DEAL; var handScore = 0; var handRank = ""; var highestScore = storage.highestScore || 0; // Hand rankings and their scores var handRankings = { "Royal Flush": 800, "Straight Flush": 500, "Four of a Kind": 400, "Full House": 300, "Flush": 250, "Straight": 200, "Three of a Kind": 100, "Two Pair": 50, "Jacks or Better": 10, "High Card": 0 }; // Create the table var table = game.addChild(LK.getAsset('table', { anchorX: 0.5, anchorY: 0.5, x: 2048 / 2, y: 2732 / 2 })); // Create scoreboard text var scoreText = new Text2("Score: 0", { size: 50, fill: 0xFFFFFF }); scoreText.anchor.set(0.5, 0); LK.gui.top.addChild(scoreText); scoreText.y = 50; // Create high score text var highScoreText = new Text2("High Score: " + highestScore, { size: 40, fill: 0xFFFFFF }); highScoreText.anchor.set(1, 0); LK.gui.topRight.addChild(highScoreText); highScoreText.x = -30; highScoreText.y = 30; // Create hand rank text var handRankText = new Text2("", { size: 60, fill: 0xFFFFFF }); handRankText.anchor.set(0.5, 0); handRankText.y = 150; LK.gui.top.addChild(handRankText); // Create draw button var drawButton = new Button("DEAL", 400, 120); drawButton.x = 2048 / 2; drawButton.y = 1300; game.addChild(drawButton); // Setup button behavior drawButton.onPress = function () { if (gameState === STATE_DEAL) { startNewGame(); gameState = STATE_PLAYER_TURN; drawButton.buttonText.setText("DRAW"); } else if (gameState === STATE_PLAYER_TURN) { drawRemainingCards(); gameState = STATE_FINAL; drawButton.buttonText.setText("DEAL AGAIN"); } else if (gameState === STATE_FINAL) { resetGame(); gameState = STATE_DEAL; } }; // Initialize deck function createDeck() { var suits = ['hearts', 'diamonds', 'clubs', 'spades']; var ranks = ['2', '3', '4', '5', '6', '7', '8', '9', '10', 'J', 'Q', 'K', 'A']; var newDeck = []; for (var s = 0; s < suits.length; s++) { for (var r = 0; r < ranks.length; r++) { newDeck.push({ suit: suits[s], rank: ranks[r] }); } } return newDeck; } // Shuffle deck function shuffleDeck(deck) { for (var i = deck.length - 1; i > 0; i--) { var j = Math.floor(Math.random() * (i + 1)); var temp = deck[i]; deck[i] = deck[j]; deck[j] = temp; } return deck; } // Deal cards to player function dealCards() { // Remove old cards from display for (var i = 0; i < playerHand.length; i++) { if (playerHand[i] && playerHand[i].parent) { playerHand[i].parent.removeChild(playerHand[i]); } } // Clear hand playerHand = []; // Create new hand for (var i = 0; i < CARDS_PER_HAND; i++) { if (deck.length > 0) { var cardData = deck.pop(); var card = new Card(cardData.suit, cardData.rank); // Position card card.x = 2048 / 2 + (i - Math.floor(CARDS_PER_HAND / 2)) * CARD_SPACING; card.y = CARD_START_Y; // Add animation card.alpha = 0; card.y += 50; tween(card, { alpha: 1, y: CARD_START_Y }, { duration: 300, easing: tween.easeOutQuad, delay: i * 100 }); playerHand.push(card); game.addChild(card); // Play sound LK.setTimeout(function () { LK.getSound('cardDeal').play(); }, i * 100); } } } // Start a new game function startNewGame() { deck = createDeck(); shuffleDeck(deck); dealCards(); handRankText.setText(""); handScore = 0; updateScore(); } // Draw new cards to replace non-held cards function drawRemainingCards() { for (var i = 0; i < playerHand.length; i++) { if (!playerHand[i].isHeld && deck.length > 0) { var cardData = deck.pop(); // Store old card for animation var oldCard = playerHand[i]; // Create new card var newCard = new Card(cardData.suit, cardData.rank); newCard.x = oldCard.x; newCard.y = oldCard.y; // Replace old card game.removeChild(oldCard); game.addChild(newCard); playerHand[i] = newCard; // Animation and sound newCard.alpha = 0; newCard.y += 20; tween(newCard, { alpha: 1, y: CARD_START_Y }, { duration: 200, easing: tween.easeOutQuad, delay: i * 50 }); LK.setTimeout(function () { LK.getSound('cardDeal').play(); }, i * 50); } } // Evaluate hand after a short delay LK.setTimeout(function () { evaluateHand(); }, 500); } // Reset the game for a new round function resetGame() { // Clear the board for (var i = 0; i < playerHand.length; i++) { if (playerHand[i] && playerHand[i].parent) { tween(playerHand[i], { alpha: 0, y: playerHand[i].y + 50 }, { duration: 300, delay: i * 50, onFinish: function () { if (this && this.parent) { this.parent.removeChild(this); } }.bind(playerHand[i]) }); } } playerHand = []; handRankText.setText(""); } // Evaluate the player's hand function evaluateHand() { var cardValues = playerHand.map(function (card) { return { value: card.getValue(), suit: card.suit }; }); // Sort cards by value (descending) cardValues.sort(function (a, b) { return b.value - a.value; }); // Count occurrences of each value var valueCounts = {}; var suitCounts = {}; for (var i = 0; i < cardValues.length; i++) { var value = cardValues[i].value; var suit = cardValues[i].suit; valueCounts[value] = (valueCounts[value] || 0) + 1; suitCounts[suit] = (suitCounts[suit] || 0) + 1; } // Check for pairs, three of a kind, etc. var pairs = 0; var threeOfAKind = false; var fourOfAKind = false; var hasPairOfJacksOrBetter = false; for (var value in valueCounts) { if (valueCounts[value] === 2) { pairs++; if (value >= 11) { // Jack or better hasPairOfJacksOrBetter = true; } } else if (valueCounts[value] === 3) { threeOfAKind = true; } else if (valueCounts[value] === 4) { fourOfAKind = true; } } // Check for flush var isFlush = false; for (var suit in suitCounts) { if (suitCounts[suit] === 5) { isFlush = true; break; } } // Check for straight var isStraight = false; if (Object.keys(valueCounts).length === 5) { var minValue = Math.min.apply(null, cardValues.map(function (c) { return c.value; })); var maxValue = Math.max.apply(null, cardValues.map(function (c) { return c.value; })); if (maxValue - minValue === 4) { isStraight = true; } // Special case for A-5 straight if (cardValues[0].value === 14 && cardValues[1].value === 5 && cardValues[2].value === 4 && cardValues[3].value === 3 && cardValues[4].value === 2) { isStraight = true; } } // Determine hand rank if (isStraight && isFlush) { if (cardValues[0].value === 14 && cardValues[1].value === 13 && cardValues[2].value === 12 && cardValues[3].value === 11 && cardValues[4].value === 10) { handRank = "Royal Flush"; } else { handRank = "Straight Flush"; } } else if (fourOfAKind) { handRank = "Four of a Kind"; } else if (threeOfAKind && pairs === 1) { handRank = "Full House"; } else if (isFlush) { handRank = "Flush"; } else if (isStraight) { handRank = "Straight"; } else if (threeOfAKind) { handRank = "Three of a Kind"; } else if (pairs === 2) { handRank = "Two Pair"; } else if (hasPairOfJacksOrBetter) { handRank = "Jacks or Better"; } else { handRank = "High Card"; } // Set score handScore = handRankings[handRank]; LK.setScore(LK.getScore() + handScore); // Update high score if needed if (LK.getScore() > highestScore) { highestScore = LK.getScore(); storage.highestScore = highestScore; highScoreText.setText("High Score: " + highestScore); } // Display hand rank handRankText.setText(handRank + " - " + handScore + " points!"); // Update score updateScore(); // Play win sound if score is positive if (handScore > 0) { LK.getSound('win').play(); } } // Update the score display function updateScore() { scoreText.setText("Score: " + LK.getScore()); } // Initialize the game LK.playMusic('bgMusic');
===================================================================
--- original.js
+++ change.js
@@ -56,8 +56,35 @@
var self = Container.call(this);
self.suit = suit;
self.rank = rank;
self.isHeld = false;
+ // Get suit symbol
+ self.getSuitSymbol = function () {
+ if (self.suit === 'hearts') {
+ return '♥';
+ }
+ if (self.suit === 'diamonds') {
+ return '♦';
+ }
+ if (self.suit === 'clubs') {
+ return '♣';
+ }
+ if (self.suit === 'spades') {
+ return '♠';
+ }
+ return '';
+ };
+ // Get card color
+ self.getCardColor = function () {
+ if (self.suit === 'hearts' || self.suit === 'diamonds') {
+ return "#ff0000";
+ }
+ return "#000000";
+ };
+ // Get card label
+ self.getCardLabel = function () {
+ return self.rank + self.getSuitSymbol();
+ };
// Front and back of card
self.cardFront = self.attachAsset('cardFront', {
anchorX: 0.5,
anchorY: 0.5
@@ -119,35 +146,8 @@
return 11;
}
return parseInt(self.rank);
};
- // Get suit symbol
- self.getSuitSymbol = function () {
- if (self.suit === 'hearts') {
- return '♥';
- }
- if (self.suit === 'diamonds') {
- return '♦';
- }
- if (self.suit === 'clubs') {
- return '♣';
- }
- if (self.suit === 'spades') {
- return '♠';
- }
- return '';
- };
- // Get card color
- self.getCardColor = function () {
- if (self.suit === 'hearts' || self.suit === 'diamonds') {
- return "#ff0000";
- }
- return "#000000";
- };
- // Get card label
- self.getCardLabel = function () {
- return self.rank + self.getSuitSymbol();
- };
// Event handlers
self.down = function (x, y, obj) {
// Scale down slightly on press
tween(self, {