Кодирование игры Connect four. checkWin () не работает должным образом. Пропуск первого и последнего столбцов

#javascript #jquery #html

#javascript #jquery #HTML

Вопрос:

Я уверен, что вы, ребята, получаете миллион подобных сообщений, поэтому я хочу сразу извиниться. Я уверен, что это довольно просто.

Рассматриваемая функция, checkWin(), еще не завершена, но она принимает список столбцов, составленный из объектов jquery, и выполняет итерации по ним. Первые две строки, которые проверяют выигрыши по диагонали, работают так, как задумано, хотя я уверен, что их можно было бы написать более аккуратно. По какой-то причине третий оператор if, который проверяет, выиграл ли игрок по вертикальному столбцу, работает отлично, за исключением того, что он полностью пропускает первый и последний столбцы. Он правильно сообщает о выигрышах во всех других столбцах, но полностью игнорирует первый и последний. Я определенно новичок в этом, поэтому уверен, что это какая-то простая ошибка, которую я допустил. Я могу также прикрепить HTML-код, если это вообще поможет.

редактировать: Я также добавил страницу HTML и CSS. Таким образом, вы действительно можете запустить страницу.

 var col1 = [$("#a1"), $("#b1"), $("#c1"), $("#d1"), $("#e1"), $("#f1")]
var col2 = [$("#a2"), $("#b2"), $("#c2"), $("#d2"), $("#e2"), $("#f2")]
var col3 = [$("#a3"), $("#b3"), $("#c3"), $("#d3"), $("#e3"), $("#f3")]
var col4 = [$("#a4"), $("#b4"), $("#c4"), $("#d4"), $("#e4"), $("#f4")]
var col5 = [$("#a5"), $("#b5"), $("#c5"), $("#d5"), $("#e5"), $("#f5")]
var col6 = [$("#a6"), $("#b6"), $("#c6"), $("#d6"), $("#e6"), $("#f6")]
var col7 = [$("#a7"), $("#b7"), $("#c7"), $("#d7"), $("#e7"), $("#f7")]
var colList = [col1, col2, col3, col4, col5, col6, col7]
var dotList = $("td")
var jumboText = $("#jumbotext")
var gameOver = false
var playerTurn = "blue"
var redName = ""
var blueName = ""


function redDrop (column){
  for (var i = column.length -1 ; i >= 0; i--) {
    if (column[i].attr("class") === "dot") {
      column[i].toggleClass("reddot")
      playerTurn = "blue"
      break
    }
  }
}

function blueDrop (column){
  for (var i = column.length -1 ; i >= 0; i--) {
    if (column[i].attr("class") === "dot") {
      column[i].toggleClass("bluedot")
      playerTurn = "red"
      break
    }
  }
}


function checkWin(){
  for (var i = 0; i < colList.length; i  ) {
    for (var x = 0; x < colList[i].length; x  ) {
      if (colList[i][x].attr("class") === "dot reddot" || colList[i][x].attr("class") === "dot bluedot") {
        try {
          if (colList[i][x].attr("class") === colList[i 1][x 1].attr("class") amp;amp; colList[i][x].attr("class") === colList[i 2][x 2].attr("class") amp;amp; colList[i][x].attr("class") === colList[i 3][x 3].attr("class")){
            alert(colList[i][x].attr("class") "Winner!")
          }
          else if (colList[i][x].attr("class") === colList[i-1][x 1].attr("class") amp;amp; colList[i][x].attr("class") === colList[i-2][x 2].attr("class") amp;amp; colList[i][x].attr("class") === colList[i-3][x 3].attr("class")){
            alert(colList[i][x].attr("class") "Winner!")
          }
////////
///////This next line seems to be the issue.
//////
          else if (colList[i][x].attr("class") === colList[i][x 1].attr("class") amp;amp; colList[i][x].attr("class") === colList[i][x 2].attr("class") amp;amp; colList[i][x].attr("class") === colList[i][x 3].attr("class")){
            alert(colList[i][x].attr("class") "Winner!")
          }

        } catch (e) {

        }
      }
    }
  }
}

