Skip to content

Commit 94aa640

Browse files
committed
Add Oasis
1 parent 89271c2 commit 94aa640

File tree

6 files changed

+413
-1
lines changed

6 files changed

+413
-1
lines changed

src-ui/js/ui/KeyPopup.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -243,7 +243,8 @@ ui.keypopup = {
243243
morningwalk: [10, 0],
244244
energywalk: [10, 0],
245245
cornerch: [10, 0],
246-
keywest: [4, 4]
246+
keywest: [4, 4],
247+
oasis: [10, 0]
247248
},
248249

249250
//---------------------------------------------------------------------------

src-ui/list.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,7 @@ <h2 id="title"><span lang="ja">パズルの種類のリスト</span><span lang="
123123
<li data-pid="smullyan"></li>
124124
<li data-pid="outofsight"></li>
125125
<li data-pid="sumiwake"></li>
126+
<li data-pid="oasis"></li>
126127
</ul>
127128
</div>
128129
<div class="lists loops">

src/pzpr/variety.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -326,6 +326,7 @@
326326
nurimisaki: [0, 0, "ぬりみさき", "Nurimisaki", "kurodoko"],
327327
nuritwin: [0, 0, "ぬりツイン", "Nuritwin", "shimaguni"],
328328
nuriuzu: [0, 0, "ぬりうず", "Nuri-uzu", "tentaisho"],
329+
oasis: [0, 0, "Oasis", "Oasis"],
329330
ovotovata: [0, 0, "Ovotovata", "Ovotovata", "country"],
330331
oneroom: [0, 0, "ワンルームワンドア", "One Room One Door", "heyawake"],
331332
onsen: [0, 0, "温泉めぐり", "Onsen-meguri", "country"],

src/res/failcode.en.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -815,6 +815,8 @@
815815
"nmNumberNe.sukoro": "The number of numbers placed in four adjacent cells is not equal to the number.",
816816
"nmNumberNe.sukororoom": "The number of numbers placed in four adjacent cells is not equal to the number.",
817817
"nmNumberNe.view": "The number of numbers placed in four adjacent cells is not equal to the number.",
818+
"nmOasisGt": "A number is larger than the amount of circles that can be reached.",
819+
"nmOasisLt": "A number is smaller than the amount of circles that can be reached.",
818820
"nmOrbitNe.orbital": "A number does not indicate the amount of white circles used by the loop.",
819821
"nmOrder.numcity": "The size of a district is larger or equal to the size of the previous district.",
820822
"nmOutOfBk.oyakodori": "A bird is outside a nest.",

src/variety/oasis.js

