|
22 | 22 | // execute the code to ensure all tests pass. |
23 | 23 |
|
24 | 24 | function getCardValue(card) { |
25 | | - // TODO: Implement this function |
| 25 | + // Student-friendly step-by-step parsing and validation. |
| 26 | + // 1) Expect a string like "A♠", "10♥", "K♦" where the last character is the suit emoji |
| 27 | + // 2) The rank is everything before the final character (so "10" or "A") |
| 28 | + // 3) Check the suit is one of the four allowed suits, and the rank is valid |
| 29 | + |
| 30 | + if (typeof card !== "string") { |
| 31 | + throw new Error('Card must be a string, e.g. "A♠"'); |
| 32 | + } |
| 33 | + |
| 34 | + const text = card.trim(); |
| 35 | + if (text.length < 2) { |
| 36 | + throw new Error( |
| 37 | + 'Invalid card: too short. Expect a rank and a suit, e.g. "10♠"' |
| 38 | + ); |
| 39 | + } |
| 40 | + |
| 41 | + // The suit is the last character, the rank is the rest |
| 42 | + const suit = text[text.length - 1]; |
| 43 | + const rank = text.slice(0, -1); |
| 44 | + |
| 45 | + const validSuits = new Set(["♠", "♥", "♦", "♣"]); |
| 46 | + if (!validSuits.has(suit)) { |
| 47 | + throw new Error(`Invalid suit "${suit}". Use one of: ♠ ♥ ♦ ♣`); |
| 48 | + } |
| 49 | + |
| 50 | + // Handle special ranks first |
| 51 | + if (rank === "A") return 11; |
| 52 | + if (rank === "J" || rank === "Q" || rank === "K") return 10; |
| 53 | + |
| 54 | + // Otherwise expect a number between 2 and 10 |
| 55 | + const n = Number(rank); |
| 56 | + if (Number.isInteger(n) && n >= 2 && n <= 10) return n; |
| 57 | + |
| 58 | + // If we get here, the rank wasn't recognised |
| 59 | + throw new Error(`Invalid rank "${rank}". Use A, 2-10, J, Q or K`); |
26 | 60 | } |
27 | 61 |
|
28 | 62 | // The line below allows us to load the getCardValue function into tests in other files. |
|
52 | 86 | } |
53 | 87 |
|
54 | 88 | // What other invalid card cases can you think of? |
| 89 | + |
| 90 | +// === Student-friendly examples === |
| 91 | +// These examples show how the function behaves. Run the file with node to see messages. |
| 92 | +console.log("\nRunning student-friendly examples for getCardValue:"); |
| 93 | + |
| 94 | +// Good cards |
| 95 | +console.log("A♠ =>", getCardValue("A♠"), "(expected 11)"); |
| 96 | +console.log("K♦ =>", getCardValue("K♦"), "(expected 10)"); |
| 97 | +console.log("10♥ =>", getCardValue("10♥"), "(expected 10)"); |
| 98 | +console.log("3♣ =>", getCardValue("3♣"), "(expected 3)"); |
| 99 | + |
| 100 | +// Examples that should throw (wrapped in try/catch so the script keeps running) |
| 101 | +const examples = ["invalid", "9x", "a♠", ""]; |
| 102 | +examples.forEach((example) => { |
| 103 | + try { |
| 104 | + const v = getCardValue(example); |
| 105 | + console.log(`${example} => ${v} (unexpected: should have thrown)`); |
| 106 | + } catch (e) { |
| 107 | + console.log(`${example} => throws: ${e.message}`); |
| 108 | + } |
| 109 | +}); |
| 110 | + |
| 111 | +console.log("\nCompleted student-friendly examples"); |
0 commit comments