<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Kevin's Pig Dice</title>
<style>
body{background-color:darkslategrey;}
#pig{
position:relative !important;
width:400px;
height:400px;
background-color:ForestGreen;
margin-left:auto;margin-right:auto;
overflow:hidden;
outline:2px solid black;
font-family:sans-serif;
font-weight:bold;
user-select:none;
text-align:center;
}
#pig_title{
width:100%;
height:40px;
color:ForestGreen;
text-shadow:0 0 3px black,
0 0 3px black;
font-style:italic;
font-size:2em;
}#pig_howToPlay{
position:absolute;
right:0px;
top:0px;
width:40px;
height:40px;
background-color:dodgerblue;
color:white;
border-radius:999px;
font-size:2em;
cursor:pointer;
}
#pig_youScore,#pig_cpuScore{
border-bottom:1px solid black;
padding-top:10px;
width:200px;
height:30px;
float:left;
}
#pig_gameMessage{
padding-top:10px;
width:100%;
font-style:italic;
float:left;
color:white;
text-shadow:0 0 3px black,
0 0 3px black;
}
#pig_gameMessage.pig_loseMessage{
font-size:1.5em;
color:LightCoral;
}
#pig_gameMessage.pig_winMessage{
animation:pig_winMessage 0.7s linear 0s infinite alternate;
}
@keyframes pig_winMessage{
from{color:Yellow;font-size:1.5em;}
to {color:DeepPink;}
}
#pig_gatherScore{
position: absolute;
right:0px;
top:200px;
width:100px;
}
#pig_gatherScoreText{font-size:1.5em;}
#pig_rollButton,#pig_holdButton{
position:absolute;
bottom:10px;
width:170px;
height:30px;
padding-top:10px;
background-color:lightskyblue;
border:5px double black;
border-radius:999px;
box-shadow: 0px 0px 10px 0px black;
cursor:pointer;
}
#pig_rollButton:hover,#pig_holdButton:hover{border-color:white;}
#pig_rollButton{left:10px;}
#pig_holdButton{left:210px;}
#pig_die{
position:absolute;
left:125px;
top:180px;
width:100px;
height:100px;
background-color:AntiqueWhite;
border-radius:20px;
box-shadow: 0px 0px 10px 0px black,
0px 0px 10px 0px black;/* X, Y, outer extent, inner extent, color */
}
#pig_die.pig_dieRolling{animation:pig_dieRolling 0.06s ease-out 0s infinite alternate;}
@keyframes pig_dieRolling{
from{background-color:khaki;box-shadow: 0px 0px 10px 0px black;}
to {background-color:white;box-shadow: 0px 0px 10px 20px rgba(0,0,0,0.1);}
}
.pig_dieDot{
position:absolute;
left:-20px;
width:20px;
height:20px;
border-radius:999px;
background-image:radial-gradient(white,black 30%);
}
.pig_dieDot:nth-of-type(1){left:calc(25% - 10px);top:calc(25% - 10px);}
.pig_dieDot:nth-of-type(2){left:calc(25% - 10px);top:calc(50% - 10px);}
.pig_dieDot:nth-of-type(3){left:calc(25% - 10px);top:calc(75% - 10px);}
.pig_dieDot:nth-of-type(4){left:calc(75% - 10px);top:calc(25% - 10px);}
.pig_dieDot:nth-of-type(5){left:calc(75% - 10px);top:calc(50% - 10px);}
.pig_dieDot:nth-of-type(6){left:calc(75% - 10px);top:calc(75% - 10px);}
.pig_dieDot:nth-of-type(7){left:calc(50% - 10px);top:calc(50% - 10px);}
/*.pig_blinking{animation:pig_blinking 0.33s linear 0s infinite normal;}
@keyframes pig_blinking{
from{text-decoration:underline;}
to {text-decoration:none;}
}*/
.pig_blinking_green{animation:pig_blinking_green 0.33s linear 0s infinite normal;}
.pig_blinking_red {animation:pig_blinking_red 0.33s linear 0s infinite normal;}
@keyframes pig_blinking_green{
from{background-color:limegreen;}
to {background-color:rgba(0,0,0,0.01);}
}
@keyframes pig_blinking_red{
from{background-color:crimson;}
to {background-color:rgba(0,0,0,0.01);}
}
</style>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<script>
"use strict";
$(document).ready(function(){
Startup();
});
function Startup(){
let html="";
html+="<div id='pig_die'>";
for(let x=0;x<7;x++){
html+="<div class='pig_dieDot'></div>";
}
html+="</div>";
html+="<div id='pig_title'>Kevin's Pig Dice</div>";
html+="<div id='pig_howToPlay'>?</div>";
html+="<div id='pig_youScore'>Your score: <span id='pig_youScoreText'>0</span></div>";
html+="<div id='pig_cpuScore'>CPU score: <span id='pig_cpuScoreText'>0</span></div>";
html+="<div id='pig_gameMessage'></div>";
html+="<div id='pig_gatherScore'>Gathered:<br><span id='pig_gatherScoreText'>0</span></div>";
html+="<div id='pig_rollButton'>Roll</div>";
html+="<div id='pig_holdButton'>Hold</div>";
$("#pig").html(html);
$("#pig_howToPlay").click(function(){
let message="===========================\n"+
"HOW TO PLAY\n\n"+
"The game has two players, you versus the CPU.\n\n"+
"On your turn, roll the die repeatedly to 'gather' points nearby.\n\n"+
"If you click HOLD, you keep those gathered points, and your turn is over.\n\n"+
"If you roll a 1, you get no points, and your turn is over.\n\n"+
"The first player to 100 points wins.\n"+
"===========================";
alert(message);
});
SetDieRandom();
dieStartPosLeft=parseInt($("#pig_die").css("left"));
dieStartPosTop=parseInt($("#pig_die").css("top"));
$("#pig_rollButton").click(Roll).text("Start");
$("#pig_holdButton").click(Hold).hide();
}
function DieRolling(){
SetDieRandom();
/* move around */
const moveSpeed=40;
const moveBounds=20;
const rotateSpeed=30;
let leftPos=parseInt($("#pig_die").css("left"));
leftPos+=(Math.random()*moveSpeed*2)-moveSpeed;
if(leftPos<dieStartPosLeft-moveBounds)leftPos=dieStartPosLeft-moveBounds;
else if(leftPos>dieStartPosLeft+moveBounds)leftPos=dieStartPosLeft+moveBounds;
$("#pig_die").css("left",leftPos);
let topPos=parseInt($("#pig_die").css("top"));
topPos+=(Math.random()*moveSpeed*2)-moveSpeed;
if(topPos<dieStartPosTop-moveBounds)topPos=dieStartPosTop-moveBounds;
else if(topPos>dieStartPosTop+moveBounds)topPos=dieStartPosTop+moveBounds;
$("#pig_die").css("top",topPos);
/* spin around */
dieRot+=(Math.random()*rotateSpeed*2)-rotateSpeed;
$("#pig_die").css("transform","rotate("+dieRot+"deg)");
}
function SetDieRandom(){
SetDie(GetRandomDieValue());
}
function GetRandomDieValue(){
return Math.floor(Math.random()*6)+1;
}
function SetDie(n){
let thisDot;
thisDot=$(".pig_dieDot:nth-of-type(1)");
n!=1 ? thisDot.show() : thisDot.hide();
thisDot=$(".pig_dieDot:nth-of-type(2)");
n==6 ? thisDot.show() : thisDot.hide();
thisDot=$(".pig_dieDot:nth-of-type(3)");
n>=4 ? thisDot.show() : thisDot.hide();
thisDot=$(".pig_dieDot:nth-of-type(4)");
n>=4 ? thisDot.show() : thisDot.hide();
thisDot=$(".pig_dieDot:nth-of-type(5)");
n==6 ? thisDot.show() : thisDot.hide();
thisDot=$(".pig_dieDot:nth-of-type(6)");
n!=1 ? thisDot.show() : thisDot.hide();
thisDot=$(".pig_dieDot:nth-of-type(7)");
n==1||n==3||n==5 ? thisDot.show() : thisDot.hide();
}
function ShowButtons(showRoll,showHold){
let element=$("#pig_rollButton");
showRoll ? element.show() : element.hide();
element=$("#pig_holdButton");
showHold ? element.show() : element.hide();
}
function SetMessage(string){
$("#pig_gameMessage").html(string);
}
function GetScoreBox(string){
switch(string){
case "you":return $("#pig_youScore");
case "cpu":return $("#pig_cpuScore");
case "gather":return $("#pig_gatherScore");
default:console.error("error");
};
}
function GetScore(string){
switch(string){
case "you":return parseInt($("#pig_youScoreText").text());
case "cpu":return parseInt($("#pig_cpuScoreText").text());
case "gather":return parseInt($("#pig_gatherScoreText").text());
default:console.error("error");
};
}
function SetScore(string,score){
switch(string){
case "you":$("#pig_youScoreText").text(score);break;
case "cpu":$("#pig_cpuScoreText").text(score);break;
case "gather":$("#pig_gatherScoreText").text(score);break;
default:console.error("error");
}
}
function BlinkScores(you,cpu,gather){
let element=GetScoreBox("you");
you ? element.addClass("pig_blinking_"+you) : element.removeClass("pig_blinking_green").removeClass("pig_blinking_red");
element=GetScoreBox("cpu");
cpu ? element.addClass("pig_blinking_"+cpu) : element.removeClass("pig_blinking_green").removeClass("pig_blinking_red");
element=GetScoreBox("gather");
gather ? element.addClass("pig_blinking_"+gather) : element.removeClass("pig_blinking_green").removeClass("pig_blinking_red");
}
let timer_dieRandom;
let timer_turnDelay;
const turnDelay=1000*3.0;
const rollDelay=1000*1.5;
let dieStartPosLeft;
let dieStartPosTop;
let dieRot=0;
let gameState="end";
function Roll(){
if(gameState=="end"){/* new game */
SetScore("you",0);
SetScore("cpu",0);
SetScore("gather",0);
gameState="you";
$("#pig_rollButton").text("Roll");
$("#pig_gameMessage").attr("class","");
}
BlinkScores(false,false,false);
ShowButtons(false,false);
if(gameState=="you"){
SetMessage("");
}else if(gameState=="cpu"){
SetMessage("CPU is rolling...");
}
timer_dieRandom=setInterval(DieRolling,1000/15);
timer_turnDelay=setTimeout(EndOfRoll,rollDelay);
$("#pig_die").addClass("pig_dieRolling");
}
function EndOfRoll(){
clearInterval(timer_dieRandom);
$("#pig_die").removeClass("pig_dieRolling");
let dieValue=GetRandomDieValue();
SetDie(dieValue);
if(gameState=="you"){
if(dieValue==1){
if(GetScore("gather")==0)SetMessage("You rolled a 1!<br>Oh no! Your turn is over.");
else SetMessage("You rolled a 1!<br>Oh no! The "+GetScore("gather")+" was lost.");
SetScore("gather",0);
BlinkScores(false,false,"red");
gameState="cpu";
timer_turnDelay=setTimeout(function(){
SetMessage("It's CPU's turn.");
BlinkScores(false,false,false);
timer_turnDelay=setTimeout(Roll,turnDelay);
},turnDelay);
}else{/* die is not a 1 */
let totalScore=GetScore("you")+GetScore("gather")+dieValue;
if(totalScore>=100){/* win */
SetMessage("YOU WIN!");
$("#pig_gameMessage").addClass("pig_winMessage");
$("#pig_rollButton").text("Play again");
ShowButtons(true,false);
SetScore("gather",GetScore("gather")+dieValue);
SetScore("you",totalScore);
BlinkScores("green",false,false);
gameState="end";
}else{
if(GetScore("gather")==0)SetMessage("You gathered "+dieValue+".");
else SetMessage("You gathered "+dieValue+" more.");
SetScore("gather",GetScore("gather")+dieValue);
BlinkScores(false,false,"green");
ShowButtons(true,true);
}
}
}else{/* cpu */
if(dieValue==1){
if(GetScore("gather")==0)SetMessage("CPU rolled a 1!<br>Their turn is over.");
else SetMessage("CPU rolled a 1!<br>The "+GetScore("gather")+" was lost.");
SetScore("gather",0);
BlinkScores(false,false,"red");
timer_turnDelay=setTimeout(function(){
gameState="you";
SetMessage("It's your turn.");
BlinkScores(false,false,false);
ShowButtons(true,false);
},turnDelay);
}else{/* die not a 1 */
let totalScore=GetScore("cpu")+GetScore("gather")+dieValue;
if(totalScore>=100){/* win */
SetMessage("CPU won!<br>Oh no! You lose.");
$("#pig_gameMessage").addClass("pig_loseMessage");
$("#pig_rollButton").text("Play again");
ShowButtons(true,false);
SetScore("gather",GetScore("gather")+dieValue);
SetScore("cpu",totalScore);
BlinkScores(false,"red",false);
gameState="end";
}else{
if(GetScore("gather")==0)SetMessage("CPU gathered "+dieValue+".");
else SetMessage("CPU gathered "+dieValue+" more.");
SetScore("gather",GetScore("gather")+dieValue);
BlinkScores(false,false,"green");
if(GetScore("gather")>=15){
timer_turnDelay=setTimeout(Hold,turnDelay);
}else{
timer_turnDelay=setTimeout(Roll,turnDelay);
}
}
}
}
}
function Hold(){
if(gameState=="you"){
ShowButtons(false,false);
SetMessage("You hold.<br>You scored the "+GetScore("gather")+"!");
SetScore("you",GetScore("you")+GetScore("gather"));
SetScore("gather",0);
BlinkScores("green",false,false);
gameState="cpu";
timer_turnDelay=setTimeout(function(){
SetMessage("It's CPU's turn.");
BlinkScores(false,false,false);
timer_turnDelay=setTimeout(Roll,turnDelay);
},turnDelay);
}else{/* cpu */
SetMessage("CPU holds.<br>They scored the "+GetScore("gather")+".");
SetScore("cpu",GetScore("cpu")+GetScore("gather"));
SetScore("gather",0);
BlinkScores(false,"green",false);
timer_turnDelay=setTimeout(function(){
gameState="you";
SetMessage("It's your turn.");
BlinkScores(false,false,false);
ShowButtons(true,false);
},turnDelay);
}
}
</script>
</head>
<body>
<div id="pig"></div>
</body>
</html>