function dropPeice(col){
  for (var i = 0; i < col.length; i  ) {
    col[i].click(function(){
        if (playerTurn === "blue") {
          blueDrop(col)
          playerTurn = "red"
          checkWin()
          jumboText.text(redName ": It's your turn. Place a red peice.")
        }else if (playerTurn === "red") {
          redDrop(col)
          playerTurn = "blue"
          checkWin()
          jumboText.text(blueName ": It's your turn. Place a blue peice.")
        }
    })
  }
}

function gamePlay(){
  blueName = prompt("Blue player, please input your name.")
  redName = prompt("Red player, please input your name.")
  jumboText.text(blueName ": You start. Place a blue piece.")
  for (var i = 0; i < colList.length; i  ) {
    dropPeice(colList[i])
  }
}
gamePlay()  
 .dot{
  height: 100px;
  width: 100px;
  background-color: #bbb;
  border-radius: 50%;
  border: 5px solid black;
  display: inline-block;
}
.reddot{
  height: 100px;
  width: 100px;
  background-color: red;
  border-radius: 50%;
  border: 5px solid maroon;
  display: inline-block;
}
.bluedot{
  height: 100px;
  width: 100px;
  background-color: blue;
  border-radius: 50%;
  border: 5px solid navy;
  display: inline-block;
}  
 <!DOCTYPE html>
<html lang="en" dir="ltr">
  <head>
    <meta charset="utf-8">
    <title>Connect 4</title>
    <script
  src="https://code.jquery.com/jquery-3.1.1.min.js"
  integrity="sha256-hVVnYaiADRTO2PzUGmuLJr8BLUSjGIZsDYGmIJLv2b8="
  crossorigin="anonymous"></script>
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
    <link rel="stylesheet" href="FrontEndMaster.css">
  </head>
  <body>
    <div class="container">
      <div class="jumbotron" align="center">
        <h1>Connect 4</h1>
        <p id= "jumbotext">This text will change to inform the player what's happening.</p>
      </div>
      <table align='center'>
        <tr>
          <td class="dot" id = "a1"></td>
          <td class="dot" id = "a2"></td>
          <td class="dot" id = "a3"></td>
          <td class="dot" id = "a4"></td>
          <td class="dot" id = "a5"></td>
          <td class="dot" id = "a6"></td>
          <td class="dot" id = "a7"></td>
        </tr>
        <tr>
          <td class="dot" id = "b1"></td>
          <td class="dot" id = "b2"></td>
          <td class="dot" id = "b3"></td>
          <td class="dot" id = "b4"></td>
          <td class="dot" id = "b5"></td>
          <td class="dot" id = "b6"></td>
          <td class="dot" id = "b7"></td>
        </tr>
        <tr>
          <td class="dot" id = "c1"></td>
          <td class="dot" id = "c2"></td>
          <td class="dot" id = "c3"></td>
          <td class="dot" id = "c4"></td>
          <td class="dot" id = "c5"></td>
          <td class="dot" id = "c6"></td>
          <td class="dot" id = "c7"></td>
        </tr>
        <tr>
          <td class="dot" id = "d1"></td>
          <td class="dot" id = "d2"></td>
          <td class="dot" id = "d3"></td>
          <td class="dot" id = "d4"></td>
          <td class="dot" id = "d5"></td>
          <td class="dot" id = "d6"></td>
          <td class="dot" id = "d7"></td>
        </tr>
        <tr>
          <td class="dot" id = "e1"></td>
          <td class="dot" id = "e2"></td>
          <td class="dot" id = "e3"></td>
          <td class="dot" id = "e4"></td>
          <td class="dot" id = "e5"></td>
          <td class="dot" id = "e6"></td>
          <td class="dot" id = "e7"></td>
        </tr>
        <tr>
          <td class="dot" id = "f1"></td>
          <td class="dot" id = "f2"></td>
          <td class="dot" id = "f3"></td>
          <td class="dot" id = "f4"></td>
          <td class="dot" id = "f5"></td>
          <td class="dot" id = "f6"></td>
          <td class="dot" id = "f7"></td>
        </tr>
      </table>
    </div>

    <script src="FrontEndScript.js" charset="utf-8"></script>
  </body>
