Минимизация блоков if-else

299
19 июля 2017, 23:30

Это кусок кода игры "крестики-нолики", который нужно сделать более компактным!
Хотя оно и так работает)

//вы выиграли
if (arr1[0] === 1 && arr1[1] === 1 && arr1[2] === 1) {
    $("#vin").text("you win");
    $("#a0").css("background-color", "red");
    $("#a1").css("background-color", "red");
    $("#a2").css("background-color", "red");
    vinner = true;
} else if (arr1[3] === 1 && arr1[4] === 1 && arr1[5] === 1) {
    $("#vin").text("you win");
    $("#a3").css("background-color", "red");
    $("#a4").css("background-color", "red");
    $("#a5").css("background-color", "red");
    vinner = true;
} else if (arr1[6] === 1 && arr1[7] === 1 && arr1[8] === 1) {
    $("#vin").text("you win");
    $("#a6").css("background-color", "red");
    $("#a7").css("background-color", "red");
    $("#a8").css("background-color", "red");
    vinner = true;
} else if (arr1[0] === 1 && arr1[3] === 1 && arr1[6] === 1) {
    $("#vin").text("you win");
    $("#a0").css("background-color", "red");
    $("#a3").css("background-color", "red");
    $("#a6").css("background-color", "red");
    vinner = true;
} else if (arr1[1] === 1 && arr1[4] === 1 && arr1[7] === 1) {
    $("#vin").text("you win");
    $("#a1").css("background-color", "red");
    $("#a4").css("background-color", "red");
    $("#a7").css("background-color", "red");
    vinner = true;
} else if  (arr1[2] === 1 && arr1[5] === 1 && arr1[8] === 1) {
    $("#vin").text("you win");
    $("#a2").css("background-color", "red");
    $("#a5").css("background-color", "red");
    $("#a8").css("background-color", "red");
    vinner = true;
} else if (arr1[0] === 1 && arr1[4] === 1 && arr1[8] === 1) {
    $("#vin").text("you win");
    $("#a0").css("background-color", "red");
    $("#a4").css("background-color", "red");
    $("#a8").css("background-color", "red");
    vinner = true;
} else if (arr1[2] === 1 && arr1[4] === 1 && arr1[6] === 1) {
    $("#vin").text("you win");
    $("#a2").css("background-color", "red");
    $("#a4").css("background-color", "red");
    $("#a6").css("background-color", "red");
    vinner = true;
}

//вы проиграли
else if (arr1[0] === 0 && arr1[1] === 0 && arr1[2] === 0) {
    $("#vin").text("you low");
    $("#a0").css("background-color", "red");
    $("#a1").css("background-color", "red");
    $("#a2").css("background-color", "red");
    vinner = true;
} else if (arr1[3] === 0 && arr1[4] === 0 && arr1[5] === 0) {
    $("#vin").text("you low");
    $("#a3").css("background-color", "red");
    $("#a4").css("background-color", "red");
    $("#a5").css("background-color", "red");
    vinner = true;
} else if (arr1[6] === 0 && arr1[7] === 0 && arr1[8] === 0) {
    $("#vin").text("you low");
    $("#a6").css("background-color", "red");
    $("#a7").css("background-color", "red");
    $("#a8").css("background-color", "red");
    vinner = true;
} else if (arr1[0] === 0 && arr1[3] === 0 && arr1[6] === 0) {
    $("#vin").text("you low");
    $("#a0").css("background-color", "red");
    $("#a3").css("background-color", "red");
    $("#a6").css("background-color", "red");
    vinner = true;
} else if (arr1[1] === 0 && arr1[4] === 0 && arr1[7] === 0) {
    $("#vin").text("you low");
    $("#a1").css("background-color", "red");
    $("#a4").css("background-color", "red");
    $("#a7").css("background-color", "red");
    vinner = true;
} else if  (arr1[2] === 0 && arr1[5] === 0 && arr1[8] === 0) {
    $("#vin").text("you low");
    $("#a2").css("background-color", "red");
    $("#a5").css("background-color", "red");
    $("#a8").css("background-color", "red");
    vinner = true;
} else if (arr1[0] === 0 && arr1[4] === 0 && arr1[8] === 0) {
    $("#vin").text("you low");
    $("#a0").css("background-color", "red");
    $("#a4").css("background-color", "red");
    $("#a8").css("background-color", "red");
    vinner = true;
} else if (arr1[2] === 0 && arr1[4] === 0 && arr1[6] === 0) {
    $("#vin").text("you low");
    $("#a2").css("background-color", "red");
    $("#a4").css("background-color", "red");
    $("#a6").css("background-color", "red");
    vinner = true;
}

