728x90
반응형
이번에도 심심해서 만들어본 스도쿠 게임입니다!
코드
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title><!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Bami`s스도쿠 게임</title>
<style>
body {
font-family: Arial, sans-serif;
display: flex;
align-items: center;
justify-content: center;
height: 100vh;
margin: 0;
background-color: #f0f0f0;
}
.sudoku-container {
text-align: center;
}
.grid {
display: grid;
grid-template-columns: repeat(9, 40px);
grid-template-rows: repeat(9, 40px);
gap: 2px;
margin: 20px 0;
}
.cell {
width: 40px;
height: 40px;
text-align: center;
font-size: 1.2em;
border: 1px solid #ccc;
background-color: #fff;
}
.cell:disabled {
background-color: #ddd;
color: #333;
}
/* 3x3 테두리를 굵게 설정 */
.cell:nth-child(3n+1) {
border-left: 2px solid #000;
}
.cell:nth-child(-n+9) {
border-top: 2px solid #000;
}
.cell:nth-child(9n) {
border-right: 2px solid #000;
}
.cell:nth-last-child(-n+9) {
border-bottom: 2px solid #000;
}
.button {
padding: 10px 20px;
margin: 5px;
font-size: 1em;
cursor: pointer;
}
</style>
</head>
<body>
<div class="sudoku-container">
<h1>Bami`s 스도쿠 게임</h1>
<div class="grid" id="sudoku-grid"></div>
<button class="button" onclick="giveHint()">힌트 보기</button>
<button class="button" onclick="resetGame()">다시 시작</button>
</div>
<script>
let initialBoard, board;
let hintsLeft = 3;
let selectedCell = null;
let difficultyLevel = 1;
// 스도쿠 보드 생성 함수
function generateCompleteBoard() {
let base = [
[1, 2, 3, 4, 5, 6, 7, 8, 9],
[4, 5, 6, 7, 8, 9, 1, 2, 3],
[7, 8, 9, 1, 2, 3, 4, 5, 6],
[2, 3, 4, 5, 6, 7, 8, 9, 1],
[5, 6, 7, 8, 9, 1, 2, 3, 4],
[8, 9, 1, 2, 3, 4, 5, 6, 7],
[3, 4, 5, 6, 7, 8, 9, 1, 2],
[6, 7, 8, 9, 1, 2, 3, 4, 5],
[9, 1, 2, 3, 4, 5, 6, 7, 8]
];
// 행, 열 및 3x3 박스를 무작위로 섞어서 스도쿠 보드를 생성합니다.
for (let i = 0; i < 10; i++) {
shuffleRows(base);
shuffleColumns(base);
}
return base;
}
// 행을 무작위로 섞는 함수
function shuffleRows(board) {
let block = Math.floor(Math.random() * 3) * 3;
let row1 = block + Math.floor(Math.random() * 3);
let row2 = block + Math.floor(Math.random() * 3);
[board[row1], board[row2]] = [board[row2], board[row1]];
}
// 열을 무작위로 섞는 함수
function shuffleColumns(board) {
let block = Math.floor(Math.random() * 3) * 3;
let col1 = block + Math.floor(Math.random() * 3);
let col2 = block + Math.floor(Math.random() * 3);
for (let i = 0; i < 9; i++) {
[board[i][col1], board[i][col2]] = [board[i][col2], board[i][col1]];
}
}
function generateNewPuzzle(difficulty) {
// 완성된 스도쿠 보드를 생성
let completeBoard = generateCompleteBoard();
// 초기 보드를 완성된 보드로 설정 (정답이 있는 상태)
initialBoard = JSON.parse(JSON.stringify(completeBoard));
// 난이도에 따라 빈 칸 개수를 설정하여 `board` 생성
let emptyCells = 20 + difficulty * 10; // 난이도에 따라 빈 칸의 개수를 늘림
board = JSON.parse(JSON.stringify(completeBoard));
for (let i = 0; i < emptyCells; i++) {
let row = Math.floor(Math.random() * 9);
let col = Math.floor(Math.random() * 9);
board[row][col] = null;
}
}
function createGrid() {
const grid = document.getElementById("sudoku-grid");
grid.innerHTML = '';
for (let row = 0; row < 9; row++) {
for (let col = 0; col < 9; col++) {
const cell = document.createElement("input");
cell.type = "text";
cell.classList.add("cell");
cell.maxLength = 1;
cell.dataset.row = row;
cell.dataset.col = col;
if (board[row][col] !== null) {
cell.value = board[row][col];
cell.disabled = true;
} else {
cell.addEventListener("click", () => selectCell(row, col));
cell.addEventListener("input", (e) => {
const value = parseInt(e.target.value);
if (!value || value < 1 || value > 9) {
e.target.value = '';
board[row][col] = null; // 빈 셀을 null로 유지
} else {
board[row][col] = value; // 숫자형으로 저장
// 퍼즐이 완성되었는지 확인
if (isBoardFull() && checkWin()) {
setTimeout(() => {
alert("퍼즐을 완성했습니다! 다음 라운드로 넘어갑니다.");
difficultyLevel++;
resetGame();
}, 100);
}
}
});
}
grid.appendChild(cell);
}
}
}
function checkWin() {
for (let row = 0; row < 9; row++) {
for (let col = 0; col < 9; col++) {
// 각 셀이 정답과 일치하지 않으면 false 반환
if (parseInt(board[row][col]) !== initialBoard[row][col]) {
return false;
}
}
}
return true;
}
// 모든 셀이 채워졌는지 확인하는 함수
function isBoardFull() {
for (let row = 0; row < 9; row++) {
for (let col = 0; col < 9; col++) {
if (board[row][col] === null) {
return false;
}
}
}
return true;
}
function selectCell(row, col) {
selectedCell = { row, col };
}
function giveHint() {
if (hintsLeft > 0 && selectedCell) {
const { row, col } = selectedCell;
// console.log(`Selected cell board[${row}][${col}] =`, board[row][col]); // 선택된 셀 값 상태 확인
// console.log(`Initial board value initialBoard[${row}][${col}] =`, initialBoard[row][col]); // 초기 보드의 값 상태 확인
// 현재 선택한 셀이 비어 있고, initialBoard에 정답 값이 있을 경우에만 힌트를 제공
if (board[row][col] == null) {
if (initialBoard[row][col] !== null) {
board[row][col] = initialBoard[row][col]; // 힌트를 보드에 적용
createGrid(); // 새로 고침하여 힌트 반영
hintsLeft--; // 힌트 횟수 감소
selectedCell = null; // 힌트를 준 후 선택 해제
console.log(`Hint applied at board[${row}][${col}] =`, board[row][col]); // 힌트 적용 확인
} else {
alert("이 셀에는 힌트를 제공할 수 없습니다.");
}
} else {
alert("이 셀에는 이미 숫자가 있습니다.");
}
} else if (!selectedCell) {
alert("힌트를 받을 셀을 먼저 선택하세요.");
} else {
alert("힌트 사용 횟수가 초과되었습니다!");
}
}
function resetGame() {
hintsLeft = 3;
selectedCell = null;
generateNewPuzzle(difficultyLevel);
createGrid();
}
// 초기 게임 설정
generateNewPuzzle(difficultyLevel);
createGrid();
</script>
</body>
</html>
728x90
반응형
'프로그래밍(Web) > Javascript(TS,Node)' 카테고리의 다른 글
[바미] JS - 오목 (0) | 2024.10.31 |
---|---|
[바미] JS - 테트리스 (0) | 2024.09.21 |
[바미] Node-Express 간단한 REST API 예제 (0) | 2024.08.01 |
[바미] 심심해서 만들어 본 슬롯머신 (0) | 2024.06.07 |
[바미] 로또 추첨기(JS) (0) | 2024.06.02 |