+
diff --git a/src/pzpr/variety.js b/src/pzpr/variety.js
index c2e0cad79..21dda3d54 100755
--- a/src/pzpr/variety.js
+++ b/src/pzpr/variety.js
@@ -456,6 +456,7 @@
teri: [0, 0, "テリトリー", "Territory", "kurodoko"],
tetrochain: [0, 0, "テトロチェーンY", "Tetro Chain-Y"],
tetrochaink: [0, 0, "テトロチェーンK", "Tetro Chain-K", "kurarin"],
+ tetroctb: [0, 0, "テトロチェーンCTB", "Tetro Chain-CTB", "shimaguni"],
tetrominous: [0, 0, "Tetrominous", "Tetrominous", "fillomino"],
tilecity: [0, 0, "タイルシティー", "Tile City"],
tilepaint: [1, 0, "タイルペイント", "Tilepaint"],
diff --git a/src/res/failcode.en.json b/src/res/failcode.en.json
index c1dfb8f99..6af69dff8 100644
--- a/src/res/failcode.en.json
+++ b/src/res/failcode.en.json
@@ -151,6 +151,7 @@
"bkMSGe2.nondango": "An area has two or more shaded circles.",
"bkMSPassedGt2.moonsun": "A line passes the marks of the moon for two rooms in a row.",
"bkMUPassedGt2.moonsun": "A line passes the marks of the sun for two rooms in a row.",
+ "bkNoBorder.tetroctb": "A block does not cross a region border.",
"bkNoChain.chainedb": "A block is not diagonally adjacent to another block.",
"bkNoChain.mrtile": "A block is not diagonally adjacent to another identical block.",
"bkNoChain.sendai": "A city is not adjacent to another city with the same shape and orientation.",
diff --git a/src/variety/shimaguni.js b/src/variety/shimaguni.js
index 3835fb2d6..0d5ba71e4 100644
--- a/src/variety/shimaguni.js
+++ b/src/variety/shimaguni.js
@@ -17,7 +17,8 @@
"cocktail",
"martini",
"nuritwin",
- "marutaring"
+ "marutaring",
+ "tetroctb"
],
{
//---------------------------------------------------------
@@ -37,13 +38,13 @@
play: ["shade", "unshade", "number"]
}
},
- "MouseEvent@cocktail,nuritwin,marutaring": {
+ "MouseEvent@cocktail,nuritwin,marutaring,tetroctb": {
inputModes: {
edit: ["border", "number", "clear", "info-blk"],
play: ["shade", "unshade", "info-blk"]
}
},
- "MouseEvent@cocktail,martini#2": {
+ "MouseEvent@cocktail,martini,tetroctb#2": {
dispInfoBlk: function() {
var cell = this.getcell();
this.mousereset();
@@ -123,7 +124,7 @@
enableSubNumberArray: true,
disableAnum: true
},
- "Cell@chocona,hinge,heyablock,cocktail": {
+ "Cell@chocona,hinge,heyablock,cocktail,tetroctb": {
minnum: 0
},
"Cell@martini": {
@@ -182,7 +183,7 @@
Board: {
hasborder: 1
},
- "Board@shimaguni,stostone,heyablock,cocktail,martini,nuritwin,marutaring": {
+ "Board@shimaguni,stostone,heyablock,cocktail,martini,nuritwin,marutaring,tetroctb": {
addExtraInfo: function() {
this.stonegraph = this.addInfoList(this.klass.AreaStoneGraph);
}
@@ -301,7 +302,7 @@
}
},
- "AreaShadeGraph@chocona": {
+ "AreaShadeGraph@chocona,tetroctb": {
enabled: true
},
"AreaShadeGraph@nuritwin,marutaring": {
@@ -316,7 +317,7 @@
component.hinge = null;
}
},
- "AreaStoneGraph:AreaShadeGraph@shimaguni,stostone,heyablock,cocktail,martini,nuritwin,marutaring": {
+ "AreaStoneGraph:AreaShadeGraph@shimaguni,stostone,heyablock,cocktail,martini,nuritwin,marutaring,tetroctb": {
// Same as LITS AreaTetrominoGraph
enabled: true,
relation: { "cell.qans": "node", "border.ques": "separator" },
@@ -356,7 +357,7 @@
"AreaRoomGraph@martini": {
hastop: false
},
- "AreaShade8Graph@cocktail,martini": {
+ "AreaShade8Graph@cocktail,martini,tetroctb": {
enabled: true
},
@@ -647,6 +648,19 @@
"checkShadeDeadEnd"
]
},
+ "AnsCheck@tetroctb#1": {
+ checklist: [
+ "checkShadeCellExist+",
+ "checkOverShadeCell",
+ "checkAdjacentShapes",
+ "checkUnderShadeCell",
+
+ "checkShadeCellCount",
+ "checkBlockHasBorder",
+ "checkConnect8Shade",
+ "doneShadingDecided"
+ ]
+ },
"AnsCheck@shimaguni,stostone,heyablock,cocktail,martini": {
checkSideAreaShadeCell: function() {
this.checkSideAreaCell(
@@ -1055,6 +1069,89 @@
);
}
},
+ "AnsCheck@tetroctb": {
+ checkOverShadeCell: function() {
+ this.checkAllArea(
+ this.board.sblkmgr,
+ function(w, h, a, n) {
+ return a <= 4;
+ },
+ "csGt4"
+ );
+ },
+ checkUnderShadeCell: function() {
+ this.checkAllArea(
+ this.board.sblkmgr,
+ function(w, h, a, n) {
+ return a >= 4;
+ },
+ "csLt4"
+ );
+ },
+ checkAdjacentShapes: function() {
+ var bd = this.board;
+ for (var c = 0; c < bd.cell.length; c++) {
+ var cell = bd.cell[c];
+ if (cell.bx === bd.maxbx - 1 || cell.by === bd.maxby - 1) {
+ continue;
+ }
+
+ var i,
+ adc = cell.adjacent;
+ var cells = [
+ [cell, adc.right.adjacent.bottom],
+ [adc.right, adc.bottom]
+ ];
+ for (i = 0; i < 2; i++) {
+ if (cells[i][0].isShade() && cells[i][1].isShade()) {
+ break;
+ }
+ }
+ if (i === 2) {
+ continue;
+ }
+
+ var block1 = cells[i][0].sblk,
+ block2 = cells[i][1].sblk;
+ if (
+ block1 === block2 ||
+ block1.clist.length !== 4 ||
+ this.isDifferentShapeBlock(block1, block2)
+ ) {
+ continue;
+ }
+
+ this.failcode.add("bsSameShape");
+ if (this.checkOnly) {
+ break;
+ }
+ block1.clist.seterr(1);
+ block2.clist.seterr(1);
+ }
+ },
+ checkBlockHasBorder: function() {
+ var areas = this.board.sblkmgr.components;
+ for (var id = 0; id < areas.length; id++) {
+ var area = areas[id],
+ clist = area.clist;
+ if (
+ clist.length < 4 ||
+ clist.length !== clist[0].stone.clist.length
+ ) {
+ continue;
+ }
+
+ this.failcode.add("bkNoBorder");
+ if (this.checkOnly) {
+ break;
+ }
+ clist.seterr(1);
+ }
+ },
+ checkConnect8Shade: function() {
+ this.checkOneArea(this.board.sblk8mgr, "csDivide");
+ }
+ },
FailCode: {
bkShadeDivide: "bkShadeDivide",
diff --git a/test/script/tetroctb.js b/test/script/tetroctb.js
new file mode 100644
index 000000000..f7e05122f
--- /dev/null
+++ b/test/script/tetroctb.js
@@ -0,0 +1,40 @@
+/* tetroctb.js */
+
+ui.debug.addDebugData("tetroctb", {
+ url: "6/6/va3orecsuf6l31h2i101h11",
+ failcheck: [
+ [
+ "brNoShade",
+ "pzprv3/tetroctb/6/6/15/0 1 2 3 4 5 /0 0 3 3 4 4 /3 3 3 3 6 7 /8 9 3 3 3 3 /10 11 3 3 12 13 /10 10 3 14 12 12 /3 1 . . 2 . /. . . . . . /. . . . . . /1 0 . . . . /1 . . . . 1 /. . . 1 . . /. . . . . . /. . . . . . /. . . . . . /. . . . . . /. . . . . . /. . . . . . /"
+ ],
+ [
+ "csGt4",
+ "pzprv3/tetroctb/6/6/15/0 1 2 3 4 5 /0 0 3 3 4 4 /3 3 3 3 6 7 /8 9 3 3 3 3 /10 11 3 3 12 13 /10 10 3 14 12 12 /3 1 . . 2 . /. . . . . . /. . . . . . /1 0 . . . . /1 . . . . 1 /. . . 1 . . /. . . . . . /. . . . . . /. . . . . . /# . . . . . /# # # # . . /. . . . . . /"
+ ],
+ [
+ "csLt4",
+ "pzprv3/tetroctb/6/6/15/0 1 2 3 4 5 /0 0 3 3 4 4 /3 3 3 3 6 7 /8 9 3 3 3 3 /10 11 3 3 12 13 /10 10 3 14 12 12 /3 1 . . 2 . /. . . . . . /. . . . . . /1 0 . . . . /1 . . . . 1 /. . . 1 . . /# # . . . . /# # . . . . /. . . . . . /# . . . . . /# # . . . . /. . . . . . /"
+ ],
+ [
+ "bsSameShape",
+ "pzprv3/tetroctb/6/6/15/0 1 2 3 4 5 /0 0 3 3 4 4 /3 3 3 3 6 7 /8 9 3 3 3 3 /10 11 3 3 12 13 /10 10 3 14 12 12 /3 1 . . 2 . /. . . . . . /. . . . . . /1 0 . . . . /1 . . . . 1 /. . . 1 . . /# # . # # # /# # . . . # /. . # # # . /# . . # . . /# # # . . # /. . . # # # /"
+ ],
+ [
+ "bkNoBorder",
+ "pzprv3/tetroctb/6/6/15/0 1 2 3 4 5 /0 0 3 3 4 4 /3 3 3 3 6 7 /8 9 3 3 3 3 /10 11 3 3 12 13 /10 10 3 14 12 12 /3 1 . . 2 . /. . . . . . /. . . . . . /1 0 . . . . /1 . . . . 1 /. . . 1 . . /# # . . # # /# # . # . # /. . # # . # /# . . # . . /# # # . # # /. . . # # . /"
+ ],
+ [
+ "csDivide",
+ "pzprv3/tetroctb/6/6/15/0 1 2 3 4 5 /0 0 3 3 4 4 /3 3 3 3 6 7 /8 9 3 3 3 3 /10 11 3 3 12 13 /10 10 3 14 12 12 /3 1 . . 2 . /. . . . . . /. . . . . . /1 0 . . . . /1 . . . . 1 /. . . 1 . . /# # . # # . /# # . . # . /. . . . # . /# . . . . . /# # # . # # /. . . # # . /"
+ ],
+ [
+ "bkShadeNe",
+ "pzprv3/tetroctb/6/6/15/0 1 2 3 4 5 /0 0 3 3 4 4 /3 3 3 3 6 7 /8 9 3 3 3 3 /10 11 3 3 12 13 /10 10 3 14 12 12 /3 1 . . 2 . /. . . . . . /. . . . . . /1 0 . . . . /1 . . . . 1 /. . . 1 . . /# # . . . . /# # . . . . /. . # # # . /# . . # . . /# # # . # # /. . . # # . /"
+ ],
+ [
+ null,
+ "pzprv3/tetroctb/6/6/15/0 1 2 3 4 5 /0 0 3 3 4 4 /3 3 3 3 6 7 /8 9 3 3 3 3 /10 11 3 3 12 13 /10 10 3 14 12 12 /3 1 . . 2 . /. . . . . . /. . . . . . /1 0 . . . . /1 . . . . 1 /. . . 1 . . /# # + # # # /# # + + + # /+ + # # # + /# + + # + + /# # # + # # /+ + + # # + /"
+ ]
+ ],
+ inputs: []
+});