</html>  

Комментарии:

1. Не могли бы вы добавить html и jquery, чтобы фрагмент кода работал. В качестве альтернативы, если вы обнаружили неработающую функцию, вы можете опубликовать минимальный пример вместо всего скрипта

2. Небольшой совет, не имеющий отношения к делу: вам следует использовать точки с запятой в конце ваших строк JS 🙂

3. Хорошая мысль, Сэм! Я определенно сделаю это, как только разберусь с этой маленькой проблемой. Спасибо за отзыв!

4. Теперь я добавил HTML, а также CSS, чтобы код можно было запускать полностью!

Ответ №1:

Вы проглатываете исключения в своем try/catch блоке. Вы обращаетесь к индексам вне массива и не все условия if / else проверяются.

Это отличный пример, почему вам следует избегать перехватов try (и использовать его только в исключительных случаях); не потому, что вы не хотите писать проверки того, что вы действительно обращаетесь к допустимому индексу массива.

Самым простым решением, которое я нашел, было создать getClass функцию, которая выполняет проверку индекса и возвращает undefined для случаев, когда индекс выходит за рамки. Благодаря добавлению этой проверки в вашем коде нет исключений, и он работает так, как ожидалось

 var col1 = [$("#a1"), $("#b1"), $("#c1"), $("#d1"), $("#e1"), $("#f1")];
var col2 = [$("#a2"), $("#b2"), $("#c2"), $("#d2"), $("#e2"), $("#f2")];
var col3 = [$("#a3"), $("#b3"), $("#c3"), $("#d3"), $("#e3"), $("#f3")];
var col4 = [$("#a4"), $("#b4"), $("#c4"), $("#d4"), $("#e4"), $("#f4")];
var col5 = [$("#a5"), $("#b5"), $("#c5"), $("#d5"), $("#e5"), $("#f5")];
var col6 = [$("#a6"), $("#b6"), $("#c6"), $("#d6"), $("#e6"), $("#f6")];
var col7 = [$("#a7"), $("#b7"), $("#c7"), $("#d7"), $("#e7"), $("#f7")];
var colList = [col1, col2, col3, col4, col5, col6, col7];
var dotList = $("td");
var jumboText = $("#jumbotext");
var gameOver = false;
var playerTurn = "blue";
var redName = "";
var blueName = "";


function redDrop(column) {
  for (var i = column.length - 1; i >= 0; i--) {
    if (column[i].attr("class") === "dot") {
      column[i].toggleClass("reddot");
      playerTurn = "blue";
      break;
    }
  }
}

function blueDrop(column) {
  for (var i = column.length - 1; i >= 0; i--) {
    if (column[i].attr("class") === "dot") {
      column[i].toggleClass("bluedot");
      playerTurn = "red";
      break;
    }
  }
}

function getClass(x, y) {
  const cell = colList[y] amp;amp; colList[y][x];
  return cell amp;amp; cell.attr("class");
}

function checkWin() {

  const boardSize = colList.length;
  for (var y = 0; y < boardSize; y  ) {
    for (var x = 0; x < boardSize; x  ) {
      // Found a blue or red dot
      const className = getClass(x, y);
      if (className === "dot reddot" || className === "dot bluedot") {
        // Look diagonally down/right
        if (className === getClass(x   1, y   1) amp;amp;
          className === getClass(x   2, y   2) amp;amp;
          className === getClass(x   3, y   3)) {
          alert(className   "Winner!");
          return;
        }
        // Look diagonally up/right
        if (className === getClass(x   1, y - 1) amp;amp;
          className === getClass(x   2, y - 2) amp;amp;
          className === getClass(x   3, y - 3)) {
          alert(className   "Winner!");
          return;
        }
        // Look down
        if (
          className === getClass(x   1, y) amp;amp;
          className === getClass(x   2, y) amp;amp;
          className === getClass(x   3, y)) {
          alert(className   "Winner!");
          return;
        }

      }
    }
  }
}

