Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #1 (permalink)  
Старый 05.05.2020, 18:58
Кандидат Javascript-наук
Отправить личное сообщение для Retro_1477 Посмотреть профиль Найти все сообщения от Retro_1477
 
Регистрация: 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('Ты победил!')
      }
    }
  }
Ответить с цитированием
  #2 (permalink)  
Старый 05.05.2020, 19:24
Аватар для рони
Профессор
Отправить личное сообщение для рони Посмотреть профиль Найти все сообщения от рони
 
Регистрация: 27.05.2010
Сообщений: 33,064

Retro_1477,
создайте массив возможных комбинаций, отфильруйте каждую на наличие всех трёх ячеек, проверьте ячейки на одинаковое содержимое.
лучше один цикл на все ячейки.
Ответить с цитированием
  #3 (permalink)  
Старый 05.05.2020, 19:40
Аватар для рони
Профессор
Отправить личное сообщение для рони Посмотреть профиль Найти все сообщения от рони
 
Регистрация: 27.05.2010
Сообщений: 33,064

Retro_1477,
https://javascript.ru/forum/showthre...153#post498153
Ответить с цитированием
  #4 (permalink)  
Старый 08.05.2020, 00:23
Кандидат Javascript-наук
Отправить личное сообщение для od0201 Посмотреть профиль Найти все сообщения от od0201
 
Регистрация: 07.05.2020
Сообщений: 105

Я б на твоем месте прислушался к Рони, но раз ты так начал, то здесь продолжение

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.
Ответить с цитированием
  #5 (permalink)  
Старый 08.05.2020, 00:30
Аватар для рони
Профессор
Отправить личное сообщение для рони Посмотреть профиль Найти все сообщения от рони
 
Регистрация: 27.05.2010
Сообщений: 33,064

od0201,
вопрос был про j+1 и т.д. , про то что таких ячеек нет!!!
Ответить с цитированием
  #6 (permalink)  
Старый 08.05.2020, 00:42
Кандидат Javascript-наук
Отправить личное сообщение для od0201 Посмотреть профиль Найти все сообщения от od0201
 
Регистрация: 07.05.2020
Сообщений: 105

Сообщение от рони Посмотреть сообщение
od0201,
вопрос был про j+1 и т.д. , про то что таких ячеек нет!!!
исправил, тему не дочитал
Ответить с цитированием
  #7 (permalink)  
Старый 08.05.2020, 00:42
Аватар для рони
Профессор
Отправить личное сообщение для рони Посмотреть профиль Найти все сообщения от рони
 
Регистрация: 27.05.2010
Сообщений: 33,064

od0201,
маловато undefined, код не рабочий.
Ответить с цитированием
  #8 (permalink)  
Старый 08.05.2020, 00:46
Аватар для рони
Профессор
Отправить личное сообщение для рони Посмотреть профиль Найти все сообщения от рони
 
Регистрация: 27.05.2010
Сообщений: 33,064

od0201,
ок.
Ответить с цитированием
  #9 (permalink)  
Старый 08.05.2020, 00:59
Аватар для рони
Профессор
Отправить личное сообщение для рони Посмотреть профиль Найти все сообщения от рони
 
Регистрация: 27.05.2010
Сообщений: 33,064

крестики нолики на поле любой величины
при игре на поле более 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} &times; ${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 (permalink)  
Старый 10.05.2020, 10:37
Кандидат Javascript-наук
Отправить личное сообщение для Retro_1477 Посмотреть профиль Найти все сообщения от Retro_1477
 
Регистрация: 14.04.2018
Сообщений: 113

Этот ответ мне более понятен, но я понимаю какое это говнокодище.
Ответить с цитированием
Ответ



Опции темы Искать в теме
Искать в теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Соединение массива Artur_Hopf Общие вопросы Javascript 4 07.06.2018 16:48
Обход многомерного массива с задержкой после каждого цикла Walk Общие вопросы Javascript 2 14.08.2017 16:17
Помогите к js коду, написать html код Modrih Элементы интерфейса 8 16.06.2015 18:08
Ввод диапазона значений массива с клавиатуры Воскобоенко Общие вопросы Javascript 11 06.06.2015 22:34
Сортировка массива по возрастанию другого массива. vas88811 Events/DOM/Window 4 12.01.2014 10:31