javascript Tic Tac Toe JS游戏[已关闭]

t3psigkw  于 2023-03-28  发布在  Java
关注(0)|答案(1)|浏览(100)

**已关闭。**此问题需要debugging details。当前不接受答案。

编辑问题以包含desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem。这将有助于其他人回答问题。
昨天关门了。
Improve this question
我不知道cod到底出了什么问题,你能帮我找到吗?我所知道的是“可用”数组没有正确清空,计算机有时会连续走两步。
链接到github上的代码:https://github.com/skrrrt-and-boom/tic-tac-toe
网站链接:https://skrrrt-and-boom.github.io/tic-tac-toe/

const board = document.querySelector('#board')
const p = document.querySelectorAll('p')
const results = document.querySelector('#results')
const square = document.querySelectorAll('.kafelek')

let content = [
  ['','',''],
  ['','',''],
  ['','',''],
];

let players = ['X', 'O'];
let computer = players[0];
let human = players[1];
let currentPlayer;
let available = [];

function random(available) {
  let x = Math.random() * 10;
  x = Math.floor(x)
  return (Math.floor(available / (x+1)))
}

function setup() {
  currentPlayer = 0;
  for (let i = 0; i < 3; i++) {
    for (let j = 0; j < 3; j++) {
      available.push([i, j]);
    }
  }
}

setup()

function equals(a, b, c) {
  return (a===b && b===c && a !== '')
}

function checkWin() {
  let winner = null;

  //    horizontal
  for (let i = 0; i < 3; i++) {
    if (equals(content[i][0], content[i][1], content[i][2])) {
      winner = content[i][0];
      return (results.textContent = winner + ' Wins')
    }
  }

  //    vertical
  for (let j = 0; j < 3; j++) {
    if (equals(content[0][j], content[1][j], content[2][j])) {
      winner = content[0][j];
      return (results.textContent = winner + ' Wins')
    }
  }

  //    Diagonal
  if (equals(content[0][0], content[1][1], content[2][2])) {
    winner = content[0][0];
    return (results.textContent = winner + ' Wins')
  }

  if (equals(content[2][0], content[1][1], content[0][2])) {
    winner = content[2][0];
    return (results.textContent = winner + ' Wins')
  }

  if (winner === null && available.length === 0) {
    return (results.textContent = 'Tie')
  }
}

function nextTurn() {
  let index = Math.floor(random(available.length));
  console.log(index);
  let spot = available.splice(index, 1)[0];
  //if (spot === undefined) {
  //  spot = available.splice(0, 1)[0];
  //}
  content[spot[0]][spot[1]] = computer;
  draw();
  checkWin()
}

function draw() {
  let k = 0;
  for (let i = 0; i < 3; i++) {
    for (let j = 0; j < 3; j++) {
      if (p[k].textContent === '') {
        square[k].addEventListener('click', () => game(i, j))
      }
      let spot = content[i][j];
      p[k].textContent = spot;
      k++;
    }
  }
}
function game(i, j) {
  content[i][j] = human;
  let sub = [i, j];
  let matchEvery = (available, ind, sub) => available[ind].every((el, i) => el == sub[i]);
  let searchForArray = (available = [], sub = []) => {
    let ind = -1;
    let {
      length: len } = available;
    while (len--) {
      if (available[len].length === sub.length && matchEvery(available, len, sub)){
        ind = len;
        break;
      };
    };
    return ind;
  };
  console.log(searchForArray(available, sub), available);
  available.splice(searchForArray(available, sub), 1);
  nextTurn();
}

nextTurn();
hmae6n7t

hmae6n7t1#

计算机连续走2步或更多步,因为每次调用draw()时都将事件处理程序附加到空单元格。用于推进游戏的事件处理程序只应在游戏设置期间附加一次,即在setup()方法中。否则,如果空单元格有多个“单击”处理程序,则当用户单击时,它们将分别执行。每一次都给计算机一个行动的机会。
我发现的另一个问题是在你的random()函数中,我不完全确定你是怎么想的,但是要返回一个上界的随机非负整数,只需执行Math.floor(Math.random() * upperBound)
关于available数组,如果我是你,我会重新考虑是否有必要摆在首位。可用的数组可以被认为是棋盘或content的“逆”,因为content显示了哪些移动已经完成,而available跟踪了哪些移动。然而,因此,您可以通过提取仍然为空的单元格的索引,仅使用content的当前状态来确定剩下的内容。否则,您实际上在2个不同的地方管理相同的状态,所以我建议你把它去掉,重新考虑一下你是如何决定电脑走哪一步的。
这些更改将修复您的一些问题,但是在您拥有完全工作的版本之前,似乎还有一些问题。而且用户可以通过点击一个被占用的单元格来完全覆盖计算机的移动。我建议遵循一个在线教程,以确保你涵盖了所有用户交互的边缘情况。最重要的是不要给予,继续学习!
下面是我建议的前两个修改的代码,以供参考。

