Skip to content

Commit 16f2965

Browse files
Added main Javascript
1 parent 000e67d commit 16f2965

File tree

1 file changed

+172
-0
lines changed

1 file changed

+172
-0
lines changed

180 - Sudoku/static/js/sudoku.js

Lines changed: 172 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,172 @@
1+
const newGrid = (size) => {
2+
let arr = new Array(size);
3+
4+
for (let i = 0; i < size; i++) {
5+
arr[i] = new Array(size);
6+
}
7+
8+
for (let i = 0; i < Math.pow(size, 2); i++) {
9+
arr[Math.floor(i/size)][i%size] = CONSTANT.UNASSIGNED;
10+
}
11+
12+
return arr;
13+
}
14+
15+
// check duplicate number in col
16+
const isColSafe = (grid, col, value) => {
17+
for (let row = 0; row < CONSTANT.GRID_SIZE; row++) {
18+
if (grid[row][col] === value) return false;
19+
}
20+
return true;
21+
}
22+
23+
// check duplicate number in row
24+
const isRowSafe = (grid, row, value) => {
25+
for (let col = 0; col < CONSTANT.GRID_SIZE; col++) {
26+
if (grid[row][col] === value) return false;
27+
}
28+
return true;
29+
}
30+
31+
// check duplicate number in 3x3 box
32+
const isBoxSafe = (grid, box_row, box_col, value) => {
33+
for (let row = 0; row < CONSTANT.BOX_SIZE; row++) {
34+
for (let col = 0; col < CONSTANT.BOX_SIZE; col++) {
35+
if (grid[row + box_row][col + box_col] === value) return false;
36+
}
37+
}
38+
return true;
39+
}
40+
41+
// check in row, col and 3x3 box
42+
const isSafe = (grid, row, col, value) => {
43+
return isColSafe(grid, col, value) && isRowSafe(grid, row, value) && isBoxSafe(grid, row - row%3, col - col%3, value) && value !== CONSTANT.UNASSIGNED;
44+
}
45+
46+
// find unassigned cell
47+
const findUnassignedPos = (grid, pos) => {
48+
for (let row = 0; row < CONSTANT.GRID_SIZE; row++) {
49+
for (let col = 0; col < CONSTANT.GRID_SIZE; col++) {
50+
if (grid[row][col] === CONSTANT.UNASSIGNED) {
51+
pos.row = row;
52+
pos.col = col;
53+
return true;
54+
}
55+
}
56+
}
57+
return false;
58+
}
59+
60+
// shuffle arr
61+
const shuffleArray = (arr) => {
62+
let curr_index = arr.length;
63+
64+
while (curr_index !== 0) {
65+
let rand_index = Math.floor(Math.random() * curr_index);
66+
curr_index -= 1;
67+
68+
let temp = arr[curr_index];
69+
arr[curr_index] = arr[rand_index];
70+
arr[rand_index] = temp;
71+
}
72+
73+
return arr;
74+
}
75+
76+
// check puzzle is complete
77+
const isFullGrid = (grid) => {
78+
return grid.every((row, i) => {
79+
return row.every((value, j) => {
80+
return value !== CONSTANT.UNASSIGNED;
81+
});
82+
});
83+
}
84+
85+
const sudokuCreate = (grid) => {
86+
let unassigned_pos = {
87+
row: -1,
88+
col: -1
89+
}
90+
91+
if (!findUnassignedPos(grid, unassigned_pos)) return true;
92+
93+
let number_list = shuffleArray([...CONSTANT.NUMBERS]);
94+
95+
let row = unassigned_pos.row;
96+
let col = unassigned_pos.col;
97+
98+
number_list.forEach((num, i) => {
99+
if (isSafe(grid, row, col, num)) {
100+
grid[row][col] = num;
101+
102+
if (isFullGrid(grid)) {
103+
return true;
104+
} else {
105+
if (sudokuCreate(grid)) {
106+
return true;
107+
}
108+
}
109+
110+
grid[row][col] = CONSTANT.UNASSIGNED;
111+
}
112+
});
113+
114+
return isFullGrid(grid);
115+
}
116+
117+
const sudokuCheck = (grid) => {
118+
let unassigned_pos = {
119+
row: -1,
120+
col: -1
121+
}
122+
123+
if (!findUnassignedPos(grid, unassigned_pos)) return true;
124+
125+
grid.forEach((row, i) => {
126+
row.forEach((num, j) => {
127+
if (isSafe(grid, i, j, num)) {
128+
if (isFullGrid(grid)) {
129+
return true;
130+
} else {
131+
if (sudokuCreate(grid)) {
132+
return true;
133+
}
134+
}
135+
}
136+
})
137+
})
138+
139+
return isFullGrid(grid);
140+
}
141+
142+
const rand = () => Math.floor(Math.random() * CONSTANT.GRID_SIZE);
143+
144+
const removeCells = (grid, level) => {
145+
let res = [...grid];
146+
let attemps = level;
147+
while (attemps > 0) {
148+
let row = rand();
149+
let col = rand();
150+
while (res[row][col] === 0) {
151+
row = rand();
152+
col = rand();
153+
}
154+
res[row][col] = CONSTANT.UNASSIGNED;
155+
attemps--;
156+
}
157+
return res;
158+
}
159+
160+
// generate sudoku base on level
161+
const sudokuGen = (level) => {
162+
let sudoku = newGrid(CONSTANT.GRID_SIZE);
163+
let check = sudokuCreate(sudoku);
164+
if (check) {
165+
let question = removeCells(sudoku, level);
166+
return {
167+
original: sudoku,
168+
question: question
169+
}
170+
}
171+
return undefined;
172+
}

0 commit comments

Comments
 (0)