5
\$\begingroup\$

Here is my first project that I made with JavaScript and jQuery with a little bit of HTML and CSS:

var currentTurn = "X"; //X or O
var turnNumber = 0;
function generateFields() {
 var y = 1;
 var top = 50;
 for (var i = 0; i < 9; i++) {
 var x = $("#board").append(
 "<div class='field hover-field' id='" + "nr" + i + "'></div>"
 );
 var fieldI = $("#nr" + i);
 if (i == 0 || i == 3 || i == 6) {
 fieldI.css("margin-left", "5px");
 }
 if (i >= 3 && i <= 8) {
 fieldI.css("margin-top", "15px");
 }
 fieldI.click(chooseField);
 }
}
$(generateFields());
/* 
How table looks like:
 var fieldsOnBoard = 
 ["nr0", "nr1", "nr2",
 "nr3", "nr4", "nr5",
 "nr6", "nr7", "nr8",];
 */
function chooseField() {
 if (currentTurn == "X") {
 $(this).html(
 "<img class='cross' src='https://s18.postimg.org/s90kaibmh/cross.png'>"
 );
 currentTurn = "O";
 } else if (currentTurn == "O") {
 $(this).html(
 "<img class='circle' src='https://s18.postimg.org/e2ktfag6x/circle.png'>"
 );
 currentTurn = "X";
 }
 $(this).css({ opacity: 0, scale: 0 });
 $(this).removeClass("hover-field");
 $(this).transition({ opacity: 1, scale: 1 }, "in-out");
 turnNumber++;
 $(".flipper").toggleClass("flipped");
 $(this).off("click");
 if (checkIfWin() != null) {
 endOfGame(checkIfWin());
 }
}
function checkIfWin() {
 var winConditions = [
 ["nr0", "nr1", "nr2"],
 ["nr3", "nr4", "nr5"],
 ["nr6", "nr7", "nr8"],
 ["nr0", "nr3", "nr6"],
 ["nr1", "nr4", "nr7"],
 ["nr2", "nr5", "nr8"],
 ["nr0", "nr4", "nr8"],
 ["nr2", "nr4", "nr6"]
 ];
 for (var x in winConditions) {
 // $("#" + winConditions[x][0] + "> img").attr("class");
 //console.log($("#" + winConditions[x][0] + "> img").attr("class") + " " + $("#" + winConditions[x][0] + "> img").attr("class") + " " + $("#" + winConditions[x][0] + "> img").attr("class"));
 var field1 = $("#" + winConditions[x][0] + "> img").attr("class");
 var field2 = $("#" + winConditions[x][1] + "> img").attr("class");
 var field3 = $("#" + winConditions[x][2] + "> img").attr("class");
 //console.log(`pierwsza = ${field1} druga = ${field2} trzecia = ${field3}`);
 if (field1 != undefined && field2 != undefined && field3 != undefined) {
 if (field1 === field2 && field2 === field3 && field1 === field3) {
 return field1;
 }
 }
 }
 var fieldsOnBoard = [
 "nr0",
 "nr1",
 "nr2",
 "nr3",
 "nr4",
 "nr5",
 "nr6",
 "nr7",
 "nr8"
 ];
 for (var z in fieldsOnBoard) {
 var full = false;
 if ($("#" + fieldsOnBoard[z] + "> img").attr("class") == undefined) {
 break;
 }
 full = true;
 }
 if (full) {
 return "draw";
 }
 return null;
}
function endOfGame(x) {
 console.log(x);
 $("." + x)
 .first()
 .clone()
 .removeClass(".field, " + x)
 .attr("id", "winned")
 .appendTo("#board");
 $(".field, #lines").hide();
 $("#winned").transition({ height: "100px", width: "100px" });
 $("#winned").transition({
 height: "200px",
 width: "200px",
 color: "#e74c3c"
 });
 if (x != "draw") {
 $("#board").append("<p id='win-text'>HAS WON!</p>");
 } else {
 $("#board").append("<p id='win-text'>DRAW</p>");
 setTimeout(() => resetBoard(), 2000);
 }
 $("#winned").click(() => {
 resetBoard();
 });
 function resetBoard() {
 $(".field, #lines").show();
 $("#board").transition({ scale: 0, rotate: "-90deg" });
 $("#board")
 .children("[id != 'lines']")
 .remove();
 generateFields();
 $("#board").transition({ scale: 1, rotate: "0deg" });
 }
}

Codepen (with HTML and CSS)

Jamal
35.2k13 gold badges134 silver badges238 bronze badges
asked Jan 21, 2018 at 21:19
\$\endgroup\$

1 Answer 1

3
\$\begingroup\$

Congrats on building this game, it's pretty cool! I just have a few suggestions for you:

  • Don't use jQuery. You really don't need it for anything. The native versions of finding elements in your DOM are much faster than jQuery's methods, and you don't have to load a library.

  • Don't append HTML as strings. Instead, create dom elements. Then you can add id's, classes and event handlers without querying for them in the DOM.

  • Put CSS rules in a CSS file, and use javascript only to add and remove CSS classes from elements.

Let me try to rewrite this function following my own rules:

function generateFields() {
 var y = 1;
 var top = 50;
 for (var i = 0; i < 9; i++) {
 var x = $("#board").append(
 "<div class='field hover-field' id='" + "nr" + i + "'></div>"
 );
 var fieldI = $("#nr" + i);
 if (i == 0 || i == 3 || i == 6) {
 fieldI.css("margin-left", "5px");
 }
 if (i >= 3 && i <= 8) {
 fieldI.css("margin-top", "15px");
 }
 fieldI.click(chooseField);
 }
}

Could become:

function generateFields() {
 let y = 1;
 let top = 50;
 let board = document.querySelector("#board");
 for (var i = 0; i < 9; i++) {
 let field = document.createElement("div");
 board.appendChild(field);
 field.classList.add("field", "hover-field");
 field.id = "nr"+i;
 if (i == 0 || i == 3 || i == 6) {
 field.addClass("marginLeft");
 }
 if (i >= 3 && i <= 8) {
 field.addClass("marginTop");
 }
 field.addEventListener("click", chooseField);
 }
}

CSS

 .marginLeft {
 margin-left: 5px;
 }
 .marginTop {
 margin-top: 15px;
 }

There's more to improve, but hopefully these tips are helpful!

Sᴀᴍ Onᴇᴌᴀ
29.5k16 gold badges45 silver badges201 bronze badges
answered Mar 4, 2018 at 19:42
\$\endgroup\$
2
  • 1
    \$\begingroup\$ You have two bugs: document.querySelector("board") should be document.querySelector("#board") (or document.getElementById("board")). And field.classList.add("field hover-field")should be field.classList.add("field", "hover-field"). \$\endgroup\$ Commented Mar 5, 2018 at 9:10
  • 1
    \$\begingroup\$ I should have tested :) \$\endgroup\$ Commented Mar 5, 2018 at 11:27

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.