05.05.2020, 18:58
|
Кандидат Javascript-наук
|
|
Регистрация: 14.04.2018
Сообщений: 113
|
|
Избежать выхода за пределы массива
Делаю игру крестики и нолики, под пользовательские размеры, не могу реализовать выигрыш по вертикале и диагонали.
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('Ты победил!')
}
}
}
|
|
05.05.2020, 19:24
|
|
Профессор
|
|
Регистрация: 27.05.2010
Сообщений: 33,109
|
|
Retro_1477,
создайте массив возможных комбинаций, отфильруйте каждую на наличие всех трёх ячеек, проверьте ячейки на одинаковое содержимое.
лучше один цикл на все ячейки.
|
|
05.05.2020, 19:40
|
|
Профессор
|
|
Регистрация: 27.05.2010
Сообщений: 33,109
|
|
|
|
08.05.2020, 00:23
|
Кандидат Javascript-наук
|
|
Регистрация: 07.05.2020
Сообщений: 108
|
|
Я б на твоем месте прислушался к Рони, но раз ты так начал, то здесь продолжение
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, 08.05.2020 в 01:20.
|
|
08.05.2020, 00:30
|
|
Профессор
|
|
Регистрация: 27.05.2010
Сообщений: 33,109
|
|
od0201,
вопрос был про j+1 и т.д. , про то что таких ячеек нет!!!
|
|
08.05.2020, 00:42
|
Кандидат Javascript-наук
|
|
Регистрация: 07.05.2020
Сообщений: 108
|
|
Сообщение от рони
|
od0201,
вопрос был про j+1 и т.д. , про то что таких ячеек нет!!!
|
исправил, тему не дочитал
|
|
08.05.2020, 00:42
|
|
Профессор
|
|
Регистрация: 27.05.2010
Сообщений: 33,109
|
|
od0201,
маловато undefined, код не рабочий.
|
|
08.05.2020, 00:46
|
|
Профессор
|
|
Регистрация: 27.05.2010
Сообщений: 33,109
|
|
od0201,
ок.
|
|
08.05.2020, 00:59
|
|
Профессор
|
|
Регистрация: 27.05.2010
Сообщений: 33,109
|
|
крестики нолики на поле любой величины
при игре на поле более 3х3, и размером выгрыша 3 ячейки подряд, тот кто ходит первым, он выигрывает, но если вы дадите шанс компьютеру ...
дело было вечером ...
<!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>
|
|
10.05.2020, 10:37
|
Кандидат Javascript-наук
|
|
Регистрация: 14.04.2018
Сообщений: 113
|
|
Этот ответ мне более понятен, но я понимаю какое это говнокодище.
|
|
|
|