From a56aabd70f8725fd19a98fe00e7256ec807c6fa6 Mon Sep 17 00:00:00 2001 From: Lennard Sprong Date: Fri, 20 Mar 2026 09:24:29 +0100 Subject: [PATCH 01/12] Add Topo --- src/puzzle/Config.js | 3 +- src/pzpr/variety.js | 1 + src/res/failcode.en.json | 2 + src/variety/fillomino.js | 169 +++++++++++++++++++++++++++++++++++---- 4 files changed, 159 insertions(+), 16 deletions(-) diff --git a/src/puzzle/Config.js b/src/puzzle/Config.js index 84af8e141..aafcb531f 100644 --- a/src/puzzle/Config.js +++ b/src/puzzle/Config.js @@ -461,7 +461,8 @@ pid === "fillomino" || pid === "symmarea" || pid === "snakepit" || - pid === "keywest"; + pid === "keywest" || + pid === "topo"; break; case "dontpassallcell": exec = pid === "arukone"; diff --git a/src/pzpr/variety.js b/src/pzpr/variety.js index 7e10b4c34..2ba85c664 100755 --- a/src/pzpr/variety.js +++ b/src/pzpr/variety.js @@ -466,6 +466,7 @@ toichika2: [0, 0, "遠い誓い2", "Toichika 2", "toichika"], tontonbeya: [0, 0, "とんとんべや", "Tontonbeya", "hakoiri"], tontti: [0, 0, "Tonttiraja", "Tonttiraja"], + topo: [0, 0, "Topo", "Topo", "fillomino"], trainstations: [0, 0, "Train Stations", "Train Stations"], tren: [0, 0, "パーキング", "Tren"], triplace: [0, 0, "トリプレイス", "Tri-place"], diff --git a/src/res/failcode.en.json b/src/res/failcode.en.json index 96528701b..0216dc9d3 100644 --- a/src/res/failcode.en.json +++ b/src/res/failcode.en.json @@ -258,6 +258,7 @@ "bkSameShape.narrow": "Two regions with the same symbol have the same shape.", "bkSameTouch.zabajaba": "Two blocks of the same shape and orientation are adjacent.", "bkSameTouch": "Two areas of the same shape and orientation are adjacent.", + "bkConsecutive.topo": "The numbers in adjacent regions don't have a difference of exactly 1.", "bkSCGe2.dosufuwa": "An area has two or more iron balls.", "bkSepColor.interbd": "One kind of color is included in different countries.", "bkSepNum.kaero": "Letters of one kind are placed in different areas.", @@ -738,6 +739,7 @@ "nmAround.ripple": "Equal numbers touch.", "nmArrowGt": "There are too many arrows adjacent to a number.", "nmArrowLt": "There are not enough arrows adjacent to a number.", + "nmAverageNe.topo": "A clue doesn't indicate the average between two adjacent numbers.", "nmBorderNe.nawabari": "The number is not equal to the number of border lines around it.", "nmBranch.snakepit": "A snake branches off.", "nmCircleNe.brownies": "A number is not equal to the amount of circles in the surrounding cells.", diff --git a/src/variety/fillomino.js b/src/variety/fillomino.js index 9a3cf0a41..005455387 100644 --- a/src/variety/fillomino.js +++ b/src/variety/fillomino.js @@ -10,7 +10,8 @@ "snakepit", "wafusuma", "tetrominous", - "numcity" + "numcity", + "topo" ]; if (typeof module === "object" && module.exports) { module.exports = [pidlist, classbase]; @@ -143,11 +144,12 @@ return false; } }, - "MouseEvent@wafusuma": { + "MouseEvent@wafusuma,topo": { inputModes: { edit: ["number", "clear"], play: ["copynum", "number", "clear", "border", "subline"] }, + // TODO: editmode mouse drag enters the wrong type of lines inputqnum: function() { if (this.puzzle.editmode) { this.inputmark_mouseup(); @@ -224,7 +226,10 @@ enablemake: true, enableplay: true, moveTarget: function(ca) { - if (this.pid === "wafusuma" && this.puzzle.editmode) { + if ( + (this.pid === "wafusuma" || this.pid === "topo") && + this.puzzle.editmode + ) { return this.moveTBorder(ca); } else if ( this.puzzle.playmode && @@ -349,7 +354,7 @@ return null; } }, - "KeyEvent@wafusuma": { + "KeyEvent@wafusuma,topo": { keyinput: function(ca) { if (this.puzzle.editmode) { this.key_inputmark(ca); @@ -373,7 +378,7 @@ border.draw(); } }, - "TargetCursor@wafusuma": { + "TargetCursor@wafusuma,topo": { adjust_modechange: function() { this.bx -= (this.bx + 1) % 2; this.by -= (this.by + 1) % 2; @@ -490,6 +495,10 @@ return Math.floor(Math.sqrt(size * 2 + 0.25) - 0.5); } }, + "Cell@topo": { + minnum: 0, + maxnum: 99 + }, Border: { posthook: { ques: function() { @@ -574,7 +583,23 @@ return false; } }, - "CellList@wafusuma": { + "Border@topo": { + minnum: 0, + maxnum: 99, + + updateGhostBorder: function() {}, + isBorder: function() { + return this.qans > 0 || this.qnum !== -1; + }, + isQuesBorder: function() { + return ( + this.qnum !== -1 || + this.sidecell[0].isEmpty() || + this.sidecell[1].isEmpty() + ); + } + }, + "CellList@wafusuma,topo": { hasLooseBorder: function() { for (var i = 0; i < this.length; i++) { var cell = this[i]; @@ -718,7 +743,9 @@ component.numkind = numkind; component.number = numkind === 1 ? filled : numkind === 0 ? clist.length : -1; - component.complete = clist.length === component.number; + if (this.pid !== "topo") { + component.complete = clist.length === component.number; + } component.looseborders = null; }, @@ -810,7 +837,7 @@ fontsizeratio: 0.65 }, - "Graphic@wafusuma": { + "Graphic@wafusuma,topo": { paint: function() { this.drawBGCells(); this.drawTargetSubNumber(); @@ -834,7 +861,7 @@ var csize = this.cw * 0.27; g.lineWidth = 1; - g.strokeStyle = this.quescolor; + g.strokeStyle = this.pid === "wafusuma" ? this.quescolor : null; var option = { ratio: 0.45 }; var blist = this.range.borders; @@ -845,7 +872,7 @@ // ○の描画 g.vid = "b_cp_" + border.id; - if (border.qnum !== -1) { + if (this.pid === "topo" ? border.qnum >= 0 : border.qnum !== -1) { g.fillStyle = border.error === 1 ? this.errbcolor1 : "white"; g.shapeCircle(px, py, csize); } else { @@ -854,9 +881,13 @@ // 数字の描画 g.vid = "border_text_" + border.id; - if (border.qnum > 0) { + if (border.qnum >= 0) { g.fillStyle = this.quescolor; - this.disptext("" + border.qnum, px, py, option); + var text = "" + border.qnum; + if (this.pid === "topo") { + text += ".5"; + } + this.disptext(text, px, py, option); } else { g.vhide(); } @@ -964,7 +995,7 @@ }); } }, - "Encode@wafusuma": { + "Encode@wafusuma,topo": { decodePzpr: function(type) { var bds = this.board.border; this.genericDecodeNumber16(bds.length, function(r, val) { @@ -982,7 +1013,7 @@ FileIO: { decodeData: function() { this.decodeConfigFlag("t", "fillomino_tri"); - if (this.puzzle.pid === "wafusuma") { + if (this.puzzle.pid === "wafusuma" || this.puzzle.pid === "topo") { this.decodeBorder(function(border, ca) { if (ca !== ".") { border.qnum = +ca; @@ -1002,7 +1033,7 @@ }, encodeData: function() { this.encodeConfigFlag("t", "fillomino_tri"); - if (this.puzzle.pid === "wafusuma") { + if (this.puzzle.pid === "wafusuma" || this.puzzle.pid === "topo") { this.encodeBorder(function(border) { return border.qnum === -1 ? ". " : border.qnum + " "; }); @@ -1586,5 +1617,113 @@ "nmAdjacent" ); } + }, + "AnsCheck@topo": { + checklist: [ + "checkLineBranch", + "checkBorderNumbers", + "checkNumKinds", + "checkSequentialBlockNumber", + "checkGivenLines", + "checkNoNumber", + "checkNoNumCell_fillomino+" + ], + + checkNoNumber: function() { + if (!this.puzzle.getConfig("forceallcell")) { + this.checkAllErrorRoom(function(area) { + return area.numkind !== 0; + }, "bkNoNum"); + } + }, + + checkBorderNumbers: function() { + var borders = this.board.border; + for (var id = 0; id < borders.length; id++) { + var border = borders[id]; + if ( + border.isnull || + border.qnum < 0 || + border.sidecell[0].isSameBlock(border.sidecell[1]) + ) { + continue; + } + + for (var side = 0; side <= 1; side++) { + var cell = border.sidecell[side]; + if ( + cell.nblk.numkind === 1 && + (cell.nblk.number < border.qnum || + cell.nblk.number > border.qnum + 1) + ) { + this.failcode.add("nmAverageNe"); + if (this.checkOnly) { + return; + } + cell.seterr(1); + + borders.setnoerr(); + border.seterr(1); + } + } + } + }, + + checkLineBranch: function() { + var bd = this.board; + + var boardcross = bd.cross; + for (var c = 0; c < boardcross.length; c++) { + var cross = boardcross[c]; + + var borders = bd.borderinside( + cross.bx - 1, + cross.by - 1, + cross.bx + 1, + cross.by + 1 + ); + + if ( + borders.filter(function(border) { + return border.isBorder() || border.isCmp(); + }).length <= 2 + ) { + continue; + } + + if (this.checkOnly) { + break; + } + + this.failcode.add("lnBranch"); + bd.cellinside( + cross.bx - 1, + cross.by - 1, + cross.bx + 1, + cross.by + 1 + ).seterr(1); + } + }, + + checkSequentialBlockNumber: function() { + var sides = this.board.numblkgraph.getSideAreaInfo(); + for (var i = 0; i < sides.length; i++) { + var area1 = sides[i][0], + area2 = sides[i][1]; + if (area1.numkind !== 1 || area2.numkind !== 1) { + continue; + } + if (Math.abs(area1.number - area2.number) === 1) { + continue; + } + + this.failcode.add("bkConsecutive"); + if (this.checkOnly) { + break; + } + area1.clist.seterr(1); + area2.clist.seterr(1); + } + } } }); From 1b114ebeba40f0934e2dd182f49dd842caa25357 Mon Sep 17 00:00:00 2001 From: Lennard Sprong Date: Mon, 23 Mar 2026 08:55:55 +0100 Subject: [PATCH 02/12] Fix edit mode inputs --- src/variety/fillomino.js | 33 ++++++++++++++++++++++++++++++--- 1 file changed, 30 insertions(+), 3 deletions(-) diff --git a/src/variety/fillomino.js b/src/variety/fillomino.js index 005455387..5430820db 100644 --- a/src/variety/fillomino.js +++ b/src/variety/fillomino.js @@ -144,12 +144,19 @@ return false; } }, - "MouseEvent@wafusuma,topo": { + "MouseEvent@wafusuma": { inputModes: { edit: ["number", "clear"], play: ["copynum", "number", "clear", "border", "subline"] - }, - // TODO: editmode mouse drag enters the wrong type of lines + } + }, + "MouseEvent@topo": { + inputModes: { + edit: ["number", "border", "clear"], + play: ["copynum", "number", "clear", "border", "subline"] + } + }, + "MouseEvent@wafusuma,topo#1": { inputqnum: function() { if (this.puzzle.editmode) { this.inputmark_mouseup(); @@ -597,6 +604,26 @@ this.sidecell[0].isEmpty() || this.sidecell[1].isEmpty() ); + }, + setBorder: function() { + if (this.puzzle.editmode && this.qnum === -1) { + this.setQnum(-2); + } else if (this.puzzle.playmode && !this.isQuesBorder()) { + this.setQans(1); + } + }, + removeBorder: function() { + if (this.puzzle.editmode) { + this.setQnum(-1); + } + this.setQans(0); + }, + posthook: { + qnum: function(num) { + if (num !== -1) { + this.setQans(0); + } + } } }, "CellList@wafusuma,topo": { From 49c5ea2a9dc3289bed78eec058e0dafbf8a6471d Mon Sep 17 00:00:00 2001 From: Lennard Sprong Date: Mon, 23 Mar 2026 09:26:35 +0100 Subject: [PATCH 03/12] WIP of example --- test/script/topo.js | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 test/script/topo.js diff --git a/test/script/topo.js b/test/script/topo.js new file mode 100644 index 000000000..abcfcc07d --- /dev/null +++ b/test/script/topo.js @@ -0,0 +1,12 @@ +/* topo.js */ + +ui.debug.addDebugData("topo", { + url: "topo/5/5/k1g3..n22..h.l.h.1j", + failcheck: [ + [ + null, + "pzprv3/topo/5/5/. . . . /. 1 . 3 /-2 -2 . . /. . . . /. . 2 2 /-2 -2 . . -2 /. . . . . /. -2 . . -2 /1 . . . . /2 2 2 3 3 /1 1 2 3 4 /2 1 2 3 . /2 2 2 . . /1 . . . . /0 0 0 0 /0 0 0 0 /0 0 0 0 /0 0 0 0 /0 0 0 0 /0 0 0 0 0 /0 0 0 0 0 /0 0 0 0 0 /0 0 0 0 0 /" + ] + ], + inputs: [] +}); From 7ecc2dd08039f3d774fc100ad5ea1c50bd921a2f Mon Sep 17 00:00:00 2001 From: Lennard Sprong Date: Tue, 24 Mar 2026 14:42:08 +0100 Subject: [PATCH 04/12] Finish example --- src-ui/js/ui/KeyPopup.js | 3 ++- src-ui/list.html | 1 + test/script/topo.js | 4 ++-- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src-ui/js/ui/KeyPopup.js b/src-ui/js/ui/KeyPopup.js index 695a7dfe0..9697e9883 100644 --- a/src-ui/js/ui/KeyPopup.js +++ b/src-ui/js/ui/KeyPopup.js @@ -248,7 +248,8 @@ ui.keypopup = { bhaibahan: [10, 0], edamame: [4, 0], heavydots: [10, 0], - marutaring: [10, 0] + marutaring: [10, 0], + topo: [10, 10] }, //--------------------------------------------------------------------------- diff --git a/src-ui/list.html b/src-ui/list.html index e1b49aa4f..4f11c7fc1 100644 --- a/src-ui/list.html +++ b/src-ui/list.html @@ -373,6 +373,7 @@

パズルの種類のリスト
  • +
  • diff --git a/test/script/topo.js b/test/script/topo.js index abcfcc07d..de9f2df26 100644 --- a/test/script/topo.js +++ b/test/script/topo.js @@ -1,11 +1,11 @@ /* topo.js */ ui.debug.addDebugData("topo", { - url: "topo/5/5/k1g3..n22..h.l.h.1j", + url: "5/5/k1g3..m.2...h.l.h.1h.g", failcheck: [ [ null, - "pzprv3/topo/5/5/. . . . /. 1 . 3 /-2 -2 . . /. . . . /. . 2 2 /-2 -2 . . -2 /. . . . . /. -2 . . -2 /1 . . . . /2 2 2 3 3 /1 1 2 3 4 /2 1 2 3 . /2 2 2 . . /1 . . . . /0 0 0 0 /0 0 0 0 /0 0 0 0 /0 0 0 0 /0 0 0 0 /0 0 0 0 0 /0 0 0 0 0 /0 0 0 0 0 /0 0 0 0 0 /" + "pzprv3/topo/5/5/. . . . /. 1 . 3 /-2 -2 . . /. . . . /. -2 2 -2 /-2 -2 . . -2 /. . . . . /. -2 . . -2 /1 . . -2 . /2 2 2 3 3 /1 1 2 3 4 /2 1 2 3 3 /2 2 2 2 2 /1 1 2 3 2 /0 0 0 0 /0 0 0 0 /0 0 0 0 /0 0 0 0 /0 0 0 0 /0 0 0 0 0 /0 0 0 0 0 /0 0 0 0 0 /0 0 0 0 0 /" ] ], inputs: [] From 2ec6e486cfcdd45c39bddf197536888dd2049a77 Mon Sep 17 00:00:00 2001 From: Lennard Sprong Date: Tue, 24 Mar 2026 16:25:48 +0100 Subject: [PATCH 05/12] Add failcases --- test/script/topo.js | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/test/script/topo.js b/test/script/topo.js index de9f2df26..d67e7d3ff 100644 --- a/test/script/topo.js +++ b/test/script/topo.js @@ -3,6 +3,35 @@ ui.debug.addDebugData("topo", { url: "5/5/k1g3..m.2...h.l.h.1h.g", failcheck: [ + [ + "lnBranch", + "pzprv3/topo/5/5/. . . . /. 1 . 3 /-2 -2 . . /. . . . /. -2 2 -2 /-2 -2 . . -2 /. . . . . /. -2 . . -2 /1 . . -2 . /. . . . . /2 2 . . . /2 1 . . . /2 2 . . . /1 1 . . . /0 0 0 0 /0 0 0 0 /0 0 0 0 /0 0 0 0 /0 0 0 0 /0 0 0 0 0 /0 1 0 0 0 /0 0 0 0 0 /0 0 0 0 0 /" + ], + [ + "lnBranch", + "pzprv3/topo/5/5/. . . . /. 1 . 3 /-2 -2 . . /. . . . /. -2 2 -2 /-2 -2 . . -2 /. . . . . /. -2 . . -2 /1 . . -2 . /. . . . . /2 2 . . . /2 1 . . . /2 2 . . . /1 1 . . . /0 0 0 0 /0 0 0 0 /0 0 0 0 /0 0 0 0 /0 0 0 0 /0 0 0 0 0 /0 0 0 0 0 /0 0 0 0 0 /0 0 0 0 0 /", + { skiprules: true } + ], + [ + "nmAverageNe", + "pzprv3/topo/5/5/. . . . /. 1 . 3 /-2 -2 . . /. . . . /. -2 2 -2 /-2 -2 . . -2 /. . . . . /. -2 . . -2 /1 . . -2 . /1 1 1 2 2 /2 2 1 2 3 /1 2 1 2 2 /1 1 1 1 1 /2 2 1 2 1 /0 0 1 0 /0 0 1 0 /0 0 1 0 /0 0 0 0 /0 0 0 0 /0 0 0 0 0 /1 0 0 0 1 /0 0 0 1 0 /0 1 0 0 0 /" + ], + [ + "bkConsecutive", + "pzprv3/topo/5/5/. . . . /. 1 . 3 /-2 -2 . . /. . . . /. -2 2 -2 /-2 -2 . . -2 /. . . . . /. -2 . . -2 /1 . . -2 . /2 2 2 4 4 /1 1 2 4 3 /2 1 2 4 4 /2 2 2 2 2 /1 1 2 3 2 /0 0 1 0 /0 0 1 0 /0 0 1 0 /0 0 0 0 /0 0 0 0 /0 0 0 0 0 /0 0 0 0 1 /0 0 0 1 0 /0 0 0 0 0 /" + ], + [ + "bdUnused", + "pzprv3/topo/5/5/. . . . /. 1 . 3 /-2 -2 . . /. . . . /. -2 2 -2 /-2 -2 . . -2 /. . . . . /. -2 . . -2 /1 . . -2 . /. . . . . /. . . . . /. . . . . /. . . . . /. . . . . /0 0 1 0 /0 0 1 0 /0 0 1 0 /0 0 0 0 /0 0 0 0 /0 0 0 0 0 /1 0 0 0 0 /0 0 0 1 0 /0 1 0 0 0 /" + ], + [ + "bkMixedNum", + "pzprv3/topo/5/5/. . . . /. 1 . 3 /-2 -2 . . /. . . . /. -2 2 -2 /-2 -2 . . -2 /. . . . . /. -2 . . -2 /1 . . -2 . /. . 2 3 . /. . . . 4 /. . . . . /. 2 . . . /1 . . 3 . /0 0 1 0 /0 0 1 0 /0 0 1 0 /0 0 0 0 /0 0 0 0 /0 0 0 0 0 /0 0 0 0 1 /0 0 0 1 0 /0 0 0 0 0 /" + ], + [ + "ceNoNum", + "pzprv3/topo/5/5/. . . . /. 1 . 3 /-2 -2 . . /. . . . /. -2 2 -2 /-2 -2 . . -2 /. . . . . /. -2 . . -2 /1 . . -2 . /2 2 2 3 3 /1 1 2 3 4 /2 1 2 3 3 /2 2 2 2 2 /. . 2 . 2 /0 0 1 0 /0 0 1 0 /0 0 1 0 /0 0 0 0 /0 0 0 0 /0 0 0 0 0 /1 0 0 0 1 /0 0 0 1 0 /0 1 0 0 0 /" + ], [ null, "pzprv3/topo/5/5/. . . . /. 1 . 3 /-2 -2 . . /. . . . /. -2 2 -2 /-2 -2 . . -2 /. . . . . /. -2 . . -2 /1 . . -2 . /2 2 2 3 3 /1 1 2 3 4 /2 1 2 3 3 /2 2 2 2 2 /1 1 2 3 2 /0 0 0 0 /0 0 0 0 /0 0 0 0 /0 0 0 0 /0 0 0 0 /0 0 0 0 0 /0 0 0 0 0 /0 0 0 0 0 /0 0 0 0 0 /" From 30ee2de3a805d2c42699353be119c969f4b68a1d Mon Sep 17 00:00:00 2001 From: Lennard Sprong Date: Tue, 24 Mar 2026 16:45:18 +0100 Subject: [PATCH 06/12] Add input tests --- test/script/topo.js | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/test/script/topo.js b/test/script/topo.js index d67e7d3ff..07f735284 100644 --- a/test/script/topo.js +++ b/test/script/topo.js @@ -37,5 +37,27 @@ ui.debug.addDebugData("topo", { "pzprv3/topo/5/5/. . . . /. 1 . 3 /-2 -2 . . /. . . . /. -2 2 -2 /-2 -2 . . -2 /. . . . . /. -2 . . -2 /1 . . -2 . /2 2 2 3 3 /1 1 2 3 4 /2 1 2 3 3 /2 2 2 2 2 /1 1 2 3 2 /0 0 0 0 /0 0 0 0 /0 0 0 0 /0 0 0 0 /0 0 0 0 /0 0 0 0 0 /0 0 0 0 0 /0 0 0 0 0 /0 0 0 0 0 /" ] ], - inputs: [] + inputs: [ + { + label: "Add borders", + input: [ + "newboard,2,2", + "editmode", + "mouse,left,2,0,2,2", + "playmode", + "mouse,left,2,2,4,2" + ], + result: "pzprv3/topo/2/2/-2 /. /. . /. . /. . /0 /0 /0 1 /" + }, + { + label: "Remove ans border", + input: ["mouse,left,4,2,2,2,2,0"], + result: "pzprv3/topo/2/2/-2 /. /. . /. . /. . /0 /0 /0 0 /" + }, + { + label: "Remove ques border", + input: ["editmode", "mouse,left,2,2,2,0"], + result: "pzprv3/topo/2/2/. /. /. . /. . /. . /0 /0 /0 0 /" + } + ] }); From 5b3ebc73a19b9de007dd93b080f6540690b60a9b Mon Sep 17 00:00:00 2001 From: Lennard Sprong Date: Sat, 28 Mar 2026 10:42:30 +0100 Subject: [PATCH 07/12] Change chassis styling --- src/variety/fillomino.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/variety/fillomino.js b/src/variety/fillomino.js index 1f851d102..305a0259a 100644 --- a/src/variety/fillomino.js +++ b/src/variety/fillomino.js @@ -872,7 +872,7 @@ paint: function() { this.drawBGCells(); this.drawTargetSubNumber(); - this.drawDashedGrid(); + this.drawDashedGrid(this.pid !== "topo"); this.drawBorders(); this.drawCursor(this.puzzle.playmode); @@ -883,7 +883,9 @@ this.drawBorderQsubs(); - this.drawChassis(); + if (this.pid !== "topo") { + this.drawChassis(); + } }, drawQuesNumbersBD: function() { From 2d459312fb5f4ee9514b83d2d7297042e8428827 Mon Sep 17 00:00:00 2001 From: Lennard Sprong Date: Sat, 28 Mar 2026 17:00:37 +0100 Subject: [PATCH 08/12] Fix mouse clue inputs --- src/variety/fillomino.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/variety/fillomino.js b/src/variety/fillomino.js index 305a0259a..c30b90908 100644 --- a/src/variety/fillomino.js +++ b/src/variety/fillomino.js @@ -166,7 +166,7 @@ }, inputmark_mouseup: function() { var pos = this.getpos(0.33); - if (!pos.isinside()) { + if (!pos.isinside() || !pos.onborder()) { return; } @@ -181,7 +181,7 @@ var qn = border.qnum, min = border.getminnum(), - max = border.maxnum(); + max = border.getmaxnum(); if (this.btn === "left") { if (qn === -1) { border.setQnum(-2); From e5aebc8988e7c027cc47c617960e85646ea9b637 Mon Sep 17 00:00:00 2001 From: Lennard Sprong Date: Sat, 28 Mar 2026 18:44:49 +0100 Subject: [PATCH 09/12] Allow given cell numbers --- src/variety/fillomino.js | 27 ++++++++++++++++++++++++--- test/script/topo.js | 6 +++--- test/script/wafusuma.js | 12 +++++++----- 3 files changed, 34 insertions(+), 11 deletions(-) diff --git a/src/variety/fillomino.js b/src/variety/fillomino.js index c30b90908..a00c5483e 100644 --- a/src/variety/fillomino.js +++ b/src/variety/fillomino.js @@ -166,7 +166,7 @@ }, inputmark_mouseup: function() { var pos = this.getpos(0.33); - if (!pos.isinside() || !pos.onborder()) { + if (!pos.isinside() || pos.oncross()) { return; } @@ -176,6 +176,10 @@ } else { var border = pos.getb(); if (border.isnull) { + var cell = this.getcell(); + if (!cell.isnull) { + this.inputqnum_main(cell); + } return; } @@ -376,6 +380,9 @@ key_inputmark: function(ca) { var border = this.cursor.getb(); if (border.isnull) { + if (this.cursor.oncell()) { + this.key_inputqnum(ca); + } return; } @@ -880,6 +887,7 @@ this.drawSubNumbers(); this.drawAnsNumbers(); + this.drawQuesNumbers(); this.drawBorderQsubs(); @@ -1034,12 +1042,20 @@ this.genericDecodeNumber16(bds.length, function(r, val) { bds[r].qnum = val; }); + this.decodeNumber16(); }, encodePzpr: function(type) { var bds = this.board.border; this.genericEncodeNumber16(bds.length, function(r) { return bds[r].qnum; }); + if ( + this.board.cell.some(function(cell) { + return cell.qnum !== -1; + }) + ) { + this.encodeNumber16(); + } } }, //--------------------------------------------------------- @@ -1052,6 +1068,10 @@ border.qnum = +ca; } }); + + if (this.filever === 1) { + this.decodeCellQnum(); + } } else { this.decodeCellQnum(); } @@ -1067,12 +1087,13 @@ encodeData: function() { this.encodeConfigFlag("t", "fillomino_tri"); if (this.puzzle.pid === "wafusuma" || this.puzzle.pid === "topo") { + this.filever = 1; this.encodeBorder(function(border) { return border.qnum === -1 ? ". " : border.qnum + " "; }); - } else { - this.encodeCellQnum(); } + this.encodeCellQnum(); + if (this.puzzle.pid === "snakepit") { this.encodeCell(function(cell) { return cell.ques >= 0 ? cell.ques + " " : ". "; diff --git a/test/script/topo.js b/test/script/topo.js index 07f735284..a38701a74 100644 --- a/test/script/topo.js +++ b/test/script/topo.js @@ -47,17 +47,17 @@ ui.debug.addDebugData("topo", { "playmode", "mouse,left,2,2,4,2" ], - result: "pzprv3/topo/2/2/-2 /. /. . /. . /. . /0 /0 /0 1 /" + result: "pzprv3.1/topo/2/2/-2 /. /. . /. . /. . /. . /. . /0 /0 /0 1 /" }, { label: "Remove ans border", input: ["mouse,left,4,2,2,2,2,0"], - result: "pzprv3/topo/2/2/-2 /. /. . /. . /. . /0 /0 /0 0 /" + result: "pzprv3.1/topo/2/2/-2 /. /. . /. . /. . /. . /. . /0 /0 /0 0 /" }, { label: "Remove ques border", input: ["editmode", "mouse,left,2,2,2,0"], - result: "pzprv3/topo/2/2/. /. /. . /. . /. . /0 /0 /0 0 /" + result: "pzprv3.1/topo/2/2/. /. /. . /. . /. . /. . /. . /0 /0 /0 0 /" } ] }); diff --git a/test/script/wafusuma.js b/test/script/wafusuma.js index bbb4b6509..2a9ea5a41 100644 --- a/test/script/wafusuma.js +++ b/test/script/wafusuma.js @@ -36,27 +36,29 @@ ui.debug.addDebugData("wafusuma", { { label: "Right-click to input clue", input: ["newboard,2,2", "editmode", "cursor,3,2", "mouse,right,3,2"], - result: "pzprv3/wafusuma/2/2/. /. /. 4 /. . /. . /0 /0 /0 0 /" + result: "pzprv3.1/wafusuma/2/2/. /. /. 4 /. . /. . /. . /. . /0 /0 /0 0 /" }, { label: "Input clues with keyboard", input: ["key,left,down,-"], - result: "pzprv3/wafusuma/2/2/. /-2 /. 4 /. . /. . /0 /0 /0 0 /" + result: + "pzprv3.1/wafusuma/2/2/. /-2 /. 4 /. . /. . /. . /. . /0 /0 /0 0 /" }, { label: "Adjust cursor when switching modes", input: ["playmode", "key,3"], - result: "pzprv3/wafusuma/2/2/. /-2 /. 4 /. . /3 . /0 /0 /0 0 /" + result: + "pzprv3.1/wafusuma/2/2/. /-2 /. 4 /. . /. . /. . /3 . /0 /0 /0 0 /" }, { label: "Erase clues", input: ["editmode,clear", "mouse,left,1,3,2,3"], - result: "pzprv3/wafusuma/2/2/. /. /. 4 /. . /3 . /0 /0 /0 0 /" + result: "pzprv3.1/wafusuma/2/2/. /. /. 4 /. . /. . /. . /3 . /0 /0 /0 0 /" }, { label: "Erase answer", input: ["playmode,clear", "mouse,left,1,3,3,3,3,2"], - result: "pzprv3/wafusuma/2/2/. /. /. 4 /. . /. . /0 /0 /0 0 /" + result: "pzprv3.1/wafusuma/2/2/. /. /. 4 /. . /. . /. . /. . /0 /0 /0 0 /" } ] }); From 02cfca86b3d1b4127f2b7157fdf666cca862c1ba Mon Sep 17 00:00:00 2001 From: Lennard Sprong Date: Sat, 28 Mar 2026 18:52:44 +0100 Subject: [PATCH 10/12] Add to changelog --- src-ui/changes.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src-ui/changes.html b/src-ui/changes.html index fd20ce7d9..1e49d3e49 100644 --- a/src-ui/changes.html +++ b/src-ui/changes.html @@ -33,13 +33,13 @@
    Latest types (all types)
    From 7ad122c2f555ee6e4b553ceb3bf3de31da973b44 Mon Sep 17 00:00:00 2001 From: Lennard Sprong Date: Sat, 28 Mar 2026 19:11:00 +0100 Subject: [PATCH 11/12] Add background --- src-ui/img/topo.png | Bin 0 -> 134 bytes src-ui/js/ui/Misc.js | 1 + 2 files changed, 1 insertion(+) create mode 100644 src-ui/img/topo.png diff --git a/src-ui/img/topo.png b/src-ui/img/topo.png new file mode 100644 index 0000000000000000000000000000000000000000..034b863f8b9b94d312c34bfc3efdc17d8b912e57 GIT binary patch literal 134 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~wg8_H*G-!? zJ%0T7#M{*efFgRHE{-7*Q!>|uOps)15xl4yd<#SYg7 dK~aH++zi4U3 Date: Sun, 29 Mar 2026 14:46:39 +0200 Subject: [PATCH 12/12] Dynamic maxnum --- src/variety/fillomino.js | 32 +++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/src/variety/fillomino.js b/src/variety/fillomino.js index a00c5483e..95a0c27b3 100644 --- a/src/variety/fillomino.js +++ b/src/variety/fillomino.js @@ -515,7 +515,9 @@ }, "Cell@topo": { minnum: 0, - maxnum: 99 + maxnum: function() { + return this.puzzle.editmode ? 99 : this.board.getHighestNumber(); + } }, Border: { posthook: { @@ -631,6 +633,7 @@ }, posthook: { qnum: function(num) { + this.board.highestNum = -1; if (num !== -1) { this.setQans(0); } @@ -677,6 +680,33 @@ cols: 7 }, + "Board@topo": { + highestNum: -1, + getHighestNumber: function() { + if (this.highestNum < 0) { + var lowest = Infinity; + for (var i = 0; i < this.border.length; i++) { + var border = this.border[i]; + if (border.qnum >= 0 && lowest > border.qnum) { + lowest = border.qnum; + } + } + for (var i = 0; i < this.cell.length; i++) { + var cell = this.cell[i]; + if (cell.qnum >= 0 && lowest > cell.qnum) { + lowest = cell.qnum; + } + } + + this.highestNum = Math.min( + lowest + Math.max(this.rows, this.cols) - 1, + 99 + ); + } + return this.highestNum; + } + }, + "AreaRoomGraph@numcity": { enabled: true },