TIL


Tic Tac Toゲーム(3 x 3チケット、三木ゲーム)
二重反復文を使用した二次元配列の処理

1.2 D配列の処理


テーブルなどの2 D配列を作成する場合は、「for」文に「for」文(またはforEach)として記述します.
const $table = document.createElement('table');
for (let i = 0; i < 3; i++) {
  const $tr = document.createElement('tr');
  for (let j = 0; j < 3; j++) {
    const $td = document.createElement('td');
    $tr.append($td);
  }
  $table.append($tr);
}
document.body.append($table);
🔽 例)4行x 3格子の2 D配列を作成する
const array = [];
for (let i = 0; i > 4; i++) {
  const cells = [];
  for (let j = 0; j > 3; j++) {
    cells.push('XOX');
  }
  array.push(cells);
}
😲 行は横行(row)!セルは縦列(column)!EXcelで塗りつぶす
addEventListenerを使用してクリックイベントを行う場合、クリックできない場合はremoveEventListenerを使用しないでください.条件が一致しない場合、関数は終了します.
ex. if (event.target.textContent) return;

2.表の再描画


構造分解割り当て(destructuring assignment)


📕最新の文法を理解します!(ES6)
オブジェクトの属性名と変数に属性を割り当てる変数名を同時に使用すると、これらの変数名を使用してコードを減らすことができます.
<構造分解の割り当て-オブジェクト>
const { body } = document;
const body = document.body; // 동일 코드

// 아래의 경우는 구조분해 할당하면 실행되지 않는다.
const createElement = document.createElement;

// document는 객체이므로 body라는 속성과 createElement라는 메서드를 가진다.
<構造分解の割り当て-配列>
各変数名を、構造分解割当時の配列形式変数インデックスに挿入します.
const arr = [1, 2, 3, 4, 5];
const one = arr[0];
const two = arr[1];
const three = arr[2];
const four = arr[3];
const five = arr[4];

// 각각 변수에 할당하는 대신 아래와 같이 한 줄로 작성
const [one, two, three, four, five] = arr;

// 공란인 인덱스가 있는 경우 생략하여 작성
const [one,, three,, five] = arr;

3.変換回数


繰り返し文の中で繰り返し文だけを実行するために、関連しない実行文を単独で関数を減算して作成します.
短い条件文では、3つの演算子を使用してコードを減らすことができます.
3項演算子𕊒・𐥊조건문 : 참일 때 실행문
let turn = 'O';

const callback = (event) => {
  if (event.target.textContent) { // 빈칸이 아닌 경우
    console.log('다른 칸을 클릭하세요');
    return;
  }
  event.target.textContent = turn; // 빈칸인 경우 현재 순서 화면에 표시
  turn = turn === 'O' ? 'X' : 'O'; // 차례 전환(삼항 연산자 이용)  
};

for (let j = 0; j < 3; j++) {
  // ...
  $td.addEventListener('click', callback);
}
let turn = 'O';

if (turn === 'O') {
  turn = 'X';
} else if (turn === 'X') {
  turn = 'O';
}

turn = (turn === 'O') ? 'X' : 'O'; // 상동
// 우선순위는 === > ?, : > =(대입 연산자) 순으로
// 헷갈리는 경우 괄호를 사용해 작성 가능하다.

4.勝負を決める



