我是编写javascript的新手,老实说,有很多事情我不明白,但我总是设法让事情顺利进行。我为odin项目写了一些东西,但我确信它不是那么干净和有条理,一切都很正常,但我希望它尽可能干净。如果有人对如何清理/改进下面的代码有建议或评论,那就太棒了。谢谢!现场演示:
const cells = document.querySelectorAll(".cell");
const statusText = document.querySelector("#statusText");
const restartBtn = document.querySelector("#restartBtn");
const winConditions = [
[0, 1, 2],
[3, 4, 5],
[6, 7, 8],
[0, 3, 6],
[1, 4, 7],
[2, 5, 8],
[0, 4, 8],
[2, 4, 6]
];
let options = ["", "", "", "", "", "", "", "", ""];
let currentPlayer = document.createElement("p")
currentPlayer.innerText = "tomato"
let running = false;
const sn0 = document.getElementById("sn0")
const sn1 = document.getElementById("sn1")
const sn2 = document.getElementById("sn2")
const sn3 = document.getElementById("sn3")
const sn4 = document.getElementById("sn4")
const sn5 = document.getElementById("sn5")
const sn6 = document.getElementById("sn6")
const sn7 = document.getElementById("sn7")
const sn8 = document.getElementById("sn8")
initializeGame();
function initializeGame(){
cells.forEach(cell => cell.addEventListener("click", cellClicked));
restartBtn.addEventListener("click", restartGame);
statusText.textContent = `${currentPlayer}'s turn`;
running = true;
}
function cellClicked(){
const cellIndex = this.getAttribute("cellIndex");
if(options[cellIndex] != "" || !running){
return;
}
updateCell(this, cellIndex);
checkWinner();
}
function updateCell(cell, index){
options[index] = currentPlayer.innerText;
cell.textContent = currentPlayer.innerText;
}
function changePlayer(){
currentPlayer.innerText = (currentPlayer.innerText == "tomato") ? "flower" : "tomato";
statusText.textContent = `${currentPlayer.innerText}'s turn`;
}
function checkWinner(){
let roundWon = false;
for(let i = 0; i < winConditions.length; i++){
const condition = winConditions[i];
const cellA = options[condition[0]];
const cellB = options[condition[1]];
const cellC = options[condition[2]];
if(cellA == "" || cellB == "" || cellC == ""){
continue;
}
if(cellA == cellB && cellB == cellC){
roundWon = true;
break;
}
}
if(roundWon){
statusText.textContent = `${currentPlayer.innerText} wins!`;
running = false;
}
else if(!options.includes("")){
statusText.textContent = `Draw!`;
running = false;
}
else{
changePlayer();
}
if (sn0.innerHTML.includes("tomato")) {
sn0.classList.add("tomato")
} else if (sn0.innerHTML.includes("flower")){
sn0.classList.add("flower")
}
if (sn1.innerHTML.includes("tomato")) {
sn1.classList.add("tomato")
} else if (sn1.innerHTML.includes("flower")){
sn1.classList.add("flower")
}
if (sn2.innerHTML.includes("tomato")) {
sn2.classList.add("tomato")
} else if (sn2.innerHTML.includes("flower")){
sn2.classList.add("flower")
}
if (sn3.innerHTML.includes("tomato")) {
sn3.classList.add("tomato")
} else if (sn3.innerHTML.includes("flower")){
sn3.classList.add("flower")
}
if (sn4.innerHTML.includes("tomato")) {
sn4.classList.add("tomato")
} else if (sn4.innerHTML.includes("flower")){
sn4.classList.add("flower")
}
if (sn5.innerHTML.includes("tomato")) {
sn5.classList.add("tomato")
} else if (sn5.innerHTML.includes("flower")){
sn5.classList.add("flower")
}
if (sn6.innerHTML.includes("tomato")) {
sn6.classList.add("tomato")
} else if (sn6.innerHTML.includes("flower")){
sn6.classList.add("flower")
}
if (sn7.innerHTML.includes("tomato")) {
sn7.classList.add("tomato")
} else if (sn7.innerHTML.includes("flower")){
sn7.classList.add("flower")
}
if (sn8.innerHTML.includes("tomato")) {
sn8.classList.add("tomato")
} else if (sn8.innerHTML.includes("flower")){
sn8.classList.add("flower")
}
}
function restartGame(){
currentPlayer.innerText = "tomato";
options = ["", "", "", "", "", "", "", "", ""];
statusText.textContent = `${currentPlayer.innerText}'s turn`;
cells.forEach(cell => cell.textContent = "");
running = true;
sn0.classList.remove("tomato")
sn0.classList.remove("flower")
sn1.classList.remove("tomato")
sn1.classList.remove("flower")
sn2.classList.remove("tomato")
sn2.classList.remove("flower")
sn3.classList.remove("tomato")
sn3.classList.remove("flower")
sn4.classList.remove("tomato")
sn4.classList.remove("flower")
sn5.classList.remove("tomato")
sn5.classList.remove("flower")
sn6.classList.remove("tomato")
sn6.classList.remove("flower")
sn7.classList.remove("tomato")
sn7.classList.remove("flower")
sn8.classList.remove("tomato")
sn8.classList.remove("flower")
}我想让这个乱七八糟的代码更干净一点。
发布于 2022-11-15 17:01:37
那么,首先,options数组是无用的,那么,为什么currentPlayer是一个<p>?它应该是一个字符串,使用它们要容易得多。不用担心,您的代码看起来不错,但是可以对可读性进行一些改进:
function name(){...} => function name () {...}if(statement){...} => if (statement) {...}`variable: ${variable}` => `variable: ${ variable }`if (condition) { a += 4 } => if (condition) a += 4 (它也适用于else、else if、for、do、while、.)这是用于js的,但是在html中,为什么要使用cellIndex和id?通过将单元格存储在数组中,我们可以摆脱它们。但是最大的问题是css,你的站点根本没有响应,背景不对小屏幕集中,单元格不匹配背景,状态只显示在特定的屏幕大小上。
我试图突出您代码的所有缺陷,但它一点也不坏!我们都犯了错误,没有错误,我们就无法取得进步。总之,我把js代码做得更好了一点,但它已经很好了,所以我认为您想要关注的是css (如果您想在它上取得进展,您只想要js,这并不丢人)
下面是我的代码:
window.onload = () => {
const cells = Array.from(document.getElementsByClassName('cell'));
const statusText = document.getElementById('statusText');
const restartBtn = document.getElementById('restartBtn');
const winConditions = [
[0, 1, 2],
[3, 4, 5],
[6, 7, 8],
[0, 3, 6],
[1, 4, 7],
[2, 5, 8],
[0, 4, 8],
[2, 4, 6]
];
const cellClicked = cell => {
if (cell.classList.contains('tomato') || cell.classList.contains('flower') || !running) return;
cell.classList.add(currentPlayer);
checkWinner();
}
const togglePlayer = () => {
currentPlayer = (currentPlayer === 'flower') ? 'tomato' : 'flower';
updateCurrentPlayerStatus()
}
const updateCurrentPlayerStatus = () => {
statusText.textContent = `${ currentPlayer }'s turn`;
}
const checkWinner = () => {
let roundWon = false;
for(let i = 0; i < winConditions.length; i++) {
const condition = winConditions[i];
const toTestCells = condition.map(condition => Array.from(cells[condition].classList.values()).find(e => [ 'tomato', 'flower' ].includes(e)))
if (toTestCells.reduce((g, c) => g === c ? g : '')) {
roundWon = true;
break;
}
}
if (roundWon) {
statusText.textContent = `${ currentPlayer } wins!`;
running = false;
}
else if (cells.every(e => e.textContent)) {
statusText.textContent = 'Draw!';
running = false;
}
else
togglePlayer();
}
const restartGame = () => {
currentPlayer = 'tomato';
updateCurrentPlayerStatus()
running = true;
}
let currentPlayer = 'tomato';
let running = false;
togglePlayer()
cells.forEach(cell => cell.onclick = () => cellClicked(cell));
restartBtn.onclick = () => restartGame()
running = true;
}* {
margin: 0;
padding: 0;
border: 0;
}
body {
width: 100%;
height: 100%;
color: white;
}
html {
background: url(https://ljaskolka.github.io/odin-tic-tac-toe/images/background.png) no-repeat center center fixed;
-webkit-background-size: cover;
-moz-background-size: cover;
-o-background-size: cover;
background-position: center;
overflow: hidden;
background-size: cover;
}
.gameboard {
display: flex;
align-items: center;
justify-content: center;
height: 100vh;
}
.cell {
width: 220px;
height: 220px;
line-height: 75px;
font-size: 100px;
cursor: pointer;
text-align: center;
line-height: 200px;
}
.cell-container {
display: grid;
grid-template-columns: repeat(3, auto);
max-width: 660px;
margin-left: 32%;
margin-top: 7.5%;
}
.tomato {
background: url(https://ljaskolka.github.io/odin-tic-tac-toe/images/tomato.png) 0 0 no-repeat;
display: block;
overflow: hidden;
}
.flower {
background: url(https://ljaskolka.github.io/odin-tic-tac-toe/images/flower.png) 0 0 no-repeat;
overflow: hidden;
}<link rel="stylesheet" href="style.css">
<script src="index.js"></script>
<div class="game-container">
<div class="cell-container">
<div class="cell"></div>
<div class="cell"></div>
<div class="cell"></div>
<div class="cell"></div>
<div class="cell"></div>
<div class="cell"></div>
<div class="cell"></div>
<div class="cell"></div>
<div class="cell"></div>
</div>
<h2 id="statusText"></h2>
<button id="restartBtn">Restart</button>
</div>
如果你有什么问题问我!
https://stackoverflow.com/questions/74449014
复制相似问题