function dropPeice(col) {
  for (var i = 0; i < col.length; i  ) {
    col[i].click(function() {
      if (playerTurn === "blue") {
        blueDrop(col);
        playerTurn = "red";
        checkWin();
        jumboText.text(redName   ": It's your turn. Place a red peice.");
      } else if (playerTurn === "red") {
        redDrop(col);
        playerTurn = "blue";
        checkWin();
        jumboText.text(blueName   ": It's your turn. Place a blue peice.");
      }
    });
  }
}

function gamePlay() {
  blueName = prompt("Blue player, please input your name.");
  redName = prompt("Red player, please input your name.");
  jumboText.text(blueName   ": You start. Place a blue piece.");
  for (var i = 0; i < colList.length; i  ) {
    dropPeice(colList[i]);
  }
}

gamePlay();  
 .dot {
  height: 100px;
  width: 100px;
  background-color: #bbb;
  border-radius: 50%;
  border: 5px solid black;
  display: inline-block;
}

.reddot {
  height: 100px;
  width: 100px;
  background-color: red;
  border-radius: 50%;
  border: 5px solid maroon;
  display: inline-block;
}

.bluedot {
  height: 100px;
  width: 100px;
  background-color: blue;
  border-radius: 50%;
  border: 5px solid navy;
  display: inline-block;
}  
 <!DOCTYPE html>
<html lang="en" dir="ltr">

<head>
  <meta charset="utf-8">
  <title>Connect 4</title>
  <script src="https://code.jquery.com/jquery-3.1.1.min.js" integrity="sha256-hVVnYaiADRTO2PzUGmuLJr8BLUSjGIZsDYGmIJLv2b8=" crossorigin="anonymous"></script>
  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
  <link rel="stylesheet" href="FrontEndMaster.css">
</head>

<body>
  <div class="container">
    <div class="jumbotron" align="center">
      <h1>Connect 4</h1>
      <p id="jumbotext">This text will change to inform the player what's happening.</p>
    </div>
    <table align='center'>
      <tr>
        <td class="dot" id="a1"></td>
        <td class="dot" id="a2"></td>
        <td class="dot" id="a3"></td>
        <td class="dot" id="a4"></td>
        <td class="dot" id="a5"></td>
        <td class="dot" id="a6"></td>
        <td class="dot" id="a7"></td>
      </tr>
      <tr>
        <td class="dot" id="b1"></td>
        <td class="dot" id="b2"></td>
        <td class="dot" id="b3"></td>
        <td class="dot" id="b4"></td>
        <td class="dot" id="b5"></td>
        <td class="dot" id="b6"></td>
        <td class="dot" id="b7"></td>
      </tr>
      <tr>
        <td class="dot" id="c1"></td>
        <td class="dot" id="c2"></td>
        <td class="dot" id="c3"></td>
        <td class="dot" id="c4"></td>
        <td class="dot" id="c5"></td>
        <td class="dot" id="c6"></td>
        <td class="dot" id="c7"></td>
      </tr>
      <tr>
        <td class="dot" id="d1"></td>
        <td class="dot" id="d2"></td>
        <td class="dot" id="d3"></td>
        <td class="dot" id="d4"></td>
        <td class="dot" id="d5"></td>
        <td class="dot" id="d6"></td>
        <td class="dot" id="d7"></td>
      </tr>
      <tr>
        <td class="dot" id="e1"></td>
        <td class="dot" id="e2"></td>
        <td class="dot" id="e3"></td>
        <td class="dot" id="e4"></td>
        <td class="dot" id="e5"></td>
        <td class="dot" id="e6"></td>
        <td class="dot" id="e7"></td>
      </tr>
      <tr>
        <td class="dot" id="f1"></td>
        <td class="dot" id="f2"></td>
        <td class="dot" id="f3"></td>
        <td class="dot" id="f4"></td>
        <td class="dot" id="f5"></td>
        <td class="dot" id="f6"></td>
        <td class="dot" id="f7"></td>
      </tr>
    </table>
  </div>

  <script src="FrontEndScript.js" charset="utf-8"></script>
</body>

</html>  

Комментарии:

1. Большое вам спасибо! И дополнительное спасибо за информацию о try catches! Я определенно буду иметь это в виду в будущем.