Lines changed: 339 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,339 @@
1+
/* global Set:false */
2+
(function(pidlist, classbase) {
3+
if (typeof module === "object" && module.exports) {
4+
module.exports = [pidlist, classbase];
5+
} else {
6+
pzpr.classmgr.makeCustom(pidlist, classbase);
7+
}
8+
})(["oasis"], {
9+
//---------------------------------------------------------
10+
// マウス入力系
11+
MouseEvent: {
12+
RBShadeCell: true,
13+
use: true,
14+
inputModes: {
15+
edit: ["number", "clear"],
16+
play: ["shade", "unshade", "peke", "completion"]
17+
},
18+
mouseinput_auto: function() {
19+
if (this.puzzle.playmode) {
20+
if (this.mousestart) {
21+
this.isDraggingPeke = this.puzzle.key.isALT;
22+
}
23+
if (this.isDraggingPeke) {
24+
this.inputpeke();
25+
} else if (this.btn === "left" && this.mousestart) {
26+
if (!this.inputdark()) {
27+
this.inputcell();
28+
}
29+
} else if (this.inputData === null || this.inputData < 20) {
30+
this.inputcell();
31+
}
32+
} else if (this.puzzle.editmode) {
33+
if (this.mousestart) {
34+
this.inputqnum();
35+
}
36+
}
37+
},
38+
inputdark: function() {
39+
var cell = this.getcell();
40+
if (cell.isnull) {
41+
return false;
42+
}
43+
44+
var distance = 0.6,
45+
dx = this.inputPoint.bx - cell.bx /* ここはtargetcellではなくcell */,
46+
dy = this.inputPoint.by - cell.by;
47+
if (cell.isNum() && dx * dx + dy * dy < distance * distance) {
48+
this.inputData = cell.qcmp !== 1 ? 21 : 20;
49+
cell.setQcmp(this.inputData === 21 ? 1 : 0);
50+
cell.draw();
51+
return true;
52+
}
53+
return false;
54+
},
55+
inputqcmp: function() {
56+
var cell = this.getcell();
57+
if (cell.isnull) {
58+
return;
59+
}
60+
61+
cell.setQcmp(+!cell.qcmp);
62+
cell.draw();
63+
64+
this.mousereset();
65+
}
66+
},
67+
68+
//---------------------------------------------------------
69+
// キーボード入力系
70+
KeyEvent: {
71+
enablemake: true
72+
},
73+
74+
//---------------------------------------------------------
75+
// 盤面管理系
76+
Cell: {
77+
numberRemainsUnshaded: true,
78+
79+
maxnum: function() {
80+
return this.board.cols * this.board.rows - 1;
81+
},
82+
83+
isCmp: function() {
84+
if (!this.isNum()) {
85+
return false;
86+
}
87+
if (this.qcmp === 1) {
88+
return true;
89+
}
90+
if (!this.isValidNum() || !this.puzzle.execConfig("autocmp")) {
91+
return false;
92+
}
93+
return this.countResult(true) === 0;
94+
},
95+
96+
countResult: function(explicit) {
97+
if (!this.isValidNum()) {
98+
return 0;
99+
}
100+
var targets = new Set();
101+
for (var dir in this.adjacent) {
102+
var c = this.adjacent[dir];
103+
if (c.isNum()) {
104+
targets.add(c);
105+
}
106+
var group = explicit ? c.autooasis : c.oasis;
107+
if (group) {
108+
group.adjclist.each(function(obj) {
109+
targets.add(obj);
110+
});
111+
}
112+
}
113+
targets.delete(this);
114+
return targets.size - this.qnum;
115+
},
116+
redrawConnected: function() {
117+
if (this.autooasis) {
118+
this.autooasis.adjclist.each(function(c) {
119+
c.draw();
120+
});
121+
} else {
122+
for (var dir in this.adjacent) {
123+
var c = this.adjacent[dir];
124+
if (c && c.autooasis) {
125+
c.redrawConnected();
126+
} else if (c && c.isNum()) {
127+
c.draw();
128+
}
129+
}
130+
}
131+
},
132+
133+
posthook: {
134+
qnum: function() {
135+
var bd = this.board;
136+
var oasis = new Set();
137+
var autooasis = new Set();
138+
139+
for (var dir in this.adjacent) {
140+
var c = this.adjacent[dir];
141+
if (c && c.oasis) {
142+
oasis.add(c.oasis);
143+
}
144+
if (c && c.autooasis) {
145+
autooasis.add(c.autooasis);
146+
}
147+
}
148+
149+
oasis.forEach(function(cmp) {
150+
bd.oasisgraph.setExtraData(cmp);
151+
});
152+
autooasis.forEach(function(cmp) {
153+
bd.autooasisgraph.setExtraData(cmp);
154+
});
155+
this.redrawConnected();
156+
},
157+
qsub: function() {
158+
this.redrawConnected();
159+
}
160+
}
161+
},
162+
Board: {
163+
hasborder: 1,
164+
cols: 8,
165+
rows: 8,
166+
167+
addExtraInfo: function() {
168+
this.oasisgraph = this.addInfoList(this.klass.ImplicitOasisGraph);
169+
this.autooasisgraph = this.addInfoList(this.klass.ExplicitOasisGraph);
170+
}
171+
},
172+
173+
AreaUnshadeGraph: {
174+
enabled: true
175+
},
176+
"ImplicitOasisGraph:AreaGraphBase": {
177+
enabled: true,
178+
relation: { "cell.qans": "node", "cell.qnum": "node", "cell.qsub": "node" },
179+
setExtraData: function(component) {
180+
this.common.setExtraData.call(this, component);
181+
182+
var set = new Set();
183+
184+
component.clist.each(function(cell) {
185+
for (var dir in cell.adjacent) {
186+
var adj = cell.adjacent[dir];
187+
if (adj.isNum()) {
188+
set.add(adj);
189+
}
190+
}
191+
});
192+
component.adjclist = new this.klass.CellList(Array.from(set));
193+
},
194+
195+
isnodevalid: function(cell) {
196+
return cell.isUnshade() && !cell.isNum();
197+
},
198+
199+
getComponentRefs: function(obj) {
200+
return obj.oasis;
201+
},
202+
setComponentRefs: function(obj, component) {
203+
obj.oasis = component;
204+
},
205+
getObjNodeList: function(nodeobj) {
206+
return nodeobj.oasisnodes;
207+
},
208+
resetObjNodeList: function(nodeobj) {
209+
nodeobj.oasisnodes = [];
210+
}
211+
},
212+
"ExplicitOasisGraph:ImplicitOasisGraph": {
213+
isnodevalid: function(cell) {
214+
return cell.isUnshade() && !cell.isNum() && cell.qsub;
215+
},
216+
getComponentRefs: function(obj) {
217+
return obj.autooasis;
218+
},
219+
setComponentRefs: function(obj, component) {
220+
obj.autooasis = component;
221+
},
222+
getObjNodeList: function(nodeobj) {
223+
return nodeobj.autooasisnodes;
224+
},
225+
resetObjNodeList: function(nodeobj) {
226+
nodeobj.autooasisnodes = [];
227+
}
228+
},
229+
230+
//---------------------------------------------------------
231+
// 画像表示系
232+
Graphic: {
233+
qanscolor: "black",
234+
bgcellcolor_func: "qsub1",
235+
gridcolor_type: "LIGHT",
236+
237+
autocmp: "number",
238+
hideHatena: true,
239+
enablebcolor: true,
240+
241+
paint: function() {
242+
this.drawBGCells();
243+
this.drawGrid();
244+
this.drawShadedCells();
245+
246+
this.drawCircledNumbers();
247+
248+
this.drawChassis();
249+
250+
this.drawPekes();
251+
252+
this.drawTarget();
253+
},
254+
255+
getCircleFillColor: function(cell) {
256+
if (!cell.isNum()) {
257+
return null;
258+
}
259+
return cell.isCmp() ? this.qcmpcolor : this.bgcolor;
260+
}
261+
},
262+
263+
//---------------------------------------------------------
264+
// URLエンコード/デコード処理
265+
Encode: {
266+
decodePzpr: function(type) {
267+
this.decodeNumber16();
268+
},
269+
encodePzpr: function(type) {
270+
this.encodeNumber16();
271+
}
272+
},
273+
//---------------------------------------------------------
274+
FileIO: {
275+
decodeData: function() {
276+
this.decodeCellQnum();
277+
this.decodeCellQanssubcmp();
278+
this.decodeBorderLine();
279+
},
280+
encodeData: function() {
281+
this.encodeCellQnum();
282+
this.encodeCellQanssubcmp();
283+
this.encodeBorderLineIfPresent();
284+
},
285+
286+
decodeCellQanssubcmp: function() {
287+
this.decodeCell(function(cell, ca) {
288+
if (ca === "+") {
289+
cell.qsub = 1;
290+
} else if (ca === "c") {
291+
cell.qsub = 1;
292+
cell.qcmp = 1;
293+
} else if (ca === "-") {
294+
cell.qcmp = 1;
295+
} else if (ca === "1") {
296+
cell.qans = 1;
297+
}
298+
});
299+
},
300+
encodeCellQanssubcmp: function() {
301+
this.encodeCell(function(cell) {
302+
if (cell.qans === 1) {
303+
return "1 ";
304+
} else if (cell.qsub === 1) {
305+
return cell.qcmp ? "c " : "+ ";
306+
} else if (cell.qcmp === 1) {
307+
return "- ";
308+
} else {
309+
return ". ";
310+
}
311+
});
312+
}
313+
},
314+
315+
//---------------------------------------------------------
316+
// 正解判定処理実行部
317+
AnsCheck: {
318+
checklist: [
319+
"checkShadeCellExist",
320+
"checkAdjacentShadeCell",
321+
"checkConnectUnshadeRB",
322+
"checkCellNumberLarge",
323+
"check2x2UnshadeCell++",
324+
"checkCellNumberSmall",
325+
"doneShadingDecided"
326+
],
327+
328+
checkCellNumberLarge: function() {
329+
this.checkAllCell(function(cell) {
330+
return cell.countResult(false) < 0;
331+
}, "nmOasisGt");
332+
},
333+
checkCellNumberSmall: function() {
334+
this.checkAllCell(function(cell) {
335+
return cell.countResult(false) > 0;
336+
}, "nmOasisLt");
337+
}
338+
}
339+
});

0 commit comments

Comments
 (0)