Skip to content

Commit 25e8c7f

Browse files
committed
Intial commit
0 parents  commit 25e8c7f

File tree

7 files changed

+363
-0
lines changed

7 files changed

+363
-0
lines changed

apple-touch-icon-114x114.png

13.8 KB
Loading

apple-touch-icon-72x72.png

8.15 KB
Loading

apple-touch-icon.png

6.1 KB
Loading

bg.png

81.5 KB
Loading

index.html

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
<!doctype html>
2+
<html>
3+
<head>
4+
<title>Tic Tac Toe</title>
5+
<meta name="viewport" content="width=600" />
6+
<meta name="apple-mobile-web-app-capable" content="yes" />
7+
<meta name="apple-mobile-web-app-status-bar-style" content="black" />
8+
9+
<link rel="apple-touch-icon" sizes="114x114" href="apple-touch-icon-114x114.png">
10+
<link rel="apple-touch-icon" sizes="72x72" href="apple-touch-icon-72x72.png">
11+
<link rel="apple-touch-icon" href="apple-touch-icon.png">
12+
13+
<link rel="stylesheet" href="main.css" type="text/css">
14+
<script src="main.js" type="text/javascript"></script>
15+
</head>
16+
<body onload="init();">
17+
<div id="players">
18+
<div id="X" class="">Player X</div>
19+
<div id="O" class="">Player O</div>
20+
</div>
21+
<table>
22+
<tr>
23+
<td id="0"></td>
24+
<td id="1"></td>
25+
<td id="2"></td>
26+
</tr>
27+
<tr>
28+
<td id="3"></td>
29+
<td id="4"></td>
30+
<td id="5"></td>
31+
</tr>
32+
<tr>
33+
<td id="6"></td>
34+
<td id="7"></td>
35+
<td id="8"></td>
36+
</tr>
37+
</table>
38+
<footer>
39+
<input type="button" class="button" value="New Game">
40+
</footer>
41+
</body>
42+
</html>

