React
by Sophie
HTML
<div id="app"></div>
CSS
body {
background: #20262E;
padding: 20px;
font-family: Helvetica;
}
.piles {
display: flex;
flex-direction: row;
}
.piles .pile {
width: 40px;
height: 80px;
margin: 10px;
}
.pile.marked {
border-style: dashed;
}
.all-cards .card {
display: inline-flex;
margin: 1px;
width: 20px;
height: 40px;
}
.all-cards li {
display: inline;
}
.card {
width: 40px;
height: 80px;
background: white;
border: 2px solid black;
border-radius: 2px;
display: inline-flex;
justify-content: center;
align-items: center;
}
.card.marked {
border-style: dashed;
}
.card.taken {
background: yellow;
}
.card.not-taken {
background: red;
}
.card.in-pile {
background: green;
}
#app {
background: #fff;
border-radius: 4px;
padding: 20px;
transition: all 0.2s;
}
li {
margin: 8px 0;
}
h2 {
font-weight: bold;
margin-bottom: 15px;
}
.done {
color: rgba(0, 0, 0, 0.3);
text-decoration: line-through;
}
input {
margin-right: 5px;
}
React
const getCards = () => {
let cards = Array.from(Array(98), (e, i) => {return {number: i + 2, taken: false, pileId: null}});
return cards;
}
const getPlayers = (numberOfPlayers) => {
return Array.from(Array(numberOfPlayers)).map((e, i) => {
return {
id: i,
name: "Player " + (i + 1),
cards: []
}
})
}
const shuffle = (a) => {
for (let i = a.length - 1; i > 0; i--) {
const j = Math.floor(Math.random() * (i + 1));
[a[i], a[j]] = [a[j], a[i]];
}
return a;
}
const isCardInPiles = (number, piles) => {
console.log("isCardTaken", number, piles);
return Object.keys(piles).some((pileId) => {
return piles[pileId].find((cardNumber) => cardNumber === number)
});
}
const isCardTaken = (number, players) => {
return players.some((player) => {
return player.cards.some((card) => card.number === number);
})
}
const removeInactiveCards = () => {
return cards.find((card) => !(isCardTaken(card.number, players) || isCardInPiles(card.number, piles) ) );
}
const giveCards = (players, cards, piles) => {
var players = [...players].map((player) => {
var cards = player.cards ? (player.cards.filter((card) => !(isCardTaken(card.number, players) || isCardInPiles(card.number, piles) ))) : [];
return {...player, cards}
});
while (players.find(player => player.cards.length < 5)) {
var nextCard = cards.find((card) => !(isCardTaken(card.number, players) || isCardInPiles(card.number, piles) ) );
(players.filter((player => player.cards.length < 5))[0]).cards.push(nextCard);
console.log("players", players)
}
return players;
}
const Card = ({card, isTaken, isInPile, onClick}) => {
return (<div onClick={() => onClick(card)}key={card.number} className={"card " + (isTaken ? " taken " : " not-taken ") + (isInPile ? " in-pile " : "") + (card.marked ? "marked" : "not-marked")}>{card.number.toString()}</div>)
}
const Pile = ({id, marked, cards, onClick}) => {
return <div ...