I have two functions (one that runs) I'm wanting to use these and create two player turn variables to switch between each other marking an X or an O when it's each players turn. I'm wanting to keep it as simple as possible but cannot even fathom where to go. I know it's not great but if I can I would like to keep these functions or something close to it.
<section >
<div ></div>
<div ></div>
<div ></div>
<div ></div>
<div ></div>
<div ></div>
<div ></div>
<div ></div>
<div ></div>
<script src="tictac.js"></script>
</section>
function clickBoxPlayerOne(event) {
var boxClicked = event.target;
if ((boxClicked.textContent = " ")) boxClicked.textContent = "X";
}
var allBoxes = document.querySelector(".allBoxes");
allBoxes.addEventListener("click", clickBoxPlayerOne);
function clickBoxPlayerTwo(event) {
var boxClicked = event.target;
if (boxClicked.textContent != "X") boxClicked.textContent = "O";
}
var allBoxes = document.querySelector(".allBoxes");
allBoxes.addEventListener("click", clickBoxPlayerTwo);
CodePudding user response:
I think what you need is a global variable to keep the current player state and update it whenever the user clicks on any box. Like in the Tic-tac-toe :)
Adding a sample working code for reference to see how the usage is.
const player1 = "X", player2 = "O";
let currentPlayer = player1;
const elements = document.getElementsByClassName("tile");
// Click handler
for (var i = 0; i < elements.length; i ) {
elements[i].addEventListener('click', playMe, false);
}
function playMe(event) {
if(event.target.innerText == "") {
event.target.innerText = currentPlayer;
currentPlayer = currentPlayer == player1 ? player2 : player1;
}
}
.tile {
padding: 10px;
border: 1px solid #CCC;
width: 40px;
display: inline-block;
text-align: center;
margin-right: 10px;
}
.row {
margin: 10px;
}
<div>
<div ><span ></span><span ></span><span ></span></div>
<div ><span ></span><span ></span><span ></span></div>
<div ><span ></span><span ></span><span ></span></div>
</div>
CodePudding user response:
To remove the need for global variables I would use the function that's called from addEventListener to set up those variables, and return a new function (closure) that is the function that's returned to the listener. The closure maintains the variables in its local lexical environment so it can update them.
I would also use CSS Grid to handle the display.
const allBoxes = document.querySelector('.allboxes');
allBoxes.addEventListener('click', handleClick(), false);
function handleClick() {
// Initialise the player variable
let player = 1;
// Return the function that will be used
// when the listener is called
return function (e) {
// Get the text content of the clicked element
const { textContent } = e.target;
if (!textContent) {
// Update the content of the square, and
// then swap the player
const content = player === 1 ? 'X' : 'O';
e.target.textContent = content;
player = player === 1 ? 2 : 1;
}
}
}
.allboxes { width: 50%; display: grid; grid-template-columns: repeat(3, 1fr); gap: 0.5em; }
.allboxes div { display: flex; border: 1px solid black; height: 2em; width: 2em; align-items: center; justify-content: center;}
<div >
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
</div>
