본문 바로가기
웹 프로그래밍/기초

웹 프로그래밍 기초 3일 - 스도쿠 채점기

by JJong | 쫑 2024. 5. 22.

3일차인 오늘은 스도쿠 채점기를 만들었다.

위 링크를 누르면 새창에서 조금 더 쾌적하게 이용할 수 있을 것같다.

 


추가하면 좋을 패치 방향

  • 채점할 때 빈자리라도 넘어가도록 하고
  • 어디에서 겹치는 숫자가 있는지 칸에 색을 칠해서 check해주고
  • 채점하기 옆에 있는 '테스트', '초기화' 버튼들을 오른쪽으로 밀던가 쉽게 터지하기 어려운 곳으로 옮기면

 

사용자에게 더 좋은 채점기가 되지 않을까 싶다.


각 요소들 설명


숫자를 입력하는 각각의 칸에 id를 부여했다.

채점, 테스트, 초기화를 할 때에 위치를 특정하기 위해서 필요하다.

			...
			<!-- 9x9 스도쿠 판 생성 -->
            <tr>
            	<td><input id="coor_1,1" type="text" maxlength="1"></td>
                <td><input id="coor_1,2" type="text" maxlength="1"></td>
                .
                .

채점하기 버튼을 누르면 모든 칸을 돌면서 그 경우에 대해 스도쿠 규칙에 맞게 입력되었는지 확인한다.

(*불필요한 채점도 진행함.)

 

스도쿠 규칙

  • 아홉 3×3 칸에 숫자가 1부터 9까지 하나씩만 들어가야 한다.
  • 아홉 가로줄에 숫자가 1부터 9까지 하나씩만 들어가야 한다.
  • 아홉 세로줄에 숫자가 1부터 9까지 하나씩만 들어가야 한다.

테스트 버튼을 누르면 미리 입력해둔 스도쿠의 정답 예제를 입력해준다.


채점하기 버튼을 누르면 스도쿠를 채점해준다. 정답인 경우엔 폭죽이 터진다. 오답이면 아무런 반응을 하지 않는다.

추후 업데이트에서 정답과 오답을 명확히 보여주겠다.


<head>
.
.
.
<!-- 폰트 적용 -->
    <link rel="preconnect" href="https://fonts.googleapis.com">
    <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
    <link href="https://fonts.googleapis.com/css2?family=Jua&display=swap" rel="stylesheet">
</head>

head 요소 안에 폰틀르 적용하기 위해 link를 걸었다. 내가 사용한 글꼴은 'jua'. 여기에서 사용할 수 있다.


자바스크립트 채점 소스

*javascript source

//가로줄 채점
// 현재 위치(좌표) 입력 받아야 함.
// 반환값은 true, false
function gradeRow(row){
    //반복문으로 채점.
    //가로줄이므로 row는 고정시켜놓고 column을 움직이면서 탐색.
  
  //count sort 응용
  var numbers = [0, 0, 0, 0, 0, 0, 0, 0, 0];
  var num;
  for (var step = 1; step < 10; step++) {
    // 각 셀의 input 값을 가져옴.
    num = parseInt(document.getElementById("coor_" + row + "," + step).value);
    numbers[num-1] += 1;
  }
  
  for (var idx = 0; idx < 10; idx++) {
    if (numbers[idx] > 1 || numbers[idx] == 0) {
     console.log("가로줄에서 실패!");	
     return false;
    }
  }
  return true;
}


// 세로줄 채점
function gradeColumn(column) {
    const numbers = Array(9).fill(0);
    let num;

    for (let step = 1; step <= 9; step++) {
        num = parseInt(document.getElementById("coor_" + step + "," + column).value);
        if (isNaN(num) || num < 1 || num > 9) {
            console.log("세로줄에서 실패!");
            return false;
        }
        numbers[num - 1]++;
    }

    return numbers.every(count => count === 1);
}

//3 by 3 집 채점
function gradeHouse(row, column) {
    var numbers = [0, 0, 0, 0, 0, 0, 0, 0, 0];

    // 각 구역의 시작 좌표 계산
    const startRow = Math.floor((row - 1) / 3) * 3 + 1;
    const startColumn = Math.floor((column - 1) / 3) * 3 + 1;

    // 해당 구역 내의 숫자 채점
    for (let i = startRow; i < startRow + 3; i++) {
        for (let j = startColumn; j < startColumn + 3; j++) {
            const num = parseInt(document.getElementById("coor_" + i.toString() + "," + j.toString()).value);
            if (isNaN(num) || num < 1 || num > 9 || ++numbers[num - 1] > 1) {
                console.log("구역에서 실패");
                return false;
            }
        }
    }

    // 모든 숫자가 한 번씩만 나왔는지 확인
    for (let idx = 0; idx < 9; idx++) {
        if (numbers[idx] !== 1) {
            return false;
        }
    }
    return true;
}

실제 내 채점 코드이다. 위 세 경우에 대해 모두 true를 받아야한다.

Array를 이용한 코드로, count sorting에서 영감을 받았다.

오늘 하루 안에 끝내려다보니 더 좋은 방법이 잘 떠오르지 않았다..


댓글