diff --git a/README.md b/README.md index 05fd261..529a2f0 100644 --- a/README.md +++ b/README.md @@ -1,18 +1,21 @@ # odin-tic-tac-toe +## Tic Tac Toe -Tic Tac Toe - -using IIFE to prevent unwanted user-forced changes, using addEventListeners +using IIFE's to prevent unwanted user-forced changes, using addEventListeners utilizing pubsub, and splitting functions into parts used by others for code readability :) ## todo: -- [ ] "setup screen" on first startup (majorly done) -- [ ] display points, turn, etc - info in GUI -- [ ] reset everything btn +- [X] "setup screen" on startup +- [X] display points, turn, etc - info in GUI +- [X] reset points / everything btn +- [ ] clean code, although most of it is fine and intact, parts from later commits (from creating the form setup screen) are quite a little messy + +### nice to haves ("todo" that will probably never be done) - [ ] localstorage or other similar implementation to save progress and players - [ ] edit player settings - name, marker # preview: -![preview](image.png) \ No newline at end of file +![preview1](image-1.png) +![preview2](image.png) \ No newline at end of file diff --git a/image-1.png b/image-1.png new file mode 100644 index 0000000..777d427 Binary files /dev/null and b/image-1.png differ diff --git a/image.png b/image.png index d1bd4ef..4dff7a1 100644 Binary files a/image.png and b/image.png differ diff --git a/index.html b/index.html index aae516b..a937359 100644 --- a/index.html +++ b/index.html @@ -11,7 +11,24 @@
-
+
+
+ + + +
diff --git a/script.js b/script.js index 6946791..b915d52 100644 --- a/script.js +++ b/script.js @@ -17,18 +17,70 @@ function generateForm() { const form = document.createElement("form"); - const player1NameLabel = generateElement({element:"label",_for:"p1name",textContent:"Player 1 name"}); - const player1Name = generateElement({element:"input",type:"text",name:"p1name",placeholder:"p1name",id:"p1name"}); - const markerX = generateElement({element:"input",type:"radio",name:"marker",value:"X",id:"mx"}); - const markerXLabel = generateElement({element:"label",_for:"mx",textContent:"X"}); - const markerO = generateElement({element:"input",type:"radio",name:"marker",value:"O",id:"mo",checked:true,required:true}); - const markerOLabel = generateElement({element:"label",_for:"mo",textContent:"O"}); - const player2NameLabel = generateElement({element:"label",_for:"p2name",textContent:"Player 2 name"}); - const player2Name = generateElement({element:"input",type:"text",name:"p2name",placeholder:"p2name",id:"p2name"}); - const submit = generateElement({element:"button",type:"submit",textContent:"Save"}); - form.append(player1NameLabel, player1Name, player2NameLabel, player2Name,markerO,markerOLabel,markerX,markerXLabel,submit); - return {form, player1Name, player2Name, markerX, markerXLabel, markerO, markerOLabel, submit}; + const title = generateElement( + {element: "h1", id: "title", textContent: "Tic Tac Toe"}); + + const player1NameLabel = generateElement( + {element: "label", _for: "p1name", textContent: "Player 1 name"}); + const player1Name = generateElement( + {element: "input", type: "text", name: "p1name", id: "p1name", required: true}); + + const player2NameLabel = generateElement( + {element: "label", _for: "p2name", textContent: "Player 2 name"}); + const player2Name = generateElement( + {element: "input", type: "text", name: "p2name", id: "p2name", required: true}); + + + const markerInfo = generateElement( + {element: "label", textContent: "Marker for player 1:"}); + + const markerO = generateElement( + {element: "input", type: "radio", name: "marker", value: "O", id: "mo", checked: true, required: true}); + const markerOLabel = generateElement( + {element: "label", _for: "mo", textContent: "O"}); + + const markerX = generateElement( + {element: "input", type: "radio", name: "marker", value: "X", id: "mx"}); + const markerXLabel = generateElement( + {element: "label", _for: "mx", textContent: "X"}); + + const markerInfoAddition = generateElement( + {element: "label", innerText: "\n(other one will go to player 2)"}); + + + const firstInfo = generateElement( + {element: "label", textContent: "Who goes first?"}); + + const firstPlayer1 = generateElement( + {element: "input", type: "radio", name: "first", value: "1", id: "fp1", checked: true, required: true}); + const firstPlayer1Label = generateElement( + {element: "label", _for: "fp1", textContent: "1"}); + + const firstPlayer2 = generateElement( + {element: "input", type: "radio", name: "first", value: "2", id: "fp2"}); + const firstPlayer2Label = generateElement( + {element: "label", _for: "fp2", textContent: "2"}); + + const submit = generateElement( + {element: "button", type: "submit", textContent: "Save"}); + + form.append( + title, + player1NameLabel, player1Name, + player2NameLabel, player2Name, + markerInfo, + markerO, markerOLabel, + markerX, markerXLabel, + markerInfoAddition, + document.createElement("br"), + firstInfo, + firstPlayer1, firstPlayer1Label, + firstPlayer2, firstPlayer2Label, + submit, + ); + + return form; } function addDismissivePopup(popup) { @@ -89,18 +141,19 @@ name: vals[1], marker: vals[2] == "O" ? "X" : "O", }, - }) + }, vals[3]) } (function popupStartInput() { const {popup, popupContent} = generatePopup(false); - const {form, player1Name, player2Name,markerX,markerO,submit} = generateForm(); + const form = generateForm(); popupContent.append(form); form.addEventListener("submit", function(event) {getFormOutput(event, popup)}); })() - const game = function(playersInput) { + const game = function(playersInput, first) { const mainGameDiv = document.querySelector("#main-game"); + const infoDiv = document.querySelector("#info"); let gameboard = new Array(9); gameboard.fill(null); @@ -141,6 +194,24 @@ // ----------------- + function updateInfo() { + const player1Info = document.querySelector("#p1info"); + player1Info.textContent = + `1) ${players.player1.name} (${players.player1.marker}) - ${players.player1.points} points`; + + const player2Info = document.querySelector("#p2info"); + player2Info.textContent = + `2) ${players.player2.name} (${players.player2.marker}) - ${players.player2.points} points`; + + const playerTurnInfo = document.querySelector("#pturn"); + playerTurnInfo.textContent = + `${activePlayer.number}) ${activePlayer.player.name} (${activePlayer.player.marker})`; + + console.log(activePlayer.number); + } + + // ----------------- + function popupWin() { const {popup, popupContent, dismissBtn} = generatePopup(true); @@ -203,10 +274,16 @@ this.player == players.player1 ? this.player = players.player2 : this.player = players.player1; + this.player == players.player1 + ? this.number = 1 + : this.number = 2; }, set(player) { if (player instanceof Player) { this.player = player; + this.player == players.player1 + ? this.number = 1 + : this.number = 2; } else { throw new Error("No such player exists"); } @@ -216,7 +293,6 @@ // ----------------- function changeField(field) { - if (gameboard[field] === null) { gameboard[field] = activePlayer.player.marker; pubsub.publish("fieldChange"); @@ -229,14 +305,43 @@ // ----------------- - pubsub.subscribe("fieldChange", displayController); - pubsub.subscribe("fieldChange", checkWin); - pubsub.subscribe("continueGame", () => {activePlayer.change()}); - pubsub.subscribe("draw", popupDraw); - pubsub.subscribe("winTrue", popupWin); - pubsub.subscribe("draw", () => {gameboard.fill(null);}) - pubsub.subscribe("winTrue", () => {gameboard.fill(null);}) - displayController(); - activePlayer.change() + function setupButtons() { + const resetPointsBtn = document.querySelector("#reset-points"); + const resetEverythingBtn = document.querySelector("#reset-everything"); + + resetPointsBtn.addEventListener("click", () => { + gameboard.fill(null); + players.player1.points = 0; + players.player2.points = 0; + updateInfo(); + displayController(); + }) + + resetEverythingBtn.addEventListener("click", () => { + if(confirm("For sure?")) { + window.location.reload(); + } + }) + } + + // ----------------- + + (function initializeLaunch() { + pubsub.subscribe("fieldChange", displayController); + pubsub.subscribe("fieldChange", checkWin); + pubsub.subscribe("continueGame", () => {activePlayer.change(); updateInfo()});; + // pubsub.subscribe("continueGame", ); + // pubsub.subscribe("fieldChange", updateInfo); + pubsub.subscribe("draw", popupDraw); + pubsub.subscribe("winTrue", popupWin); + pubsub.subscribe("draw", () => {gameboard.fill(null);}) + pubsub.subscribe("winTrue", () => {gameboard.fill(null);}) + activePlayer.set( + first == "1" ? players.player1 : players.player2 + ) + displayController(); + updateInfo(); + setupButtons(); + })(); } })() \ No newline at end of file diff --git a/style.css b/style.css index 9fdc44e..705bf5a 100644 --- a/style.css +++ b/style.css @@ -10,6 +10,7 @@ html, body { display: flex; justify-content: center; align-items: center; + flex-direction: column; min-height: 100dvh; } @@ -73,9 +74,12 @@ html, body { cursor: pointer; } +h1#title { + font-size: 2rem; + margin: 0 0 10px 0; +} - -form input[type="text"], form button[type="submit"] { +form input[type="text"], form button[type="submit"], button { padding: 6px; font-size: 1rem; display: block; @@ -85,6 +89,24 @@ form input[type="text"], form button[type="submit"] { margin: auto; } -form button[type="submit"] { +button { cursor: pointer; +} + +label:has(+ input[type="text"]) { + font-size: 0.95rem; + display: block; + margin: 2px 0 0 0; + text-transform: uppercase; + font-weight: bold; +} + +li li { + margin-left: 15px; + font-size: 1.2rem; +} + +li > strong { + font-weight: bold; + font-size: 1.5rem; } \ No newline at end of file