同じ値がある場合は、行インデックスとセルインデックスが格納され、その値が何行目と何列目にあるかがわかります.
二重複文を使用してforeachはindexを使用できます.
スペースをクリックするたびにcheckWinnerは比較値を実行し、hasWinnerがtrue/falseであるかどうかを確認するために何行目/スペースを保存します.
// target과 위의 배열에서 $td들 중 같은 값이 있는지 이중 반복문을 이용해 확인
// 같은 값이 있으면 해당 $td가 몇번째 줄, 몇번째 칸인지 인덱스를 저장
const checkWinner = (target) => { // event.target($td)이 target
  let rowIndex;
  let colIndex;
  rows.forEach((row, ri) => {
    row.forEach((col, ci) => {
      if (col === target) {
        rowIndex = ri;
        colIndex = ci;
      }
    });
  });
  // 9칸이 모두 채워져있는가?
  let hasWinner = false;
  // ...(이기는 조건들 코드)
チェックするときは、まず変数hasWinnerをfalseの先頭にします.
中間に勝者がいればtrueに変換します.
勝負を判断するコードを減らす(ダイエット!🏋️‍♂️)
<親子関係>
  • parentNode:現在のタグの親タグを選択する属性
  • 小児:サブタブの属性を取得
    親タグは1つですが、サブタグは複数であるため、類似配列の類似配列オブジェクト(array-like object)です.
    ex.{0:td,1:td,2:td,length:3}のオブジェクトとしてchildren[0]のように使用できますがindexOf,forEachなどの配列方法は使用できないので配列ではありません!
  • etc.거짓일 때 실행문メソッドを使用して、類似した配列のオブジェクトを真の配列に変換できます.(アレイメソッドが使用可能)
    const checkWinner = (target) => { // target은 td 태그
      let rowIndex = target.parentNode.rowIndex; // rowIndex 속성은 $tr($td의 부모요소)이 제공
      let colIndex = target.colIndex; // $td는 colIndex 속성을 제공
      
      let hasWinner = false;
      // ...(이기는 조건들 코드)
    };
    <チェック引き分け>
    9コマともクリックしたが、勝負はつかなかった.
    つまり、2つのforゲートを回して、スペースがあるかどうかを確認し、9グリッドに1つのスペースがあれば、引き分けではないことを意味します.
    (チェックの場合ですが、この場合falseは出ないのでtrueで始まる)
    let draw = true;
      rows.forEach((row) => {
        row.forEach((col) => {
          if (!col.textContent) { // 한 칸이라도 비어있으면
            draw = false; // 무승부가 아님
          }
        });
      });
      if (draw) {
        $result.textContent = `무승부!`;
        return;
      }
    知っておくべきコンセプト!👩‍🏫 暗記する

    ①イベントBubbling、イベントスクリーンショット(html特性)


    サブエレメントにaddEventListenerを掛けた場合、ゲームが終了してremoveEventListenerが採用され、この現象を繰り返すとエラーが発生し、親エレメントにイベントが追加される可能性があります.
    イベントは、addEventListenerを持つサブエレメントからすべての親エレメント上のジオメトリに伝播され、実行されます.

  • event.target:実際にイベントが発生した要素(どのサブラベルなのか分からない)$tr? $td?

  • event.CurrentTarget:イベントの(親)要素$tableを貼り付け

  • イベントのバブル化を阻止する方法:event.stopPropagation();

  • デフォルトの動作をマークする方法:event.preventDefault();

  • 親要素から子要素のジオメトリにイベントが伝播し、そのイベントが実行されます.
    🙉唯一の例❗(その他常用X)
    ポップアップウィンドウの外で空白の画面をクリックしてポップアップウィンドウ(select/option)を閉じることができます.
    ポップアップウィンドウの親要素は空の画面にキャプチャされ、イベントキャプチャで空の画面をクリックすると、ポップアップウィンドウに転送され、閉じます.
    デフォルトで発生する現象はイベントbundlingですので、イベントキャプチャを行う場合は、3番目のパラメータ(userCapture)をtrueと書きます.
    (イベントbundlingの場合、デフォルト値はfalseと省略できます)
    例)$table.addEventListener('click', callback, true);

    ② every, some, flat


    ドローチェックをする場合、空席が1つあっても引き分けではありません.
    foreachを利用して中間で複文を終了するのは難しい.
    最初のチェック・セルから空白のセルに移動する場合は、次の配置方法を使用して、繰り返し文を返さずに終了します.
    繰り返し文ではなく、効率的なアルゴリズムコードを作成できます.
    each,someは繰り返し文の一種であり,要素を遍歴すると同時に条件関数の戻り値がメソッドの戻り値を変化させる.
    1 D配列で可能な配列メソッドで、中間がfalseの場合、関数をすばやく終了します.
  • each:全てtrue=true、一つはfalse=false
  • theme:一つはtrueがtrueで、いずれもfalseがfalse
  • プレート:2次元アレイを1次元アレイに変換する方法
  • rows // (3) [Array(3), Array(3), Array(3)] - 2차원 배열
    rows.flat() // (9) [td, td, td, ..., td] - 1차원 배열
    
    rows.flat().every((td) => td.textContent)
    // 모두 칸이 차있으면 true
    // 한 칸이라도 비어있으면 false
    戻り値はtdです.textContentの値がfalseの場合、eachはfalseになり、終了します.
    (値は「」、false、0、null、undefined、NaN)