我的函式有問題,應該將卡值加在一起。當我用這些引數呼叫函式時,它應該記錄 21 。
score([{ suit: 'HEARTS', value: 1 }, { suit: 'SPADES', value: 11 }]) //Logs 21 as it should
但是當我用相同的值呼叫函式但反轉它時,它會記錄 11
score([{ suit: 'HEARTS', value: 11 }, { suit: 'SPADES', value: 1 }]) // Logs 11 but should log 21
我不明白我應該如何讓它作業,也許有人可以引導我朝著正確的方向前進。下面的代碼:
let score = function (cardObject) {
let getScore = 0;
for (let i = 0; i < cardObject.length; i ) {
let cardValue = cardObject[i].value;
if (cardValue >= 10 && cardValue <= 13) {
getScore = 10;
} else if (cardValue >= 2 && cardValue <= 9) {
getScore = cardValue;
} else if (cardValue === 1) { //Ace
getScore = 11;
if (getScore cardValue > 21) {
getScore -= 10;
}
}
}
return getScore;
}
score([{ suit: 'HEARTS', value: 11 }, { suit: 'SPADES', value: 1 }]) // Logs 11 but should log 21
score([{ suit: 'HEARTS', value: 1 }, { suit: 'SPADES', value: 11 }]) //Logs 21 as it should
score([{ suit: 'HEARTS', value: 1 }, { suit: 'SPADES', value: 1 }, { suit: 'SPADES', value: 1 }, { suit: 'SPADES', value: 10 }]) //Logs 23 but should log 13
score([{ suit: 'HEARTS', value: 10 }, { suit: 'SPADES', value: 1 }, { suit: 'SPADES', value: 1 }, { suit: 'SPADES', value: 1 }]) //Logs 13 as it should
uj5u.com熱心網友回復:
問題是您仍然將 Ace 添加value到總數中以將其與 21 進行比較,此時您已經增加了分數以說明該 Ace。第二個問題會出現在 A 提前出現時,被計為 11,然后隨后的牌仍然突破 21 的上限。
這是一個可能的解決方案:
let score = function (cardObject) {
let getScore = 0;
let hasAce = false;
for (const {value} of cardObject) {
getScore = Math.min(10, value); // Count Ace as 1
hasAce ||= value == 1; // Remember if there was an Ace
}
// Only at the end consider whether an Ace could count as 11
return hasAce && getScore <= 11 ? getScore 10 : getScore;
}
console.log(score([{ suit: 'HEARTS', value: 11 }, { suit: 'SPADES', value: 1 }])) // should log 21
console.log(score([{ suit: 'HEARTS', value: 1 }, { suit: 'SPADES', value: 11 }])) // should logs 21
console.log(score([{ suit: 'HEARTS', value: 1 }, { suit: 'SPADES', value: 1 }, { suit: 'SPADES', value: 1 }, { suit: 'SPADES', value: 10 }])) // should log 13
console.log(score([{ suit: 'HEARTS', value: 10 }, { suit: 'SPADES', value: 1 }, { suit: 'SPADES', value: 1 }, { suit: 'SPADES', value: 1 }])) // should logs 13
關于代碼的一些解釋:
回圈語法在
for..of這里更合適,因為您不需要陣列中的索引,只需要物件。{value}立即獲取value陣列中訪問的物件的屬性。這稱為解構。它在這里很合適,因為我們不需要物件中的任何其他內容——只需要值。Math.min(10, value)是將值 11,12 和 13 轉換為 10 的便捷快捷方式。它不會更改 1 的值,但這是有意的。||=賦值是縮寫,因此hasAce = hasAce || value == 1它確保一旦找到了一個 ace,這個布林值就永遠不會回傳false,而是保留true。在回圈結束時,檢查是否有 ace,以及總分是否允許一個 ace 計為 11,如果是,則回傳總分多 10,否則按原樣回傳總分。條件運算子用于此 (
? :)。
uj5u.com熱心網友回復:
派對有點晚了,因為 trincot 已經解釋了為什么你的代碼不能像你預期的那樣作業,并為你提供了一個解決方案。我的解決方案有點冗長,但我很喜歡陣列方法,所以如果有人對此感興趣,那就是:
const score = (cards) => {
// add up all the cards
const total = cards.reduce((acc, { value }) => {
if (value > 9) {
return acc 10;
}
return acc value;
}, 0);
// check if there is ace in the cards
const hasAce = cards.some(({ value }) => value === 1);
// add 10 if cards contain and ace AND your result won't exceed 21
return hasAce && total <= 11 ? total 10 : total;
};
uj5u.com熱心網友回復:
points為每個物件設定一個屬性并將其保持在 2 到 11 的范圍內可能會更容易,如下所示:
{suit: '?', face: 'ACE', points: 11}
那么手將是一個物件陣列,通過這樣的函式傳遞:
function score(hand) {
let ace = 0; // Define a variable to count aces
// total is an accumulating sum of points
// current is the current object (card)
return hand.reduce((total, current) => {
// If object.points is 11 then increment ace
if (current.points === 11) ace ;
// As long as the total and the object's points is more than 21 AND ace is more than 0
while (total current.points > 21 && ace > 0) {
// total is 10 points less
total = total - 10;
// ace is decremented
ace--;
}
// result is total and object's points
return total current.points;
}, 0);
}
細節在例子中注釋
/* For demo purposes */
/* Returns a shuffled array of objects -- each object represents a card
Example: {suit: '?', face: 'ACE', points: 11}
*/
function deck() {
const suits = ['?', '?', '?', '?'];
const faces = ['TWO', 'THREE', 'FOUR', 'FIVE', 'SIX', 'SEVEN', 'EIGHT', 'NINE', 'TEN', 'JACK', 'QUEEN', 'KING', 'ACE'];
const points = [2, 3, 4, 5, 6, 7, 8, 9, 10, 10, 10, 10, 11];
let deck = [];
for (let s=0; s < suits.length; s ) {
for (let f=0; f < faces.length; f ) {
deck.push({suit: suits[s], face: faces[f], points: points[f]});
}
}
return shuffle(deck);
}
/* For demo purposes */
/* Returns an array in a random order */
function shuffle(array) {
let qty = array.length, temp, i;
while (qty) {
i = Math.floor(Math.random() * qty--);
temp = array[qty];
array[qty] = array[i];
array[i] = temp;
}
return array;
}
/* For demo purposes */
/* Returns a given number of cards */
function draw(cards, qty) {
return [...Array(qty)].map(_ => cards.pop());
}
/**
* Returns the total points of a given array of objects
* @param {array<object>} hand - An array of objects
* @return {number} - The total amount of points
*/
function score(hand) {
let ace = 0;
return hand.reduce((total, current) => {
if (current.points === 11) ace ;
while (total current.points > 21 && ace > 0) {
total = total - 10;
ace--;
}
return total current.points;
}, 0);
}
let D = deck();
console.log("========ROUND 1========");
let handA = draw(D, 2);
let scoreA = score(handA);
console.log("Player A draws: ");
console.log(handA);
console.log("Player A score: " scoreA);
console.log("=======================");
let handB = draw(D, 2);
let scoreB = score(handB);
console.log("Player B draws: ");
console.log(handB);
console.log("Player B score: " scoreB);
console.log("=======================");
console.log("========ROUND 2========");
let hitA = draw(D, 1);
/* After Round 1, merge new draws with the previous draw */
handA = [...handA, ...hitA];
scoreA = score(handA);
console.log("Player A draws: ");
console.log(hitA);
console.log("Player A score: " scoreA);
console.log("=======================");
let hitB = draw(D, 1);
handB = [...handB, ...hitB];
scoreB = score(handB);
console.log("Player B draws: ")
console.log(hitB);
console.log("Plater B score: " scoreB);
console.log("=======================");
console.log("========TEST ACE========");
let handC = [{points: 11}, {points: 4}];
let scoreC = score(handC);
console.log(JSON.stringify(handC));
console.log(scoreC);
let hitC = [{points: 8}];
handC = [...handC, ...hitC];
scoreC = score(handC);
console.log(JSON.stringify(handC));
console.log(scoreC);
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/512634.html
