1- 'use strict' ;
2- // SECTOR_1:定数群
3- const ORB_COLORS = 5 ;
4- const [ BASE_SCORE , SCORE_EXPONENT ] = [ 100 , 1.5 ] ;
5- const ANIM_SPEED = 100 ;
6- const SHORTEST_CHAIN = 3 ;
7- const MAIN_BOARD = document . querySelector ( "#puz_board" ) ;
8- const DIV_PUZ_DISPLAY = document . querySelector ( "#puz_display" ) ;
9- const DIV_STAGE_SELECT = document . querySelector ( "#stage_select" ) ;
10- const DATALINK = "../Data/Stage/1.js" ;
11- const [ ALT_ORB , ALT_OBJECT , ALT_FIELD ] = [ "□🔴🔵🟢🟡🟣" , "□🧱🌸" , "□🥬" ] ;
12- // SECTOR_2:変数群
13- let [ chain_now , chainable ] = [ false , false ] ;
14- let chain_info = { color : null , count : 0 } ;
15- let chain_yx = new Array ( ) ; //[i].(x | y)
16- let adj_list = new Array ( ) ; //[i].(y | x)
17- //SECTOR_2.5:準const変数群
18- let PUZ_BOARD_BONE = new Array ( ) ;
19- let DATA = { } ;
20- // SECTOR_3:関数マニュアル
21- // fallable(obj_type) : 該当オブジェクトが落下物か確認
22- // is_adj_break(obj_type) : 該当オブジェクトがadj_breakを持つか確認
23- // update_cell(y,x) : 1マスだけ画面を更新
24- // update_display() : 関数名通り
25- // obj_erase(y,x,draw=false) : 指定したマスを消す。drawなら描画する。
26- // load_board() : [TODO] ファイルからパズルの読み込みをする
27- // falling_orb() : 関数名通り
28- // onmouce_cell(cell) : チェイン中の処理とかやってます
29- // chain_toggler(cell) : 関数名通り
30- // board_init() : 関数名通り
31- // startgame() : 関数名通り
32- const fallable = obj_type => ( obj_type > 0 ) || [ - 2 ] . includes ( obj_type ) ;
33- const is_adj_break = obj_type => [ - 2 ] . includes ( obj_type ) ;
34- const dest_sync = field_type => [ 1 ] . includes ( field_type ) ;
35- const alt_text = ( type , isobj ) => isobj ?( type < 0 ?ALT_OBJECT [ - type ] :ALT_ORB [ type ] ) :ALT_FIELD [ type ] ;
36- const update_cell = ( y , x ) => {
37- const CELL = PUZ_BOARD_BONE [ y ] [ x ] ;
38- [ CELL . querySelector ( "img.object" ) . src , CELL . querySelector ( "img.field" ) . src ,
39- CELL . querySelector ( "img.object" ) . alt , CELL . querySelector ( "img.field" ) . alt ] =
40- [ `Pictures/Orbs/${ DATA . board . obj [ y ] [ x ] [ 0 ] } .svg` , `Pictures/Fields/${ DATA . board . field [ y ] [ x ] [ 0 ] } .svg` ,
41- alt_text ( DATA . board . obj [ y ] [ x ] [ 0 ] , true ) , alt_text ( DATA . board . field [ y ] [ x ] [ 0 ] , false ) ] ;
42- }
43- const object_copy = x => JSON . parse ( JSON . stringify ( x ) ) ;
1+ export default ( ) => {
2+ // SECTOR_1:定数群
3+ const ORB_COLORS = 5 ;
4+ const [ BASE_SCORE , SCORE_EXPONENT ] = [ 100 , 1.5 ] ;
5+ const ANIM_SPEED = 100 ;
6+ const SHORTEST_CHAIN = 3 ;
7+ const MAIN_BOARD = document . querySelector ( "#puz_board" ) ;
8+ const DIV_PUZ_DISPLAY = document . querySelector ( "#puz_display" ) ;
9+ const DATALINK = "../Data/Stage/1.js" ;
10+ const [ ALT_ORB , ALT_OBJECT , ALT_FIELD ] = [ "□🔴🔵🟢🟡🟣" , "□🧱🌸" , "□🥬" ] ;
11+ // SECTOR_2:変数群
12+ let [ chain_now , chainable ] = [ false , false ] ;
13+ let chain_info = { color : null , count : 0 } ;
14+ let chain_yx = new Array ( ) ; //[i].(x | y)
15+ let adj_list = new Array ( ) ; //[i].(y | x)
16+ //SECTOR_2.5:準const変数群
17+ let PUZ_BOARD_BONE = new Array ( ) ;
18+ let DATA = { } ;
19+ // SECTOR_3:関数マニュアル
20+ // fallable(obj_type) : 該当オブジェクトが落下物か確認
21+ // is_adj_break(obj_type) : 該当オブジェクトがadj_breakを持つか確認
22+ // update_cell(y,x) : 1マスだけ画面を更新
23+ // update_display() : 関数名通り
24+ // obj_erase(y,x,draw=false) : 指定したマスを消す。drawなら描画する。
25+ // load_board() : [TODO] ファイルからパズルの読み込みをする
26+ // falling_orb() : 関数名通り
27+ // onmouce_cell(cell) : チェイン中の処理とかやってます
28+ // chain_toggler(cell) : 関数名通り
29+ // board_init() : 関数名通り
30+ // startgame() : 関数名通り
31+ const fallable = obj_type => ( obj_type > 0 ) || [ - 2 ] . includes ( obj_type ) ;
32+ const is_adj_break = obj_type => [ - 2 ] . includes ( obj_type ) ;
33+ const dest_sync = field_type => [ 1 ] . includes ( field_type ) ;
34+ const alt_text = ( type , isobj ) => isobj ?( type < 0 ?ALT_OBJECT [ - type ] :ALT_ORB [ type ] ) :ALT_FIELD [ type ] ;
35+ const update_cell = ( y , x ) => {
36+ const CELL = PUZ_BOARD_BONE [ y ] [ x ] ;
37+ [ CELL . querySelector ( "img.object" ) . src , CELL . querySelector ( "img.field" ) . src ,
38+ CELL . querySelector ( "img.object" ) . alt , CELL . querySelector ( "img.field" ) . alt ] =
39+ [ `Pictures/Orbs/${ DATA . board . obj [ y ] [ x ] [ 0 ] } .svg` , `Pictures/Fields/${ DATA . board . field [ y ] [ x ] [ 0 ] } .svg` ,
40+ alt_text ( DATA . board . obj [ y ] [ x ] [ 0 ] , true ) , alt_text ( DATA . board . field [ y ] [ x ] [ 0 ] , false ) ] ;
41+ }
42+ const object_copy = x => JSON . parse ( JSON . stringify ( x ) ) ;
4443
45- const update_display = ( ) => {
46- for ( let i = 0 ; i < DATA . size . Height ; i ++ ) for ( let j = 0 ; j < DATA . size . Width ; j ++ ) update_cell ( i , j ) ;
47- document . querySelector ( "#puz_info" ) . innerText = `Score : ${ DATA . target . score } Hand : ${ DATA . target . hand } ` ;
48- }
49- const obj_erase = ( y , x , isobj = true ) => {
50- ( isobj ?DATA . board . obj :DATA . board . field ) [ y ] [ x ] = [ 0 , 0 ] ;
51- update_cell ( y , x ) ;
52- }
53- const break_obj = ( y , x , ischain , isobj = true ) => {
54- const TARGET = isobj ?DATA . board . obj [ y ] [ x ] :DATA . board . field [ y ] [ x ] ;
55- if ( -- TARGET [ 1 ] <= 0 || ischain ) {
56- if ( ! isobj && TARGET [ 0 ] === 1 ) DATA . target . score += BASE_SCORE ;
57- obj_erase ( y , x , isobj ) ;
58- isobj && dest_sync ( DATA . board . field [ y ] [ x ] [ 0 ] ) && break_obj ( y , x , false , false ) ;
44+ const update_display = ( ) => {
45+ for ( let i = 0 ; i < DATA . size . Height ; i ++ ) for ( let j = 0 ; j < DATA . size . Width ; j ++ ) update_cell ( i , j ) ;
46+ document . querySelector ( "#puz_info" ) . innerText = `Score : ${ DATA . target . score } Hand : ${ DATA . target . hand } ` ;
5947 }
60- }
61- const fall_obj = ( yfrom , xfrom , yto , xto ) => {
62- const [ OBJ_TO , OBJ_FROM ] = [ DATA . board . obj [ yto ] [ xto ] , DATA . board . obj [ yfrom ] [ xfrom ] ] ;
63- if ( OBJ_TO [ 0 ] === 0 && fallable ( OBJ_FROM [ 0 ] ) ) {
64- [ OBJ_TO [ 0 ] , OBJ_TO [ 1 ] ] = OBJ_FROM ;
65- update_cell ( yto , xto ) ;
66- obj_erase ( yfrom , xfrom ) ;
67- return true ;
48+ const obj_erase = ( y , x , isobj = true ) => {
49+ ( isobj ?DATA . board . obj :DATA . board . field ) [ y ] [ x ] = [ 0 , 0 ] ;
50+ update_cell ( y , x ) ;
6851 }
69- else return false ;
70- }
71- const falling_orb = ( ) => {
72- chainable = false ;
73- const FALL_TIMER = setInterval ( ( ) => {
74- let refall = false ;
75- for ( let i = DATA . size . Height - 1 ; i > 0 ; i -- ) /*性質上、下から探索したほうがいい*/ {
76- for ( let j = 0 ; j < DATA . size . Width ; j ++ ) refall = fall_obj ( i - 1 , j , i , j ) || refall ; //C-shift
77- for ( let j = 1 ; j < DATA . size . Width ; j ++ ) refall = fall_obj ( i - 1 , j , i , j - 1 ) || refall ; //L-shift
78- for ( let j = 0 ; j < DATA . size . Width - 1 ; j ++ ) refall = fall_obj ( i - 1 , j , i , j + 1 ) || refall ; //R-shift
52+ const break_obj = ( y , x , ischain , isobj = true ) => {
53+ const TARGET = isobj ?DATA . board . obj [ y ] [ x ] :DATA . board . field [ y ] [ x ] ;
54+ if ( -- TARGET [ 1 ] <= 0 || ischain ) {
55+ if ( ! isobj && TARGET [ 0 ] === 1 ) DATA . target . score += BASE_SCORE ;
56+ obj_erase ( y , x , isobj ) ;
57+ isobj && dest_sync ( DATA . board . field [ y ] [ x ] [ 0 ] ) && break_obj ( y , x , false , false ) ;
7958 }
80- DATA . board . obj [ 0 ] = DATA . board . obj [ 0 ] . map ( x => ( x [ 0 ] === 0 ) ?( refall = true , [ ~ ~ ( Math . random ( ) * ORB_COLORS ) + 1 , 1 ] ) :x ) ;
81- if ( ! refall ) {
82- clearInterval ( FALL_TIMER ) ;
83- chainable = true ;
59+ }
60+ const fall_obj = ( yfrom , xfrom , yto , xto ) => {
61+ const [ OBJ_TO , OBJ_FROM ] = [ DATA . board . obj [ yto ] [ xto ] , DATA . board . obj [ yfrom ] [ xfrom ] ] ;
62+ if ( OBJ_TO [ 0 ] === 0 && fallable ( OBJ_FROM [ 0 ] ) ) {
63+ [ OBJ_TO [ 0 ] , OBJ_TO [ 1 ] ] = OBJ_FROM ;
64+ update_cell ( yto , xto ) ;
65+ obj_erase ( yfrom , xfrom ) ;
66+ return true ;
8467 }
85- update_display ( ) ;
86- } , ANIM_SPEED ) ;
87- }
88- const onmouce_cell = cell => {
89- const [ CELL_Y , CELL_X ] = [ cell . target . parentNode . rowIndex , cell . target . cellIndex ] ;
90- const CELL_COLOR = DATA . board . obj [ CELL_Y ] [ CELL_X ] [ 0 ] ;
91- if ( chain_now &&
92- Math . abs ( chain_yx . at ( - 1 ) . y - CELL_Y ) <= 1 && Math . abs ( chain_yx . at ( - 1 ) . x - CELL_X ) <= 1 /*位置チェック*/ &&
93- chain_info . color === CELL_COLOR && ! chain_yx . some ( e => e . x === CELL_X && e . y === CELL_Y ) ) /*条件チェック*/ {
94- cell . target . querySelector ( "img" ) . classList . add ( "chaining" ) ;
95- chain_yx . push ( { x : CELL_X , y : CELL_Y } ) ;
96- chain_info . count ++ ;
68+ else return false ;
9769 }
98- }
99- const chain_toggler = cell => {
100- if ( ! chainable ) return ;
101- const [ CELL_Y , CELL_X ] = [ cell . target . parentNode . rowIndex , cell . target . cellIndex ] ;
102- const CELL_COLOR = DATA . board . obj [ CELL_Y ] [ CELL_X ] [ 0 ] ;
103- if ( chain_now ) { //チェイン終了時の処理
104- chain_now = false ;
105- if ( ! ( chain_info . count < SHORTEST_CHAIN ) ) {
106- DATA . target . score += ~ ~ ( chain_info . count ** SCORE_EXPONENT * BASE_SCORE ) ;
107- DATA . target . hand -- ;
108- chain_yx . forEach ( pos => {
109- break_obj ( pos . y , pos . x , true ) ;
110- for ( let dy = - 1 ; dy <= 1 ; dy ++ ) {
111- const NEWY = pos . y + dy ;
112- for ( let dx = - 1 ; dx <= 1 ; dx ++ ) {
113- const NEWX = pos . x + dx ;
114- DATA . board . obj [ NEWY ] ?. [ NEWX ] && ( adj_list . some ( e => e . x === NEWX && e . y === NEWY ) || adj_list . push ( { y : NEWY , x : NEWX } ) ) ;
115- }
116- }
117- } ) ;
118- adj_list . forEach ( pos => is_adj_break ( DATA . board . obj [ pos . y ] [ pos . x ] [ 0 ] ) && break_obj ( pos . y , pos . x , false ) ) ;
70+ const falling_orb = ( ) => {
71+ chainable = false ;
72+ const FALL_TIMER = setInterval ( ( ) => {
73+ let refall = false ;
74+ for ( let i = DATA . size . Height - 1 ; i > 0 ; i -- ) /*性質上、下から探索したほうがいい*/ {
75+ for ( let j = 0 ; j < DATA . size . Width ; j ++ ) refall = fall_obj ( i - 1 , j , i , j ) || refall ; //C-shift
76+ for ( let j = 1 ; j < DATA . size . Width ; j ++ ) refall = fall_obj ( i - 1 , j , i , j - 1 ) || refall ; //L-shift
77+ for ( let j = 0 ; j < DATA . size . Width - 1 ; j ++ ) refall = fall_obj ( i - 1 , j , i , j + 1 ) || refall ; //R-shift
78+ }
79+ DATA . board . obj [ 0 ] = DATA . board . obj [ 0 ] . map ( x => ( x [ 0 ] === 0 ) ?( refall = true , [ ~ ~ ( Math . random ( ) * ORB_COLORS ) + 1 , 1 ] ) :x ) ;
80+ if ( ! refall ) {
81+ clearInterval ( FALL_TIMER ) ;
82+ chainable = true ;
83+ }
11984 update_display ( ) ;
120- falling_orb ( ) ;
85+ } , ANIM_SPEED ) ;
86+ }
87+ const onmouce_cell = cell => {
88+ const [ CELL_Y , CELL_X ] = [ cell . target . parentNode . rowIndex , cell . target . cellIndex ] ;
89+ const CELL_COLOR = DATA . board . obj [ CELL_Y ] [ CELL_X ] [ 0 ] ;
90+ if ( chain_now &&
91+ Math . abs ( chain_yx . at ( - 1 ) . y - CELL_Y ) <= 1 && Math . abs ( chain_yx . at ( - 1 ) . x - CELL_X ) <= 1 /*位置チェック*/ &&
92+ chain_info . color === CELL_COLOR && ! chain_yx . some ( e => e . x === CELL_X && e . y === CELL_Y ) ) /*条件チェック*/ {
93+ cell . target . querySelector ( "img" ) . classList . add ( "chaining" ) ;
94+ chain_yx . push ( { x : CELL_X , y : CELL_Y } ) ;
95+ chain_info . count ++ ;
12196 }
122- chain_yx . forEach ( pos => PUZ_BOARD_BONE [ pos . y ] [ pos . x ] . querySelector ( "img" ) . classList . remove ( "chaining" ) ) ;
123- chain_info = { count : 0 , color : null } ;
124- adj_list = chain_yx = [ ] ;
125- if ( DATA . target . hand <= 0 ) {
126- alert ( `ゲームオーバー! スコアは${ DATA . target . score } でした!` ) ;
127- DIV_STAGE_SELECT . style . display = "block" ;
128- DIV_PUZ_DISPLAY . style . display = "none" ;
97+ }
98+ const chain_toggler = cell => {
99+ if ( ! chainable ) return ;
100+ const [ CELL_Y , CELL_X ] = [ cell . target . parentNode . rowIndex , cell . target . cellIndex ] ;
101+ const CELL_COLOR = DATA . board . obj [ CELL_Y ] [ CELL_X ] [ 0 ] ;
102+ if ( chain_now ) { //チェイン終了時の処理
103+ chain_now = false ;
104+ if ( ! ( chain_info . count < SHORTEST_CHAIN ) ) {
105+ DATA . target . score += ~ ~ ( chain_info . count ** SCORE_EXPONENT * BASE_SCORE ) ;
106+ DATA . target . hand -- ;
107+ chain_yx . forEach ( pos => {
108+ break_obj ( pos . y , pos . x , true ) ;
109+ for ( let dy = - 1 ; dy <= 1 ; dy ++ ) {
110+ const NEWY = pos . y + dy ;
111+ for ( let dx = - 1 ; dx <= 1 ; dx ++ ) {
112+ const NEWX = pos . x + dx ;
113+ DATA . board . obj [ NEWY ] ?. [ NEWX ] && ( adj_list . some ( e => e . x === NEWX && e . y === NEWY ) || adj_list . push ( { y : NEWY , x : NEWX } ) ) ;
114+ }
115+ }
116+ } ) ;
117+ adj_list . forEach ( pos => is_adj_break ( DATA . board . obj [ pos . y ] [ pos . x ] [ 0 ] ) && break_obj ( pos . y , pos . x , false ) ) ;
118+ update_display ( ) ;
119+ falling_orb ( ) ;
120+ }
121+ chain_yx . forEach ( pos => PUZ_BOARD_BONE [ pos . y ] [ pos . x ] . querySelector ( "img" ) . classList . remove ( "chaining" ) ) ;
122+ chain_info = { count : 0 , color : null } ;
123+ adj_list = chain_yx = [ ] ;
124+ if ( DATA . target . hand <= 0 ) {
125+ alert ( `ゲームオーバー! スコアは${ DATA . target . score } でした!` ) ;
126+ DIV_PUZ_DISPLAY . style . display = "none" ;
127+ document . querySelector ( "#move_START" ) . onclick ( ) ;
128+ }
129+ } else if ( CELL_COLOR > 0 ) { //チェイン開始の処理
130+ chain_now = true ;
131+ chain_info = { count : 1 , color : CELL_COLOR } ;
132+ chain_yx . push ( { x : CELL_X , y : CELL_Y } ) ;
133+ cell . target . querySelector ( "img" ) . classList . add ( "chaining" ) ;
129134 }
130- } else if ( CELL_COLOR > 0 ) { //チェイン開始の処理
131- chain_now = true ;
132- chain_info = { count : 1 , color : CELL_COLOR } ;
133- chain_yx . push ( { x : CELL_X , y : CELL_Y } ) ;
134- cell . target . querySelector ( "img" ) . classList . add ( "chaining" ) ;
135135 }
136- }
137- const load_board = ( ) => {
138- PUZ_BOARD_BONE = new Array ( DATA . size . Height ) . fill ( ) . map ( _ => Array ( DATA . size . Width ) ) ;
139- MAIN_BOARD . innerHTML = null ;
140- for ( let i = 0 ; i < DATA . size . Height ; i ++ ) {
141- const TR = document . createElement ( "tr" ) ;
142- TR . classList . add ( "puz_board_tr" ) ;
143- for ( let j = 0 ; j < DATA . size . Width ; j ++ ) {
144- const TD = document . createElement ( "td" ) ;
145- TD . classList . add ( "inboard" ) ;
146- TD . onmouseover = onmouce_cell ;
147- TD . addEventListener ( 'click' , chain_toggler ) ;
148- TR . appendChild ( TD ) ;
149- TD . innerHTML = `<img src="Pictures/Orbs/0.svg",width="40" height="40" class="notouch upper object" alt=" ">
150- <img src="Pictures/Fields/0.svg",width="40" height="40" class="notouch field" alt=" ">` ;
151- PUZ_BOARD_BONE [ i ] [ j ] = TD ;
136+ const load_board = ( ) => {
137+ PUZ_BOARD_BONE = new Array ( DATA . size . Height ) . fill ( ) . map ( _ => Array ( DATA . size . Width ) ) ;
138+ MAIN_BOARD . innerHTML = null ;
139+ for ( let i = 0 ; i < DATA . size . Height ; i ++ ) {
140+ const TR = document . createElement ( "tr" ) ;
141+ TR . classList . add ( "puz_board_tr" ) ;
142+ for ( let j = 0 ; j < DATA . size . Width ; j ++ ) {
143+ const TD = document . createElement ( "td" ) ;
144+ TD . classList . add ( "inboard" ) ;
145+ TD . onmouseover = onmouce_cell ;
146+ TD . addEventListener ( 'click' , chain_toggler ) ;
147+ TR . appendChild ( TD ) ;
148+ TD . innerHTML = `<img src="Pictures/Orbs/0.svg",width="40" height="40" class="notouch upper object" alt=" ">
149+ <img src="Pictures/Fields/0.svg",width="40" height="40" class="notouch field" alt=" ">` ;
150+ PUZ_BOARD_BONE [ i ] [ j ] = TD ;
151+ }
152+ MAIN_BOARD . appendChild ( TR ) ;
152153 }
153- MAIN_BOARD . appendChild ( TR ) ;
154154 }
155- }
156- const board_init = ( ) => {
157- console . log ( document . querySelector ( "#startbutton" ) ) ;
158- load_board ( ) ;
159- falling_orb ( ) ;
160- adj_list = chain_yx = [ ] ;
161- update_display ( ) ;
162- }
163- const startgame = ( ) => {
164- DIV_STAGE_SELECT . style . display = "none" ;
165- DIV_PUZ_DISPLAY . style . display = "block" ;
166- import ( DATALINK )
167- . then ( x => { DATA = object_copy ( x . default ) ; board_init ( ) } ) ;
168- } ;
169- document . querySelector ( "#startbutton" ) . onclick = startgame ;
155+ const board_init = ( ) => {
156+ load_board ( ) ;
157+ falling_orb ( ) ;
158+ adj_list = chain_yx = [ ] ;
159+ update_display ( ) ;
160+ }
161+ const startgame = ( ) => {
162+ DIV_PUZ_DISPLAY . style . display = "block" ;
163+ import ( DATALINK )
164+ . then ( x => { DATA = object_copy ( x . default ) ; board_init ( ) } ) ;
165+ } ;
166+ document . querySelector ( "#move_GAME" ) . onclick = startgame ;
167+ }
0 commit comments