Избежать выхода за пределы массива
Делаю игру крестики и нолики, под пользовательские размеры, не могу реализовать выигрыш по вертикале и диагонали.
field - хранит двумерный массив. gameTurn - ход игрока. 1 игрок = 1 2 игрок = -1 пустая ячейка = 0 const checkWin = (field) =>{ for (let i = 0; i < field.length; i++) { for(let j = 0; j < field[i].length; j++){ if(gameTurn === field[i][j] && (field[i][j] === field[i][j+1] && field[i][j] === field[i][j+2])) alert('Ты победил!') } } } |
Retro_1477,
создайте массив возможных комбинаций, отфильруйте каждую на наличие всех трёх ячеек, проверьте ячейки на одинаковое содержимое. лучше один цикл на все ячейки. |
|
Я б на твоем месте прислушался к Рони, но раз ты так начал, то здесь продолжение
const checkWin = (field) =>{ for (let i = 0; i < field.length; i++) { for(let j = 0; j < field[i].length; j++){ if(gameTurn === field[i][j] && (field[i][j+1] !==undefined && gameTurn === field[i][j+1] && field[i][j+2] !==undefined && gameTurn === field[i][j+2]) || (field[i+1][j] !==undefined && gameTurn === field[i+1][j] && field[i+2][j] !==undefined && gameTurn === field[i+2][j]) || (field[i+1][j+1] !==undefined && gameTurn === field[i+1][j+1] && field[i+2][j+2] !==undefined && gameTurn === field[i+2][j+2]) || (field[i-1][j-1] !==undefined && gameTurn === field[i-1][j-1] && field[i-2][j-2] !==undefined && gameTurn === field[i-2][j-2]) ) alert('Ты победил!') } } } но лучше делать отдельные циклы по всем четырем направлениям (горизонт, вертикаль, диагонали в разных направлениях) и в for "не добегать" до края на 2 клетки. И тогда у нас можно не проверять на существования элемента и меньше операций будет совершено const checkWin = (field) =>{ gameTurn=1; for (let i = 0; i < field.length; i++) { for(let j = 0; j < field[i].length-2; j++){ if(gameTurn === field[i][j] && (gameTurn === field[i][j+1] && gameTurn === field[i][j+2]) ) alert('Ты победил! 1') } } for (let i = 0; i < field.length-2; i++) { for(let j = 0; j < field[i].length; j++){ if(gameTurn === field[i][j] && (gameTurn === field[i+1][j] && gameTurn === field[i+2][j]) ) alert('Ты победил! 2') } } for (let i = 0; i < field.length-2; i++) { for(let j = 0; j < field[i].length-2; j++){ if(gameTurn === field[i][j] && (gameTurn === field[i+1][j+1] && gameTurn === field[i+2][j+2]) ) alert('Ты победил! 3') } } for (let i = 0; i < field.length-2; i++) { for(let j = 2; j < field[i].length; j++){ if(gameTurn === field[i][j] && (gameTurn === field[i+1][j-1] && gameTurn === field[i+2][j-2]) ) alert('Ты победил! 4') } } } checkWin([[,1,1],[,1,],[1,,]]) |
od0201,
вопрос был про j+1 и т.д. , про то что таких ячеек нет!!! |
Цитата:
|
od0201,
маловато undefined, код не рабочий. |
od0201,
ок. |
крестики нолики на поле любой величины
при игре на поле более 3х3, и размером выгрыша 3 ячейки подряд, тот кто ходит первым, он выигрывает, но если вы дадите шанс компьютеру ...
:write: дело было вечером ... <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> <style> body{text-align: center;} .game > div{ outline: 1px solid black; height: 0; background-color: #FFFFFF; transition: 1s; padding-bottom: 100%; } .game > div.red{ background-color: #FF0000; color: #FFFFFF; } .game { display: grid; grid-template-columns: repeat(var(--colls), 1fr); grid-column-gap: 0px; grid-row-gap: 0px; width: 400px; margin: 30px auto; line-height: calc(400px/var(--colls)); font-size: calc(400px/var(--colls)); } h3{ height: 2em; } </style> </head> <body> <h3>Step X</h3> <div class="game"></div> </body> <script> let length = 3 + Math.trunc(Math.random() * 7); let rows = 3 + Math.trunc(Math.random() * 5); let parent = document.querySelector('.game'); parent.style.setProperty('--colls', length); let div = document.createElement('div'); for (var i = 0; i < length * rows; i++) { parent.append(div.cloneNode()) }; let boxs = parent.querySelectorAll('div'); let value = 'O'; const checkWin = (cells, length, value, free) => { const arrWin = [ [-length, length], [-1, 1], [-length - 1, length + 1], [-length + 1, length - 1] ]; const arrContinue = [0, length - 1, cells.length - length, cells.length - 1]; let temp = []; for (let i = 0; i < cells.length; i++) { if (arrContinue.includes(i)) continue; let cell = cells[i]; if (cell !== value && !free) continue; let check = arrWin.slice(0); if (i < arrContinue[1] || i > arrContinue[2]) check = [[-1, 1]]; if (i % length === 0 || i % length === length - 1) check = [[-length, length]]; check = check.map(([a, b]) => [a + i, b + i]).filter(([a, b]) => { a = cells[a]; b = cells[b]; let c = [a, b, cell].filter(a => a === value); return free ? (!a || !b || !cell) && c.length === 2 : (a === value && b === value) }) if (check.length) { temp = temp.concat(Array.from(check, a => (a.splice(1, 0, i), a))); } } if(free && temp.length) { temp = temp.flat().filter(a => !cells[a]); let set = new Set(); set.add(...temp); temp = [...set] } return temp; } let out = document.querySelector('h3'); let combo = { 1 : 10, 2 : 25, 3 : 50, 4 : 80, 5 : 100, 6 : 150}; let compute; const gameClick = ({target}) => { if (compute) return; if (target.textContent) return; let title = `Step ${value}`; value = value == 'X' ? 'O' : 'X'; target.textContent = value; let cells = Array.from(boxs, ({textContent}) => textContent); let win = checkWin(cells, length, value); if (win.length) { let set = new Set(); win.forEach(a => a.forEach(i => { set.add(i); boxs[i].classList.add('red') })); parent.removeEventListener('click', gameClick); title = `Win ${value}!!!<br> Total : ${set.size} × ${combo[win.length]} = ${set.size * combo[win.length]}!!!` }; out.innerHTML = title; win.length || value == 'X' && autoClick(value); } const randomItem = arr => arr[Math.trunc(arr.length * Math.random())] const autoClick = (val) => { compute = true; let oldTitle = out.innerHTML; out.innerHTML = `... examination of options for ${val}` let cells = Array.from(boxs, ({ textContent }) => textContent); val = val == 'X' ? 'O' : 'X'; out.innerHTML = `... examination of options for ${val}` let win = checkWin(cells, length, val, true); let box; if (!win.length) { val = val == 'X' ? 'O' : 'X'; win = checkWin(cells, length, val, true); }; if (win.length) { let i = randomItem(win); box = boxs[i] } else { win = [...boxs].filter(({ textContent }) => !textContent) box = randomItem(win); }; if (box) { window.setTimeout(() => { compute = false; gameClick({ target: box }) }, 800) } else out.innerHTML = `End!` } parent.addEventListener('click', gameClick) </script> </html> |
Этот ответ мне более понятен, но я понимаю какое это говнокодище.:D
|
Часовой пояс GMT +3, время: 11:26. |