Skip to content

Commit 2706eed

Browse files
author
Simon he
committed
⚡️ feature: add no matching function
1 parent b9e6e19 commit 2706eed

File tree

4 files changed

+158
-86
lines changed

4 files changed

+158
-86
lines changed

src/components/MatchingPicture.vue

Lines changed: 9 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
<script setup lang="ts">
22
import { arrayPic, emptyFlag, ratio, loading, height, n } from "../config";
3-
import { reset } from "../pic";
3+
import { reset, bfs, noMatching } from "../pic";
44
import { Block } from "../type";
55
import { baseImage } from "../request";
66
const pre = ref<Block>({});
77
function match(block: Block) {
8+
noMatching();
89
if (block.url === emptyFlag) return;
910
if (pre.value === block) {
1011
pre.value.animate = false;
@@ -29,9 +30,13 @@ function match(block: Block) {
2930
_pre.disappear = false;
3031
if (isWin()) {
3132
setTimeout(() => {
32-
alert("You Win!");
3333
baseImage();
34-
});
34+
alert("You Win!");
35+
}, 100);
36+
} else if (noMatching()) {
37+
setTimeout(() => {
38+
alert("You Lose! no matching");
39+
}, 100);
3540
}
3641
}, 200);
3742
}
@@ -41,76 +46,7 @@ function match(block: Block) {
4146
}
4247
4348
function canEliminate(block: Block) {
44-
return bfs(block, pre.value) || bfs(pre.value, block);
45-
}
46-
47-
function bfs(block, target, path = new Set()) {
48-
const copyArray = JSON.parse(JSON.stringify(arrayPic.value));
49-
const queue = [block];
50-
while (queue.length) {
51-
const cur = queue.shift();
52-
const y = cur.y;
53-
const x = cur.x;
54-
// 处理边界
55-
if (y > 0) {
56-
const top = copyArray[y - 1][x];
57-
const types: string[] = JSON.parse(JSON.stringify(cur.types || []));
58-
top.types = types ? ["down", ...types] : ["down"];
59-
if (preReturn(top)) {
60-
if (top.pos === target.pos) {
61-
console.log("find", top);
62-
return true;
63-
}
64-
if (top.url === emptyFlag) {
65-
queue.push(top);
66-
}
67-
}
68-
}
69-
if (y < copyArray.length - 1) {
70-
const bottom = copyArray[y + 1][x];
71-
const types: string[] = JSON.parse(JSON.stringify(cur.types || []));
72-
bottom.types = types ? ["up", ...types] : ["up"];
73-
if (preReturn(bottom)) {
74-
if (bottom.pos === target.pos) {
75-
console.log("find", bottom);
76-
return true;
77-
}
78-
if (bottom.url === emptyFlag) {
79-
queue.push(bottom);
80-
}
81-
}
82-
}
83-
if (x > 0) {
84-
const left = copyArray[y][x - 1];
85-
const types: string[] = JSON.parse(JSON.stringify(cur.types || []));
86-
left.types = types ? ["right", ...types] : ["right"];
87-
if (preReturn(left)) {
88-
if (left.pos === target.pos) {
89-
console.log("find", left);
90-
return true;
91-
}
92-
if (left.url === emptyFlag) {
93-
queue.push(left);
94-
}
95-
}
96-
}
97-
if (x < copyArray[0].length - 1) {
98-
const right = copyArray[y][x + 1];
99-
const types: string[] = JSON.parse(JSON.stringify(cur.types || []));
100-
right.types = types ? ["left", ...types] : ["left"];
101-
102-
if (preReturn(right)) {
103-
if (right.pos === target.pos) {
104-
console.log("find", right);
105-
return true;
106-
}
107-
if (right.url === emptyFlag) {
108-
queue.push(right);
109-
}
110-
}
111-
}
112-
}
113-
return false;
49+
return bfs(block, pre.value);
11450
}
11551
11652
function preReturn(block) {

src/pic.ts

Lines changed: 146 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { emptyFlag, arrayPic } from './config';
1+
import { emptyFlag, arrayPic, loading } from './config';
22
import type { Block } from './type';
33

44
const pictureMap = new Map<string, any>()
@@ -27,7 +27,6 @@ async function generateImage(image: any, n: number) {
2727
const ctx = canvas.getContext("2d")!;
2828
const w = image.width / n;
2929
const h = image.height / n;
30-
let count = 0
3130
const cacheUrl = new Map<string, string>()
3231
for (let j = 0; j <= 2 * n + 1; j++) {
3332
const col = [];
@@ -59,7 +58,9 @@ async function generateImage(image: any, n: number) {
5958
url,
6059
x: i,
6160
y: j,
62-
pos: ++count
61+
pos: j > n
62+
? i - 1 + (j - n - 1) * n
63+
: i - 1 + (j - 1) * n
6364
};
6465

6566
numbers.push(JSON.parse(JSON.stringify(block)))
@@ -114,45 +115,178 @@ function randomPic(numbers: any[]) {
114115
return result
115116
}
116117
export async function initData(n: number, src: string) {
117-
const { result: arrayPic, numbers } = await splitImage(n, src) as any
118+
const { result: array, numbers } = await splitImage(n, src) as any
118119
const copyNumbers = JSON.parse(JSON.stringify(numbers))
119-
const copyArrayPic = JSON.parse(JSON.stringify(arrayPic))
120+
const copyArrayPic = JSON.parse(JSON.stringify(array))
121+
let targetMap: Record<number, any> | null = {}
120122

121-
for (let i = 1; i < arrayPic.length - 1; i++) {
122-
for (let j = 1; j < arrayPic[i].length - 1; j++) {
123+
for (let i = 1; i < array.length - 1; i++) {
124+
for (let j = 1; j < array[i].length - 1; j++) {
123125
const { url, pos, } = randomPic(copyNumbers)
126+
if (targetMap[pos] === undefined) {
127+
targetMap[pos] = copyArrayPic[i][j]
128+
} else {
129+
copyArrayPic[i][j].target = targetMap[pos]
130+
}
124131
copyArrayPic[i][j].url = url
125132
copyArrayPic[i][j].pos = pos
126133
}
127134
}
128-
return copyArrayPic
135+
targetMap = null
136+
arrayPic.value = copyArrayPic
137+
if (noMatching()) {
138+
reset()
139+
}
129140
}
130141

131142
export function reset() {
143+
loading.value = true
132144
const numbers: any[] = []
133145
const copyArrayPic: Array<Block[]> = JSON.parse(JSON.stringify(arrayPic.value))
146+
let targetMap: Record<number, any> | null = {}
134147

135-
console.log(arrayPic.value)
136148
arrayPic.value.forEach(row => {
137149
row.forEach(block => {
138150
if (block.url !== emptyFlag) {
139151
numbers.push(block)
140152
}
141153
})
142154
})
143-
copyArrayPic.forEach(row => {
144-
row.forEach(block => {
155+
copyArrayPic.forEach((row, i) => {
156+
row.forEach((block, j) => {
145157
if (block.url !== emptyFlag) {
146158
const { url, pos } = randomPic(numbers)
159+
delete block.target
160+
if (targetMap![pos] === undefined) {
161+
targetMap![pos] = copyArrayPic[i][j]
162+
} else {
163+
block.target = targetMap![pos]
164+
}
147165
block.url = url
148166
block.pos = pos
149167
}
150168
})
151169
})
152-
console.log(copyArrayPic)
153170
arrayPic.value = copyArrayPic
171+
if (noMatching()) {
172+
reset()
173+
} else {
174+
loading.value = false
175+
}
154176
}
155177

156178

179+
export function noMatching() {
180+
// 判断是否无解了
181+
const array: Block[] = []
182+
arrayPic.value.forEach((row) => {
183+
row.forEach((block) => {
184+
if (block.target && block.url !== emptyFlag) {
185+
array.push(block)
186+
}
187+
})
188+
});
189+
const result = array.every(block => !bfs(block, block.target!))
190+
console.log(result)
191+
return result
192+
}
157193

158194

195+
function preReturn(block: Block | null) {
196+
if (!block) {
197+
return false
198+
}
199+
let count = 0;
200+
let pre = null,
201+
cur = null;
202+
if (block.types!.length < 4) {
203+
return true;
204+
}
205+
206+
for (let i = 1; i < block.types!.length; i++) {
207+
cur = block.types![i];
208+
pre = block.types![i - 1];
209+
if (pre !== cur) {
210+
count++;
211+
}
212+
if (count > 2) {
213+
return false;
214+
}
215+
}
216+
return true;
217+
}
218+
219+
220+
function sameBlock(block: Block, target: Block) {
221+
return block.pos === target.pos && block.x === target.x && block.y === target.y
222+
}
223+
224+
export function bfs(block: Block, target: Block, map = new Set) {
225+
const queue = [block];
226+
const maxHeight = arrayPic.value[0].length - 1
227+
const maxWidth = arrayPic.value.length - 1
228+
while (queue.length) {
229+
const cur: Block = queue.shift()!;
230+
if (map.has(cur)) {
231+
continue
232+
}
233+
map.add(cur)
234+
const y = cur.y;
235+
const x = cur.x;
236+
const types: string[] = cur.types || []
237+
const top = y > 0 ? JSON.parse(JSON.stringify(arrayPic.value[y - 1][x])) : null
238+
const bottom = y < maxWidth ? JSON.parse(JSON.stringify(arrayPic.value[y + 1][x])) : null
239+
const left = x > 0 ? JSON.parse(JSON.stringify(arrayPic.value[y][x - 1])) : null
240+
const right = x < maxHeight ? JSON.parse(JSON.stringify(arrayPic.value[y][x + 1])) : null
241+
pushTypes(top, types, 'down')
242+
pushTypes(bottom, types, 'up')
243+
pushTypes(left, types, 'right')
244+
pushTypes(right, types, 'left')
245+
246+
// 处理边界
247+
if (preReturn(top) && (block.x !== target.x || block.y > target.y)) {
248+
if (sameBlock(top, target)) {
249+
console.log("find", top);
250+
return true;
251+
}
252+
if (top.url === emptyFlag) {
253+
queue.push(top);
254+
}
255+
}
256+
if (preReturn(bottom) && (block.x !== target.x || block.y < target.y)) {
257+
if (sameBlock(bottom, target)) {
258+
console.log("find", bottom);
259+
return true;
260+
}
261+
if (bottom.url === emptyFlag) {
262+
queue.push(bottom);
263+
}
264+
}
265+
if (preReturn(left) && (block.y !== target.y || block.x > target.x)) {
266+
if (sameBlock(left, target)) {
267+
console.log("find", left);
268+
return true;
269+
}
270+
if (left.url === emptyFlag) {
271+
queue.push(left);
272+
}
273+
274+
}
275+
if (preReturn(right) && (block.y !== target.y || block.x < target.x)) {
276+
if (sameBlock(right, target)) {
277+
console.log("find", right);
278+
return true;
279+
}
280+
if (right.url === emptyFlag) {
281+
queue.push(right);
282+
}
283+
}
284+
}
285+
return false;
286+
}
287+
288+
function pushTypes(block: Block | null, types: string[], type: string) {
289+
if (!block)
290+
return
291+
block.types = types ? [type, ...types] : [type];
292+
}

src/request.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ function picIndex(): number {
5050

5151
async function dealPicture(baseUrl: string, resolve: any) {
5252
base64.value = baseUrl
53-
arrayPic.value = await initData(n.value, base64.value);
53+
await initData(n.value, base64.value);
5454
const image = new Image();
5555
image.src = base64.value;
5656
image.onload = () => {

src/type.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,6 @@ export type Block = {
55
animate: boolean | undefined
66
disappear: boolean | undefined
77
url: string,
8+
target?: Block
9+
types: string[]
810
}

0 commit comments

Comments
 (0)