<commit_before>//
// パズル固有スクリプト部 島国・チョコナ・ストストーン版 shimaguni.js
//
(function(pidlist, classbase){
	if(typeof module==='object' && module.exports){module.exports = [pidlist, classbase];}
	else{ pzpr.classmgr.makeCustom(pidlist, classbase);}
}(
['shimaguni','chocona','stostone'], {
//---------------------------------------------------------
// マウス入力系
MouseEvent:{
	use : true,
	
	mouseinput : function(){
		if(this.puzzle.playmode){
			if(this.mousestart || this.mousemove){ this.inputcell();}
		}
		else if(this.puzzle.editmode){
			if(this.mousestart || this.mousemove){ this.inputborder();}
			else if(this.mouseend && this.notInputted()){ this.inputqnum();}
		}
	}
},

//---------------------------------------------------------
// キーボード入力系
KeyEvent:{
	enablemake : true
},

//---------------------------------------------------------
// 盤面管理系
Cell:{
	maxnum : function(){
		return Math.min(255, this.room.clist.length);
	}
},
"Cell@chocona":{
	minnum : 0
},
"Cell@stostone":{
	getFallableLength : function(isdrop){
		if(!this.base.sblk){ return 0;}
		var cell2 = this, len = 0, move = ((isdrop!==false) ? 2 : -2);
		while(!cell2.isnull){
			cell2 = cell2.relcell(0,move);
			if(cell2.isnull || (!!cell2.base.sblk && this.base.sblk!==cell2.base.sblk)){ break;}
			len++;
		}
		return len;
	}
},

Board:{
	hasborder : 1
},
"Board@stostone":{
	cols : 8,
	rows : 8,

	falling : false,

	initBoardSize : function(col,row){
		this.common.initBoardSize.call(this,col,row);
		this.falling = false;
	},
	errclear : function(){
		this.falling = false;
		this.common.errclear.call(this);
	},
	operate : function(type){
		switch(type){
		case 'drop':
		case 'raise':
			this.drop(type==='drop');
			this.falling = true;
			this.haserror = true;
			this.puzzle.redraw();
			break;
		case 'resetpos':
			this.resetpos();
			this.board.errclear();
			break;
		default:
			this.common.operate.call(this,type);
			break;
		}
	},
	resetpos : function(){
		for(var i=0;i<this.cell.length;i++){
			var cell = this.cell[i];
			cell.base = cell.destination = (cell.isShade() ? cell : this.emptycell);
		}
	},
	drop : function(isdrop){
		this.resetpos();
		var fallable = true, blks = this.sblkmgr.components;
		while(fallable){
			fallable = false;
			for(var n=blks.length-1;n>=0;--n){
				var length = blks[n].clist.fall(isdrop);
				if(length>0){ fallable = true;}
			}
		}
	}
},

CellList:{
	getLandAreaOfClist : function(){
		var cnt = 0;
		for(var i=0,len=this.length;i<len;i++){
			if(this[i].isShade()){ cnt++;}
		}
		return cnt;
	},

	isSeqBlock : function(){
		var stack=(this.length>0?[this[0]]:[]), count=this.length, passed={};
		for(var i=0;i<count;i++){ passed[this[i].id]=0;}
		while(stack.length>0){
			var cell=stack.pop();
			if(passed[cell.id]===1){ continue;}
			count--;
			passed[cell.id]=1;
			var list = cell.getdir4clist();
			for(var i=0;i<list.length;i++){
				if(passed[list[i][0].id]===0){ stack.push(list[i][0]);}
			}
		}
		return (count===0);
	}
},
"CellList@stostone":{
	fall : function(isdrop){
		var length = this.board.rows, move = ((isdrop!==false) ? 2 : -2);
		for(var i=0;i<this.length;i++){
			if(this[i].sblk===this[i].relcell(0,move).sblk){ continue;} // Skip if the block also contains bottom neighbor cell
			var len = this[i].destination.getFallableLength(isdrop);
			if(length>len){ length = len;}
			if(length===0){ return 0;}
		}
		var totallen = length + (Math.abs(this[0].destination.by - this[0].by)>>1);
		for(var i=0;i<this.length;i++){
			this[i].destination.base = this.board.emptycell;
		}
		for(var i=0;i<this.length;i++){
			var newcell = this[i].relcell(0,move*totallen);
			this[i].destination = newcell;
			newcell.base = this[i];
		}
		return length;
	}
},

AreaShadeGraph:{
	enabled : true
},
AreaRoomGraph:{
	enabled : true,
	hastop : true
},

//---------------------------------------------------------
// 画像表示系
Graphic:{
	gridcolor_type : "LIGHT",

	enablebcolor : true,
	bgcellcolor_func : "qsub1",

	paint : function(){
		this.drawBGCells();
		this.drawGrid();
		if(this.pid==='stostone'){ this.drawDotCells();}
		this.drawShadedCells();

		this.drawNumbers();

		this.drawBorders();

		this.drawChassis();

		this.drawBoxBorders(false);

		this.drawTarget();
	}
},
"<EMAIL>":{
	bcolor : "rgb(191, 191, 255)"
},
"<EMAIL>":{
	irowakeblk : true,
	enablebcolor : false,
	bgcellcolor_func : "error1",

	minYdeg : 0.08,
	maxYdeg : 0.50,

	getShadedCellColor : function(cell){
		var cell0 = cell;
		if(this.board.falling){ cell = cell.base;}
		if(cell.qans!==1){ return null;}
		var info = cell0.error || cell0.qinfo;
		if     (info===1){ return this.errcolor1;}
		else if(info===2){ return this.errcolor2;}
		else if(cell.trial){ return this.trialcolor;}
		else if(this.puzzle.execConfig('irowakeblk')){ return cell.sblk.color;}
		return this.shadecolor;
	},
	getBorderColor : function(border){
		if(this.board.falling){
			var sblk1 = border.sidecell[0].base.sblk;
			var sblk2 = border.sidecell[1].base.sblk;
			if(!!sblk1 && !!sblk2 && sblk1!==sblk2){ return "white";}
			else if(!!sblk1 || !!sblk2){ return null;}
		}
		if(border.isBorder()){ return this.quescolor;}
		return null;
	},
	getNumberColor : function(cell){
		if(this.board.falling){ cell = cell.base;}
		return this.common.getNumberColor_mixed.call(this,cell);
	}
},

//---------------------------------------------------------
// URLエンコード/デコード処理
Encode:{
	decodePzpr : function(type){
		this.decodeBorder();
		this.decodeRoomNumber16();
	},
	encodePzpr : function(type){
		this.encodeBorder();
		this.encodeRoomNumber16();
	}
},
//---------------------------------------------------------
FileIO:{
	decodeData : function(){
		this.decodeAreaRoom();
		this.decodeCellQnum();<commit_msg>stostone: Fix the shape of the blocks when they are moving<commit_after>//
// パズル固有スクリプト部 島国・チョコナ・ストストーン版 shimaguni.js
//
(function(pidlist, classbase){
	if(typeof module==='object' && module.exports){module.exports = [pidlist, classbase];}
	else{ pzpr.classmgr.makeCustom(pidlist, classbase);}
}(
['shimaguni','chocona','stostone'], {
//---------------------------------------------------------
// マウス入力系
MouseEvent:{
	use : true,
	
	mouseinput : function(){
		if(this.puzzle.playmode){
			if(this.mousestart || this.mousemove){ this.inputcell();}
		}
		else if(this.puzzle.editmode){
			if(this.mousestart || this.mousemove){ this.inputborder();}
			else if(this.mouseend && this.notInputted()){ this.inputqnum();}
		}
	}
},

//---------------------------------------------------------
// キーボード入力系
KeyEvent:{
	enablemake : true
},

//---------------------------------------------------------
// 盤面管理系
Cell:{
	maxnum : function(){
		return Math.min(255, this.room.clist.length);
	}
},
"<EMAIL>":{
	minnum : 0
},
"Cell@stostone":{
	getFallableLength : function(isdrop){
		if(!this.base.sblk){ return 0;}
		var cell2 = this, len = 0, move = ((isdrop!==false) ? 2 : -2);
		while(!cell2.isnull){
			cell2 = cell2.relcell(0,move);
			if(cell2.isnull || (!!cell2.base.sblk && this.base.sblk!==cell2.base.sblk)){ break;}
			len++;
		}
		return len;
	}
},

Board:{
	hasborder : 1
},
"Board@stostone":{
	cols : 8,
	rows : 8,

	falling : false,

	initBoardSize : function(col,row){
		this.common.initBoardSize.call(this,col,row);
		this.falling = false;
	},
	errclear : function(){
		this.falling = false;
		this.common.errclear.call(this);
	},
	operate : function(type){
		switch(type){
		case 'drop':
		case 'raise':
			this.drop(type==='drop');
			this.falling = true;
			this.haserror = true;
			this.puzzle.redraw();
			break;
		case 'resetpos':
			this.resetpos();
			this.board.errclear();
			break;
		default:
			this.common.operate.call(this,type);
			break;
		}
	},
	resetpos : function(){
		for(var i=0;i<this.cell.length;i++){
			var cell = this.cell[i];
			cell.base = cell.destination = (cell.isShade() ? cell : this.emptycell);
		}
	},
	drop : function(isdrop){
		this.resetpos();
		var fallable = true, blks = this.sblkmgr.components;
		while(fallable){
			fallable = false;
			for(var n=blks.length-1;n>=0;--n){
				var length = blks[n].clist.fall(isdrop);
				if(length>0){ fallable = true;}
			}
		}
	}
},

CellList:{
	getLandAreaOfClist : function(){
		var cnt = 0;
		for(var i=0,len=this.length;i<len;i++){
			if(this[i].isShade()){ cnt++;}
		}
		return cnt;
	},

	isSeqBlock : function(){
		var stack=(this.length>0?[this[0]]:[]), count=this.length, passed={};
		for(var i=0;i<count;i++){ passed[this[i].id]=0;}
		while(stack.length>0){
			var cell=stack.pop();
			if(passed[cell.id]===1){ continue;}
			count--;
			passed[cell.id]=1;
			var list = cell.getdir4clist();
			for(var i=0;i<list.length;i++){
				if(passed[list[i][0].id]===0){ stack.push(list[i][0]);}
			}
		}
		return (count===0);
	}
},
"CellList@stostone":{
	fall : function(isdrop){
		var length = this.board.rows, move = ((isdrop!==false) ? 2 : -2);
		for(var i=0;i<this.length;i++){
			if(this[i].sblk===this[i].relcell(0,move).sblk){ continue;} // Skip if the block also contains bottom neighbor cell
			var len = this[i].destination.getFallableLength(isdrop);
			if(length>len){ length = len;}
			if(length===0){ return 0;}
		}
		var totallen = length + (Math.abs(this[0].destination.by - this[0].by)>>1);
		for(var i=0;i<this.length;i++){
			this[i].destination.base = this.board.emptycell;
		}
		for(var i=0;i<this.length;i++){
			var newcell = this[i].relcell(0,move*totallen);
			this[i].destination = newcell;
			newcell.base = this[i];
		}
		return length;
	}
},

AreaShadeGraph:{
	enabled : true
},
AreaRoomGraph:{
	enabled : true,
	hastop : true
},

//---------------------------------------------------------
// 画像表示系
Graphic:{
	gridcolor_type : "LIGHT",

	enablebcolor : true,
	bgcellcolor_func : "qsub1",

	paint : function(){
		this.drawBGCells();
		this.drawGrid();
		if(this.pid==='stostone'){ this.drawDotCells();}
		this.drawShadedCells();

		this.drawNumbers();

		this.drawBorders();

		this.drawChassis();

		this.drawBoxBorders(false);

		this.drawTarget();
	}
},
"<EMAIL>":{
	bcolor : "rgb(191, 191, 255)"
},
"<EMAIL>":{
	irowakeblk : true,
	enablebcolor : false,
	bgcellcolor_func : "error1",

	minYdeg : 0.08,
	maxYdeg : 0.50,

	getShadedCellColor : function(cell){
		var cell0 = cell;
		if(this.board.falling){ cell = cell.base;}
		if(cell.qans!==1){ return null;}
		var info = cell0.error || cell0.qinfo;
		if     (info===1){ return this.errcolor1;}
		else if(info===2){ return this.errcolor2;}
		else if(cell.trial){ return this.trialcolor;}
		else if(this.puzzle.execConfig('irowakeblk')){ return cell.sblk.color;}
		return this.shadecolor;
	},
	getBorderColor : function(border){
		if(this.board.falling){
			var sblk1 = border.sidecell[0].base.sblk;
			var sblk2 = border.sidecell[1].base.sblk;
			if(sblk1!==sblk2){ return "white";}
			else if(!!sblk1 || !!sblk2){ return null;}
		}
		if(border.isBorder()){ return this.quescolor;}
		return null;
	},
	getNumberColor : function(cell){
		if(this.board.falling){ cell = cell.base;}
		return this.common.getNumberColor_mixed.call(this,cell);
	}
},

//---------------------------------------------------------
// URLエンコード/デコード処理
Encode:{
	decodePzpr : function(type){
		this.decodeBorder();
		this.decodeRoomNumber16();
	},
	encodePzpr : function(type){
		this.encodeBorder();
		this.encodeRoomNumber16();
	}
},
//---------------------------------------------------------
FileIO:{
	decodeData : function(){
		this.decodeAreaRoom();
		this.decodeCellQnum();
{'fraction_non_alphanumeric': 0.245663220606273, 'fraction_numerical': 0.015419660066584896, 'mean_word_length': 3.0637237451050194, 'pattern_counts': {'":': 12, '<': 22, '<?xml version=': 0, '>': 22, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1747087', 'n_tokens_mistral': 4769, 'n_tokens_neox': 4326, 'n_words': 723}