皆さん絵クロスって知っていますか?
書き方が様々(?)あるようですのでピンと来ない方もいらっしゃいますよね…。
こう書いた方がわかりやすいかな?「イラストロジック」とか「マリ●のピクロス(爆」
マス目を塗りつぶして行き1つの絵にするものです。
下記スクリーンショットを見ていただければどんな感じのものか想像できますよね。

#define cols 15 ; 1辺のマス数 dim data,cols,cols ; クリックしてスイッチONになったマス dim msgx,cols+1/2,cols ; 横に書かれる塗りつぶすマスのヒント dim msgy,cols+1/2,cols ; 横に書かれる塗りつぶすマスのヒント
;------ ココから問題となるマス --------- msgx.0.0=2,2,2 msgx.0.1=7,3,2 msgx.0.2=7,2,2 msgx.0.3=2,2,2 msgx.0.4=2,3 msgx.0.5=5,6 msgx.0.6=4,5 msgx.0.7=3 msgx.0.8=6,3,2 msgx.0.9=10,2 msgx.0.10=2,2,2,1 msgx.0.11=2,2,2,1 msgx.0.12=3,3,2,1 msgx.0.13=4,2,4 msgx.0.14=3,2,3 msgy.0.0=2,2,2 msgy.0.1=2,2,2,4 msgy.0.2=3,2,2,4 msgy.0.3=6,2,2 msgy.0.4=5,7 msgy.0.5=3,6 msgy.0.6=1,1,1,2 msgy.0.7=3,3 msgy.0.8=6,2,2 msgy.0.9=5,2,3 msgy.0.10=2,2 msgy.0.11=7,2 msgy.0.12=7,3 msgy.0.13=2,5 msgy.0.14=4,4
;-------------- ココまで -------------
初めに一辺の数を定義しています。とりあえず縦横15×15マス位でいいでしょう。
問題マスと書かれたコメントから下は埋めるマスのヒントとなるものを表示する数字です。
例えば「msgx.0.0=2,2,2」は横キーの一番上段のヒントに「2」「2」「2」を入れるということです。
イメージ的には下記の感じです。
┌────┬─┬─┬─┬ │ │ │4│4│ │ │1│2│2│ │ │2│2│2│ │ │2│2│3│ ├────┼─┼─┼─┼ │ 222│ │ │ │ ├────┼─┼─┼─┼ │ 732│ │ │ │ ├────┼─┼─┼─┼
今回初めて2次元配列が出てきました。
a.0.0=1,2,3 a.0.1=4,5,6
上記例は「dim a,3,2」と既に宣言されているものとして、下記の様に書いたものと全く同じです。
a.0.0=1 a.1.0=2 a.2.0=3 a.0.1=4 a.1.1=5 a.2.1=6
縦横共に1次元目が「一辺のマス数+1÷2」と宣言されているのは何でしょう?
これは表示するヒントの最大数です。
つまり長さ15マスでは「1,1,1,1,1,1,1,1」左記の8個あるのが限界ですね。
埋めるマスの間には1マス以上空きがないと繋がった状態になってしまいますし、
2以上の数値が入っているとヒントの最大数が減ってしまいます。
で偶数マス数も偶数に1引いた奇数マス数も最大数は同じです。ココでは15マスも16マスも同じです。
「÷2」とされているのは「最少1マス+空ける最少1マス」を割ったものです(分かりにくい...)。
コレで問題部分の準備は出来ました。
それでは次に上記の問題(ヒント)となる数字やマスの描画処理部分に入ります。
screen 0,cols*20+100,cols*20+100 title "" font "MS ゴシック",13 redraw 0 color 192,192,192 boxf 0,0,winx,100 boxf 0,0,100,winy color boxf 0,0,100,100 repeat cols line cnt*20+100,-1,cnt*20+100,winy line -1,cnt*20+100,winx,cnt*20+100 loop repeat cols repeat cols+1/2 tmp=cols+1/2-cnt-1 if msgx.tmp.cont=0 : continue cont.1+ pos 105-(cont.1*20),104+(cont*20) : mes msgx.tmp.cont ; ヒント描画 loop cont+ cont.1=0 loop cont=0 repeat cols repeat cols+1/2 if msgy.cnt.cont=0 : continue cont.1+ pos 106+(cont*20),102-(cont.1*20) : mes msgy.cnt.cont ; 端からつめてヒントを描画 loop cont+ cont.1=0 loop redraw stop
ココで注意すべき(?)点は一点くらいですね。
ヒントの描画位置・順番なのですが、
通常の順番(左,上が先)ではなく最後・奥(右,下)から始めます。
ソレはマスに近い所にヒントを表示させるためです。
先ほどのイメージだと縦キー左端に「1,2,2」がありますけど「1」(上)側に詰めると不細工ですね^^;
それではユーザーがクリックでマスを埋めて行ける様にキー判定を入れましょう。
左クリックでマスの塗りつぶし、右クリックで塗りつぶしキャンセルとなっています。
塗りつぶし位置ですが、脱初心者ということでif文の多用による塗りつぶし位置チェックをしていません。
*main
wait 5
stick key,768,1
if key&768 {
mx=mousex-100/20
my=mousey-100/20
if mx<0|(my<0)|(mx>=cols)|(my>=cols) : goto *main
if key&256 : color 100,100,100 : data.mx.my = 1 : boxf mx * 20 + 101, my * 20 + 101, mx * 20 + 119, my * 20 + 119
if key&512 : color 255,255,255 : data.mx.my = 0 : boxf mx * 20 + 101, my * 20 + 101, mx * 20 + 119, my * 20 + 119
}
goto *main
それではコレを拡張していきましょうか…。
塗りつぶさないと決定しているマスにチェックを入れておけるとわかりやすくなりますね?
問題もファイルとして保存させて読み込ませるようにしましょうか…。
…ということで問題となるファイルを作成するものが必要となってきますよね。
その問題の作成部分から作って行きましょうか。
ファイルとして保存させておかなければならない情報は何があるでしょう?
まずは縦と横の塗りつぶす数ですね、それも連続している場合は連続した数値を分ける必要もでてきます。
塗りつぶしを1と表わしデータが「1101」の場合、塗るのは「2,1」となってほしいわけです。
また縦横の長さも保存する必要がありますね…大体はコレくらいでしょうか?
では上記のものをファイルとして保存するスクリプトを書いてみましょう。
size=15 ; 1辺のマス数
dim data,size,size
sdim filename,256
screen 0,150,50
title "問題作成ツール"
objsize 150,25
button"保存",save
objsize 100,25
input size,50,,2
pos 50,25 : button"変更",change
ginfo 2
screen 2,size*20,size*20,,prmx+155,prmy
title ""
redraw 0
gosub *drawline
redraw
*main
wait 1
stick key,768,1
if key&768 {
ginfo 1
if prmx=0 : goto *main
mx=mousex/20
my=mousey/20
if mx>=size|(my>=size) : goto *main
if key&256 : data.mx.my=1
if key&512 : data.mx.my=0
gosub *drawmasu
}
goto *main
*drawline
color
repeat size
line -1,cnt*20,size*20,cnt*20
loop
repeat size
line cnt*20,-1,cnt*20,size*20
loop
return
*drawmasu
redraw 0
if key&512 : color 255,255,255 : boxf : gosub *drawline
color 100,100,100
cont=0
repeat size
repeat size
if data.cnt.cont=1 : boxf cnt*20+1,cont*20+1,cnt*20+19,cont*20+19
loop
cont+
loop
redraw
return
*save
dialog"crs",17
if stat=0 : goto *main
filename=refstr
sdim savedata,6144
savedata=""+size+"\n"
cont=0
repeat size
cont.1=0
repeat size
if data.cnt.cont = 1 {
cont.1+
} else {
if cont.1 : str cont.1,2 : savedata += "" + cont.1 : cont.1 = 0
}
loop
if cont.1 : str cont.1,2 : savedata+=""+cont.1
savedata+="\n"
cont+
loop
cont=0
repeat size
cont.1=0
repeat size
if data.cont.cnt = 1 {
cont.1+
} else {
if cont.1 : str cont.1,2 : savedata += "" + cont.1 : cont.1 = 0
}
loop
if cont.1 : str cont.1,2 : savedata+=""+cont.1
if cont<size : savedata+="\n"
cont+
loop
strlen len,savedata
strmid tmp,filename,-1,4
if tmp!=".crs" : filename+=".crs"
bsave filename,savedata,len
goto *main
*change
if size<10 : dialog"10マス未満は指定できません" : goto *main
if size>36 : dialog"36マス以上は指定できません" : goto *main
dim data,size,size
gsel 0
ginfo 2
screen 2,size*20,size*20,,prmx+155,prmy
redraw 0
gosub *drawline
redraw
goto *main
説明するところは…特にないですよね…。
塗りつぶし部分の処理は本体の方とほぼ同じでいけますので、重要な部分はやはり保存だけでしょう。
重要と言っても決して難しいわけではなく(人によっては難しいかもしれませんが…)、
塗りつぶす部分が続いていればループカウンタとは別にカウンタを設けておいてやるだけですね。
そのカウンタの保存の形式ですが、
連続した数が1桁や2桁あったりするのでこれは1桁、あれは2桁とわかるようにしないといけません。
例えば「132104」は「1,3,2,10,4」「13,2,10,4」「1,3,21,10,4」「1,32,10,4」なのかわかりませんね。
ですのでコンマで区切り、コンマまでが1つの数値である、とか決めておきましょう。
私は10未満のものも2桁にしてしまい2桁取り出して数値化すればわかるようにしてみました。
右記の感じで。「13021004」と保存することで「13,2(02),10,4(04)」とわかる。
一列のマス数も分かるようにしておかなければなりません。列数も同時に保存しておきます。
それではこれで作成したファイルを読み込むタイプの絵クロスを完成させましょう。
また微妙にいろいろな部分が変わったりしていますので初めから最後まで書きます。
dialog"crs",16,"絵クロス問題データ" if stat=0 : end sdim filename,256 filename=refstr exist filename sdim filedata,strsize+1 bload filename,filedata notesel filedata noteget cols,0 ; 列数読み込み int cols dim data,cols,cols dim msgx,cols+1/2,cols dim msgy,cols+1/2,cols
; ---------- 問題読み込み ---------- repeat cols linex+ noteget tmpstr,linex strlen len,tmpstr len=len/2 arrangement=linex-1 repeat len strmid tmp,tmpstr,cnt*2,2 int tmp if tmp=0 : break msgx.cnt.arrangement=tmp loop loop repeat cols linex+ noteget tmpstr,linex strlen len,tmpstr len=len/2 arrangement=linex-cols-1 repeat len strmid tmp,tmpstr,cnt*2,2 int tmp if tmp=0 : break msgy.cnt.arrangement=tmp loop loop
; ------------ ココまで ------------ screen 0,cols*20+(cols*8),cols*20+(cols*8) title "" font "MS ゴシック",12 redraw 0 color 192,192,192 boxf 0,0,winx,(cols*8) boxf 0,0,(cols*8),winy color boxf 0,0,(cols*8),(cols*8) repeat cols line cnt*20+(cols*8),-1,cnt*20+(cols*8),winy line -1,cnt*20+(cols*8),winx,cnt*20+(cols*8) loop repeat cols repeat cols+1/2 tmp=cols+1/2-cnt-1 if msgx.tmp.cont=0 : continue cont.1+ pos cols*8-(cont.1*15),cols*8+(cont*20)+5 : mes msgx.tmp.cont loop cont+ cont.1=0 loop cont=0 repeat cols repeat cols+1/2 tmp=cols+1/2-cnt-1 if msgy.tmp.cont=0 : continue cont.1+ pos cols*8+(cont*20)+5,cols*8-(cont.1*16) : mes msgy.tmp.cont loop cont+ cont.1=0 loop redraw *main wait 1 stick key,256,1 if key&768 { mx=mousex-(cols*8)/20 my=mousey-(cols*8)/20 if mx<0|(my<0)|(mx>=cols)|(my>=cols) : goto *main if key&256 { data.mx.my=1 color 100,100,100 boxf mx*20+(cols*8)+1,my*20+(cols*8)+1,mx*20+(cols*8)+19,my*20+(cols*8)+19 } if key&512 { if data.mx.my=0 { data.mx.my=-1 color 255 line mx*20+(cols*8),my*20+(cols*8),mx*20+19+(cols*8),my*20+19+(cols*8) ; ×印 line mx*20+(cols*8)+19,my*20+(cols*8),mx*20+(cols*8)+1,my*20+(cols*8)+19 ; ×印 goto *main } data.mx.my=0 color 255,255,255 boxf mx*20+(cols*8)+1,my*20+(cols*8)+1,mx*20+(cols*8)+19,my*20+(cols*8)+19 } } goto *main
このサンプルはただ単にマスを塗りつぶしていくだけのもので出来上がってもクリアというものがありません。
その辺は各自いろいろと工夫してください。
またバグ等もありましたら頑張って取り除いてください(--;
スクリプトはコチラをどうぞ。経過時間表示が付いただけです。
それでは〜。