<h1>Sheldon's <div>Rock-Paper-Scissors-</div>
<div>Lizard-Spock</div>
</h1>
<div class="cs-game">
<div class="cs-score">
<div class="cs-score-1">Score: <span>0</span></div>
<div class="cs-spacer">
</div>
<div class="cs-score-2">Score: <span>0</span></div>
</div>
<div class="cs-win-lose win">
<p>You win!</p>
<div><button class="cs-play-btn">Play again!</button></div>
</div>
<div class="cs-game-board">
<div class="cs-game-number">1 / 10</div>
<div class="cs-computer">
<div>
<div class="cs-player-1" data-choice="2"><span>Me</span></div>
<div class="cs-spacer"></div>
<div class="cs-player-2" data-choice="2"><span>PC</span></div>
</div>
</div>
<div class="cs-player">
<div>
<button class="cs-hand" data-hand="0" data-image="🤛">
<span class="visually-hidden">rock</span>
</button>
<button class="cs-hand" data-hand="1" data-image="✋">
<span class="visually-hidden">paper</span>
</button>
<button class="cs-hand" data-hand="2" data-image="✌">
<span class="visually-hidden">scissor</span>
</button>
<button class="cs-hand" data-hand="3" data-image="🦎">
<span class="visually-hidden">lizard</span>
</button>
<button class="cs-hand" data-hand="4" data-image="🖖">
<span class="visually-hidden">spock</span>
</button>
</div>
</div>
</div>
</div>
<div class="info">
<div>
<label for="toggle-rules"><i>i</i><strong>Rules</strong></label>
<input type="checkbox" id="toggle-rules" class="visually-hidden">
<div class="rule-list">
<p>Best score of 10 plays - wins!</p>
<ul>
<li>Scissors cuts Paper
</li>
<li>Paper covers Rock
</li>
<li>Rock crushes Lizard
</li>
<li>Lizard poisons Spock
</li>
<li>Spock smashes Scissors
</li>
<li>Scissors decapitates Lizard
</li>
<li>Lizard eats Paper
</li>
<li>Paper disproves Spock
</li>
<li>Spock vaporizes Rock
</li>
<li>(and as it always has) Rock crushes Scissors
</li>
</ul>
<p><a href="https://bigbangtheory.fandom.com/wiki/Rock,_Paper,_Scissors,_Lizard,_Spock" target="_blank" rel="noopener noreferrer">https://bigbangtheory.fandom.com/wiki/Rock,_Paper,_Scissors,_Lizard,_Spock</a></p>
</div>
</div>
</div>
/**
Rock Paper Scissors Lizard Spock Game
author: @chrisbautista
website: https://www.codespud.com
*/
@import url("https://fonts.googleapis.com/css2?family=Fredoka+One&family=Source+Serif+Pro:ital@1&display=swap");
.visually-hidden {
position: absolute;
top: -9999px;
left: -9999px;
display: none;
}
body {
font-family: serif;
font-family: "Source Serif Pro", serif;
background-color: #f1f2f3;
}
h1 {
font-family: "Fredoka One", cursive;
font-size: 2.3vw;
margin-left: 2rem;
text-align: left;
background: -webkit-linear-gradient(red, green);
background: linear-gradient(red, green);
-webkit-background-clip: text;
background-clip: text;
-webkit-text-fill-color: transparent;
text-fill-color: transparent;
margin-block-end: 0;
@media screen and (max-width: 1200px) {
font-size: 3vw;
}
@media screen and (max-width: 900px) {
font-size: 4vw;
}
@media screen and (max-width: 600px) {
font-size: 6vw;
}
}
.cs-game {
display: flex;
justify-content: center;
padding: 1rem 2rem;
flex-direction: column;
&-board {
border-top: 4px solid #333;
}
}
%-padding-container {
font-size: 2rem;
padding: 1.5rem 0;
}
.cs-score {
@extend %-padding-container;
display: flex;
justify-content: space-between;
}
.cs-win-lose,
.cs-computer,
.cs-player {
@extend %-padding-container;
display: flex;
align-items: center;
justify-content: center;
min-width: 70%;
border-bottom: 4px solid #333;
}
.cs-player {
div {
display: inline-flex;
justify-content: center;
flex-wrap: wrap;
}
}
.win {
background-color: rgba(187, 241, 187, 0.5);
}
.lose {
background-color: rgba(214, 187, 187, 0.5);
}
.tie {
background-color: #ccc;
}
.hidden {
display: none;
}
.cs-game-number {
padding: 0;
display: inline-block;
width: 120px;
text-align: left;
font-size: 1.2rem;
font-weight: bolder;
margin: 0 auto;
position: relative;
top: 8px;
left: 8px;
color: #333;
}
.cs-win-lose {
border: 3px solid #333;
flex-direction: column;
padding: 2rem;
p {
padding-top: 0;
margin: 0 0 20px;
font-size: 3rem;
}
.cs-play-btn {
cursor: pointer;
border: 2px solid #333;
border-radius: 0.8rem;
padding: 0.8rem 1.2rem;
box-shadow: 2px 4px 8px 0 rgba(0, 0, 0, 0.2);
background-color: #ffc83d;
font-weight: bold;
font-family: "Fredoka One", cursive;
font-size: 1.2rem;
letter-spacing: 3px;
transition: all 0.2s;
margin-top: 3rem;
border-radius: 20px;
box-shadow: 4px 4px 8px 0 rgba(0, 0, 0, 0.25),
/* Outset shadow */ inset -4px -4px 8px 0 rgba(0, 0, 0, 0.25),
/* Dark inset shadow */ inset 4px 4px 8px 0 rgba(255, 255, 255, 0.4); /* Light inset shadow */
&:hover {
transform: rotate(-10deg);
}
}
}
%-hand {
border: none;
padding: 1.5rem;
background-color: transparent;
border-radius: 0.9rem;
font-size: 3rem;
text-shadow: -2px 2px 4px rgba(0, 0, 0, 0.3);
transition: text-shadow 0.4s;
}
@keyframes popleft {
50% {
transform: scale(-1.2, 1.2) rotate(90deg);
}
}
@keyframes popleft2 {
50% {
transform: scale(-1.2, 1.2) rotate(0deg);
}
}
@keyframes popright {
50% {
transform: scale(1.2, 1.2) rotate(90deg);
}
}
@keyframes popright2 {
50% {
transform: scale(1.2, 1.2) rotate(0deg);
}
}
.cs-computer {
color: green;
font-family: "Fredoka One", cursive;
font-style: bold;
font-size: 3rem;
padding: 3rem 0;
transition: background-color 0.4s ease-out;
position: relative;
@media screen and (max-width: 600px) {
font-size: 2.5rem;
}
@media screen and (max-width: 420px) {
font-size: 1.5rem;
}
div {
display: inline-flex;
}
.cs-spacer {
width: 4px;
background-color: #333;
}
.cs-player-1,
.cs-player-2 {
position: relative;
&[data-choice]:after {
@extend %-hand;
width: 160px;
font-size: 5rem;
display: inline-flex;
justify-content: center;
@media screen and (max-width: 600px) {
width: 75px;
font-size: 3rem;
}
}
&[data-choice="0"]:after {
content: "🤛";
}
&[data-choice="1"]:after {
content: "✋";
}
&[data-choice="2"]:after {
content: "✌";
}
&[data-choice="3"]:after {
content: "🦎";
}
&[data-choice="4"]:after {
content: "🖖";
}
}
.cs-player-1 {
color: red;
&[data-choice]:after {
transform: scale(-1, 1) rotate(0deg);
}
&[data-choice="2"]:after,
&[data-choice="1"]:after {
transform: scale(-1, 1) rotate(-90deg);
}
&.enter {
&[data-choice]:after {
animation: popleft 0.3s ease-out 1;
}
&[data-choice="2"]:after,
&[data-choice="1"]:after {
animation: popleft2 0.3s ease-out 1;
}
}
}
.cs-player-2 {
flex-direction: row-reverse;
&[data-choice]:after {
transform: scale(1, 1) rotate(0deg);
}
&[data-choice="2"]:after,
&[data-choice="1"]:after {
transform: scale(1, 1) rotate(-90deg);
}
&.enter {
&[data-choice]:after {
animation: popright 0.3s ease-out 1;
}
&[data-choice="2"]:after,
&[data-choice="1"]:after {
animation: popright2 0.3s ease-out 1;
}
}
}
}
.cs-hand {
@extend %-hand;
background-color: #ffc83d;
width: 150px;
height: 150px;
margin-right: 12px;
margin-top: 12px;
transition: all 0.2s;
cursor: pointer;
text-shadow: 2px 2px 0 #333, 2px 2px 4px #333, 2px -2px 0 #333,
-2px 2px 0 #333, -2px -2px 0 #333, 2px 0px 0 #333, 0px 2px 0 #333,
-2px 0px 0 #333, 0px -4px 0 #333;
border-radius: 20px;
box-shadow: 4px 4px 8px 0 rgba(0, 0, 0, 0.25),
/* Outset shadow */ inset -4px -4px 8px 0 rgba(0, 0, 0, 0.25),
/* Dark inset shadow */ inset 4px 4px 8px 0 rgba(255, 255, 255, 0.4); /* Light inset shadow */
&:before {
display: inline-flex;
content: attr(data-image);
}
&:hover {
transform: scale(1.1);
}
&.clicked {
text-shadow: 4px 4px 0 #4074b5, 4px -4px 0 #4074b5, -4px 4px 0 #4074b5,
-4px -4px 0 #4074b5, 4px 0px 0 #4074b5, 0px 4px 0 #4074b5,
-4px 0px 0 #4074b5, 0px -4px 0 #4074b5;
}
@media screen and (max-width: 600px) {
width: 80px;
height: 80px;
font-size: 2rem;
}
}
.info {
position: absolute;
top: 0;
right: 40px;
padding: 3px;
background-color: #f8f9fb;
border-radius: 1rem;
margin: 1rem auto 0;
width: 99px;
box-sizing: border-box;
@media screen and (max-width: 600px) {
width: 60px;
padding: 0;
}
p {
padding-left: 20px;
word-break: break-all;
}
label {
cursor: pointer;
width: 100%;
text-align: center;
}
& > div {
padding: 1.2rem;
@media screen and (max-width: 600px) {
padding: 0.5rem;
}
}
.rule-list {
overflow: hidden;
transition: height 0.3s ease-out;
}
#toggle-rules + .rule-list {
height: 0;
width: 0;
transition: right 0.8s, width 0.3s ease-out, height 0.3s ease-out;
background-color: #f8f9fb;
border-radius: 1rem;
padding: 0;
position: absolute;
right: 0;
}
#toggle-rules:checked ~ .rule-list {
height: 360px;
width: 500px;
right: 0;
background-color: #f8f9fb;
border-radius: 1rem;
padding: 1rem 1.5rem;
box-sizing: content-box;
box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.2);
@media screen and (max-width: 600px) {
width: calc(100vw - 4rem);
min-height: 50vh;
}
}
strong {
margin-left: 8px;
font-family: "Fredoka One", cursive;
font-size: 1.2rem;
@media screen and (max-width: 600px) {
display: none;
}
}
i {
display: inline-flex;
width: 1.2rem;
height: 1.2rem;
position: relative;
top: -4px;
left: 10px;
justify-content: center;
align-items: center;
background-color: blue;
color: #f1f2f3;
margin: 0 10px;
}
li {
list-style-type: "👉";
padding-inline-start: 1ch;
}
}
View Compiled
/**
Rock Paper Scissors Lizard Spock Game
author: @chrisbautista
website: https://www.codespud.com
*/
(function () {
const Hands = {
Rock: 0,
Paper: 1,
Scissor: 2,
Lizard: 3,
Spock: 4
};
let score = [0, 0];
let maxGames = 10;
let games = 0;
let done = false;
const buttons = document.querySelectorAll(".cs-hand");
const playerNode1 = document.querySelector(".cs-computer .cs-player-1");
const playerNode2 = document.querySelector(".cs-computer .cs-player-2");
const scoreNode1 = document.querySelector(".cs-score-1");
const scoreNode2 = document.querySelector(".cs-score-2");
const boardNode = document.querySelector(".cs-computer");
const winLoseNode = document.querySelector(".cs-win-lose");
const playBtn = document.querySelector(".cs-play-btn");
const gameNumber = document.querySelector(".cs-game-number");
let boardTimeout = null;
function playGame() {
console.log("start game");
resetGame();
Array.from(buttons).forEach((button) =>
button.addEventListener("click", runHand)
);
playBtn.addEventListener("click", () => {
resetGame();
});
}
function runHand(e) {
if (done) {
return;
}
const target = e.currentTarget;
const choice = parseInt(target.dataset.hand);
const computerChoice = getComputerHand();
popHand(playerNode1, choice);
popHand(playerNode2, computerChoice);
target.classList.add("clicked");
setTimeout((_) => target.classList.remove("clicked"), 200);
setScore(parseInt(choice), parseInt(computerChoice));
setGame();
gameOver();
}
function gameOver() {
let [yourScore, pcScore] = score;
if (games >= maxGames) {
done = true;
if (yourScore === pcScore) {
gameResult("It's a draw!", "tie");
} else if (yourScore > pcScore) {
gameResult("You win!", "win");
} else {
gameResult("You lost!", "lose");
}
return;
}
}
function setGame() {
gameNumber.innerHTML = `${++games} / ${maxGames}`;
}
function gameResult(message, state) {
boardNode.classList.add("hidden");
winLoseNode.querySelector("p").innerHTML = message;
winLoseNode.classList.remove("hidden");
winLoseNode.classList.add(state);
gameNumber.innerHTML = `${games} / ${maxGames}`;
}
function resetGame() {
score = [0, 0];
games = 0;
done = false;
renderScore(scoreNode1, 0);
renderScore(scoreNode2, 0);
popHand(playerNode1, 0);
popHand(playerNode2, 0);
boardNode.classList.remove("hidden");
winLoseNode.setAttribute("class", "cs-win-lose hidden");
gameNumber.innerHTML = `${games} / ${maxGames}`;
}
function popHand(node, choice) {
node.classList.add("enter");
node.setAttribute("data-choice", choice);
setTimeout((_) => node.classList.remove("enter"), 400);
}
function animateBoard(state) {
clearTimeout(boardTimeout);
boardNode.setAttribute("class", "cs-computer");
boardNode.classList.add(state);
boardTimeout = setTimeout((_) => boardNode.classList.remove(state), 900);
}
function getComputerHand() {
return Math.floor(Math.random() * Object.keys(Hands).length);
}
function renderScore(node, value) {
node.querySelector("span").innerHTML = value;
}
function setScore(choice, computerChoice) {
if (choice === computerChoice) {
// tie
animateBoard("tie");
return;
}
if (
(choice === Hands.Paper && computerChoice === Hands.Rock) ||
(choice === Hands.Rock && computerChoice === Hands.Scissor) ||
(choice === Hands.Scissor && computerChoice === Hands.Paper) ||
(choice === Hands.Rock && computerChoice === Hands.Lizard) ||
(choice === Hands.Lizard && computerChoice === Hands.Spock) ||
(choice === Hands.Spock && computerChoice === Hands.Scissors) ||
(choice === Hands.Scissors && computerChoice === Hands.Lizard) ||
(choice === Hands.Lizard && computerChoice === Hands.Paper) ||
(choice === Hands.Paper && computerChoice === Hands.Spock) ||
(choice === Hands.Spock && computerChoice === Hands.Rock)
) {
animateBoard("win");
renderScore(scoreNode1, ++score[0]);
return;
}
animateBoard("lose");
renderScore(scoreNode2, ++score[1]);
}
playGame();
})();
This Pen doesn't use any external CSS resources.
This Pen doesn't use any external JavaScript resources.