Вот ссылка всего кода и если у вас еще есть идеи как сделать, чтобы комп думал более логически, подскажите.

(function addLink(links) { 
  links.reduce((head, l) => { 
    var el = document.createElement('link'); 
    el.href = l; 
    el.rel = "stylesheet"; 
    head.insertBefore(el, head.firstElementChild); 
    return head; 
  }, document.querySelector('head')) 
})(["https://cdnjs.cloudflare.com/ajax/libs/animate.css/3.5.2/animate.min.css", "https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/css/bootstrap.min.css", "https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.0.0-alpha.6/css/bootstrap.min.css"].reverse()); 
$(document).ready(function() { 
  var flag; 
  var vinner; 
  var winCombo = [ 
    [0, 1, 2], 
    [3, 4, 5], 
    [6, 7, 8], 
    [0, 3, 6], 
    [1, 4, 7], 
    [2, 5, 8], 
    [0, 4, 8], 
    [2, 4, 6] 
  ]; 
  var arr = [0, 1, 2, 3, 4, 5, 6, 7, 8]; 
  var arr1 = [3, 3, 3, 3, 3, 3, 3, 3, 3]; 
  var testArr = []; 
  var nar1; 
 
  function rand() { 
    return nar1[Math.floor(Math.random() * nar1.length)]; 
  } 
  $(".xo").click(function() { 
    if (vinner === true) { 
      return false; 
    } 
    if (flag === undefined) { 
      alert('To start, click Start GAME and select "X" or "O"') 
    } 
    var a = $(this).text(); 
    var b = parseInt($(this).attr("data-value")); 
    if (a === "") { //если пустая клетка 
      $(this).text(flag); 
      testArr.push(b); 
      arr1[b] = 1; 
      nar1 = arr.filter(el => testArr.indexOf(el) === -1); 
      var randNumb = rand(); 
      idItem = '#a' + randNumb; 
      testArr.push(randNumb); 
      var f_map = { 
        "X": "O", 
        "O": "X" 
      } 
      $(idItem).html(f_map[flag]); 
      arr1[randNumb] = 0; 
    } 
 
    //вы выиграли 
    if (arr1[0] === 1 && arr1[1] === 1 && arr1[2] === 1) { 
      $("#vin").text("you win"); 
      $("#a0").css("background-color", "red"); 
      $("#a1").css("background-color", "red"); 
      $("#a2").css("background-color", "red"); 
      vinner = true; 
    } else if (arr1[3] === 1 && arr1[4] === 1 && arr1[5] === 1) { 
      $("#vin").text("you win"); 
      $("#a3").css("background-color", "red"); 
      $("#a4").css("background-color", "red"); 
      $("#a5").css("background-color", "red"); 
      vinner = true; 
    } else if (arr1[6] === 1 && arr1[7] === 1 && arr1[8] === 1) { 
      $("#vin").text("you win"); 
      $("#a6").css("background-color", "red"); 
      $("#a7").css("background-color", "red"); 
      $("#a8").css("background-color", "red"); 
      vinner = true; 
    } else if (arr1[0] === 1 && arr1[3] === 1 && arr1[6] === 1) { 
      $("#vin").text("you win"); 
      $("#a0").css("background-color", "red"); 
      $("#a3").css("background-color", "red"); 
      $("#a6").css("background-color", "red"); 
      vinner = true; 
    } else if (arr1[1] === 1 && arr1[4] === 1 && arr1[7] === 1) { 
      $("#vin").text("you win"); 
      $("#a1").css("background-color", "red"); 
      $("#a4").css("background-color", "red"); 
      $("#a7").css("background-color", "red"); 
      vinner = true; 
    } else if (arr1[2] === 1 && arr1[5] === 1 && arr1[8] === 1) { 
      $("#vin").text("you win"); 
      $("#a2").css("background-color", "red"); 
      $("#a5").css("background-color", "red"); 
      $("#a8").css("background-color", "red"); 
      vinner = true; 
    } else if (arr1[0] === 1 && arr1[4] === 1 && arr1[8] === 1) { 
      $("#vin").text("you win"); 
      $("#a0").css("background-color", "red"); 
      $("#a4").css("background-color", "red"); 
      $("#a8").css("background-color", "red"); 
      vinner = true; 
    } else if (arr1[2] === 1 && arr1[4] === 1 && arr1[6] === 1) { 
      $("#vin").text("you win"); 
      $("#a2").css("background-color", "red"); 
      $("#a4").css("background-color", "red"); 
      $("#a6").css("background-color", "red"); 
      vinner = true; 
    } 
 
    //вы проиграли 
    else if (arr1[0] === 0 && arr1[1] === 0 && arr1[2] === 0) { 
      $("#vin").text("you low"); 
      $("#a0", "#a1", "#a2").css("background-color", "red"); 
      vinner = true; 
    } else if (arr1[3] === 0 && arr1[4] === 0 && arr1[5] === 0) { 
      $("#vin").text("you low"); 
      $("#a3").css("background-color", "red"); 
      $("#a4").css("background-color", "red"); 
      $("#a5").css("background-color", "red"); 
      vinner = true; 
    } else if (arr1[6] === 0 && arr1[7] === 0 && arr1[8] === 0) { 
      $("#vin").text("you low"); 
      $("#a6").css("background-color", "red"); 
      $("#a7").css("background-color", "red"); 
      $("#a8").css("background-color", "red"); 
      vinner = true; 
    } else if (arr1[0] === 0 && arr1[3] === 0 && arr1[6] === 0) { 
      $("#vin").text("you low"); 
      $("#a0").css("background-color", "red"); 
      $("#a3").css("background-color", "red"); 
      $("#a6").css("background-color", "red"); 
      vinner = true; 
    } else if (arr1[1] === 0 && arr1[4] === 0 && arr1[7] === 0) { 
      $("#vin").text("you low"); 
      $("#a1").css("background-color", "red"); 
      $("#a4").css("background-color", "red"); 
      $("#a7").css("background-color", "red"); 
      vinner = true; 
    } else if (arr1[2] === 0 && arr1[5] === 0 && arr1[8] === 0) { 
      $("#vin").text("you low"); 
      $("#a2").css("background-color", "red"); 
      $("#a5").css("background-color", "red"); 
      $("#a8").css("background-color", "red"); 
      vinner = true; 
    } else if (arr1[0] === 0 && arr1[4] === 0 && arr1[8] === 0) { 
      $("#vin").text("you low"); 
      $("#a0").css("background-color", "red"); 
      $("#a4").css("background-color", "red"); 
      $("#a8").css("background-color", "red"); 
      vinner = true; 
    } else if (arr1[2] === 0 && arr1[4] === 0 && arr1[6] === 0) { 
      $("#vin").text("you low"); 
      $("#a2").css("background-color", "red"); 
      $("#a4").css("background-color", "red"); 
      $("#a6").css("background-color", "red"); 
      vinner = true; 
    } 
 
 
  }) 
  //сброс поля 
  $("#reset").click(function() { 
    $(".xo").css("background-color", "#C1B2E9"); 
    $("#vin").text(""); 
    $(".xo").text(""); 
    arr1 = [3, 3, 3, 3, 3, 3, 3, 3, 3]; 
    testArr = []; 
    vinner = false; 
  }) 
  //старт игры 
  $("#start").click(function() { 
    vinner = false; 
    $(".xo").css("background-color", "#C1B2E9"); 
    $("#vin").text(""); 
    $(".xo").text(""); 
    arr1 = [3, 3, 3, 3, 3, 3, 3, 3, 3]; 
    testArr = []; 
    $("#table").hide(1300); 
    var tes = setTimeout(function() { 
      var div = document.createElement('div'); 
      div.className = "alert row cointeiner "; 
      div.innerHTML = "<p>choose</p><button id='qX' class='btn knop1'>X</button><p>or</p><button id='qO' class='btn knop1'>O</button>"; 
      document.body.appendChild(div); 
      $("#qX").click(function() { 
        $(".xo").text(""); 
        $("#table").show(1300); 
        flag = "X"; 
        div.parentNode.removeChild(div); 
      }) 
      $("#qO").click(function() { 
        $(".xo").text(""); 
        $("#table").show(1300); 
        flag = "O"; 
        div.parentNode.removeChild(div); 
      }) 
    }, 1400); 
  }) 
});
body { 
  background: url("http://www.dinosaurlifestyle.com/prod_img/zoom/GGLFS013000_04_L.jpg") no-repeat; 
  color: black; 
  background-size: 100%; 
  font-family: 'Pacifico', cursive; 
} 
 
.xo { 
  width: 33%; 
  height: 100px; 
  padding: 0.3%; 
  border: 2px solid black; 
  font-size: 40px; 
  text-align: center; 
} 
 
#table { 
  padding: 0.3%; 
  background: #C1B2E9; 
  margin-top: 10%; 
} 
 
.row { 
  margin: auto; 
} 
 
.knop { 
  background-color: #E9E060; 
  font-size: 20px; 
  border-radius: 38px; 
  margin: auto; 
} 
 
.knop:hover { 
  background: #FFA91E; 
  cursor: pointer; 
  border-radius: 40px; 
  box-shadow: 10px 0px 10px 0px #00FFA9; 
} 
 
.alert { 
  background-color: red; 
  margin: auto; 
  width: 70%; 
  padding: 0.3%; 
  margin-top: 10%; 
  font-size: 60px; 
} 
 
.knop1 { 
  background-color: #69DB5E; 
  font-size: 50px; 
  border-radius: 45%; 
  margin: auto; 
} 
 
#vin { 
  font-size: 150px; 
  text-align: center; 
  color: red; 
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script> 
<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/js/bootstrap.min.js"></script> 
<link href="https://fonts.googleapis.com/css?family=Frijole|Lobster|Pacifico|Monoton" rel="stylesheet"> 
<div id="vin"></div> 
<div class="container" id="table"> 
  <div class="row"> 
    <button type="button" id="start" class="btn knop">Start GAME</button> 
    <button type="button" id="reset" class="btn knop">RESET</button> 
  </div> 
  <div class="row"> 
    <div class="xo" id="a0" data-value="0"></div> 
    <div class="xo" id="a1" data-value="1"></div> 
    <div class="xo" id="a2" data-value="2"></div> 
  </div> 
  <div class="row"> 
    <div class="xo" id="a3" data-value="3"></div> 
    <div class="xo" id="a4" data-value="4"></div> 
    <div class="xo" id="a5" data-value="5"></div> 
  </div> 
  <div class="row"> 
    <div class="xo" id="a6" data-value="6"></div> 
    <div class="xo" id="a7" data-value="7"></div> 
    <div class="xo" id="a8" data-value="8"></div> 
  </div> 
</div>

Answer 1

В предоставленном куске кода можно выделить две абсолютно одинаковые части. Перед ними даже комментарии стоят: вы выиграли и вы проиграли

Единственное их отличие - это число, с которым идет сравнение (1,0) и выводимый текст.

Поэтому одинаковую часть можно вынести в функцию:

vinner = checkState(1, 'win');
if(!vinner) vinner = checkState(0, 'low');

где checkState будет иметь следующий вид:

function checkState(player, text){
    if (arr1[0] === player && arr1[1] === player && arr1[2] === player) {
        $("#vin").text(text);
        $("#a0").css("background-color", "red");
        $("#a1").css("background-color", "red");
        $("#a2").css("background-color", "red");
        return true;
    } else if (arr1[3] === player && arr1[4] === player && arr1[5] === player) {
        $("#vin").text(text);
        $("#a3").css("background-color", "red");
        $("#a4").css("background-color", "red");
        $("#a5").css("background-color", "red");
        return true;
    } else if (arr1[6] === player && arr1[7] === player && arr1[8] === player) {
        $("#vin").text(text);
        $("#a6").css("background-color", "red");
        $("#a7").css("background-color", "red");
        $("#a8").css("background-color", "red");
        return true;
    } else if (arr1[0] === player && arr1[3] === player && arr1[6] === player) {
        $("#vin").text(text);
        $("#a0").css("background-color", "red");
        $("#a3").css("background-color", "red");
        $("#a6").css("background-color", "red");
        return true;
    } else if (arr1[1] === player && arr1[4] === player && arr1[7] === player) {
        $("#vin").text(text);
        $("#a1").css("background-color", "red");
        $("#a4").css("background-color", "red");
        $("#a7").css("background-color", "red");
        return true;
    } else if  (arr1[2] === player && arr1[5] === player && arr1[8] === player) {
        $("#vin").text(text);
        $("#a2").css("background-color", "red");
        $("#a5").css("background-color", "red");
        $("#a8").css("background-color", "red");
        return true;
    } else if (arr1[0] === player && arr1[4] === player && arr1[8] === player) {
        $("#vin").text(text);
        $("#a0").css("background-color", "red");
        $("#a4").css("background-color", "red");
        $("#a8").css("background-color", "red");
        return true;
    } else if (arr1[2] === player && arr1[4] === player && arr1[6] === player) {
        $("#vin").text(text);
        $("#a2").css("background-color", "red");
        $("#a4").css("background-color", "red");
        $("#a6").css("background-color", "red");
        return true;
    }
}

