-
-
Save sadasant/91f68703cc59533ea88e7744604ce92a to your computer and use it in GitHub Desktop.
Tic-Tac-Toe// source https://jsbin.com/qototad
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
<!DOCTYPE html> | |
<html> | |
<head> | |
<meta charset="utf-8"> | |
<meta id="viewport" name="viewport" content="width=device-width, initial-scale=1"> | |
<title>Tic-Tac-Toe</title> | |
</head> | |
<body> | |
<div class='wrapper'> | |
<div id='intro'> | |
<div class='title'> | |
<div class='x'>Tic-</div> | |
<div class='o'>Tac-</div> | |
<div class='x'>Toe!</div> | |
</div> | |
<div class='message'>Click in the board</div> | |
<button id='restart'>Restart</button> | |
</div> | |
<div id='tic-tac-toe' class='.noselect'> | |
<div class=''></div> | |
<div class=''></div> | |
<div class=''></div> | |
<div class=''></div> | |
<div class=''></div> | |
<div class=''></div> | |
<div class=''></div> | |
<div class=''></div> | |
<div class=''></div> | |
</div> | |
<div id='winner'> | |
<!-- | |
PLAYER | |
<b>X</b> | |
WINS! | |
--> | |
</div> | |
<div class='author'> | |
Made with | |
<span class='hearts'>♥</span> | |
by | |
<a href='http://twitter.com/sadasant' target='_blank'> | |
@sadasant | |
</a> | |
</div> | |
</div> | |
</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
html { | |
background: #f5f5f5; | |
} | |
/* The wrapper | |
* wraps the app | |
*/ | |
.wrapper { | |
width: 41.5vh; | |
height: 90.3vh; | |
display: block; | |
margin-left: auto; | |
margin-right: auto; | |
margin-top: 5.1vh; | |
font-family: sans-serif; | |
} | |
/* The wrapper's intro. | |
* Here goes the title | |
* and the controls. | |
*/ | |
.wrapper #intro { | |
text-align: center; | |
} | |
.wrapper #intro .title { | |
font-size: 6.2vh; | |
font-weight: bold; | |
display: inline-block; | |
} | |
.wrapper #intro .title .x, | |
.wrapper #intro .title .o { | |
opacity: 0; | |
float: left; | |
} | |
.wrapper #intro .title .x { | |
color: #e88; | |
} | |
.wrapper #intro .title .o { | |
color: #8be; | |
} | |
.wrapper #intro .message { | |
opacity: 0; | |
font-size: 2.58vh; | |
color: #999; | |
margin-top: -4px; | |
margin-bottom: 4px; | |
transition: opacity 0.3s; | |
} | |
.wrapper #intro #restart { | |
background: none; | |
color: #e88; | |
border: none; | |
font-weight: bold; | |
text-transform: uppercase; | |
font-size: 2.58vh; | |
display: none; | |
cursor: pointer; | |
text-align: center; | |
width: 100%; | |
margin-top: -0.75vh; | |
} | |
.wrapper #intro #restart.visible { | |
display: block; | |
} | |
/* tic-tac-toe blocks. | |
* People play here. | |
*/ | |
.wrapper #tic-tac-toe div { | |
display: block; | |
float: left; | |
width: 12.99vh; | |
height: 12.8vh; | |
margin-left: 0.6vh; | |
margin-top: 0.7vh; | |
font-size: 11.35vh; | |
font-weight: bold; | |
text-align: center; | |
background: white; | |
color: #888; | |
cursor: pointer; | |
opacity: 0; | |
} | |
.wrapper #tic-tac-toe div.x { | |
color: #e88; | |
cursor: default; | |
} | |
.wrapper #tic-tac-toe div.o { | |
color: #8be; | |
cursor: default; | |
} | |
.wrapper #tic-tac-toe div.yellow { | |
background: #ffb; | |
} | |
.wrapper #tic-tac-toe div.showCursor:before { | |
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAgAAAAIACAMAAADDpiTIAAADAFBMVEX///8zMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMvIC5hAAAA/3RSTlMAAf3+AvsD/PkHBQT3+AkIERL69Q4L9iPsBvMMChQPSucQ8hntIQ3o8RYYHOtCF9sT5D8sNFEVKBtF6StM4yBP9DswJ10tNS7qHzk+Iirw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); | |
background-size: 6.19vh 6.19vh; | |
display: block; | |
width: 6.19vh; | |
height: 6.19vh; | |
content: ''; | |
opacity: 0; | |
margin-left: 3.5vh; | |
margin-top: 3vh; | |
animation: click 5s 0s infinite; | |
} | |
@keyframes click { | |
0% { | |
opacity: 0; | |
} | |
3% { | |
opacity: 0.5; | |
} | |
15% { | |
margin-left: 3.5vh; | |
margin-top: 3vh; | |
} | |
20% { | |
margin-left: 3.4vh; | |
margin-top: 2.8vh; | |
} | |
25% { | |
margin-left: 3.5vh; | |
margin-top: 3vh; | |
} | |
30% { | |
margin-left: 3.4vh; | |
margin-top: 2.8vh; | |
} | |
35% { | |
margin-left: 3.5vh; | |
margin-top: 3vh; | |
} | |
47% { | |
opacity: 0.5; | |
} | |
50% { | |
opacity: 0; | |
} | |
} | |
/* | |
* Winner highlight | |
*/ | |
.wrapper #winner { | |
display: none; | |
float: left; | |
margin-top: -41.2vh; | |
margin-bottom: -113px; | |
margin-left: -2.6vh; | |
width: 46.5vh; | |
height: 35vh; | |
font-size: 11.35vh; | |
text-align: center; | |
text-transform: uppercase; | |
padding-top: 8.8vh; | |
background: rgba(245, 245, 245, .8); | |
} | |
/* The author. | |
* Hi mom! | |
*/ | |
.wrapper .author { | |
font-size: 1.55vh; | |
color: #999; | |
float: right; | |
margin-right: 5px; | |
margin-top: 1.2vh; | |
margin-bottom: 5vw; | |
} | |
.wrapper .author .hearts { | |
color: #e88; | |
} | |
.wrapper .author a { | |
text-decoration: none; | |
color: #8be; | |
} | |
.wrapper .author a:hover { | |
text-decoration: underline; | |
} | |
/* | |
* Misc - taken from elsewhere | |
* Sources: | |
* .noselect - https://stackoverflow.com/questions/826782/how-to-disable-text-selection-highlighting-using-css | |
*/ | |
.noselect, .wrapper #tic-tac-toe div { | |
-webkit-touch-callout: none; /* iOS Safari */ | |
-webkit-user-select: none; /* Chrome/Safari/Opera */ | |
-khtml-user-select: none; /* Konqueror */ | |
-moz-user-select: none; /* Firefox */ | |
-ms-user-select: none; /* Internet Explorer/Edge */ | |
user-select: none; /* Non-prefixed version, currently | |
not supported by any browser */ | |
} |
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
window.onload = function() { | |
// Makes arrays | |
function makeArray(obj) { | |
return Array.prototype.slice.call(obj) | |
} | |
// Vanilla jQuery for the lazy | |
var $ = function() { | |
var args = makeArray(arguments); | |
var r = document.querySelectorAll.apply(document, args); | |
return r.length === 1 ? r[0] : r; | |
} | |
// Vanilla class functions | |
function addClass(el, className) { | |
removeClass(el, className) | |
el.className += ' ' + className | |
} | |
function removeClass(el, className) { | |
el.className = el.className.replace(className, '') | |
} | |
// Our main variables | |
var title = $('.wrapper #intro .title'); | |
var message = $('.wrapper #intro .message'); | |
var tictactoe = $('.wrapper #tic-tac-toe'); | |
var blocks = $('.wrapper #tic-tac-toe div'); | |
var restart = $('#restart'); | |
var winner = $('#winner'); | |
// Animated intro! | |
intro() | |
function intro() { | |
function show(el) { | |
el.style.opacity = 1; | |
} | |
function hide(el) { | |
el.style.opacity = 0; | |
} | |
var delayer = new Delayer(); | |
var titleParts = makeArray(title.children); | |
var blocksArray = makeArray(blocks); | |
// Flushing | |
message.style.display = 'block' | |
winner.style.display = 'none' | |
hide(message) | |
removeClass(restart, 'visible') | |
titleParts.map(hide) | |
blocksArray.map(function(el) { | |
el.className = ''; | |
el.innerText = ''; | |
hide(el) | |
}) | |
delayer.add(titleParts, show, 500) | |
delayer.add(blocksArray, show, 100) | |
delayer.add([message], show, 500) | |
delayer.add([blocks[0]], function(first) { | |
addClass(first, 'showCursor') | |
blocksArray.map(function(el) { | |
el.onclick = function() { | |
removeClass(first, 'showCursor') | |
message.style.display = 'none' | |
first.onclick = undefined | |
startGame(el) | |
} | |
}) | |
}, 0) | |
delayer.run() | |
} | |
// Main game logic | |
var startsX = true; | |
function startGame(el) { | |
var player1 = { | |
str: startsX ? 'x' : 'o' | |
} | |
var player2 = { | |
str: !startsX ? 'x' : 'o', | |
} | |
var goesP1 = true; | |
var turns = 0; | |
addClass(restart, 'visible') | |
restart.onclick = function() { | |
intro() | |
} | |
var blocksArray = makeArray(blocks); | |
blocksArray.map(function(el) { | |
el.onclick = function() { | |
if (el.innerText) return | |
var player = goesP1 ? player1 : player2; | |
el.innerText = player.str.toUpperCase(); | |
addClass(el, player.str); | |
goesP1 = !goesP1; | |
turns++ | |
if (turns === 9) { | |
setTimeout(tie, 125); | |
} else | |
if (turns >= 5) { | |
setTimeout(function() { | |
checkWinner(player, el); | |
}, 125) | |
} | |
} | |
}) | |
function checkWinner(player, el) { | |
var B = blocksArray; | |
var i = B.indexOf(el); | |
var str = player.str.toUpperCase() | |
function eqAt(a, b, c) { | |
return B[a].innerText === B[b].innerText && B[a].innerText === B[c].innerText; | |
} | |
var col = i % 3; | |
var row = i - col; | |
if (eqAt(row, row + 1, row + 2)) return won(player, row, row + 1, row + 2); | |
if (eqAt(col, col + 3, col + 6)) return won(player, col, col + 3, col + 6); | |
if (eqAt(0, 4, 8)) return won(player, 0, 4, 8) | |
if (eqAt(2, 4, 6)) return won(player, 2, 4, 6) | |
} | |
function won(player, a, b, c) { | |
addClass(blocksArray[a], 'yellow') | |
addClass(blocksArray[b], 'yellow') | |
addClass(blocksArray[c], 'yellow') | |
winner.style.display = 'block'; | |
winner.style.color = player.str === 'x' ? '#e88' : '#8be'; | |
winner.innerHTML = 'player <b>' + player.str + '</b> wins!' | |
blocksArray.map(function(el) { | |
el.onclick = undefined | |
}) | |
} | |
function tie() { | |
winner.style.display = 'block'; | |
winner.style.color = '#999'; | |
winner.innerHTML = 'IT WAS<br>A TIE' | |
} | |
el.onclick() | |
} | |
// Delayer object | |
// adds animation *frames* into | |
// a strack, then replays them | |
function Delayer() { | |
var stack = [] | |
this.add = function(arr, func, time) { | |
if (!(arr && arr.length)) { | |
throw 'Delayer.add error: invalid first argument, must be an array' | |
} | |
arr.map(function(el) { | |
stack.push({ | |
el: el, | |
func: func, | |
timeout: time | |
}) | |
}) | |
} | |
var that = this | |
this.run = function() { | |
if (!stack.length) return | |
var current = stack.shift() | |
setTimeout(function() { | |
current.func(current.el) | |
that.run() | |
}, current.timeout) | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment