Created
July 22, 2016 06:23
-
-
Save chemok78/a7a93de1a7395e461682a7349c4b4817 to your computer and use it in GitHub Desktop.
Simon Game
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<html lang="en"> | |
<head> | |
<meta charset="utf-8"> | |
<meta http-equiv="X-UA-Compatible" content="IE=edge"> | |
<!--Make sure latest rendering mode in IE--> | |
<meta name="viewport" content="width=device-width, initial-scale=1"> | |
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-switch/3.3.2/css/bootstrap2/bootstrap-switch.min.css"> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-switch/3.3.2/js/bootstrap-switch.min.js"></script> | |
<link href="https://fonts.googleapis.com/css?family=Ubuntu" rel="stylesheet"> | |
<!--to ensure proper rendering and touch zooming--> | |
<title>Simon Game</title> | |
</head> | |
<body> | |
<div class="wrapper"> | |
<div id="green"></div> | |
<div id="red"></div> | |
<div id="yellow"></div> | |
<div id="blue"></div> | |
</div><!--wrapper--> | |
<div class="innerCircle text-center"> | |
<h1 id="innerTitle">Simon Game</h1> | |
<div class="gameControls"> | |
<div id="counter" class="control">--</div> | |
<button type="button" class="btn btn-primary btn-md control" id="startButton">Start</button> | |
<button type="button" class="btn btn-primary btn-md control" id="strictButton" data-toggle="button">Strict</button> | |
</div><!--gameControls--> | |
<div class="btn-group" data-toggle="buttons"> | |
<label class="btn btn-primary" id="on"> | |
<input type="radio" name="switch"> On | |
</label> | |
<label class="btn btn-primary active" id="off"> | |
<input type="radio" name="switch" checked>Off | |
</label> | |
</div> | |
</div><!--innerCircle--> | |
</body> | |
</html> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
$(document).ready(function() { | |
var resize = function() { | |
$('.wrapper').css({ | |
position: 'absolute', | |
left: ($(window).width() - $('.wrapper').outerWidth()) / 2, | |
//outerWidth is a jQuery for wdith including padding and behavior | |
//difference between window width and wrapper width divided by 2 | |
top: ($(window).height() - $('.wrapper').outerHeight()) / 2 | |
}); | |
} //resize | |
var resizeCircle = function() { | |
$('.innerCircle').css({ | |
position: 'absolute', | |
left: ($(window).width() - $('.innerCircle').outerWidth()) / 2, | |
//outerWidth is a jQuery for wdith including padding and behavior | |
//difference between window width and wrapper width divided by 2 | |
top: ($(window).height() - $('.innerCircle').outerHeight()) / 2 | |
}); | |
} | |
resize(); | |
//call resize function once when the page is loaded | |
resizeCircle(); | |
$(window).resize(function() { | |
//call resize every time the window resizes | |
resize(); | |
resizeCircle(); | |
}) | |
//global variables | |
var board = ["green", "red", "blue", "yellow"]; | |
//global array for gameplay buttons with different colors | |
var clickCount = 0; | |
//global variable to hold the click sequence by the human player to compare with the computer sequence | |
var currentGame = null; | |
//global variable to hold the current game, toggled by on/off button | |
var currentState = null; | |
//global variable to hold the current state of the game | |
var animateAudio = function(button, speed) { | |
//public function to create button sound and bind to colored button | |
//used both in click by user and animate sequence by computer | |
//input: string for button color: "red", "blue", "yellow", "green" | |
var audio = document.createElement('audio'); | |
//create audio element | |
audio.defaultPlaybackRate = speed; | |
//set the playbackrate to the speed parameter | |
switch (button) { | |
//bind sounds to the different color buttons | |
case "red": | |
audio.setAttribute('src', 'https://s3.amazonaws.com/freecodecamp/simonSound1.mp3'); | |
break; | |
case "blue": | |
audio.setAttribute('src', 'https://s3.amazonaws.com/freecodecamp/simonSound2.mp3'); | |
break; | |
case "yellow": | |
audio.setAttribute('src', 'https://s3.amazonaws.com/freecodecamp/simonSound3.mp3'); | |
break; | |
case "green": | |
audio.setAttribute('src', 'https://s3.amazonaws.com/freecodecamp/simonSound1.mp3'); | |
}; | |
audio.play(); | |
//play the audio | |
} | |
var animateButton = function(buttonID, time) { | |
//public function for animate button highlight using jQuery UI | |
//Used in both in click by user and animate sequence by computer | |
//input: button ID and animation time | |
$(buttonID).effect("highlight", {}, time); | |
} | |
var State = function() { | |
//State class to represent state of the current game | |
this.sequence = []; | |
//sequence of button presses currently playing | |
this.makeSequence = function() { | |
//generate a first sequence (called from currentGame.startSequence()) | |
//adds a new button to the sequence | |
var number = Math.floor(Math.random() * 4); | |
//generate random index number between 0-3 | |
var color = board[number]; | |
//get the color from the board belonging to random index | |
currentState.sequence.push(color); | |
//add the color to the end of the sequence array in currentState | |
$('#counter').html(currentState.sequence.length); | |
//display the length of the sequence as the counter in the display | |
} //makeSequence | |
this.animateSequence = function() { | |
//public: animate the sequence in array with button highlights and sounds | |
currentGame.status = "animating"; | |
//game is not clickable when computer is animating sequence | |
var sequence = currentState.sequence; | |
//save copy of sequence array in local variable | |
var animate = function(i) { | |
//private function that calls the public animate function with an index parameter | |
animateAudio(sequence[i], 0.5); | |
animateButton("#" + sequence[i], 1000); | |
} | |
var i = 0; | |
//local counter to use in recursive loop | |
function loop() { | |
//recursive function that calls itself from a setTimeout function, that calls animate from within | |
//setTimeout returns right away. So increment counter and call next loop within, when each setTimeout finishes | |
setTimeout(function() { | |
$('#counter').html(currentState.sequence.length).css("font-size", "24px"); | |
animate(i); | |
i++ | |
//increment counter from within function | |
if (i < sequence.length) { | |
loop(); | |
//recursive call if the sequence has not been completely iterated yet | |
} else { | |
currentGame.status = "running"; | |
//set status back to running again in last loop, so board is clickable again | |
}; | |
}, 1000); | |
} | |
loop(); | |
//call the recursive animate loop | |
currentState.changeTurn("computer"); | |
} //animate sequence | |
} //class State | |
var Game = function() { | |
//class to represent the current Game | |
this.on = false; | |
//public: is the game turned on or not | |
//nothing runs or is clickable when game is turned off. | |
///When turning on from off, the game resets | |
this.status = "off"; | |
//off, beginning (still needs to press start for sequence), running | |
this.strict = false; | |
//public: game being played in strict mode or not | |
//if true: game restarts when one time press wrong button in sequence | |
this.setState = function() { | |
//public: to reset and start a new State | |
//when turned on from off | |
//when 1 wrong button press if strict mode | |
//when press start while game is running | |
currentState = new State(); | |
//create a new state (reset state) | |
$('#counter').html("Press Start!").css("font-size", "15px"); | |
//display the length of the current sequence in display | |
$('#startButton').effect("highlight"); | |
} | |
this.startSequence = function() { | |
//public: to start the game: | |
//when the game is turned on and player presses start (called from click start) | |
if (currentGame.status !== "off") { | |
//start button only clickable if game is turned on; | |
currentState.sequence = []; | |
//when click start, the sequence starts from beginning: reset the array. | |
currentState.makeSequence(); | |
//make sequence for the first time = make the first button press | |
$('#counter').html(currentState.sequence.length).css("font-size", "24px"); | |
//set counter to display the current sequence length = 1; | |
currentState.animateSequence(); | |
//animate the sequence | |
} // if status is not off | |
} //startSequence | |
this.checkSequence = function(button) { | |
//public: use in UI button clicks to check if the clicks match the current sequence | |
//if match complete sequence: change turn back to computer who generates a new sequence | |
//if one button does not match sequence: animate again. If strict mode: reset state | |
//called from button clicks with the button name as input | |
var sequence = currentState.sequence; | |
//make a copy of current sequence in local variable | |
if (sequence[clickCount] === button) { | |
//if button is same as current position in sequence, press is correct | |
clickCount = clickCount + 1; | |
//increase the clickcount by 1 for the next click | |
if (sequence.length === clickCount) { | |
//if the clickcount reaches the sequence length: whole sequence was correctly pressed and in right order | |
if (sequence.length === 20) { | |
//first check if we have reached 20 correct presses | |
$('#counter').html("Win!").css("font-size", "24px"); | |
//display win | |
setTimeout(function() { | |
//restart state after a few seconds | |
currentGame.startSequence(); | |
}, 3000); | |
} else { | |
//correctly pressed sequence but not 20 buttons yet | |
clickCount = 0; | |
//reset clickCount for the computer for a new check after computer has generated new button for sequence | |
$('#counter').html("Great!").css("font-size", "24px"); | |
currentState.makeSequence(); | |
//add a new button to currentState.sequence | |
currentState.animateSequence(); | |
//animate the sequence | |
} //check if end game, length = 21 | |
} //if end of matching sequence | |
} else { | |
//wrong button press: does not match current element of sequence | |
if (currentGame.strict === false) { | |
//not strictmode: animate the sequence again and set clickCount | |
$('#counter').html("Wrong!").css("font-size", "24px"); | |
clickCount = 0; | |
currentState.animateSequence(); | |
} else { | |
//strict mode: restart the game | |
$('#counter').html("Wrong!").css("font-size", "24px"); | |
setTimeout(function(){ | |
//Restart after 1 second, show Wrong message first | |
currentGame.startSequence(); | |
}, 1000); | |
} | |
} //click count = current button | |
} //checkSequence | |
}; // var Game | |
//Board control UI for human player to match sequence; | |
$('#yellow').on('click', function() { | |
if(currentGame.status === "running" && currentGame.status !== "animating"){ | |
animateAudio("yellow", 1); | |
animateButton("#yellow", 500); | |
currentGame.checkSequence("yellow"); | |
//check sequence match with button | |
} | |
}); | |
$('#green').on('click', function() { | |
if(currentGame.status === "running" && currentGame.status !== "animating"){ | |
animateAudio("green", 1); | |
animateButton("#green", 500); | |
currentGame.checkSequence("green"); | |
} | |
}); | |
$('#blue').on('click', function() { | |
if(currentGame.status === "running" && currentGame.status !== "animating"){ | |
animateAudio("blue", 1); | |
animateButton("#blue", 500); | |
currentGame.checkSequence("blue"); | |
} | |
}); | |
$('#red').on('click', function() { | |
if(currentGame.status === "running" && currentGame.status !== "animating"){ | |
animateAudio("red", 1); | |
animateButton("#red", 500); | |
currentGame.checkSequence("red"); | |
} | |
}); | |
//Game Control UI: | |
$('#on').on('click', function() { | |
currentGame = new Game(); | |
//intiliaze a new currentGame object | |
currentGame.on = true; | |
//set game on to true | |
currentGame.status = "beginning"; | |
//set game status to beginning (when click start will be running) | |
currentGame.setState(); | |
//call setState method to initialize a new currentState object | |
//also sets the display to show "--" | |
$('#off').on('click', function() { | |
currentGame.on = false; | |
//set game on to false | |
currentGame.status = "off"; | |
//set game status to off | |
$('#counter').html("--"); | |
//set display to show "--" again because it's turned off | |
}); | |
}); //on button | |
$('#startButton').on('click', function() { | |
//start sequence when | |
currentState.status = "running"; | |
currentGame.startSequence(); | |
}); | |
$('#strictButton').on('click', function() { | |
//toggle strict mode | |
if (currentGame.strict === false) { | |
currentGame.strict = true; | |
$('#strictButton').addClass('ui-state-focus'); | |
$('#strictButton').css('color', '#e74c3c'); | |
} else { | |
currentGame.strict = false; | |
$('#strictButton').removeClass('ui-state-focus'); | |
$('#strictButton').css('color', 'white'); | |
} | |
}); | |
}); //document.ready |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<script src="https://code.jquery.com/jquery-2.2.4.min.js"></script> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.11.4/jquery-ui.min.js"></script> | |
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
body { | |
background-color: #bdc3c7; | |
font-family:ubuntu; | |
} | |
.wrapper { | |
width: 600px; | |
height: 600px; | |
background-color:black; | |
border-radius: 50%; | |
} | |
#green { | |
width:300px; | |
height: 300px; | |
background-color: #27ae60; | |
float:left; | |
border-top-left-radius:100%; | |
border-left: 8px solid black; | |
border-top: 8px solid black; | |
border-bottom: 4px solid black; | |
border-right: 4px solid black; | |
} | |
#red{ | |
width:300px; | |
height:300px; | |
background-color:#c0392b; | |
float:left; | |
border-top-right-radius:100%; | |
border-left: 4px solid black; | |
border-top: 8px solid black; | |
border-bottom: 4px solid black; | |
border-right: 8px solid black; | |
} | |
#yellow { | |
width:300px; | |
height:300px; | |
background-color:#f1c40f; | |
float:left; | |
border-bottom-left-radius: 100%; | |
border-left: 8px solid black; | |
border-top: 4px solid black; | |
border-bottom: 8px solid black; | |
border-right: 4px solid black; | |
} | |
#red{ | |
width:300px; | |
height:300px; | |
background-color:#c0392b; | |
float:left; | |
border-top-right-radius:100%; | |
border-left: 4px solid black; | |
border-top: 8px solid black; | |
border-bottom: 4px solid black; | |
border-right: 8px solid black; | |
} | |
#blue{ | |
width:300px; | |
height:300px; | |
background-color:#2980b9; | |
float:left; | |
border-bottom-right-radius:100%; | |
border-left: 4px solid black; | |
border-top: 4px solid black; | |
border-bottom: 8px solid black; | |
border-right: 8px solid black; | |
} | |
.innerCircle { | |
width:300px; | |
height:300px; | |
background-color:white; | |
border-radius:50%; | |
border: 8px solid black; | |
} | |
#innerTitle{ | |
/*text-align:center;*/ | |
padding-top:50px; | |
} | |
.gameControls { | |
background-color:transparant; | |
height:100px; | |
width:250px; | |
margin:auto; | |
} | |
#counter{ | |
background-color:black; | |
border-radius: 15%; | |
width:100px; | |
height:50px; | |
color:white; | |
font-size:24px; | |
text-align:center; | |
padding-top:3%; | |
} | |
.control { | |
float:left; | |
margin-right:10px; | |
margin-top:10px; | |
} | |
#startButton { | |
background-color: #e74c3c; | |
border-color: #e74c3c; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet" /> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment