Good day. I am writing a tic-tac-toe game using a table, the dimensions depend on the entered value. After each user move, the computer makes its move. To identify the winner using the above function.

The problem is that the function does not work correctly. Always gives "victory" when you put a cross in the last cell. And it should, as follows from the rules of the game, issue a "victory" only if there is a fully filled row, column or diagonal.

function proverka() { var table = document.getElementById("myTable"); var flag; var tdQuan = 3; for (var k = 0; k < tdQuan; k++) { for (var i = 0; i < tdQuan; i++) { for (var j = 0; j < tdQuan; j++) { if (table.rows[k].cells[i].innerHTML == table.rows[k].cells[j].innerHTML && table.rows[k].cells[i].innerHTML == "X" || table.rows[j].cells[k].innerHTML == table.rows[i].cells[k].innerHTML && table.rows[j].cells[k].innerHTML == "X" || table.rows[j].cells[j].innerHTML == "X") { flag = true; } else { flag = false; continue; } } } if (flag === true) { alert("победа "); } } } var tds = document.getElementsByTagName('td'); for(var i = 0; i < tds.length; i++){ tds[i].addEventListener('click', function(){ if(this.innerHTML !== 'X'){ this.innerHTML = 'X'; } else { this.innerHTML = ''; } proverka(); }) } 
 td{ width: 30px; height: 30px; border: 1px solid black; cursor: pointer; text-align: center; font-family: cursive; } 
 <table id="myTable"> <tr> <td></td> <td></td> <td></td> </tr> <tr> <td></td> <td></td> <td></td> </tr> <tr> <td></td> <td></td> <td></td> </tr> </table> 

  • It seems you forgot to say the problem to be solved. - Pavel Mayorov
  • @PavelMayorov is written down below - Tigran
  • Apparently, I'm blind - I see nothing. - Pavel Mayorov
  • @PavelMayorov, to identify the winner wrote such a function. This function compares only the last cell with - X. Why it is so, and how to actually write such a function - Tigran
  • So what should the function do? Maybe this is the right behavior, we do not know. - Pavel Mayorov

1 answer 1

Honestly, I could not understand your checks. But, I am sure, they are not even close workers. I tried to rewrite your condition, but I got 5 times more comparisons. Ten-story incomprehensible footcloth code. And I decided to rewrite it in a different way.

Flexible and simple option, not depending on the number of cells

With a fresh mind, he wrote a much simpler and concise version. It does not depend on the number of cells and does not require any configuration.

The logic of the work is based on the following rule for determining the victory in the game:

  • the winning combination is either a complete set of cells of a single row (the index is the same for the row, the cells are iterated from 0 to the maximum in turn)
  • or by a set of cells of one column (the same index of the column, the rows are iterated from 0 to the maximum)
  • or a diagonal from the top-left corner to the bottom right (we iterate through all the cells that are located at the intersection of the same row and column indices: 0x0, 1x1, 2x2, etc)
  • or diagonal from the left-bottom to the right-top corner (cell coordinates can be expressed in [max - n - 1] x [n] . That is, for a 3x3 table, you need to sort the cells (n is the iteration number) n = 0: [3 - 0 - 1] x [0] (2x0), n = 1: [3 - 1 - 1] x [1] (1x1), n ​​= 2: [3 - 2 - 1] x [2] (0x2)

Jsfiddle working example: https://jsfiddle.net/ipshenicyn/ds08m36y/1/

The example is supplemented with an input in which you need to enter a number, after which the table will be redrawn with the appropriate number of column rows.

The full js-code from the example (except for the function proverka added the functionality of redrawing the table and hanging listeners):

 var table = document.getElementById("myTable"); function proverka() { var flag; var count = table.getElementsByTagName('tr').length; for(var i = 0; i < count; i++){ var winRow = true, winColumn = true, winLeftTop = true, winLeftBottom = true; for(var k = 0; k < count; k++){ if(table.rows[i].cells[k].innerHTML !== 'X') winRow = false; if(table.rows[k].cells[i].innerHTML !== 'X') winColumn = false; if(table.rows[k].cells[k].innerHTML !== 'X') winLeftTop = false; if(table.rows[count-1-k].cells[k].innerHTML !== 'X') winLeftBottom = false; } if(winRow || winColumn || winLeftTop || winLeftBottom){ flag = true; break; } } if (flag) { alert("победа"); } } //вешаем слушатели события click на поля таблицы после ее перерисовки var setTdListeners = function(){ var tds = document.getElementsByTagName('td'); for(var i = 0; i < tds.length; i++){ tds[i].addEventListener('click', function(){ if(this.innerHTML !== 'X'){ this.innerHTML = 'X'; } else { this.innerHTML = ''; } proverka(); }) }; }; //перерисовка таблицы после потери фокуса полем input document.getElementById('count').addEventListener('blur', function(){ var count = this.value; table.innerHTML = ''; for(var i = 0; i < count; i++){ var tr = document.createElement('tr'); for(var k = 0; k < count; k++){ var td = document.createElement('td'); tr.appendChild(td); } table.appendChild(tr); } setTdListeners(); }); 

The first option is not scalable.

But the presented version, at least in this form, is difficult to scale. To make a 4x4 field you have to hammer in combinations with your hands. True, there are only 10, so it is not difficult.

Jsfiddle working example: https://jsfiddle.net/ipshenicyn/ds08m36y/

 var pos = [ //перечисление комбинаций выигрыша. массивы из двух элементов указывают позицию ячейки [строка, столбец] [[0,0],[0,1],[0,2]], //1 строка [[1,0],[1,1],[1,2]], //2 строка [[2,0],[2,1],[2,2]], //3 строка [[0,0],[1,0],[2,0]], //1 столбец [[0,1],[1,1],[2,1]], //2 столбец [[0,2],[1,2],[2,2]], //3 столбец [[0,0],[1,1],[2,2]], //лево-верх - право-низ [[2,0],[1,1],[0,2]], //лево-низ - право-верх ]; function proverka() { var table = document.getElementById("myTable"); var flag; for(var i = 0; i < pos.length; i++){ var win = true; for(var k = 0; k < pos[i].length; k++){ if(table.rows[pos[i][k][0]].cells[pos[i][k][1]].innerHTML !== 'X') win = false; } if(win){ flag = true; break; } } if (flag) { alert("победа"); } } 
  • Thank you for responding, the fact is that I wrote a simple X zero (3 * 3) and there I immediately set options (like you are here, I immediately compared the innerHTML in the function, although not the point), now the situation is different, the table is created on the basis of the input number in the input, say, if we keep 10, we get a table 10 * 10, and so, it is necessary that the rules of this game are preserved even on such a scale - Tigran
  • I put all the code here exactly as I have in HTML, but for some reason it does not recognize the click2 () function jsfiddle.net/Tigran_Hovhannisan/asvtf61h/3/… - Tigran
  • @Tigran added a new version in response. Fresh head came today) In my opinion - a great option, try it. - Ivan Pshenitsyn
  • one
    @Tigran looked and corrected your version on jsfiddle: jsfiddle.net/ipshenicyn/asvtf61h/5 He did not see the function, I suppose, due to some peculiarities of the virtual jsfiddle engine. It seems that everything was correctly written with you. - Ivan Pshenitsyn
  • ,, I will see, in the evening or at night, I will write - Tigran