diff --git a/css/main.css b/css/main.css
new file mode 100644
index 0000000..76a44fa
--- /dev/null
+++ b/css/main.css
@@ -0,0 +1,64 @@
+* {
+ box-sizing: border-box;
+}
+
+body {
+ height: 100vh;
+ margin: 0;
+ font-family: 'Audiowide', cursive;
+ font-family: 'Open Sans', sans-serif;
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ align-items: center;
+}
+
+header {
+ font-size: 4vmin;
+ color: darkgray;
+ letter-spacing: 1vmin;
+}
+
+h1 {
+ color: gray;
+ font-size: 3vmin;
+}
+
+.cell {
+ transform: scale(0.7);
+ display: flex;
+ justify-content: center;
+ align-items: center;
+}
+
+.cell:hover {
+ transform: scale(0.9);
+ transition: transform 150ms ease-in;
+}
+
+#board {
+ display: grid;
+ grid-template-columns: repeat(3, 10vmin);
+ grid-template-rows: repeat(3, 10vmin);
+ gap: .2vmin;
+ margin-top: 2vmin;
+}
+
+#board > div {
+ border: 0.1vmin solid lightgray;
+}
+
+button {
+ margin-top: 4vmin;
+ padding: 2vmin;
+ font-size: 2vmin;
+ border-radius: 4vmin;
+ border: 0.1vmin solid gray;
+ border-color: darkgray;
+ color: gray;
+}
+
+button:hover {
+ color: white;
+ background-color: darkgray;
+}
\ No newline at end of file
diff --git a/index.html b/index.html
new file mode 100644
index 0000000..8dbbd3b
--- /dev/null
+++ b/index.html
@@ -0,0 +1,35 @@
+
+
+
+
+
+
+
+
+
+ Tic Tac Toe
+
+
+
+
+
+ Player One's turn
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/js/main.js b/js/main.js
new file mode 100644
index 0000000..e5f3f03
--- /dev/null
+++ b/js/main.js
@@ -0,0 +1,179 @@
+ /*----- constants -----*/
+ // const COLORS = {
+ // '0': 'white',
+ // '1': 'black',
+ // '-1': 'red'
+ // };
+
+ const VALUE = {
+ '0': ' ',
+ '1': 'X',
+ '-1': 'O'
+ };
+
+ /*----- state variables -----*/
+
+// Decide State Variables for Game:
+// 1. Keep track of who's turn it is (turn: Player One (1)/ Player Two (-1))
+// 2. Track board state (board: 2D array)
+// null -> no player
+// Player One (1) / Player Two (-1) -> player at that cell
+// 3. Variable for winner (winner: yes or no)
+// null -> no winner / in play
+// Player One (1) / Player Two (-1) -> winner
+// 'T' -> tie
+
+let board; //this will be an array of 3 column arrays
+let turn; //this will be Player One (1) & Player Two's turns (-1)
+let winner; // null = no winner; 1 or -1 = winner; 'T' = tie game
+
+ /*----- cached elements -----*/
+const messageEl = document.querySelector('h1');
+const resetButton = document.querySelector('button');
+const markerEls = [...document.querySelectorAll('#board > .cell')];
+
+
+ /*----- event listeners -----*/
+document.querySelectorAll('#board > .cell').forEach(cell => {
+ cell.addEventListener('click', handleDrop);
+ });
+resetButton.addEventListener('click', init);
+
+
+ /*----- functions -----*/
+init();
+
+// Initialize all state, then call render()
+function init() {
+ //to visualize the board's mapping to the DOM, rotate the board array 90 degrees counter-clockwise
+ board = [
+ [0, 0, 0], //this is column 0
+ [0, 0, 0], //this is column 1
+ [0, 0, 0], //this is column 2
+ ];
+ turn = 1;
+ winner = null;
+ render();
+}
+
+//in response to user interaction, update all impacted state, then call render();
+function handleDrop(event) {
+ const cellId = event.target.id;
+ const columnIdx = parseInt(cellId.charAt(1));
+ const rowIdx = parseInt(cellId.charAt(3));
+ // guards
+ if (columnIdx === undefined || rowIdx === undefined || winner) return;
+ // check if the cell is empty
+ if (board[columnIdx][rowIdx] !== 0) return;
+ // update board state with current player value
+ board[columnIdx][rowIdx] = turn;
+ // switch turns
+ turn *= -1;
+ // check for winner
+ winner = getWinner(columnIdx, rowIdx);
+ render();
+}
+
+//check for winner in board state & return null if no winner, 1/-1 if a player has won, or 'T' if there's a tie
+function getWinner(columnIdx, rowIdx) {
+ const hasTie = board.every(row => row.every(cell => cell !== 0));
+ if (hasTie) {
+ return 'T'; // Return 'T' to indicate a tie
+ }
+ return checkVerticalWin(columnIdx, rowIdx) ||
+ checkHorizontalWin(columnIdx, rowIdx) ||
+ checkDiagonalWinNESW(columnIdx, rowIdx) ||
+ checkDiagonalWinNWSE(columnIdx, rowIdx);
+}
+
+function checkVerticalWin(columnIdx, rowIdx) {
+ const adjacentCountUp = countAdjacent(columnIdx, rowIdx, 0, 1);
+ const adjacentCountDown = countAdjacent(columnIdx, rowIdx, 0, -1);
+ return (adjacentCountUp + adjacentCountDown) >= 2 ? board[columnIdx][rowIdx] : null;
+}
+
+function checkHorizontalWin(columnIdx, rowIdx) {
+ const adjacentCountLeft = countAdjacent(columnIdx, rowIdx, -1, 0);
+ const adjacentCountRight = countAdjacent(columnIdx, rowIdx, 1, 0);
+ return (adjacentCountLeft + adjacentCountRight) >= 2 ? board[columnIdx][rowIdx] : null;
+}
+
+function checkDiagonalWinNESW(columnIdx, rowIdx) {
+ const adjacentCountNE = countAdjacent(columnIdx, rowIdx, 1, 1);
+ const adjacentCountSW = countAdjacent(columnIdx, rowIdx, -1, -1);
+ return (adjacentCountNE + adjacentCountSW) >= 2 ? board[columnIdx][rowIdx] : null;
+}
+
+function checkDiagonalWinNWSE(columnIdx, rowIdx) {
+ const adjacentCountNW = countAdjacent(columnIdx, rowIdx, -1, 1);
+ const adjacentCountSE = countAdjacent(columnIdx, rowIdx, 1, -1);
+ return (adjacentCountNW + adjacentCountSE) >= 2 ? board[columnIdx][rowIdx] : null;
+}
+
+function countAdjacent(columnIdx, rowIdx, columnOffset, rowOffset) {
+ //shortcut variable to the player value
+ const player = board[columnIdx][rowIdx];
+ //track count of adjacent cells with the same player value
+ let count = 0;
+ //initialize new coordinates
+ columnIdx += columnOffset;
+ rowIdx += rowOffset;
+ while (
+ //ensure columnIdx is within bounds of the board array
+ board[columnIdx] !== undefined &&
+ board[columnIdx][rowIdx] !== undefined &&
+ board[columnIdx][rowIdx] === player
+ ) {
+ count++;
+ columnIdx += columnOffset;
+ rowIdx += rowOffset;
+ }
+ return count;
+}
+
+// Visualize all state in the DOM
+function render() {
+ renderBoard();
+ renderMessage();
+ //hide/show UI elements (controls)
+ renderControls();
+}
+
+function renderBoard() {
+ board.forEach(function (columnArr, columnIdx) {
+ //iterate over the cells in the current column (columnArr)
+ columnArr.forEach(function(cellValue, rowIdx) {
+ const cellId = `c${columnIdx}r${rowIdx}`;
+ const cellEl = document.getElementById(cellId);
+// cellEl.style.backgroundColor = COLORS[cellValue];
+ cellEl.innerText = VALUE[cellValue];
+ });
+ });
+}
+
+function renderMessage() {
+ if (winner === 'T') {
+ messageEl.innerText = "It's a tie!!!";
+ } else if (winner) {
+ //message for winner
+ // messageEl.innerHTML = `${COLORS[winner].toUpperCase()} wins!`;
+ messageEl.innerHTML = `${VALUE[winner].toUpperCase()} wins!`;
+ } else {
+ //message when game is in play
+ // messageEl.innerHTML = `It's your turn, ${COLORS[turn].toUpperCase()}.`;
+ messageEl.innerHTML = `It's your turn, ${VALUE[turn].toUpperCase()}.`;
+ }
+}
+
+function renderControls() {
+ resetButton.style.visibility = winner ? 'visible' : 'hidden';
+ board.forEach(function (columnArr, columnIdx) {
+ // iterate over the cells in the current column (columnArr)
+ columnArr.forEach(function(cellValue, rowIdx) {
+ const cellId = `c${columnIdx}r${rowIdx}`;
+ const cellEl = document.getElementById(cellId);
+ // cellEl.style.backgroundColor = COLORS[cellValue];
+ cellEl.style.backgroundColor = VALUE[cellValue];
+ });
+ });
+}
\ No newline at end of file