For an interview, I had to create a card game called match
. The rules were the following:
Players can choose a number of packs of playing cards and combine them into a single deck. The deck can be shuffled.
Cards are played sequentially from the top of the deck into the pile,
If two cards played sequentially match, the first player to declare "Match" takes all the cards in the pile.
(For the purpose of the simulation the program should randomly choose a player to have declared "Match" first).
The play then continues with the next card in the deck, starting a new pile. The game ends no more cards can be drawn from the deck and no player can declare "Match!".
The player that has taken the most cards is the winner. The game may end in a draw.
The match condition can be the following
The suits of two cards must match
Example: "3 of hearts" and "5 of hearts" match because they are both hearts.
The values of two cards must match
Example: "7 of hearts" and "7 of clubs" match because they both have the value 7.
Both suit and value must match
Example: "Jack of spades" only matches another "Jack of spades"
The program
As input, the program should ask:
how many packs of cards to use for the deck
which match condition to use
It should then simulate the game.
The program should output the results by either declaring the winner, or a draw.
I had a timebox of 90 minutes to complete this task but I ran out of time. My approach was to basically eventually have a front end plugged into this so wrote the code with that approach. After I submitted I realized I didn't add the check for a draw.
Here is deck.js
const suits = ["♠", "♥", "♣", "♦"];
const values = [
"2",
"3",
"4",
"5",
"6",
"7",
"8",
"9",
"10",
"J,",
"Q",
"K",
"A",
];
class Deck {
constructor(packs = 1) {
this.packs = packs;
this.deck = [];
}
newDeck() {
let counter = this.packs;
while (counter) {
for (let suit of suits) {
for (let value of values) {
this.deck.push(new Card(value, suit));
}
}
counter--;
}
return this.deck;
}
get deckSize() {
return this.deck.length;
}
shuffle() {
let counter = this.deckSize,
temp,
i;
while (counter) {
i = Math.floor(Math.random() * counter--);
temp = this.deck[counter];
this.deck[counter] = this.deck[i];
this.deck[i] = temp;
}
return this.deck;
}
deal() {
let hand = [];
while (hand.length < 2) {
hand.push(this.deck.shift());
}
return hand;
}
}
class Card {
constructor(value, suit) {
this.value = value;
this.suit = suit;
}
}
module.exports = {Deck, Card}
here is my app.js
const { Deck } = require("./deck.js");
const MatchCondition = Object.freeze({ suits: 1, values: 2, both: 3 });
const players = ["playerOne", "playerTwo"];
const playerScores = {
playerOne: 3,
playerTwo: 4,
};
let deck;
let cards = {};
let result = "";
const cardsAreEqual = (card1, card2) => {
Object.keys(card1).length === Object.keys(card2).length &&
Object.keys(card1).every((p) => card1[p] === card2[p]);
};
const matchCondition = (cards, condition) => {
//Need to add some error handling for when the conditions
//Does not match a MatchCondition
let result = "";
if (condition === MatchCondition.suits) {
if (cards[0].suit === cards[1].suit) {
result = `The Suits MATCH !!!`;
}
}
if (condition === MatchCondition.value) {
if (cards[0].value === cards[1].value) {
result = `The Values MATCH !!!`;
}
}
if (condition === MatchCondition.both) {
if (cardsAreEqual(cards[0], cards[1])) {
result = `The Cards MATCH !!!`;
}
}
return result;
};
const winningScore = (playerObj) => {
const [key, value] = Object.entries(playerObj).reduce((r, e) =>
e[1] > r[1] ? e : r
);
return { [key]: value };
};
const startGame = (numOfPacks, condition) => {
const randomPlayer = Math.floor(Math.random() * players.length);
deck = new Deck(numOfPacks);
deck.newDeck();
deck.shuffle();
if (deck.deckSize !== 0) {
cards = deck.deal();
result = matchCondition(cards, condition);
if (result !== "") {
playerScores[players[randomPlayer]]++;
return `${players[randomPlayer]} shouted ${result}`;
}
} else {
return winningScore(playerScores);
}
};
startGame(2, MatchCondition.suits);