forked from CmdBlockZQG/cbjq
-
Notifications
You must be signed in to change notification settings - Fork 3
/
index.html
793 lines (730 loc) · 31 KB
/
index.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>尘白禁区信源研析</title>
<script src="https://cdn.bootcdn.net/ajax/libs/vue/3.2.47/vue.global.prod.min.js"></script>
<script src="./calc.js"></script>
</head>
<body>
<div>
原作者:<a href="https://space.bilibili.com/277401945" target="_blank">Bilibili 方形的块状代码</a>
此分支GitHub:<a href="https://github.com/halozhy/cbjq" target="_blank">halozhy/cbjq</a>
</div>
<div id="app">
<div>
<!-- <input type="button" value="更新日志" @click="confirmBoard"> -->
<button v-if="cache" @click="changeCacheState(false)">缓存状态:开</button>
<button v-else @click="changeCacheState(true)">缓存状态:关</button>
<button style="margin-left: 5px;" @click="changeCacheHelpDialogVisible(true)">❓</button>
<dialog id="cacheHelpDialog" ref="cacheHelpDialog">
<div id="cacheHelpDialogDiv" style="padding: -20px;">
<p>【测试性功能】</p>
<p>遇到 bug 可以带上出错的情况于 <a href="https://github.com/halozhy/cbjq" target="_blank">GitHub 分支仓库</a> 或 <a href="https://www.bilibili.com/video/BV1hp4y1j75k/" target="_blank">BV1hp4y1j75k</a> 反馈</p>
<hr>
<p>(点击缓存状态按钮即可改变缓存状态)</p>
<p>
缓存状态为“开”时,当页面刷新,关闭或可见性被改变后,程序会将<b>页面数据</b>保存在浏览器的 LocalStorage 中
</p>
<p>
<b>页面数据主要包含:格子行列数据,各个方块个数,回收个数,但不包含计算得到的方案</b>(因为方案种类可能很多,以至于 LocalStorage 存不下)
</p>
<p>
如果需要清除缓存数据,请将缓存状态改为“关”,即可清除
</p>
</div>
<div style="text-align: center;">
<button @click="changeCacheHelpDialogVisible(false)">确认</button>
</div>
</dialog>
</div>
<p>行数:<input type="text" v-model="row" /></p>
<p>列数:<input type="text" v-model="col" /></p>
<input type="button" value="确定" @click="confirmBoard">
<p>红色表示需要摆放的格子,白色表示这里没有格子,点击切换</p>
<div v-for="(r, i) in board" style="height: 32px;">
<div
class="box"
v-for="(c, j) in r"
@click="tuneBox(i, j)"
:style="{ 'background-color': c === 0 ? 'white' : 'red' }"
></div>
</div>
<div v-if="board.length" style="margin-top: 0px;">
<div style="width:fit-content;">
<table>
<tr>
<th></th>
<th>
<div style="margin-left: 0px;">
必选
</div>
</th>
<th>
<div style="margin-left: 0px;">
回收
</div>
</th>
<th>
<div style="margin-left: 0px;">
回收个数
</div>
</th>
<th>
<div style="margin-left: 0px;">
取消回收
</div>
</th>
</tr>
<tr v-for="(b, i) in num">
<td>
方块{{ i + 1 }}个数:
<div v-if="i+1 === 9" style="display: inline-block;">
{{ num[i] + recycledComponents.length}} =
<input style="width: 100px;" type="text" v-model.number="num[i]" />
+ {{ recycledComponents.length }}
</div>
<div v-else style="display: inline; float: right;">
<input type="text" v-model.number="num[i]" />
</div>
</td>
<td style=" zoom: 100%; vertical-align: middle; margin-top: 80px; text-align: center;">
<input type="checkbox"
style="text-align: left; vertical-align: middle; margin-top: 5px;"
v-model="selected[i]"
:title="'信源 ' + (i+1) + ' 必选'"
@click="select(i)"/>
</td>
<td>
<Button type="" @click="recycle(i)">🗑️</Button>
</td>
<td style="vertical-align: middle; text-align: center;">
{{ recycledNum[i] }}
</td>
<td style="text-align: center;">
<Button type="" @click="cancelRecycle(i)">🗑️-1</Button>
</td>
</tr>
</table>
<div
style="margin-top: 5px;
margin-bottom: 5px;
margin-right: 10px;
border: dashed 2px;
border-radius: 10px;
padding: 5px;
">
<div style="font-size: medium;">
方块9个数=用户输入 {{ num[8] }} + 回收得到 {{ recycledComponents.length }} <br>
</div>
<div style="margin-top: 7px; margin-bottom: 5px;">
回收的方块9构成:
</div>
<div v-for="(v, i) in recycledComponents">
<div style="display:inline-block;" v-for="(v2, j) in recycledComponents[i]">
方块 {{v2}},
</div>
<br>
<hr />
</div>
</div>
<!-- <div
style="margin-top: 5px;
margin-bottom: 5px;
margin-right: 10px;
border: dashed 2px;
border-radius: 10px;
padding: 5px;
">
<p>【2023-09-24注】目前对于方块 10 和 11 的支持仅经过了简单测试</p>
<p>如果遇到关于方块 10 和 11 的 bug 可以带上出错的情况给我的 <a href="https://github.com/halozhy/cbjq">GitHub 分支仓库</a> 提 Issue</p>
<p>(或者在 <a href="https://www.bilibili.com/video/BV1hp4y1j75k/">BV1hp4y1j75k</a> 这个视频下面评论区带上出错的情况留言)</p>
</div> -->
<div>
<input type="button" value="计算完美方案" @click="calc">
<!-- <input type="button" value="按照此结果扣除对应方块" @click="calcFull" style="margin-left: 10px;" > -->
<input type="button" style="margin-left: 10px;" value="一键回收并计算" @click="calcFull">
<input type="button" style="margin-right: 10px; float: right;" value="撤销所有回收" ref="resetRecycleBtn" @click="resetRecycle" disabled>
</div>
</div>
</div>
<div v-if="res !== false">
<p>方案数:{{ res.length }}</p>
<p>方案数(filterd):{{ selectResult.length }}/{{ res.length }}</p>
</div>
<div v-if="res.length">
<p>当前展示方案:{{ now + 1 }} / {{ res.length }}</p>
<p>当前展示方案(filterd):{{ now + 1 }} / {{ selectResult.length }}</p>
<input type="button" value="<-" @click="now -= (now > 0)">
<input type="button" value="->" @click="now += (now + 1 < selectResult.length)">
<div v-for="(r, i) in sol" style="height: 32px;">
<div
class="box"
v-for="(c, j) in r"
:style="{ 'background-color': color[c] }"
>{{ c }}</div>
</div>
<div>
<input type="button" value="按照此结果扣除对应方块" ref="decreaseBtn" @click="decreaseBlock" >
<input type="button" value="撤销此次扣除" ref="resetDecreaseBtn" style="margin-left: 10px;" @click="resetBlock" disabled>
</div>
</div>
</div>
<script>
const { createApp } = Vue
createApp({
data() {
return {
row: 5,
col: 6,
board: [],
// board: [[-1, -1, 0, 0], [-1, -1, -1, -1]],
num: new Array(11).fill(0),
// num: [6,3,8,9,9,5,5,0,1,0,0],
// num: [0,2,2,2,2,2,1,1,1,0,0],
// num: [2,2,2,2,2,2,2,1,0,0,0],
// num: [1,1,1,2,2,2,2,1,0,0,0],
// num: [6,1,1,2,2,2,2,1,1,1,1],
// num: [2,2,2,2,2,0,0,0,0,0,0],
numBackup: new Array(11).fill(0),
solBackup: new Array(11).fill(0),
recycledNum: new Array(11).fill(0),
recycledComponents: new Array(0),
recycledComponentsBackup: new Array(0),
// isDecreased: false, // 表示有没有点击过“按照此结果扣除对应方块”按钮
selected: new Array(11).fill(false),
res: false,
selectResult: false,
now: 0,
cache: false,
canCloseCacheHelpDialog: true,
color: ['white', '#75C0FF', '#3B66CF', '#78ACC5', '#C8FAFD', '#FDFF00', '#4BFF00', '#FF9800', '#B9B24B', '#FF00AE', '#8A2BE2', '#FF00FF']
}
},
// watch: {
// recycledNum:{
// handler(newVal, oldVal) {
// // console.log(newVal);
// },
// deep: true
// }
// },
methods: {
confirmBoard() {
const row = Number(this.row)
const col = Number(this.col)
this.board = new Array(row)
for (let i = 0; i < row; ++i) {
const r = new Array(col).fill(-1)
this.board[i] = r
}
},
tuneBox(x, y) {
if (this.board[x][y] === -1) {
this.board[x][y] = 0
} else {
this.board[x][y] = -1
}
},
calc() {
let num = Object.assign([], this.num)
num[8] = this.num[8] + this.recycledComponents.length
this.res = Solve(this.board, num)
this.now = 0
this.filter();
// await nextTick()
if (this.res.length > 0) {
// 重置撤销前备份
this.solBackup = []
this.recycledComponentsBackup = []
// 重置扣除相关的两个按钮的状态
if (this.$refs.decreaseBtn != undefined) {
this.$refs.decreaseBtn.disabled = false
this.$refs.resetDecreaseBtn.disabled = true
}
}
},
filter(requiredInfoIds) {
// console.log('in filter');
if(!this.res){
return;
}
if(!requiredInfoIds){
requiredInfoIds = this.selected.map((v,i)=>v?i+1:-1).filter(v => v !== -1);
}
// console.log("filter array:",requiredInfoIds);
if(requiredInfoIds.length == 0){
this.selectResult = this.res;
return;
}
this.selectResult = this.res.filter(function(result){
let temp = [].concat(...result);
let cnt = 0;
for(let i=0;i<requiredInfoIds.length;++i){
if(!temp.includes(requiredInfoIds[i])){
return false;
}
}
return true;
});
},
select(index) {
// console.log('select');
let requiredInfoIds = new Array();
this.selected.forEach((isSelect, i) => {
if(isSelect && i!=index || !isSelect && i==index){
requiredInfoIds.push(i+1);
}
});
this.filter(requiredInfoIds);
},
// 返回能够回收到的最多的9号断片的回收方案
find9Max(recycledNum) {
// 其实就是找出所有的回收方案,之后从里面找一个最长的
let allPathArr = this.find9All(recycledNum);
let max = 0
let maxPathArr = [];
allPathArr.forEach(onePath => {
if (onePath.length > max) {
max = onePath.length;
maxPathArr = onePath;
}
});
return maxPathArr;
},
// 返回所有9号断片的回收方案
find9All(recycledNum) {
let num = Object.assign([], recycledNum);
let allPathArr = [];
// 计算组合数 C(9,5) 结果应该是固定的126种可能
let chooseResult = choose(Array.from({length:9}, (v,k) => k), 5);
// https://juejin.cn/post/6959102042279247909
function choose(arr, size) {
var allResult = [];
(function (arr, size, result) {
var arrLen = arr.length;
if (size > arrLen) {
return;
}
if (size == arrLen) {
allResult.push([].concat(result, arr))
} else {
for (var i = 0; i < arrLen; i++) {
var newResult = [].concat(result);
newResult.push(arr[i]);
if (size == 1) {
allResult.push(newResult);
} else {
var newArr = [].concat(arr);
newArr.splice(0, i + 1);
arguments.callee(newArr, size - 1, newResult);
}
}
}
})(arr, size, []);
return allResult;
}
// 递归查找
recursionFind(num, [], 0);
/**
* 进行递归凑数查找9号碎片的函数
* @param {*} nowRecycleNum 可回收的num数组
* @param {*} pathArr 记录了回收结果的数组,也相当于是递归路径
* @param {*} layer 递归层数
*/
function recursionFind(nowRecycleNum, pathArr, layer) {
// 如果回收方案超过1000种,就停止递归,否则会太容易因计算量过大而卡死崩溃
if (allPathArr.length >= 1000) {
return
}
layer++;
let okResultList = [];
for (let i = 0; i < chooseResult.length; i++) {
const result = chooseResult[i];
// console.log(result);
let flag = true;
for (let j = 0; j < result.length; j++) {
const index = result[j];
if (nowRecycleNum[index] <= 0 ) {
// console.log('存在0,无法回收');
flag = false;
break;
}
}
if (flag) {
// 记录下来能回收的可能性
okResultList.push(result);
// break;
}
}
// console.log('这层的所有方案数量', layer, okResultList.length);
if (okResultList.length == 0) {
// 这层已经找不到方案了,因此return结束此层递归
return;
}
else {
// 这层仍有方案,则记录在allPathArr里面
for (let index = 0; index < okResultList.length; index++) {
const thisPath = okResultList[index];
// let newOne = [pathArr , thisPath];
let newOne = [].concat(pathArr);
newOne.push(thisPath);
allPathArr.push(newOne)
}
// console.log(allPathArr);
}
// console.log('okResultList', layer, okResultList, pathArr);
for (let i = 0; i < okResultList.length; i++) {
const okResult = okResultList[i];
// 按照方案对nowRecycleNum执行删减
let nRN = [].concat(nowRecycleNum);
okResult.forEach(index => {
nRN[index]--;
});
let pa = JSON.parse(JSON.stringify(pathArr));
pa.push(okResult)
recursionFind(nRN, pa, layer);
}
}
return allPathArr;
},
calcFull() {
// 一键回收并计算
// 先尝试不回收,直接计算,如果能出结果就不进行回收
// 如果不能出结果,计算出所有的9号回收方案,依次尝试,直到出结果为止
// 如果均尝试过了,但没结果,则认为无解
// 先尝试不回收,直接计算,若有结果,直接return结束
this.calc();
if (this.selectResult.length > 0 ) {
return;
}
else {
// 如果不能直接出结果,计算出所有的9号回收方案
let allPathArr = this.find9All(this.num);
// 依次尝试,直到calc计算后有结果为止
for (let index = 0; index < allPathArr.length; index++) {
const onePath = allPathArr[index];
// 按照这个方案进行回收
for (let j = 0; j < onePath.length; j++) {
const one9 = onePath[j];
one9.forEach(index => {
// 执行num--和recycle++
this.num[index]--;
this.recycledNum[index]++;
});
// 对界面上的回收区进行更新
let one9ForView = one9.map((i)=>(i+1));
this.recycledComponents.push(one9ForView);
}
// 执行calc计算,看看有没有结果
this.calc();
if (this.selectResult.length > 0 ) {
// 有结果了,return结束
return;
}
else {
// 无结果,恢复num,recycleNum,recycledComponents
for (let j = 0; j < onePath.length; j++) {
const one9 = onePath[j];
one9.forEach(index => {
// 执行num++和recycle--
this.num[index]++;
this.recycledNum[index]--;
});
}
this.recycledComponents = [];
}
}
}
},
// resetRecycle() {
// for (let index = 0; index < this.recycledNum.length; index++) {
// const value = this.recycledNum[index];
// while (this.recycledNum[index] > 0 ){
// this.cancelRecycle(index)
// }
// }
// this.calc()
// },
// 撤销所有回收
resetRecycle(){
for (let index = 0; index < this.recycledNum.length; index++) {
const value = this.recycledNum[index];
if (this.recycledNum[index] > 0 ){
this.num[index] = this.num[index] + this.recycledNum[index];
this.recycledNum[index] = 0;
}
}
this.recycledComponents = []
// this.calc()
},
// 对index号方块进行回收
recycle(index) {
if (this.num[index] > 0 ){
this.num[index] = this.num[index] - 1;
this.recycledNum[index] = this.recycledNum[index] + 1;
}
this.calcAfterRecycle();
},
// 对index号方块取消回收
cancelRecycle(index) {
if (this.recycledNum[index] > 0 ){
this.num[index] = this.num[index] + 1;
this.recycledNum[index] = this.recycledNum[index] - 1;
}
this.calcAfterRecycle();
},
// 回收或取消回收后都会调用的一个函数
calcAfterRecycle(){
// 算出回收区中能凑出的最大9号数量方案maxPathArr
let maxPathArr = this.find9Max(this.recycledNum);
let max = maxPathArr.length;
// 制作this.recycledComponents,目的是将各个9号碎片的回收组成显示出来
this.recycledComponents = [];
maxPathArr.forEach(path => {
path = path.map((i)=>(i+1));
this.recycledComponents.push(path);
});
},
// 打开缓存状态的帮助对话框
changeCacheHelpDialogVisible(param) {
const dialog = this.$refs.cacheHelpDialog
dialog.showModal()
let that = this
// let canCloseCacheHelpDialog = true
function dialogClickCallback() {
// console.log("in dialogClickCallback", that.canCloseCacheHelpDialog);
if (that.canCloseCacheHelpDialog == false) {
// console.log('不关闭modal,并重置状态量');
that.canCloseCacheHelpDialog = true
}
else{
// console.log('正常关闭modal,并移除监听器');
dialog.close()
document.querySelector("#cacheHelpDialog").removeEventListener('click', dialogClickCallback);
document.querySelector("#cacheHelpDialogDiv").removeEventListener('click', dialogDivClickCallback);
}
}
function dialogDivClickCallback(){
// console.log('不能关闭modal,不能移除监听器');
that.canCloseCacheHelpDialog = false
}
if(param == false){
// this.canCloseCacheHelpDialog = true
dialogClickCallback()
return
}
else{
document.querySelector("#cacheHelpDialog").addEventListener('click', dialogClickCallback);
document.querySelector("#cacheHelpDialogDiv").addEventListener('click', dialogDivClickCallback);
}
},
// closeCacheHelpDialog(){
// const dialog = this.$refs.cacheHelpDialog
// dialog.close()
// document.querySelector("#cacheHelpDialog").onclick = null
// document.querySelector("#cacheHelpDialogDiv").onclick = null
// // document.querySelector("#cacheHelpDialog").removeEventListener('click', dialogClickCallback);
// // document.querySelector("#cacheHelpDialogDiv").removeEventListener('click', dialogDivClickCallback);
// },
// 保存数据到本地localStorage
saveData(){
if(this.cache === true) {
// deep copy
const data = {...this._.data}
delete data["res"]
delete data["selectResult"]
localStorage.setItem('data', JSON.stringify(data))
}
},
// 改变缓存状态
changeCacheState(param) {
if (param === true) {
this.cache = true
this.saveData()
}
else if(param === false){
let result = window.confirm("这会清空本地缓存的数据(当前页面上的内容按下确认后不会丢失),请确认")
if (result){
this.cache = false
localStorage.removeItem('data')
}
}
},
// 按照当前方案扣除对应方块
decreaseBlock() {
// arr[index] 代表第index号方块占的格子数,这个是固定值
arr = [4,4,4,4,4,4,4,5,1,2,3]
// arr_num[index] 代表当前方案下,第index号方块的所占的格子的个数
arr_num = new Array(11).fill(0)
// 得出每个方块的个数
for (let index = 0; index < this.sol.length; index++) {
const element = this.sol[index];
for (let j = 0; j < element.length; j++) {
const value = element[j];
arr_num[value-1]++;
}
}
// sol_num[index] 代表当前方案下,第index号方块的个数
sol_num = new Array(11).fill(0)
for (let index = 0; index < arr_num.length; index++) {
sol_num[index] = arr_num[index]/arr[index]
}
// console.log(sol_num);
// 由于结果算出来之后,num区域仍然是可编辑的
// 用户可能在此期间增加或减少了某个方块的数量,所以还是要验证一下能不能按照此方案扣除
flag = true
for (let index = 0; index < sol_num.length; index++) {
const sol_one_num = sol_num[index];
let my_one_num = this.num[index];
if (index+1 === 9) {
// 特殊处理9号方块
my_one_num = my_one_num + this.recycledComponents.length
}
if (my_one_num < sol_one_num) {
alert(`目前的方块 ${index+1} 个数为 ${my_one_num},小于此方案要求的 ${sol_one_num} 个,无法执行扣除`)
flag = false
break
}
}
if (!flag) {
return
}
// 当前的sol_num数组备份到solBackup里面
this.solBackup = [].concat(sol_num)
// this.numBackup = [].concat(this.num)
// 遍历sol_num,得到当前方案下,每个方块的数量,并对num数组执行减去操作
for (let index = 0; index < sol_num.length; index++) {
let one_num = sol_num[index]
// console.log(index+1, one_num);
if (this.num[index] > 0) {
if (index+1 === 9 && this.num[index] < one_num) {
// 如果是9号方块,而且自己的9号少于需要的9号
// 说明自己填入的9号数量不够,为了不被减法减为负数,直接赋0
this.num[index] = 0
// 也说明此时需要备份 recycledComponents 回收方案数组
// 当前的recycledComponents数组备份到recycledComponentsBackup里面
this.recycledComponentsBackup = [].concat(this.recycledComponents)
// 按照recycledComponents数组,扣除回收区recycledNum里的内容
for (let index = 0; index < this.recycledComponents.length; index++) {
const component_arr = this.recycledComponents[index];
// console.log(element);
for (let j = 0; j < component_arr.length; j++) {
let component_index = component_arr[j];
// 数组里面读出来的index是用于显示的,已经加过1了,此处要减1再用
component_index--;
if (this.recycledNum[component_index] > 0) {
this.recycledNum[component_index]--
}
}
}
this.recycledComponents = []
}
else{
this.num[index] = this.num[index] - one_num
this.recycledComponentsBackup = []
}
}
}
this.$refs.decreaseBtn.disabled = true
this.$refs.resetDecreaseBtn.disabled = false
},
// 撤销此次方块扣除
resetBlock(){
// 根据solBackup恢复num,用户输入区
for (let index = 0; index < this.num.length; index++) {
if (index+1 === 9 && this.recycledComponentsBackup.length > 0) {
// 如果是9号方块,而且的备份回收方案数组大于0
// 说明之前用户填入的9号数量是不够的,不能简单粗暴直接把结果需要的9号数量都加回到num上面
// 而是先算出用户之前填入的9号数量,这个数量 = 结果中需要的9号数量 - 回收得到的9号数量
const user9Num = this.solBackup[index] - this.recycledComponentsBackup.length
// 之后把用户填入的9号数量加回到num数组上
this.num[index] = this.num[index] + user9Num
// 也说明此时需要恢复 recycledComponents 回收方案数组和 recycledNum 回收区
// 根据this.recycledComponentsBackup恢复回收方案数组recycledComponents
for (let index = 0; index < this.recycledComponentsBackup.length; index++) {
const component_arr = this.recycledComponentsBackup[index]
this.recycledComponents.push(component_arr)
}
// 根据this.recycledComponentsBackup恢复回收区recycledNum
for (let index = 0; index < this.recycledComponentsBackup.length; index++) {
const component_arr = this.recycledComponentsBackup[index];
// console.log(element);
for (let j = 0; j < component_arr.length; j++) {
let component_index = component_arr[j];
component_index--;
this.recycledNum[component_index]++
}
}
}
else{
this.num[index] = this.num[index] + this.solBackup[index]
}
}
this.$refs.decreaseBtn.disabled = false
this.$refs.resetDecreaseBtn.disabled = true
}
},
computed: {
sol() {
return this.selectResult[this.now]
}
},
mounted(){
console.log('on mounted');
// 读取本地数据,看看有没有存储的数据,如果有,则恢复
let storeData = JSON.parse(localStorage.getItem('data'))
console.log('read', storeData);
if (storeData!=null && storeData.cache === true) {
let vueData = this._.data
// console.log(vueData)
for (const key in vueData) {
if (Object.hasOwnProperty.call(vueData, key)) {
const value = vueData[key];
// console.log(key, value);
if (Object.hasOwnProperty.call(storeData, key)) {
this[key] = storeData[key]
}
}
}
}
// 对recycledNum回收区启动监听,如果回收区里面都是0,使得“撤销所有回收”按钮变为灰色
this.$watch('recycledNum', (newVal, oldVal) => {
this.$refs.resetRecycleBtn.disabled = true
for (let index = 0; index < newVal.length; index++) {
const element = newVal[index];
if (element > 0) {
this.$refs.resetRecycleBtn.disabled = false
break
}
}
}, {deep:true})
// 监听页面的可见性变化和刷新事件,发生这些事件则及时保存数据至本地
document.addEventListener('visibilitychange', () => {
this.saveData()
})
window.addEventListener('beforeunload', () => {
this.saveData()
})
},
beforeunmounted(){
// this.saveData()
},
}).mount('#app')
</script>
<style>
p {
margin: 4px 0;
}
.box {
display: inline-block;
box-sizing: border-box;
width: 32px;
height: 32px;
border: 1px black solid;
cursor: pointer;
}
</style>
</body>
</html>