'How can i turn these two functions into a turn by turn for Naughts and crosses
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 class="allBoxes">
<div class="box1"></div>
<div class="box2"></div>
<div class="box3"></div>
<div class="box4"></div>
<div class="box5"></div>
<div class="box6"></div>
<div class="box7"></div>
<div class="box8"></div>
<div class="box9"></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);
Solution 1:[1]
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 class="row"><span class="tile"></span><span class="tile"></span><span class="tile"></span></div>
<div class="row"><span class="tile"></span><span class="tile"></span><span class="tile"></span></div>
<div class="row"><span class="tile"></span><span class="tile"></span><span class="tile"></span></div>
</div>
Solution 2:[2]
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 class="allboxes">
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
</div>
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | |
| Solution 2 |
