Skip to content

Commit ea6bb68

Browse files
committedFeb 5, 2023
ABSTRACTION!!!
1 parent 63f1475 commit ea6bb68

17 files changed

+3269
-6299
lines changed
 
File renamed without changes.
File renamed without changes.

‎pzz-akari/play/App.svelte

+16-837
Large diffs are not rendered by default.

‎pzz-akari/play/boardComponent.svelte

+253
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,253 @@
1+
<script lang="ts">
2+
import { createEventDispatcher } from 'svelte';
3+
const dispatch = createEventDispatcher();
4+
5+
export let blockInteraction:boolean = false;
6+
export let boardHeight: number = 0;
7+
export let boardWidth: number = 0;
8+
type boardData = {
9+
v: number
10+
/*
11+
-2 : light
12+
-1: block
13+
0: empty
14+
1-4: number
15+
*/
16+
w: boolean // confirmed wrong
17+
}
18+
19+
let Val: boardData[][] = [[]];
20+
21+
function mainPanelClick(i: number, j : number, e:MouseEvent) {
22+
if (blockInteraction) {
23+
blockInteraction = false;
24+
return;
25+
}
26+
27+
if (Val[i][j].v == 0) {
28+
Val[i][j].v = -2;
29+
} else if (Val[i][j].v == -2) {
30+
Val[i][j].v = 0;
31+
}
32+
33+
dispatch("SaveState");
34+
}
35+
36+
export const boardController = {
37+
getColnum(): number {
38+
return Val.length;
39+
},
40+
getRownum(): number {
41+
return Val[0].length;
42+
},
43+
cleanWrong(): void {
44+
for (let i = 0; i < Val.length; i++) {
45+
for (let j = 0; j < Val.length; j++) {
46+
Val[i][j].w = false;
47+
}
48+
}
49+
},
50+
initializeData(dt: any): void {
51+
Val = dt.map((e: number[]) => {
52+
return (e.map(e2 => {
53+
let a: boardData = {
54+
v: e2,
55+
w: false
56+
}
57+
return (a);
58+
}));
59+
});
60+
},
61+
resetState(dt: any):void {
62+
Val = dt.map((e: number[]) => {
63+
return (e.map(e2 => {
64+
let a: boardData = {
65+
v: e2,
66+
w: false
67+
}
68+
return (a);
69+
}));
70+
});
71+
},
72+
loadData(dt: any): void {
73+
Val = dt.map((e: number[]) => {
74+
return (e.map(e2 => {
75+
let a: boardData = {
76+
v: e2,
77+
w: false
78+
}
79+
return (a);
80+
}));
81+
});
82+
},
83+
doubleClickMouse(e: HTMLElement): void {
84+
const id = e.id.split(" ");
85+
mainPanelClick(Number(id[0]), Number(id[1]), null);
86+
},
87+
getSavingData(): any {
88+
return (Val.map(e => {
89+
return (e.map(e2 => {
90+
return e2.v;
91+
}));
92+
}));
93+
},
94+
checkAnswer(): boolean {
95+
let clear = true;
96+
const colNum = Val.length;
97+
const rowNum = Val[0].length;
98+
99+
for (let i = 0; i < Val.length; i++) {
100+
for (let j = 0; j < Val[i].length; j++) {
101+
if (Val[i][j].v > 0) {
102+
let lightBulb: number = 0;
103+
if (i > 0) {
104+
if (Val[i - 1][j].v == -2) {
105+
lightBulb++;
106+
}
107+
}
108+
109+
if (j > 0) {
110+
if (Val[i][j - 1].v == -2) {
111+
lightBulb++;
112+
}
113+
}
114+
if (i + 1 < colNum) {
115+
if (Val[i + 1][j].v == -2) {
116+
lightBulb++;
117+
}
118+
}
119+
if (j + 1 < rowNum) {
120+
if (Val[i][j + 1].v == -2) {
121+
lightBulb++;
122+
}
123+
}
124+
if (lightBulb != Val[i][j].v) {
125+
Val[i][j].w = true;
126+
clear = false;
127+
}
128+
}
129+
}
130+
}
131+
132+
let tempBoard: boolean[][] = [];
133+
while (tempBoard.length < rowNum) {
134+
let a: boolean[] = [];
135+
while (a.length < colNum) {
136+
a.push(false);
137+
}
138+
tempBoard.push(a);
139+
}
140+
141+
for (let i = 0; i < Val.length; i++) {
142+
for (let j = 0; j < Val[i].length; j++) {
143+
if (Val[i][j].v == -2) {
144+
tempBoard[i][j] = true;
145+
for (let x = i - 1; x >= 0; x--){
146+
if (Val[x][j].v == -2) {
147+
clear = false;
148+
Val[i][j].w = true;
149+
Val[x][j].w = true;
150+
} else if (Val[x][j].v == 0) {
151+
tempBoard[x][j] = true;
152+
} else {
153+
break;
154+
}
155+
}
156+
157+
for (let x = i + 1; x < rowNum; x++){
158+
if (Val[x][j].v == -2) {
159+
clear = false;
160+
Val[i][j].w = true;
161+
Val[x][j].w = true;
162+
} else if (Val[x][j].v == 0) {
163+
tempBoard[x][j] = true;
164+
} else {
165+
break;
166+
}
167+
}
168+
169+
for (let y = j - 1; y >= 0; y--){
170+
if (Val[i][y].v == -2) {
171+
clear = false;
172+
Val[i][j].w = true;
173+
Val[i][y].w = true;
174+
} else if (Val[i][y].v == 0) {
175+
tempBoard[i][y] = true;
176+
} else {
177+
break;
178+
}
179+
}
180+
181+
for (let y = j + 1; y < colNum; y++){
182+
if (Val[i][y].v == -2) {
183+
clear = false;
184+
Val[i][j].w = true;
185+
Val[i][y].w = true;
186+
} else if (Val[i][y].v == 0) {
187+
tempBoard[i][y] = true;
188+
} else {
189+
break;
190+
}
191+
}
192+
} else if (Val[i][j].v != 0) {
193+
tempBoard[i][j] = true;
194+
}
195+
}
196+
}
197+
198+
for (let i = 0; i < Val.length; i++) {
199+
for (let j = 0; j < Val[i].length; j++) {
200+
if (!tempBoard[i][j]) {
201+
Val[i][j].w = true;
202+
clear = false;
203+
}
204+
}
205+
}
206+
207+
return clear;
208+
},
209+
getCheckingData(): any {
210+
return (Val.map(e => {
211+
return (e.map(e2 => {
212+
return e2.v;
213+
}))
214+
}));
215+
}
216+
}
217+
</script>
218+
219+
<div
220+
id="mainBoard"
221+
style="
222+
display: grid;
223+
grid-template-columns: repeat({Val.length}, 1fr);
224+
grid-template-rows: repeat({Val[0].length}, 1fr);
225+
height: {boardHeight}px; width: {boardWidth}px;
226+
font-size: inherit;
227+
"
228+
>
229+
{#each Val as box, i}
230+
{#each box as e, j}
231+
<div id={i.toString() + " " + j.toString()}
232+
class="boardCell" class:empty={(e.v == 0) || (e.v == -2)} class:wrong={e.w}
233+
on:click={(e) => mainPanelClick(i, j, null)}
234+
>
235+
{ (e.v == -2) ? "O" : ((e.v > 0) ? e.v : "") }
236+
</div>
237+
{/each}
238+
{/each}
239+
</div>
240+
241+
<style>
242+
/* MAIN PANEL */
243+
.boardCell {
244+
cursor: pointer;
245+
display: flex;
246+
justify-content: center;
247+
align-items: center;
248+
font-size: inherit;
249+
border-width: 2px;
250+
border-style: solid;
251+
}
252+
253+
</style>

‎pzz-futoshiki/play/App.svelte

+16-643
Large diffs are not rendered by default.
+384
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,384 @@
1+
<script lang="ts">
2+
import { createEventDispatcher } from 'svelte';
3+
const dispatch = createEventDispatcher();
4+
5+
export let boardHeight: number = 0;
6+
export let boardWidth: number = 0;
7+
type boardData = {
8+
v: string
9+
w: boolean // confirmed wrong
10+
u: undefined | boolean,
11+
l: undefined | boolean,
12+
f: boolean,
13+
}
14+
15+
let Val: boardData[][] = [[]];
16+
$: sizeBox = Val.length;
17+
18+
function clickMouse(e: MouseEvent) {
19+
const target = e.target as HTMLElement;
20+
if (target.firstChild) {
21+
if (target.firstChild.nodeName.toUpperCase() == "DIV") {
22+
(target.firstChild as HTMLElement).focus();
23+
}
24+
}
25+
}
26+
27+
function validateInput(i: number, j: number) {
28+
let check = parseInt(Val[i][j].v);
29+
30+
if (isNaN(check)) {
31+
Val[i][j].v = "";
32+
} else if (check > sizeBox) {
33+
Val[i][j].v = "";
34+
} else if (check < 1) {
35+
Val[i][j].v = "";
36+
} else {
37+
Val[i][j].v = check.toString();
38+
}
39+
dispatch("SaveState");
40+
}
41+
42+
function selectAllText(e: Event) {
43+
window.getSelection().selectAllChildren((e.target as Element))
44+
}
45+
46+
function forceRefresh() {
47+
Val = Val;
48+
}
49+
50+
export const boardController = {
51+
getColnum(): number {
52+
return Val.length;
53+
},
54+
getRownum(): number {
55+
return Val[0].length;
56+
},
57+
cleanWrong(): void {
58+
for (let i = 0; i < Val.length; i++) {
59+
for (let j = 0; j < Val.length; j++) {
60+
Val[i][j].w = false;
61+
}
62+
}
63+
},
64+
initializeData(dt: any): void {
65+
Val = dt.map((e: any[]) => {
66+
return (e.map(e2 => {
67+
let a: boardData = {
68+
v: e2.v,
69+
w: false,
70+
u: (e2.u != undefined) ? e2.u : undefined,
71+
l: (e2.l != undefined) ? e2.l : undefined,
72+
f: (e2.v != "")
73+
}
74+
return (a);
75+
}))
76+
});
77+
},
78+
resetState(dt: any): void {
79+
Val = dt.map((e: any[]) => {
80+
return (e.map(e2 => {
81+
let a: boardData = {
82+
v: e2.v,
83+
w: false,
84+
u: (e2.u != undefined) ? e2.u : undefined,
85+
l: (e2.l != undefined) ? e2.l : undefined,
86+
f: (e2.v != ""),
87+
}
88+
return (a);
89+
}))
90+
});
91+
},
92+
loadData(dt: any): void {
93+
for (let i = 0; i < dt.length; i++) {
94+
for (let j = 0; j < dt[i].length; j++){
95+
Val[i][j].v = dt[i][j];
96+
}
97+
}
98+
99+
forceRefresh();
100+
},
101+
doubleClickMouse(e: HTMLElement): void {
102+
const target = e as HTMLElement;
103+
if (target.firstChild) {
104+
if (target.firstChild.nodeName.toUpperCase() == "DIV") {
105+
(target.firstChild as HTMLElement).focus();
106+
}
107+
}
108+
},
109+
getSavingData(): any {
110+
return (Val.map(e => {
111+
return (e.map(e2 => {
112+
return e2.v;
113+
}));
114+
}));
115+
},
116+
checkAnswer(): boolean {
117+
let clear = true;
118+
119+
for (let i = 0; i < Val.length; i++) {
120+
for (let j = 0; j < Val[i].length; j++) {
121+
if (Val[i][j].v == "") {
122+
Val[i][j].w = true;
123+
clear = false;
124+
continue;
125+
} else {
126+
let check = parseInt(Val[i][j].v);
127+
128+
if (isNaN(check)) {
129+
Val[i][j].w = true;
130+
} else if (check > sizeBox) {
131+
Val[i][j].w = true;
132+
} else if (check < 1) {
133+
Val[i][j].w = true;
134+
}
135+
136+
if (Val[i][j].w) {
137+
clear = false;
138+
continue;
139+
}
140+
141+
for (let x = 0; x < Val.length; x++) {
142+
if (x == i) {
143+
continue;
144+
}
145+
146+
if (Val[i][j].v == Val[x][j].v) {
147+
Val[i][j].w = true;
148+
break;
149+
}
150+
}
151+
152+
if (Val[i][j].w) {
153+
clear = false;
154+
continue;
155+
}
156+
157+
for (let y = 0; y < Val[i].length; y++) {
158+
if (y == j) {
159+
continue;
160+
}
161+
162+
if (Val[i][j].v == Val[i][y].v) {
163+
Val[i][j].w = true;
164+
break;
165+
}
166+
}
167+
168+
if (Val[i][j].w) {
169+
clear = false;
170+
continue;
171+
}
172+
173+
if (i > 0) {
174+
if (Val[i][j].u != undefined) {
175+
let check2 = parseInt(Val[i - 1][j].v);
176+
if (isNaN(check2)) {
177+
continue;
178+
}
179+
180+
if (Val[i][j].u) {
181+
if (check2 > check) {
182+
Val[i][j].w = true;
183+
Val[i - 1][j].w = true;
184+
}
185+
} else {
186+
if (check2 < check) {
187+
Val[i][j].w = true;
188+
Val[i - 1][j].w = true;
189+
}
190+
}
191+
}
192+
}
193+
194+
if (Val[i][j].w) {
195+
clear = false;
196+
continue;
197+
}
198+
199+
if (j > 0) {
200+
if (Val[i][j].l != undefined) {
201+
let check2 = parseInt(Val[i][j - 1].v);
202+
if (isNaN(check2)) {
203+
continue;
204+
}
205+
206+
if (Val[i][j].l) {
207+
if (check2 > check) {
208+
Val[i][j].w = true;
209+
Val[i][j - 1].w = true;
210+
}
211+
} else {
212+
if (check2 < check) {
213+
Val[i][j].w = true;
214+
Val[i][j - 1].w = true;
215+
}
216+
}
217+
}
218+
}
219+
220+
if (Val[i][j].w) {
221+
clear = false;
222+
continue;
223+
}
224+
}
225+
}
226+
}
227+
228+
return clear;
229+
},
230+
getCheckingData(): any {
231+
return (Val.map(e => {
232+
return (e.map(e2 => {
233+
return {
234+
v: parseInt(e2.v),
235+
u: e2.u,
236+
l: e2.l
237+
};
238+
}));
239+
}));
240+
}
241+
}
242+
</script>
243+
244+
<div
245+
id="mainBoard"
246+
style="
247+
display: grid;
248+
grid-template-columns: repeat({Val.length}, 1fr);
249+
grid-template-rows: repeat({Val[0].length}, 1fr);
250+
height: {boardHeight}px; width: {boardWidth}px;
251+
font-size: 50%;
252+
"
253+
>
254+
{#each Val as box, j}
255+
{#each box as e, i}
256+
<div id={i + " " + j}
257+
class="boardCell back"
258+
>
259+
<div class="boardCell middle"
260+
class:fix={e.f}
261+
class:empty={!e.f}
262+
class:wrong={e.w}
263+
on:click={clickMouse}
264+
>
265+
{#if e.f}
266+
<div class="front"
267+
contenteditable = "false"
268+
bind:innerHTML={e.v}
269+
></div>
270+
{:else}
271+
<div class="front"
272+
on:focusout={() => {validateInput(j, i)}}
273+
on:focusin={(e2) => {selectAllText(e2)}}
274+
contenteditable = "true"
275+
bind:innerHTML={e.v}
276+
></div>
277+
{/if}
278+
</div>
279+
{#if j > 0}
280+
<div
281+
class="boardCell empty sign t"
282+
>
283+
{#if Val[j][i].u == undefined}
284+
<div class="signCircle"></div>
285+
{:else if Val[j][i].u}
286+
<div class="arrow">▲</div>
287+
{:else}
288+
<div class="arrow">▼</div>
289+
{/if}
290+
</div>
291+
{/if}
292+
{#if i > 0}
293+
<div
294+
class="boardCell empty sign l"
295+
>
296+
{#if Val[j][i].l == undefined}
297+
<div class="signCircle"></div>
298+
{:else if Val[j][i].l}
299+
<div class="arrow">◀</div>
300+
{:else}
301+
<div class="arrow">▶</div>
302+
{/if}
303+
</div>
304+
{/if}
305+
</div>
306+
{/each}
307+
{/each}
308+
</div>
309+
310+
<style>
311+
.boardCell {
312+
display: flex;
313+
justify-content: center;
314+
align-items: center;
315+
font-size: inherit;
316+
position: relative;
317+
}
318+
319+
.boardCell.back {
320+
padding: 18%;
321+
background-color: transparent;
322+
}
323+
324+
.boardCell.middle {
325+
cursor: pointer;
326+
height: 100%;
327+
width: 100%;
328+
border-width: 3px;
329+
}
330+
331+
.front {
332+
cursor: pointer;
333+
color: inherit;
334+
background-color: inherit;
335+
border-color: inherit;
336+
}
337+
338+
.arrow {
339+
text-align: center;
340+
display: flex;
341+
justify-content: center;
342+
align-items: center;
343+
padding-bottom: 7%;
344+
color: inherit;
345+
}
346+
347+
.sign {
348+
position: absolute;
349+
padding: 2px;
350+
z-index: 1;
351+
}
352+
353+
.sign div {
354+
aspect-ratio: 1;
355+
}
356+
357+
.signCircle {
358+
border-width: 0px;
359+
}
360+
361+
.sign.l div {
362+
width: 100%;
363+
}
364+
365+
.sign.t div {
366+
height: 100%;
367+
}
368+
369+
.sign.t {
370+
width: 100%;
371+
height: 36%;
372+
left: 0%;
373+
top: -18%;
374+
background-color: transparent;
375+
}
376+
377+
.sign.l {
378+
width: 36%;
379+
height: 100%;
380+
left: -18%;
381+
top: 0%;
382+
background-color: transparent;
383+
}
384+
</style>

‎pzz-hashi/play/App.svelte

+16-1,085
Large diffs are not rendered by default.

‎pzz-hashi/play/boardComponent.svelte

+502
Large diffs are not rendered by default.

‎pzz-kakuro/play/App.svelte

+16-921
Large diffs are not rendered by default.

‎pzz-kakuro/play/boardComponent.svelte

+334
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,334 @@
1+
<script lang="ts">
2+
import { createEventDispatcher } from 'svelte';
3+
const dispatch = createEventDispatcher();
4+
5+
export let blockInteraction:boolean = false;
6+
export let boardHeight: number = 0;
7+
export let boardWidth: number = 0;
8+
type boardData = {
9+
v: string,
10+
/*
11+
-2: block
12+
-1: border
13+
0: empty
14+
1-9: number
15+
*/
16+
f:boolean,
17+
dt1: string,
18+
dt2: string,
19+
w: boolean, // confirmed wrong
20+
w1: boolean,
21+
w2: boolean
22+
}
23+
24+
let Val: boardData[][] = [[]];
25+
26+
function mainPanelClick(e: HTMLElement) {
27+
if (blockInteraction) {
28+
blockInteraction = false;
29+
return;
30+
}
31+
32+
e.focus();
33+
}
34+
35+
function validateInput(i: number, j: number) {
36+
let check = parseInt(Val[i][j].v);
37+
38+
if (isNaN(check)) {
39+
Val[i][j].v = "";
40+
} else if (check > 9) {
41+
Val[i][j].v = "";
42+
} else if (check < 1) {
43+
Val[i][j].v = "";
44+
} else {
45+
Val[i][j].v = check.toString();
46+
}
47+
dispatch("SaveState");
48+
}
49+
50+
function selectAllText(e: Event) {
51+
window.getSelection().selectAllChildren((e.target as Element))
52+
}
53+
54+
function forceRefresh() {
55+
Val = Val;
56+
}
57+
58+
export const boardController = {
59+
getColnum(): number {
60+
return Val.length;
61+
},
62+
getRownum(): number {
63+
return Val[0].length;
64+
},
65+
cleanWrong(): void {
66+
for (let i = 0; i < Val.length; i++) {
67+
for (let j = 0; j < Val.length; j++) {
68+
Val[i][j].w = false;
69+
Val[i][j].w1 = false;
70+
Val[i][j].w2 = false;
71+
}
72+
}
73+
},
74+
initializeData(dt: any): void {
75+
Val = dt.map(e => {
76+
return (e.map(e2 => {
77+
let a: boardData = {
78+
v: (e2.v == 0) ? "" : e2.v,
79+
f: (e2.v != 0),
80+
w: false,
81+
w1: false,
82+
w2: false,
83+
dt1: e2.dt1 ? e2.dt1 : "",
84+
dt2: e2.dt2 ? e2.dt2 : ""
85+
}
86+
return (a);
87+
}))
88+
});
89+
},
90+
resetState(dt: any): void {
91+
Val = dt.map(e => {
92+
return (e.map(e2 => {
93+
let a: boardData = {
94+
v: (e2.v == 0) ? "" : e2.v,
95+
f: (e2.v != 0),
96+
w: false,
97+
w1: false,
98+
w2: false,
99+
dt1: e2.dt1 ? e2.dt1 : "",
100+
dt2: e2.dt2 ? e2.dt2 : ""
101+
}
102+
return (a);
103+
}))
104+
});
105+
},
106+
loadData(dt: any): void {
107+
for (let i = 0; i < dt.length; i++) {
108+
for (let j = 0; j < dt[i].length; j++){
109+
Val[i][j].v = dt[i][j];
110+
}
111+
}
112+
forceRefresh();
113+
},
114+
doubleClickMouse(e: HTMLElement): void {
115+
mainPanelClick(e as HTMLElement);
116+
},
117+
getSavingData(): any {
118+
return (Val.map(e => {
119+
return (e.map(e2 => {
120+
return e2.v;
121+
}));
122+
}));
123+
},
124+
checkAnswer(): boolean {
125+
let clear = true;
126+
127+
for (let i = 0; i < Val.length; i++) {
128+
for (let j = 0; j < Val[i].length; j++) {
129+
if (!Val[i][j].f) {
130+
if ((Val[i][j].v == "0") || (Val[i][j].v == "")) {
131+
Val[i][j].w = true;
132+
clear = false;
133+
}
134+
135+
for (let x = i - 1; x > 0; x--){
136+
if (Val[x][j].f) {
137+
break;
138+
} else if (Val[x][j].v == Val[i][j].v) {
139+
Val[i][j].w = true;
140+
Val[x][j].w = true;
141+
clear = false;
142+
}
143+
}
144+
145+
for (let x = i + 1; x < Val.length; x++){
146+
if (Val[x][j].f) {
147+
break;
148+
} else if (Val[x][j].v == Val[i][j].v) {
149+
Val[i][j].w = true;
150+
Val[x][j].w = true;
151+
clear = false;
152+
}
153+
}
154+
155+
for (let y = j - 1; y > 0; y--){
156+
if (Val[i][y].f) {
157+
break;
158+
} else if (Val[i][y].v == Val[i][j].v) {
159+
Val[i][j].w = true;
160+
Val[i][y].w = true;
161+
clear = false;
162+
}
163+
}
164+
165+
for (let y = j + 1; y < Val.length[i]; y++){
166+
if (Val[i][y].f) {
167+
break;
168+
} else if (Val[i][y].v == Val[i][j].v) {
169+
Val[i][j].w = true;
170+
Val[i][y].w = true;
171+
clear = false;
172+
}
173+
}
174+
175+
} else if (Val[i][j].v == "-1") {
176+
if (Val[i][j].dt1 != "") {
177+
let vSum = 0;
178+
let hSum = 0;
179+
180+
for (let x = i - 1; x > 0; x--){
181+
if (Val[x][j].f) {
182+
break;
183+
} else {
184+
vSum += parseInt(Val[x][j].v);
185+
}
186+
}
187+
188+
for (let y = j + 1; y < Val[i].length; y++){
189+
if (Val[i][y].f) {
190+
break;
191+
} else {
192+
hSum += parseInt(Val[i][y].v);
193+
}
194+
}
195+
196+
if ((parseInt(Val[i][j].dt1) != vSum) && (parseInt(Val[i][j].dt1) != hSum)) {
197+
Val[i][j].w1 = true;
198+
clear = false;
199+
}
200+
}
201+
202+
if (Val[i][j].dt2 != "") {
203+
let vSum = 0;
204+
let hSum = 0;
205+
206+
for (let x = i + 1; x < Val.length; x++){
207+
if (Val[x][j].f) {
208+
break;
209+
} else {
210+
vSum += parseInt(Val[x][j].v);
211+
}
212+
}
213+
214+
for (let y = j - 1; y > 0; y--){
215+
if (Val[i][y].f) {
216+
break;
217+
} else {
218+
hSum += parseInt(Val[i][y].v);
219+
}
220+
}
221+
222+
if ((parseInt(Val[i][j].dt2) != vSum) && (parseInt(Val[i][j].dt2) != hSum)) {
223+
Val[i][j].w2 = true;
224+
clear = false;
225+
}
226+
}
227+
}
228+
}
229+
}
230+
231+
return clear;
232+
},
233+
getCheckingData(): any {
234+
return (Val.map(e => {
235+
return (e.map(e2 => {
236+
return (e2.f && (e2.v == "-1")) ? ({ dt1: parseInt(e2.dt1), dt2: parseInt(e2.dt2) }) : ({ v: parseInt(e2.v)});
237+
}));
238+
}));
239+
}
240+
}
241+
</script>
242+
243+
<div
244+
id="mainBoard"
245+
class="kakuro"
246+
style="
247+
display: grid;
248+
grid-template-columns: repeat({Val.length}, 1fr);
249+
grid-template-rows: repeat({Val[0].length}, 1fr);
250+
height: {boardHeight}px; width: {boardWidth}px;
251+
font-size: inherit;
252+
"
253+
>
254+
{#each Val as box, j}
255+
{#each box as e, i}
256+
{#if e.f}
257+
<div id={i.toString()}
258+
class="boardCell kakuro" class:border={e.v == "-1"} class:wrong={e.w && (e.v == "0")}
259+
>
260+
{#if e.v == "-1"}
261+
<svg xmlns='http://www.w3.org/2000/svg' version='1.1' preserveAspectRatio='none' viewBox='0 0 10 10' style="position: absolute; height: {boardHeight/Val[0].length}px; width: {boardWidth/Val.length}px;">
262+
<line x1='0' y1='0' x2='10' y2='10' style='stroke-width:0.1px'/>
263+
</svg>
264+
265+
<div class="cir1" class:empty={!e.w1 && (e.dt1 != "")} class:wrong={e.w1}>
266+
<div
267+
class="borderInner"
268+
>{e.dt1}
269+
</div>
270+
</div>
271+
<div class="cir2" class:empty={!e.w2 && (e.dt2 != "")} class:wrong={e.w2}>
272+
<div
273+
class="borderInner"
274+
>{e.dt2}
275+
</div>
276+
</div>
277+
{/if}
278+
</div>
279+
{:else}
280+
<div id={i.toString()}
281+
class="boardCell kakuro empty" class:wrong={e.w}
282+
on:focusout={() => {validateInput(j, i)}}
283+
on:focusin={(e2) => {selectAllText(e2)}}
284+
contenteditable = "true"
285+
bind:innerHTML={e.v}
286+
></div>
287+
{/if}
288+
{/each}
289+
{/each}
290+
</div>
291+
292+
<style>
293+
.boardCell {
294+
cursor: pointer;
295+
display: flex;
296+
justify-content: center;
297+
align-items: center;
298+
font-size: inherit;
299+
border-width: 2px;
300+
border-style: solid;
301+
}
302+
303+
.boardCell.kakuro {
304+
border-width: 1px;
305+
border-style: solid;
306+
}
307+
308+
.boardCell.kakuro.border {
309+
display: unset;
310+
font-size: 0.45em;
311+
}
312+
313+
.boardCell.kakuro.border div {
314+
height: 50%;
315+
width: 50%;
316+
border-radius: 50%;
317+
text-align: center;
318+
display: flex;
319+
justify-content: center;
320+
align-items: center;
321+
}
322+
323+
.boardCell.kakuro.border div.cir1 {
324+
position: relative;
325+
left: 46%;
326+
top: 4%;
327+
}
328+
329+
.boardCell.kakuro.border div.cir2 {
330+
position: relative;
331+
bottom: 4%;
332+
left: 4%;
333+
}
334+
</style>

‎pzz-nurikabe/play/App.svelte

+16-864
Large diffs are not rendered by default.
+271
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,271 @@
1+
<script lang="ts">
2+
import { createEventDispatcher } from 'svelte';
3+
const dispatch = createEventDispatcher();
4+
5+
export let blockInteraction:boolean = false;
6+
export let boardHeight: number = 0;
7+
export let boardWidth: number = 0;
8+
type boardData = {
9+
v: string,
10+
w: boolean // confirmed wrong
11+
}
12+
let Val: boardData[][] = [[]];
13+
14+
function mainPanelClick(i: number, j : number, e:MouseEvent) {
15+
if (blockInteraction) {
16+
blockInteraction = false;
17+
return;
18+
}
19+
20+
if (Val[i][j].v == "") {
21+
Val[i][j].v = "B";
22+
} else if (Val[i][j].v == "B") {
23+
Val[i][j].v = "";
24+
}
25+
26+
dispatch("SaveState");
27+
}
28+
29+
function arrayDoubletSearch(target: any, list: any[]) {
30+
for (let i = 0; i < list.length; i++) {
31+
if ((list[i][0] == target[0]) && (list[i][1] == target[1])) {
32+
return true;
33+
}
34+
}
35+
return false;
36+
}
37+
38+
export const boardController = {
39+
getColnum(): number {
40+
return Val.length;
41+
},
42+
getRownum(): number {
43+
return Val[0].length;
44+
},
45+
cleanWrong(): void {
46+
for (let i = 0; i < Val.length; i++) {
47+
for (let j = 0; j < Val[i].length; j++) {
48+
Val[i][j].w = false;
49+
}
50+
}
51+
},
52+
initializeData(dt: any): void {
53+
Val = dt.map((e: string[]) => {
54+
return (e.map(e2 => {
55+
let a: boardData = {
56+
v: e2,
57+
w: false
58+
}
59+
return (a);
60+
}))
61+
});
62+
},
63+
resetState(dt: any): void {
64+
Val = dt.map((e: string[]) => {
65+
return (e.map(e2 => {
66+
let a: boardData = {
67+
v: e2,
68+
w: false
69+
}
70+
return (a);
71+
}));
72+
});
73+
},
74+
loadData(dt: any): void {
75+
Val = dt.map((e: string[]) => {
76+
return (e.map(e2 => {
77+
let a: boardData = {
78+
v: e2,
79+
w: false
80+
}
81+
return (a);
82+
}));
83+
});
84+
},
85+
doubleClickMouse(e: HTMLElement): void {
86+
const id = e.id.split(" ");
87+
mainPanelClick(Number(id[0]), Number(id[1]), null);
88+
},
89+
getSavingData(): any {
90+
return (Val.map(e => {
91+
return (e.map(e2 => {
92+
return e2.v;
93+
}));
94+
}));
95+
},
96+
checkAnswer(): boolean {
97+
let clear = true;
98+
99+
//--- WHITE ROOM CHECKS ---
100+
for (let i = 0; i < Val.length; i++) {
101+
for (let j = 0; j < Val[i].length; j++) {
102+
let check = parseInt(Val[i][j].v)
103+
104+
if (!isNaN(check)) {
105+
if (Val[i][j].w) {
106+
continue;
107+
}
108+
109+
let testBox = [[i, j]];
110+
let count = 0;
111+
let err = false;
112+
113+
for (let k = 0; k < testBox.length; k++) {
114+
const targetBox = testBox[k];
115+
116+
if (Val[targetBox[0]][targetBox[1]].v == "B") {
117+
testBox.splice(k, 1);
118+
k--;
119+
continue;
120+
} else {
121+
if ((Val[targetBox[0]][targetBox[1]].v != "") && (targetBox[0] != i) && (targetBox[1] != j)) {
122+
err = true;
123+
}
124+
125+
count++;
126+
if ((targetBox[0] > 0) && (!arrayDoubletSearch([targetBox[0] - 1, targetBox[1]], testBox))) {
127+
testBox.push([targetBox[0] - 1, targetBox[1]]);
128+
}
129+
if ((targetBox[0] < Val.length - 1) && (!arrayDoubletSearch([targetBox[0] + 1, targetBox[1]], testBox))) {
130+
testBox.push([targetBox[0] + 1, targetBox[1]]);
131+
}
132+
if ((targetBox[1] > 0) && (!arrayDoubletSearch([targetBox[0], targetBox[1] - 1], testBox))) {
133+
testBox.push([targetBox[0], targetBox[1] - 1]);
134+
}
135+
if ((targetBox[1] < Val[0].length - 1) && (!arrayDoubletSearch([targetBox[0], targetBox[1] + 1], testBox))) {
136+
testBox.push([targetBox[0], targetBox[1] + 1]);
137+
}
138+
}
139+
}
140+
141+
if (count != check) {
142+
err = true;
143+
}
144+
145+
if (err) {
146+
clear = false;
147+
148+
testBox.forEach(e => {
149+
Val[e[0]][e[1]].w = true;
150+
})
151+
}
152+
}
153+
}
154+
}
155+
156+
//--- CLUSTERING CHECKS ---
157+
for (let i = 0; i < Val.length - 1; i++) {
158+
for (let j = 0; j < Val[i].length - 1; j++) {
159+
if (Val[i][j].v == "B") {
160+
if ((Val[i + 1][j].v == "B") && (Val[i][j + 1].v == "B") && (Val[i + 1][j + 1].v == "B")) {
161+
Val[i][j].w = true;
162+
Val[i + 1][j].w = true;
163+
Val[i][j + 1].w = true;
164+
Val[i + 1][j + 1].w = true;
165+
clear = false;
166+
}
167+
}
168+
}
169+
}
170+
171+
//--- WALL CONTINUITY CHECKS ---
172+
let wallMap: boolean[][] = Val.map(e => {
173+
return e.map(e2 => {
174+
return e2.v != "B"
175+
})
176+
})
177+
178+
for (let i = 0; i < wallMap.length; i++) {
179+
for (let j = 0; j < wallMap[i].length; j++) {
180+
if (!wallMap[i][j]) {
181+
182+
let testBox = [[i, j]];
183+
184+
for (let k = 0; k < testBox.length; k++) {
185+
const targetBox = testBox[k];
186+
187+
if (wallMap[targetBox[0]][targetBox[1]]) {
188+
continue;
189+
} else {
190+
wallMap[targetBox[0]][targetBox[1]] = true;
191+
if ((targetBox[0] > 0) && (!arrayDoubletSearch([targetBox[0] - 1, targetBox[1]], testBox))) {
192+
testBox.push([targetBox[0] - 1, targetBox[1]]);
193+
}
194+
if ((targetBox[0] < wallMap.length - 1) && (!arrayDoubletSearch([targetBox[0] + 1, targetBox[1]], testBox))) {
195+
testBox.push([targetBox[0] + 1, targetBox[1]]);
196+
}
197+
if ((targetBox[1] > 0) && (!arrayDoubletSearch([targetBox[0], targetBox[1] - 1], testBox))) {
198+
testBox.push([targetBox[0], targetBox[1] - 1]);
199+
}
200+
if ((targetBox[1] < wallMap[0].length - 1) && (!arrayDoubletSearch([targetBox[0], targetBox[1] + 1], testBox))) {
201+
testBox.push([targetBox[0], targetBox[1] + 1]);
202+
}
203+
}
204+
}
205+
206+
for (i = 0; i < wallMap.length; i++) {
207+
for (j = 0; j < wallMap[i].length; j++) {
208+
if (!wallMap[i][j]) {
209+
for (i = 0; i < wallMap.length; i++) {
210+
for (j = 0; j < wallMap[i].length; j++) {
211+
if (Val[i][j].v == "B") {
212+
Val[i][j].w = true;
213+
}
214+
}
215+
}
216+
break;
217+
}
218+
}
219+
}
220+
221+
i = wallMap.length + 1;
222+
j = wallMap[0].length + 1;
223+
break;
224+
}
225+
}
226+
}
227+
return clear;
228+
},
229+
getCheckingData(): any {
230+
return (Val.map(e => {
231+
return (e.map(e2 => {
232+
return e2.v;
233+
}));
234+
}));
235+
}
236+
}
237+
</script>
238+
239+
<div
240+
id="mainBoard"
241+
style="
242+
display: grid;
243+
grid-template-columns: repeat({Val.length}, 1fr);
244+
grid-template-rows: repeat({Val[0].length}, 1fr);
245+
height: {boardHeight}px; width: {boardWidth}px;
246+
font-size: inherit;
247+
"
248+
>
249+
{#each Val as box, i}
250+
{#each box as e, j}
251+
<div id={i.toString() + " " + j.toString()}
252+
class="boardCell" class:empty={(e.v != "B")} class:wrong={e.w}
253+
on:click={(e) => mainPanelClick(i, j, null)}
254+
>
255+
{ (e.v != "B") ? e.v : "" }
256+
</div>
257+
{/each}
258+
{/each}
259+
</div>
260+
261+
<style>
262+
.boardCell {
263+
cursor: pointer;
264+
display: flex;
265+
justify-content: center;
266+
align-items: center;
267+
font-size: inherit;
268+
border-width: 2px;
269+
border-style: solid;
270+
}
271+
</style>

‎pzz-slitherlink/play/App.svelte

+16-1,062
Large diffs are not rendered by default.

‎pzz-slitherlink/play/boardComponent.svelte

+475
Large diffs are not rendered by default.

‎pzz-sudoku/play/App.svelte

+16-887
Large diffs are not rendered by default.

‎pzz-sudoku/play/boardComponent.svelte

+284
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,284 @@
1+
<script lang="ts">
2+
import { createEventDispatcher } from 'svelte';
3+
const dispatch = createEventDispatcher();
4+
5+
export let blockInteraction:boolean = false;
6+
export let boardHeight: number = 0;
7+
export let boardWidth: number = 0;
8+
type boardData = {
9+
v: string
10+
w: boolean // confirmed wrong
11+
f: boolean // fixed
12+
}
13+
14+
let Val: boardData[][] = [[]];
15+
$: sizeBox = Math.round(Math.sqrt(Val.length));
16+
17+
function validateInput(i: number, j: number) {
18+
let check = parseInt(Val[i][j].v);
19+
20+
if (isNaN(check)) {
21+
Val[i][j].v = "";
22+
} else if (check > sizeBox*sizeBox) {
23+
Val[i][j].v = "";
24+
} else if (check < 1) {
25+
Val[i][j].v = "";
26+
} else {
27+
Val[i][j].v = check.toString();
28+
}
29+
dispatch("SaveState");
30+
}
31+
32+
function selectAllText(e: Event) {
33+
window.getSelection().selectAllChildren((e.target as Element))
34+
}
35+
36+
function mainPanelClick(e: HTMLElement) {
37+
if (blockInteraction) {
38+
blockInteraction = false;
39+
return;
40+
}
41+
e.focus();
42+
}
43+
44+
export const boardController = {
45+
getColnum(): number {
46+
return Val.length;
47+
},
48+
getRownum(): number {
49+
return Val[0].length;
50+
},
51+
cleanWrong(): void {
52+
for (let i = 0; i < Val.length; i++) {
53+
for (let j = 0; j < Val.length; j++) {
54+
Val[i][j].w = false;
55+
}
56+
}
57+
},
58+
initializeData(dt: any): void {
59+
Val = dt.map((e: string[]) => {
60+
return (e.map(e2 => {
61+
let a: boardData = {
62+
v: e2,
63+
w: false,
64+
f: (e2 != "")
65+
}
66+
return (a);
67+
}))
68+
});
69+
},
70+
resetState(dt: any):void {
71+
Val = dt.map((e: string[]) => {
72+
return (e.map(e2 => {
73+
let a: boardData = {
74+
v: e2,
75+
w: false,
76+
f: (e2 != "")
77+
}
78+
return (a);
79+
}))
80+
});
81+
},
82+
loadData(dt: any): void {
83+
Val = dt.map((e: string[]) => {
84+
return (e.map(e2 => {
85+
let a: boardData = {
86+
v: e2,
87+
w: false,
88+
f: (e2 != "")
89+
}
90+
return (a);
91+
}))
92+
});
93+
},
94+
doubleClickMouse(e: HTMLElement): void {
95+
mainPanelClick(e);
96+
},
97+
getSavingData(): any {
98+
return (Val.map(e => {
99+
return (e.map(e2 => {
100+
return e2.v;
101+
}))
102+
}));
103+
},
104+
checkAnswer(): boolean {
105+
let clear = true;
106+
107+
// Vertical Checking
108+
for (let i = 0; i < Val.length; i++) {
109+
for (let j = 0; j < Val[i].length; j++) {
110+
if (Val[i][j].v != "") {
111+
let nOccur : number = 0;
112+
for (let k = 0; k < Val[i].length; k++) {
113+
if (Val[i][j].v == Val[i][k].v) {
114+
nOccur++;
115+
}
116+
}
117+
if (nOccur > 1) {
118+
clear = false;
119+
for (let k = 0; k < Val[i].length; k++) {
120+
if (Val[i][j].v == Val[i][k].v) {
121+
Val[i][k].w = true;
122+
nOccur--;
123+
}
124+
if (nOccur == 0) {
125+
break;
126+
}
127+
}
128+
}
129+
} else {
130+
clear = false;
131+
Val[i][j].w = true;
132+
}
133+
}
134+
}
135+
136+
// Horizontal Checking
137+
for (let i = 0; i < Val.length; i++) {
138+
for (let j = 0; j < Val[i].length; j++) {
139+
if (Val[i][j].v != "") {
140+
let nOccur : number = 0;
141+
for (let k = 0; k < Val.length; k++) {
142+
if (Val[i][j].v == Val[k][j].v) {
143+
nOccur++;
144+
}
145+
}
146+
if (nOccur > 1) {
147+
clear = false;
148+
for (let k = 0; k < Val.length; k++) {
149+
if (Val[i][j].v == Val[k][j].v) {
150+
Val[k][j].w = true;
151+
nOccur--;
152+
}
153+
if (nOccur == 0) {
154+
break;
155+
}
156+
}
157+
}
158+
} else {
159+
clear = false;
160+
Val[i][j].w = true;
161+
}
162+
}
163+
}
164+
165+
// Box checking
166+
for (let i = 0; i < Val.length; i++) {
167+
for (let j = 0; j < Val[i].length; j++) {
168+
if (Val[i][j].v != "") {
169+
let nOccur : number = 0;
170+
let xBox: number = Math.floor(i/sizeBox);
171+
let yBox: number = Math.floor(j/sizeBox);
172+
173+
for (let k = 0; k < sizeBox; k++) {
174+
for (let l = 0; l < sizeBox; l++) {
175+
if (Val[i][j].v == Val[k + xBox*sizeBox][l + yBox*sizeBox].v) {
176+
nOccur++;
177+
}
178+
}
179+
}
180+
181+
if (nOccur > 1) {
182+
clear = false;
183+
for (let k = 0; k < sizeBox; k++) {
184+
for (let l = 0; l < sizeBox; l++) {
185+
if (Val[i][j].v == Val[k + xBox*sizeBox][l + yBox*sizeBox].v) {
186+
Val[k + xBox*sizeBox][l + yBox*sizeBox].w = true;
187+
nOccur--;
188+
}
189+
if (nOccur == 0) {
190+
break;
191+
}
192+
}
193+
}
194+
}
195+
} else {
196+
clear = false;
197+
Val[i][j].w = true;
198+
}
199+
}
200+
}
201+
202+
return clear;
203+
},
204+
getCheckingData(): any {
205+
return (Val.map(e => {
206+
return (e.map(e2 => {
207+
return parseInt(e2.v);
208+
}));
209+
}));
210+
}
211+
}
212+
</script>
213+
214+
<div
215+
id="mainBoard"
216+
style="
217+
display: grid;
218+
grid-template-columns: repeat({Val.length}, 1fr);
219+
grid-template-rows: repeat({Val[0].length}, 1fr);
220+
height: {boardHeight}px; width: {boardWidth}px;
221+
font-size: inherit;
222+
"
223+
>
224+
{#each Val as box, j}
225+
{#each box as e, i}
226+
{#if e.f}
227+
<div id={i + " " + j}
228+
class="boardCell"
229+
class:oddCell={!e.w && (((Math.floor(i/sizeBox) + Math.floor(j/sizeBox)) % 2) == 1)}
230+
class:wrong={e.w}
231+
class:fix={true}
232+
class:bl={i % sizeBox == 0} class:br={(i + 1) % sizeBox == 0}
233+
class:bt={j % sizeBox == 0} class:bb={(j + 1) % sizeBox == 0}
234+
>
235+
{e.v}
236+
</div>
237+
{:else}
238+
<div id={i + " " + j}
239+
class="boardCell empty"
240+
class:oddCell={!e.w && (((Math.floor(i/sizeBox) + Math.floor(j/sizeBox)) % 2) == 1)}
241+
class:wrong={e.w}
242+
class:bl={i % sizeBox == 0} class:br={(i + 1) % sizeBox == 0}
243+
class:bt={j % sizeBox == 0} class:bb={(j + 1) % sizeBox == 0}
244+
on:focusout={() => {validateInput(j, i)}}
245+
on:focusin={(e2) => {selectAllText(e2)}}
246+
contenteditable = "true"
247+
bind:innerHTML={e.v}
248+
></div>
249+
{/if}
250+
{/each}
251+
{/each}
252+
</div>
253+
254+
<style>
255+
.boardCell {
256+
cursor: pointer;
257+
display: flex;
258+
justify-content: center;
259+
align-items: center;
260+
font-size: inherit;
261+
border-width: 2px;
262+
border-style: solid;
263+
}
264+
265+
.bl {
266+
border-left-width: 5px;
267+
border-left-style: solid;
268+
}
269+
270+
.br {
271+
border-right-width: 5px;
272+
border-right-style: solid;
273+
}
274+
275+
.bt {
276+
border-top-width: 5px;
277+
border-top-style: solid;
278+
}
279+
280+
.bb {
281+
border-bottom-width: 5px;
282+
border-bottom-style: solid;
283+
}
284+
</style>

‎util/pagePlayTemplate.svelte

+654
Large diffs are not rendered by default.

0 commit comments

Comments
 (0)
Please sign in to comment.