const board = document.querySelector('#board')
const p = document.querySelectorAll('p')
const results = document.querySelector('#results')
const square = document.querySelectorAll('.kafelek')

let content = [
  ['', '', ''],
  ['', '', ''],
  ['', '', ''],
];

let players = ['X', 'O'];
let computer = players[0];
let human = players[1];
let currentPlayer;
let available = [];

function random(upperBound) {
  return Math.floor(Math.random() * upperBound);
}

function setup() {
  currentPlayer = 0;
  for (let i = 0; i < 3; i++) {
    for (let j = 0; j < 3; j++) {
      available.push([i, j]);
      square[i * 3 + j].addEventListener('click', () => game(i, j))
    }
  }
}

setup()

function equals(a, b, c) {
  return (a === b && b === c && a !== '')
}

function checkWin() {
  let winner = null;

  //    horizontal
  for (let i = 0; i < 3; i++) {
    if (equals(content[i][0], content[i][1], content[i][2])) {
      winner = content[i][0];
      return (results.textContent = winner + ' Wins')
    }
  }

  //    vertical
  for (let j = 0; j < 3; j++) {
    if (equals(content[0][j], content[1][j], content[2][j])) {
      winner = content[0][j];
      return (results.textContent = winner + ' Wins')
    }
  }

  //    Diagonal
  if (equals(content[0][0], content[1][1], content[2][2])) {
    winner = content[0][0];
    return (results.textContent = winner + ' Wins')
  }

  if (equals(content[2][0], content[1][1], content[0][2])) {
    winner = content[2][0];
    return (results.textContent = winner + ' Wins')
  }

  if (winner === null && available.length === 0) {
    return (results.textContent = 'Tie')
  }
}

function nextTurn() {
  let index = Math.floor(random(available.length));
  // console.log(index);
  let spot = available.splice(index, 1)[0];
  //if (spot === undefined) {
  //  spot = available.splice(0, 1)[0];
  //}
  content[spot[0]][spot[1]] = computer;
  draw();
  checkWin()
}

function draw() {
  for (let i = 0; i < 3; i++) {
    for (let j = 0; j < 3; j++) {
      let spot = content[i][j];
      p[i * 3 + j].textContent = spot;
    }
  }
}

function game(i, j) {
  content[i][j] = human;
  let sub = [i, j];
  let matchEvery = (available, ind, sub) => available[ind].every((el, i) => el == sub[i]);
  let searchForArray = (available = [], sub = []) => {
    let ind = -1;
    let {
      length: len
    } = available;
    while (len--) {
      if (available[len].length === sub.length && matchEvery(available, len, sub)) {
        ind = len;
        break;
      };
    };
    return ind;
  };
  // console.log(searchForArray(available, sub), available);
  available.splice(searchForArray(available, sub), 1);
  nextTurn();
}

nextTurn();
html {
  height: 100%;
}

body {
  height: 100%;
  margin: 0;
  display: flex;
  justify-content: center;
  font-size: 120px;
  font-family: sans;
  flex-direction: column;
}

#board {
  align-self: center;
  width: 500px;
  height: 500px;
  border: 3px solid;
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
}

.kafelek {
  display: flex;
  justify-content: center;
  border: 3px solid;
  cursor: pointer;
}

p {
  margin: 0;
  height: 144px;
  align-self: center;
  cursor: pointer;
}

#results {
  font-size: 70px;
  margin-top: 70px;
  text-align: center;
}
<div id="board">
    <div class="kafelek">
        <p></p>
    </div>
    <div class="kafelek">
        <p></p>
    </div>
    <div class="kafelek">
        <p></p>
    </div>
    <div class="kafelek">
        <p></p>
    </div>
    <div class="kafelek">
        <p></p>
    </div>
    <div class="kafelek">
        <p></p>
    </div>
    <div class="kafelek">
        <p></p>
    </div>
    <div class="kafelek">
        <p></p>
    </div>
    <div class="kafelek">
        <p></p>
    </div>
</div>
<div id="results">Click to play</div>

相关问题