Можно заметить, что цифры в селекторах совпадают с цифрам в условии if, при этом сами блоки if отличаются только этими цифрами, поэтому их можно вынести в функцию:

function checkCombo(player, text, point1, point2, point3){
    if (arr1[point1] === player && arr1[point2] === player && arr1[point3] === player) {
        $("#vin").text(text);
        $("#a2").css("background-color", "red");
        $("#a4").css("background-color", "red");
        $("#a6").css("background-color", "red");
        return true;
    }
    return false;
}

И функция checkState примет вид:

function checkState(player, text){
    return (checkCombo(player, text, 0, 1, 2)  // winCombo[0] = [0, 1, 2]
        || (checkCombo(player, text, 3, 4, 5)  // winCombo[1] = [3, 4, 5]
        || (checkCombo(player, text, 6, 7, 8)  // winCombo[2] = [6, 7, 8]
        || (checkCombo(player, text, 0, 3, 6)  // winCombo[3] = [0, 3, 6]
        || (checkCombo(player, text, 1, 4, 7)  // winCombo[4] = [1, 4, 7]
        || (checkCombo(player, text, 2, 5, 8)  // winCombo[5] = [2, 5, 8]
        || (checkCombo(player, text, 0, 4, 8)  // winCombo[6] = [0, 4, 8]
        || (checkCombo(player, text, 2, 4, 6); // winCombo[7] = [2, 4, 6]
}

Теперь видно, что параметры points совпадают с уже существующим массивом winCombo.

Следовательно вместо ручного перебора можно использовать цикл:

for(var i=0; i<winCombo.length;i++){
    if(checkCombo(player,text,winCombo[i][0],winCombo[i][1],winCombo[i][2])) return true;
}

Передавать по индексам не очень удобно, поэтому можно просто передать сам элемент массива winCombo

for(var i=0; i<winCombo.length;i++){
    if(checkCombo(player,text,winCombo[i])) return true;
}

При этом изменится функция checkCombo

function checkCombo(player, text, line){
    if (arr1[line[0]] === player && arr1[line[1]] === player && arr1[line[2]] === player) { ... }
    return false;
}

Что происходит внутри if - для каждого элемента массива line проверяется условие, для этого у массивов есть специальный метод every. С ним условие можно переписать так:

if(line.every(point=>arr1[point]===player))

Далее отметим, что в функции, которая просто проверяет есть ли заполненная линия, еще выводится текст и закрашивают ячейки. Их можно вынести во внешнюю функцию checkState, в этом случае checkCombo упростится до следующего вида:

function checkCombo(player, line){
    return line.every(point=>arr1[point]===player);
}

И это выражение так же можно вынести наружу и убрать функцию:

function checkState(player, text){
    for(var i=0; i<winCombo.length;i++){
        if(winCombo[i].every(point=>arr1[point]===player))) {
            $("#vin").text(text);
            ...
            return true;
        }
    }
    return false;
}

Для выделения ячеек можно воспользоваться тем, что id элементов совпадают с номерами в том же массиве winCombo, поэтому на его основе можно собрать нужный селектор, например:

winCombo[i].map(point=>`#a${point}`).join(',');

При более внимательном просмотре можно заметить цикл внутри checkState просто проверяет, есть ли в массиве winCombo хотя бы один элемент удовлетворяющий условию и производит с найденным элементом какие-то действия. Для этого у массивов есть специальная функция find, при ее использовании получим

return winCombo.find(combo=> combo.every(point=> arr1[point]==player));

При этом установка текста и закраска ячеек может быть вынесена наружу.

В итоге саму checkState так же можно убрать, оставив одно условие.

Тексты можно хранить в объекте, тогда конечный вариант проверки может быть таким:

var players={
    '0':'you low',
    '1':'you win'
}
for(var player in players){
    vinner = winCombo.find(combo=> combo.every(point=> arr1[point]==player));
    if(vinner){
        $("#vin").text(players[player]);
        $(vinner .map(point=>`#a${point}`).join(',')).css("background-color", "red");
        break;// дальше нет смысла проверять
    }
}

Итоговый пример:

(function addLink(links) { 
  links.reduce((head, l) => { 
    var el = document.createElement('link'); 
    el.href = l; 
    el.rel = "stylesheet"; 
    head.insertBefore(el, head.firstElementChild); 
    return head; 
  }, document.querySelector('head')) 
})(["https://cdnjs.cloudflare.com/ajax/libs/animate.css/3.5.2/animate.min.css", "https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/css/bootstrap.min.css", "https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.0.0-alpha.6/css/bootstrap.min.css"].reverse()); 
$(document).ready(function() { 
  var flag; 
  var vinner; 
  var winCombo = [ 
    [0, 1, 2], 
    [3, 4, 5], 
    [6, 7, 8], 
    [0, 3, 6], 
    [1, 4, 7], 
    [2, 5, 8], 
    [0, 4, 8], 
    [2, 4, 6] 
  ]; 
  var arr = [0, 1, 2, 3, 4, 5, 6, 7, 8]; 
  var arr1 = [3, 3, 3, 3, 3, 3, 3, 3, 3]; 
  var testArr = []; 
  var nar1; 
 
  function rand() { 
    return nar1[Math.floor(Math.random() * nar1.length)]; 
  } 
  $(".xo").click(function() { 
    if (vinner === true) { 
      return false; 
    } 
    if (flag === undefined) { 
      alert('To start, click Start GAME and select "X" or "O"') 
    } 
    var a = $(this).text(); 
    var b = parseInt($(this).attr("data-value")); 
    if (a === "") { //если пустая клетка 
      $(this).text(flag); 
      testArr.push(b); 
      arr1[b] = 1; 
      nar1 = arr.filter(el => testArr.indexOf(el) === -1); 
      var randNumb = rand(); 
      idItem = '#a' + randNumb; 
      testArr.push(randNumb); 
      var f_map = { 
        "X": "O", 
        "O": "X" 
      } 
      $(idItem).html(f_map[flag]); 
      arr1[randNumb] = 0; 
    } 
 
    var players = { 
      '0': 'you low', 
      '1': 'you win' 
    }; 
    for (var player in players) { 
      vinner = winCombo.find(combo => combo.every(point => arr1[point] == player)); 
      if (vinner) { 
        $("#vin").text(players[player]); 
        $(vinner.map(point => `#a${point}`).join(',')).css("background-color", "red"); 
        break; // дальше нет смысла проверять 
      } 
    } 
 
 
  }) 
  //сброс поля 
  $("#reset").click(function() { 
    $(".xo").css("background-color", "#C1B2E9"); 
    $("#vin").text(""); 
    $(".xo").text(""); 
    arr1 = [3, 3, 3, 3, 3, 3, 3, 3, 3]; 
    testArr = []; 
    vinner = false; 
  }) 
  //старт игры 
  $("#start").click(function() { 
    vinner = false; 
    $(".xo").css("background-color", "#C1B2E9"); 
    $("#vin").text(""); 
    $(".xo").text(""); 
    arr1 = [3, 3, 3, 3, 3, 3, 3, 3, 3]; 
    testArr = []; 
    $("#table").hide(1300); 
    var tes = setTimeout(function() { 
      var div = document.createElement('div'); 
      div.className = "alert row cointeiner "; 
      div.innerHTML = "<p>choose</p><button id='qX' class='btn knop1'>X</button><p>or</p><button id='qO' class='btn knop1'>O</button>"; 
      document.body.appendChild(div); 
      $("#qX").click(function() { 
        $(".xo").text(""); 
        $("#table").show(1300); 
        flag = "X"; 
        div.parentNode.removeChild(div); 
      }) 
      $("#qO").click(function() { 
        $(".xo").text(""); 
        $("#table").show(1300); 
        flag = "O"; 
        div.parentNode.removeChild(div); 
      }) 
    }, 1400); 
  }) 
});
body { 
  background: url("http://www.dinosaurlifestyle.com/prod_img/zoom/GGLFS013000_04_L.jpg") no-repeat; 
  color: black; 
  background-size: 100%; 
  font-family: 'Pacifico', cursive; 
} 
 
.xo { 
  width: 33%; 
  height: 100px; 
  padding: 0.3%; 
  border: 2px solid black; 
  font-size: 40px; 
  text-align: center; 
} 
 
#table { 
  padding: 0.3%; 
  background: #C1B2E9; 
  margin-top: 10%; 
} 
 
.row { 
  margin: auto; 
} 
 
.knop { 
  background-color: #E9E060; 
  font-size: 20px; 
  border-radius: 38px; 
  margin: auto; 
} 
 
.knop:hover { 
  background: #FFA91E; 
  cursor: pointer; 
  border-radius: 40px; 
  box-shadow: 10px 0px 10px 0px #00FFA9; 
} 
 
.alert { 
  background-color: red; 
  margin: auto; 
  width: 70%; 
  padding: 0.3%; 
  margin-top: 10%; 
  font-size: 60px; 
} 
 
.knop1 { 
  background-color: #69DB5E; 
  font-size: 50px; 
  border-radius: 45%; 
  margin: auto; 
} 
 
#vin { 
  font-size: 150px; 
  text-align: center; 
  color: red; 
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script> 
<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/js/bootstrap.min.js"></script> 
<link href="https://fonts.googleapis.com/css?family=Frijole|Lobster|Pacifico|Monoton" rel="stylesheet"> 
<div id="vin"></div> 
<div class="container" id="table"> 
  <div class="row"> 
    <button type="button" id="start" class="btn knop">Start GAME</button> 
    <button type="button" id="reset" class="btn knop">RESET</button> 
  </div> 
  <div class="row"> 
    <div class="xo" id="a0" data-value="0"></div> 
    <div class="xo" id="a1" data-value="1"></div> 
    <div class="xo" id="a2" data-value="2"></div> 
  </div> 
  <div class="row"> 
    <div class="xo" id="a3" data-value="3"></div> 
    <div class="xo" id="a4" data-value="4"></div> 
    <div class="xo" id="a5" data-value="5"></div> 
  </div> 
  <div class="row"> 
    <div class="xo" id="a6" data-value="6"></div> 
    <div class="xo" id="a7" data-value="7"></div> 
    <div class="xo" id="a8" data-value="8"></div> 
  </div> 
</div>

Answer 2

Все эти условия можно занести в цикл, поскольку у вас уже есть переменная winCombo

function showResult(text,a1,a2,a3){
      $("#vin").text(text);
      $("#a"+a1+",#a"+a2+",#a"+a3).css("background-color", "red");
      vinner = true;
  }
  for(var i=0;i<winCombo.length;i++){
    var a1 = winCombo[i][0],
        a2 = winCombo[i][1],
        a3 = winCombo[i][2];
    if(arr1[a1]=== 1 && arr1[a2] === 1 && arr1[a3] === 1){
          showResult('you win',a1,a2,a3);
          break;
       }
    //вы проиграли
      if(arr1[a1] === 0 && arr1[a2] === 0 && arr1[a3] === 0){
         showResult('you loose',a1,a2,a3);
          break;
       }
  }

Полный пример на https://codepen.io/anon/pen/bRyZPz?editors=1111

Answer 3

А вот как полностью может выглядеть весь ваш код, если его и правда оптимизировать:

$(document).ready(function() {
let flag;
let vinner;
let winCombo = [
    [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 arr = [0, 1, 2, 3, 4, 5, 6, 7, 8];
let arr1 = [3, 3, 3, 3, 3, 3, 3, 3, 3];
let testArr = [];
let nar1;
$(".xo").click(function() {
    if (vinner === true) {return false}
    // Сокращённая запись(Если левый операнд до && равен false, то правый операнд даже не будет вычислен, потому, что всё выражение ложно):
    (flag === 'undefined') && alert('To start, click Start GAME and select "X" or "O"');
    let b = parseInt($(this).attr("data-value"));
    if ($(this).text() === "") {//если пустая клетка
        $(this).text(flag);
        testArr.push(b);
        arr1[b] = 1;
        nar1 = arr.filter(el=> testArr.indexOf(el) === -1);
        let randNumb = rand();
        idItem = '#a' + randNumb;
        testArr.push(randNumb);
        let f_map = {
            "X": "O",
            "O": "X"
        }
        $(idItem).html(f_map[flag]);
        arr1[randNumb] = 0;
    }
    // Код написанный Stepan Kasyanenko. Начало:
    for(var i=0;i<winCombo.length;i++){
        var a1 = winCombo[i][0],
            a2 = winCombo[i][1],
            a3 = winCombo[i][2];
        if(arr1[a1]=== 1 && arr1[a2] === 1 && arr1[a3] === 1){
            showResult('you win',a1,a2,a3);
            break;
        }
        if(arr1[a1] === 0 && arr1[a2] === 0 && arr1[a3] === 0){
            showResult('you loose',a1,a2,a3);
            break;
        }
    }
   // Код написанный Stepan Kasyanenko. Конец.
})
//сброс поля
$("#reset").click(function() {
    ResetXO();
    vinner = false;
})
//старт игры
$("#start").click(function() {
    // Сброс красного поля (дублирования) при повторном нажатии старта
    $('.alert').remove();
    vinner = false;
    ResetXO();
    $("#table").hide(1300);
    setTimeout(function() { // Здесь ненужно создавать лишнюю переменную
        // Коли взялись за jQuery - то уж будьте любезны его и использовать: :)
        // Создаём нужные классы и присоединяем к body
        $('<div>', {class: 'alert row cointeiner'}).appendTo('body');
        $('.alert').append("<p>choose</p><button id='qX' class='btn knop1'>X</button><p>or</p><button id='qO' class='btn knop1'>O</button>");
        showXO($("#qX"), 'X');
        showXO($("#qO"), 'O');
    }, 1400);
})
function showResult(text,a1,a2,a3){
    $("#vin").text(text);
    $("#a"+a1+",#a"+a2+",#a"+a3).css("background-color", "red");
    vinner = true;
}
function rand() {
    return nar1[Math.floor(Math.random() * nar1.length)];
}
function ResetXO(){
    $(".xo").css("background-color", "#C1B2E9").empty(); // лучше делать так
    $("#vin").empty(); // лучше делать так
    arr1 = [3, 3, 3, 3, 3, 3, 3, 3, 3];
    testArr = [];
}
function showXO(obj, fl){
    obj.click(function() {
        $(".xo").text("");
        $("#table").show(1300);
        flag = fl;
    })
}

});

READ ALSO
Переменная реального времени.

Переменная реального времени.

Добрый день! Хочу проконсультироваться касательно следующей идеиПодскажите, как можно вызвать реальное время (к прим

221
Сохранение данных без нажатия кнопки

Сохранение данных без нажатия кнопки

Имеется несколько input на странице, где пользователь вводит данные о себе

213
Как удалить все &ldquo;&amp;&rdquo; со строки?

Как удалить все “&” со строки?

С помощью re = /\&*/g; не получается

197