main.css

Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
body {
2+
text-align: center;
3+
font-size: 16px;
4+
font-family: Helvetica, sans-serif;
5+
background: #1a1a1a url(bg.png) repeat;
6+
}
7+
8+
table {
9+
margin-left: auto;
10+
margin-right: auto;
11+
width: 551px;
12+
-webkit-user-select: none;
13+
-khtml-user-select: none;
14+
-moz-user-select: none;
15+
-ms-user-select: none;
16+
-o-user-select: none;
17+
user-select: none;
18+
font-family: 'Comic Sans MS', Helvetica, sans-serif;
19+
}
20+
21+
td {
22+
height: 175px;
23+
width: 175px;
24+
text-align: center;
25+
font-size: 120px;
26+
border: 2px solid rgba(200, 200, 200, 0.4);
27+
-webkit-border-radius: 100px;
28+
-moz-border-radius: 100px;
29+
-ms-border-radius: 100px;
30+
-o-border-radius: 100px;
31+
border-radius: 100px;
32+
background-color: rgba(16, 16, 16, 0.5);
33+
}
34+
35+
#players {
36+
margin: 0 auto 10px auto;
37+
padding: 0px 10px 10px 10px;
38+
width: 511px;
39+
text-align: left;
40+
}
41+
42+
#players > div {
43+
display: inline-block;
44+
padding-right: 25px;
45+
margin: 10px 10px 0 50px;
46+
color: #666;
47+
-webkit-transition-duration: 200ms;
48+
-moz-transition-duration: 200ms;
49+
-o-transition-duration: 200ms;
50+
transition-duration: 200ms;
51+
}
52+
53+
#players #O {
54+
float: right;
55+
}
56+
57+
.current-player {
58+
color: #ccc !important;
59+
-webkit-transform: scale(1.8);
60+
-moz-transform: scale(1.8);
61+
-ms-transform: scale(1.8);
62+
-o-transform: scale(1.8);
63+
transform: scale(1.8);
64+
}
65+
66+
.X-marker, #X.current-player {
67+
color: #3BB5DE !important;
68+
}
69+
70+
.X-marker:before {
71+
content: "X";
72+
}
73+
74+
.O-marker, #O.current-player {
75+
color: #DD1144 !important;
76+
}
77+
78+
.O-marker:before {
79+
content: "O";
80+
}
81+
82+
footer {
83+
margin-top: 15px;
84+
}
85+
86+
.button {
87+
position: relative;
88+
overflow: visible;
89+
display: inline-block;
90+
padding: 0.5em 1em;
91+
border: 1px solid #d4d4d4;
92+
margin: 0 auto 0 auto;
93+
text-decoration: none;
94+
text-shadow: 1px 1px 0 #fff;
95+
font-size:14px;
96+
color: #333;
97+
white-space: nowrap;
98+
cursor: pointer;
99+
outline: none;
100+
background-color: #ececec;
101+
background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#f4f4f4), to(#ececec));
102+
background-image: -moz-linear-gradient(#f4f4f4, #ececec);
103+
background-image: -o-linear-gradient(#f4f4f4, #ececec);
104+
background-image: linear-gradient(#f4f4f4, #ececec);
105+
-webkit-background-clip: padding;
106+
-moz-background-clip: padding;
107+
-o-background-clip: padding-box;
108+
-webkit-border-radius: 0.2em;
109+
-moz-border-radius: 0.2em;
110+
border-radius: 0.2em;
111+
/* IE hacks */
112+
zoom: 1;
113+
*display: inline;
114+
}
115+
116+
.button:hover,
117+
.button:active,
118+
.button.active {
119+
border-color: #3094B5;
120+
border-bottom-color: #2B84A1;
121+
text-decoration: none;
122+
text-shadow: -1px -1px 0 rgba(0,0,0,0.3);
123+
color: #fff;
124+
background-color: #3BB5DE;
125+
background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#5BBCDC), to(#3094B5));
126+
background-image: -moz-linear-gradient(#5BBCDC, #3094B5);
127+
background-image: -o-linear-gradient(#5BBCDC, #3094B5);
128+
background-image: linear-gradient(#5BBCDC, #3094B5);
129+
}
130+
131+
.button:active,
132+
.button.active {
133+
border-color: #2B84A1;
134+
border-bottom-color: #3AAACF;
135+
background-color: #3096B5;
136+
background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#3096B5), to(#5BBCDC));
137+
background-image: -moz-linear-gradient(#3094B5, #5BBCDC);
138+
background-image: -o-linear-gradient(#3094B5, #5BBCDC);
139+
background-image: linear-gradient(#3094B5, #5BBCDC);
140+
}
141+
142+
/* overrides extra padding on button elements in Firefox */
143+
.button::-moz-focus-inner {
144+
padding: 0;
145+
border: 0;
146+
}

main.js

Lines changed: 175 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,175 @@
1+
var board = new Array(9);
2+
3+
function init() {
4+
/* use touch events if they're supported, otherwise use mouse events */
5+
var down = "mousedown"; var up = "mouseup";
6+
if ('createTouch' in document) { down = "touchstart"; up ="touchend"; }
7+
8+
/* add event listeners */
9+
document.querySelector("input.button").addEventListener(up, newGame, false);
10+
var squares = document.getElementsByTagName("td");
11+
for (var s = 0; s < squares.length; s++) {
12+
squares[s].addEventListener(down, function(evt){squareSelected(evt, getCurrentPlayer());}, false);
13+
}
14+
15+
/* create the board and set the initial player */
16+
createBoard();
17+
setInitialPlayer();
18+
}
19+
20+
21+
function createBoard() {
22+
/* create a board from the stored version, if a stored version exists */
23+
if (window.localStorage && localStorage.getItem('tic-tac-toe-board')) {
24+
25+
/* parse the string that represents our playing board to an array */
26+
board = (JSON.parse(localStorage.getItem('tic-tac-toe-board')));
27+
for (var i = 0; i < board.length; i++) {
28+
if (board[i] != "") {
29+
fillSquareWithMarker(document.getElementById(i), board[i]);
30+
}
31+
}
32+
}
33+
/* otherwise, create a clean board */
34+
else {
35+
for (var i = 0; i < board.length; i++) {
36+
board[i] = "";
37+
document.getElementById(i).innerHTML = "";
38+
}
39+
}
40+
}
41+
42+
function squareSelected(evt, currentPlayer) {
43+
var square = evt.target;
44+
/* check to see if the square already contains an X or O marker */
45+
if (square.className.match(/marker/)) {
46+
alert("Sorry, that space is taken! Please choose another square.");
47+
return;
48+
}
49+
/* if not already marked, mark the square, update the array that tracks our board, check for a winner, and switch players */
50+
else {
51+
fillSquareWithMarker(square, currentPlayer);
52+
updateBoard(square.id, currentPlayer);
53+
checkForWinner();
54+
switchPlayers();
55+
}
56+
}
57+
58+
function fillSquareWithMarker(square, player) {
59+
var marker = document.createElement('div');
60+
/* set the class name on the new div to X-marker or O-marker, depending on the current player */
61+
marker.className = player + "-marker";
62+
square.appendChild(marker);
63+
}
64+
65+
function updateBoard(index, marker) {
66+
board[index] = marker;
67+
68+
/* HTML5 localStorage only allows storage of strings - convert our array to a string */
69+
var boardstring = JSON.stringify(board);
70+
71+
/* store this string to localStorage, along with the last player who marked a square */
72+
localStorage.setItem('tic-tac-toe-board', boardstring);
73+
localStorage.setItem('last-player', getCurrentPlayer());
74+
}
75+
76+
77+
function declareWinner() {
78+
if (confirm("We have a winner! New game?")) {
79+
newGame();
80+
}
81+
}
82+
83+
function weHaveAWinner(a, b, c) {
84+
if ((board[a] === board[b]) && (board[b] === board[c]) && (board[a] != "" || board[b] != "" || board[c] != "")) {
85+
setTimeout(declareWinner(), 100);
86+
return true;
87+
}
88+
else
89+
return false;
90+
}
91+
92+
function checkForWinner() {
93+
/* check rows */
94+
var a = 0; var b = 1; var c = 2;
95+
while (c < board.length) {
96+
if (weHaveAWinner(a, b, c)) {
97+
return;
98+
}
99+
a+=3; b+=3; c+=3;
100+
}
101+
102+
/* check columns */
103+
a = 0; b = 3; c = 6;
104+
while (c < board.length) {
105+
if (weHaveAWinner(a, b, c)) {
106+
return;
107+
}
108+
a+=1; b+=1; c+=1;
109+
}
110+
111+
/* check diagonal right */
112+
if (weHaveAWinner(0, 4, 8)) {
113+
return;
114+
}
115+
/* check diagonal left */
116+
if (weHaveAWinner(2, 4, 6)) {
117+
return;
118+
}
119+
120+
/* if there's no winner but the board is full, ask the user if they want to start a new game */
121+
if (!JSON.stringify(board).match(/,"",/)) {
122+
if (confirm("It's a draw. New game?")) {
123+
newGame();
124+
}
125+
}
126+
}
127+
128+
129+
function getCurrentPlayer() {
130+
return document.querySelector(".current-player").id;
131+
}
132+
133+
function setInitialPlayer() {
134+
var playerX = document.getElementById("X");
135+
var playerO = document.getElementById("O");
136+
playerX.className = "";
137+
playerO.className = "";
138+
139+
/* if there's no localStorage, or no last-player stored in localStorage, always set the first player to X by default */
140+
if (!window.localStorage || !localStorage.getItem('last-player')) {
141+
playerX.className = "current-player";
142+
return;
143+
}
144+
145+
var lastPlayer = localStorage.getItem('last-player');
146+
if (lastPlayer == 'X') {
147+
playerO.className = "current-player";
148+
}
149+
else {
150+
playerX.className = "current-player";
151+
}
152+
}
153+
154+
function switchPlayers() {
155+
var playerX = document.getElementById("X");
156+
var playerO = document.getElementById("O");
157+
158+
if (playerX.className.match(/current-player/)) {
159+
playerO.className = "current-player";
160+
playerX.className = "";
161+
}
162+
else {
163+
playerX.className = "current-player";
164+
playerO.className = "";
165+
}
166+
}
167+
168+
function newGame() {
169+
/* clear the currently stored game out of local storage */
170+
localStorage.removeItem('tic-tac-toe-board');
171+
localStorage.removeItem('last-player');
172+
173+
/* create a new game */
174+
createBoard();
175+
}

0 commit comments

Comments
 (0)