Hatena::Groupnadesiko

雪乃☆雫のなでしこ日和

2019-06-10

お絵描き

| 12:33

 なでしこ3が、バージョンアップしていました☆

 こんな感じ~。

v3.0.61
・ブラウザ番にタッチイベントを追加(#388)
・『取り込む』でモジュールの読み込みを修正(#387)
・『オーディオ開く』『オーディオ再生』などの命令を追加(#386)
・REPLが動かなかった問題を修正(#384)

 早速、audio関係の命令を追加して頂けました!(≧▽≦)

 ありがたや~。

 でも、なかなか思うようにならないので、色々お試し中~。


 さて、マイナビ連載44目は、クレカのチェックディジットの計算でした。

https://news.mynavi.jp/article/nadeshiko-44/

 チェックディジットとゆうものについては、前にNDLの書籍検索をやっていた時に、ISBNのチェックディジットを学んだ。

https://nadesiko.g.hatena.ne.jp/snowdrops89/20180322/1521734784

 ・・・ので、これをv3に移植してみようかと思ったんだけど、出来なかったorz

 NDLAPIがクロスドメイン? に対応してないっぽい。AJAX送信が、出来ないんだよね。

 この問題はどうも、向こうが対応してくれない限り、こっちからはどうしようも出来ないっぽい?

 GoogleBooksAPIでなら出来そうだけど、日本語のリファレンスがないからにゃー(´・ω・`)

 ・・・て感じで、記事には出来なかった;;;


 して、マイナビ連載45目は「ブラウザで使える手書きメモCanvas APIで作ってみよう」でした。

https://news.mynavi.jp/article/nadeshiko-45/

 前にね、掲示板の質問で、手書きメモのプログラムがマウスを早く動かすと点になっちゃうんだけどどうしたら良いんでしょうとゆうのがあって、なにゆえ「」なんだろうと思ったけど、元が10行プログラムのだったので、の方がプログラムが短くできるんですよね。

 して、ので理由がもう一つ発覚だ。かわいいからw

 色を変えるとなんか急に可愛くなるwww


 しかしまぁ、ここはやっぱり、あえて描画で滑らかなが引けるようにしてみようと思ったワケです。

 ところが! 滑らかに引けません。なに~?!

元x=0。元y=0。x=0。y=0。20に太設定。
押下フラグ=オフ
C=描画中キャンバス。
# --- (*1) 
Cをマウス押した時には
  押下フラグ=オン。
  元x=マウスX。元y=マウスY。
ここまで。
# --- (*2)
Cをマウス移動した時には
  もし、押下フラグがオフならば戻る。
  x=マウスX。y=マウスY。
  [元x,元y]から[x,y]へ描画。
  元x=x。元y=y。
ここまで。
# --- (*3)
Cをマウス離した時には
  押下フラグ=オフここまで。
「描画を開始」と表示

 太いを斜めに引くと切れ切れになるよ!

 どうやら、の終端のスタイルがv1のとは違うんですね。

 v1のは終端が丸になっているので、が埋められ滑らかなになるんです。

 これは、太くて短いが描けないとゆうことでもあるので、どっちが良いとゆう話ではありませんが。

 javascriptではそうゆう様々なスタイルが変更も可能らしいんだけども、具合わるくなるからやめて、どうよこの素敵な無理矢理系!www

元x=0。元y=0。x=0。y=0。
押下フラグ=オフ
C=描画中キャンバス。
# --- (*1) 
Cをマウス押した時には
  押下フラグ=オン。
  元x=マウスX。元y=マウスY。
ここまで。
# --- (*2)
Cをマウス移動した時には
  もし、押下フラグがオフならば戻る。
  x=マウスX。y=マウスY。
  1に太設定。
  [x,y]へ9の描画。
  20に太設定。
  [元x,元y]から[x,y]へ描画。
  元x=x。元y=y。
ここまで。
# --- (*3)
Cをマウス離した時には
  押下フラグ=オフここまで。
「描画を開始」と表示

 ・・・あれ?

 忘れてたけど、の場合、スマホの時にはどうすればいいんだ?

 、タッチした時のイベントが追加されて、これまで15パズルもジャンケンマンもスマホで出来たから、マウスのイベントでスマホも出来るとばかり思っていたけど、なるほど「移動した時」は出来ないっぽい?

 タッチ開始時とタッチ時にすれば出来るのかなあ。

 おっと、できたできた(喜)

 良き良き♪

#-----------------------------------------------
# お絵描き
#-----------------------------------------------
画面w=640。画面h=480。押下フラグ=オフ。
元x=0。元y=0。x=0。y=0。ペン=10。色=「#000000」

#---HTMLの設置----------
HTML=「
  <div id="main">
    <canvas id='canvas_1' width={画面w} height={画面h}></canvas>
  </div><!--main-->
  <div id="gui">
  <input type="color" id="color">
  <select id="pen">
    <option value="20">極太</option>
    <option value="15">太</option>
    <option value="10" selected>中</option>
    <option value="5">細</option>
    <option value="2">極細</option>
  </select>
  </div><!--gui-->
」
「#nako3_div_1」にHTMLを、DOM_HTML設定。
「canvas#canvas_1」のDOM要素取得。
それへ描画開始

#---GUI設置----------
「#gui」にDOM親要素設定。
//ペンサイズ=["極太","太","中","細","極細"]
//ペンサイズのセレクトボックス作成し、太セレクトに代入。  #selectedとvalueの設定が出来ない・・・
「クリア」のボタン作成し、クリアボタン代入。

#---GUIイベント----------
クリアボタンをクリックした時には
  [0, 0, 640, 480]の描画クリア。
ここまで。

#---CSS設定----------
「#main」に{
  "幅": "{画面w}px"
  "高さ": "{画面h}px"
  "border": "2px solid #999999"
}をDOMスタイル一括設定。

「#gui」に{
  "幅": "{画面w}px"
  "高さ": "30px"
}をDOMスタイル一括設定。

「#color」に{
  "margin":"2px 10px"
}をDOMスタイル一括設定。

「#pen」に{
  "margin":"0px 10px"
  "padding":"2px 10px 0px 10px"
}をDOMスタイル一括設定。

クリアボタンに{
  "margin":"0px 10px"
  "padding":"3px 10px 0px 10px"
}をDOMスタイル一括設定。

#---マウスイベント----------
C=描画中キャンバス。
Cをマウス押した時には
  押下フラグ=オン。
  元x=マウスX。元y=マウスY。
  ペン設定。
ここまで。
Cをマウス移動した時には
  もし、押下フラグがオフならば戻る。
  x=マウスX。y=マウスY。
  絵描。
ここまで。
Cをマウス離した時には
  押下フラグ=オフここまで。

#---タッチイベント----------
Cをタッチ開始した時には(E)
  EのDOMイベント処理停止
  元x=タッチX。元y=タッチY。
  ペン設定。
ここまで。
Cをタッチした時には
  x=タッチX。y=タッチY。
  絵描。
ここまで。


●ペン設定
  色=「#color」の「value」をDOM属性取得。
  色に線色設定。色に塗色設定。
  ペン=「#pen」の「value」をDOM属性取得。
ここまで。

●絵描
  1に太設定。
  [x,y]へペン/2-1の描画。
  ペンに太設定。
  [元x,元y]から[x,y]へ描画。
  元x=x。元y=y。
ここまで。

 して、の色と太さも変えられるようにしてみました☆

 なんとHTML5には、色選択ダイアログを表示するためのGUIあるんですね~♪

http://snowdrops.starfree.jp/wnako3_test/18_paint.html

トラックバック - http://nadesiko.g.hatena.ne.jp/snowdrops89/20190610

2019-05-07

ぽん!

| 16:15

 皆様、長すぎる10連休はいかがお過ごしでしたか?

 めいっぱい羽を伸ばせた方、はあ? 何のことっすか?! 休みなんかねーよ!とゆう方、滅多にあることじゃないから有効活用しなきゃと頑張って、なんかもうむしろぐったり…な方などいらっしゃることでしょう。

 ワタシはこの季節は標準で、休日ごと山菜採ったり、畑耕したりと忙しいもので、今年は何気に肉体労働にいしむ忙しい日が増えたのでした(´д`)

 んな中、『押されたキー』『マウスX』『マウスY』のイベント値が取れるようになって以来、ゲームゲームと言い続けながらも放置していたゲームを頑張って完成させてみた。

 昔懐かしいPONG的なテーブルテニスゲームです。

#---宣言----------
画面w=640。画面h=480。マウス上マージン=80。
玉w=10。玉h=10。dx=0。dy=0。
玉初期x=画面w/2-玉w/2。玉初期y=画面h/2-玉h/2。
玉x=玉初期x。玉y=玉初期y。
玉タイマーID=。

パドルw=5。パドルh=50。パドル位置=25。
パドルx=配列。パドルy=配列。
パドルx[1]=パドル位置。パドルy[1]=画面h/2-パドルh/2。
パドルx[0]=画面w-パドル位置。パドルy[0]=画面h/2-パドルh/2。
COMパドルタイマーID=。COM早さ=4。
元y=画面h/2-パドルh/2。y=画面h/2-パドルh/2。

得点=配列。得点[1]=0。得点[0]=0。
勝点=5。ラリー=0。単ラリー=0。

側面音=「Pong_8_7F.mp3」
パドル音=「Pong_8_8F.mp3」
失点音=「Bu_71_2B.mp3」
得点音=「SE_16_7FGB.mp3URL=「15_Pong.html」

#---HTMLの設置----------
HTML=「<div id="base"><div id="main"><div id="msk"></div>
    <canvas id="court" width=640 height=480></canvas>
    <canvas id="Paddle1" width=5 height=50></canvas>
    <canvas id="Paddle0" width=5 height=50></canvas>
    <canvas id="ball" width=10 height=10></canvas>
    <div id="Player1"></div><div id="Player0"></div>
    <div id="Point1">0</div><div id="Point0">0</div>
    <span id="syohai"></span>
    <fieldset id="option">
    <legend>設定</legend>
      <fieldset id="P"> <!-- P(プレイヤー位置) -->
        <input type="radio" id="P1" name="Player">1P(左側)でプレイする<BR>
        <input type="radio" id="P0" name="Player">2P(右側)でプレイする
      </fieldset> <!-- P -->
      <fieldset id="S"> <!-- S(効果音有り無し) -->
        <input type="checkbox" id="SE">効果音を鳴らす?
      </fieldset> <!-- S -->
    </fieldset> <!-- option -->
</div></div> <!-- main / base -->
<div id="se0" style="height:80px"></div><div id="se1"></div><div id="se2"></div>」
「#nako3_div_1」にHTMLHTML設定。


#---画面描画----------
「#court」へ描画開始。黒色線色設定。黒色に塗色設定。[0,0,640,480]へ四角描画。
2に太設定。白色線色設定。

30
  A=画面h/30。
  [画面w/2,(回数-1)*A+5]から[画面w/2,(回数-1)*A+5+5]へ描画。
ここまで。

「#ball」へ描画開始。白色線色設定。白色に塗色設定。[5,5]へ4の描画。
「#Paddle1」へ描画開始。白色線色設定。白色に塗色設定。[0,0,5,50]へ四角描画。
「#Paddle0」へ描画開始。白色線色設定。白色に塗色設定。[0,0,5,50]へ四角描画。

#---CSS設定----------
「#base」に{
  "margin": "auto",
  "幅": "{画面w}px",
  "高さ": "{画面h}px",
  "border": "2px solid #999999",
}をDOMスタイル一括設定。

「#main」に{
  "position": "absolute",
}をDOMスタイル一括設定。

「#msk」に{
  "position": "absolute",
  "top":"{-1*マウス上マージン}px",
  "左":"{-360}px",
  "幅": "1360px",
  "高さ": "660px",
  "z-index": "-1",
}をDOMスタイル一括設定。

「#ball」に{
  "position": "absolute",
  "左": "{玉x}px",
  "top": "{玉y}px",
  "z-index": "-1",
}をDOMスタイル一括設定。

「#Paddle0」に{
  "position":"absolute",
  "左":"{パドルx[0]}px",
  "top":"{パドルy[0]}px",
  "z-index":"2",
}をDOMスタイル一括設定。
「#Paddle1」に{
  "position":"absolute",
  "左":"{パドルx[1]}px",
  "top":"{パドルy[1]}px",
  "z-index":"2",
}をDOMスタイル一括設定。

「#court」に{
  "position":"absolute",
  "z-index":"1",
}をDOMスタイル一括設定。

「#Player0」に{
  "position":"absolute",
  "top":"0px",
  "左":"{画面w/4*3-35}px",
  "z-index":"1",
  "font-size":"24px",
  "color":"#FFFFFF",
}をDOMスタイル一括設定。
「#Player1」に{
  "position":"absolute",
  "top":"0px",
  "左":"{画面w/4-35}px",
  "z-index":"1",
  "font-size":"24px",
  "color":"#FFFFFF",
}をDOMスタイル一括設定。

「#Point0」に{
  "position":"absolute",
  "z-index":"1",
  "top":"30px",
  "左":"{画面w/4*3-35}px",
  "幅":"50px",
  "width":"50px",
  "text-align":"center",
  "font-size":"38px",
  "font-weight":"bold",
  "color":"#FFFFFF",
}をDOMスタイル一括設定。
「#Point1」に{
  "position":"absolute",
  "z-index":"1",
  "top":"30px",
  "左":"{画面w/4-35}px",
  "幅":"50px",
  "text-align":"center",
  "font-size":"38px",
  "font-weight":"bold",
  "color":"#FFFFFF",
}をDOMスタイル一括設定。

「#syohai」に{
  "position":"absolute",
  "display":"table-cell",
  "top":"170px",
  "width":"640px",
  "padding":"30px 0px",
  "z-index":"-1",
  "background-color":"rgba(0, 0, 0, 0)",
  "text-align":"center",
  "vertical-align":"middle",
  "font-weight":"bold",
  "font-size":"42px",

  "transition": "opacity 0.5s, transform 0.5s",    /* 0.5秒かけて透明度とサイズの変化 */
  "opacity":"0",
  "transform": "scale(.1)",
}をDOMスタイル一括設定。

「fieldset#option」に{
  "position":"absolute",
  "top": "490px",
  "font-size": "small",
  "width": "400px",
  "height": "60px",
}をDOMスタイル一括設定。

「fieldset#P」に{
  "position":"absolute",
  "width": "200px",
  "border": "none",
  "padding": "0px",
}をDOMスタイル一括設定。

「fieldset#S」に{
  "position":"absolute",
  "left": "220px",
  "border": "none",
  "padding": "0px",
}をDOMスタイル一括設定。


#---ボタン作成----------
「#main」にDOM親要素設定。
「ゲームスタート」のボタン作成し、スタートボタン代入。
スタートボタンに{
  "position": "absolute",
  "幅": "150px",
  "top": "280px",
  "左": "{画面w/2-75}px",
  "padding":"5px 0px",
  "z-index": "3",
}をDOMスタイル一括設定。

「遊び方」のボタン作成し、説明ボタン代入。
説明ボタンに{
  "position": "absolute",
  "幅": "80px",
  "top": "490px",
  "左": "{画面w-80}px",
}をDOMスタイル一括設定。

#---ローカルストレージからオプション設定-----
もし、(「ぽんの設定」が存在)=いいえならば、
  #プレイヤーは、1P(左)を1、2P(右)を0としている。
  設定={"プレイヤー":1,"SE":1}
  設定を「ぽんの設定」に保存違えば、
  設定=「ぽんの設定」を開くここまで。

SE=設定["SE"]。
プレイヤー=設定["プレイヤー"]。
COM=(プレイヤー+1)%2。
サーブ権=プレイヤー。サーブ待ち=オフ。
打者=(サーブ権+1)%2。
プレイヤー表示変更。

「#P{プレイヤー}」の「checked」に「checked」をDOM属性設定。
もしSE=オンならば、「#SE」の「checked」に「checked」をDOM属性設定。


#---イベント設定---------
説明ボタンをクリックした時には
 「いわゆるテーブルテニス。
パドルをマウスで上下に動かしてボールを打ち返し、得点を狙うゲームです。
{勝点}点先取すれば勝ち。ジュース制度はありません。

サーブ権はユーザーからで、得点に関わりなく交互に入れ替わります。
サーブ権がある時は、パドルにボールが付いており、クリックでサーブ。
ボールの速度と角度はランダムです。

打ち返した時のパドルの動きでボールの動きが変化します。
(基本的に早く動かすほど加速し、角度が付く)
卓球と言うより、エアホッケーに近い感じですね。
」と言うここまで。

「#msk」をクリックした時には
 もし、(サーブ待ち=オン)かつ(サーブ権=プレイヤー)ならば、
  サーブ待ち=オフ。玉移動。COMパドル操作。
 ここまで。
ここまで。

「#msk」をマウス移動した時には
  もし、(マウスY<マウス上マージン)ならば、    #mskの上マージン
    パドルy[プレイヤー]=0。
  違えばもし、(マウスY<画面h+マウス上マージン-パドルh)ならば、
    パドルy[プレイヤー]=マウスY-マウス上マージン。
  違えばもし、(マウスY≧画面h+マウス上マージン-パドルh)ならば、
    パドルy[プレイヤー]=画面h-パドルh。
  ここまで。
  「#Paddle{プレイヤー}」の「top」に「{パドルy[プレイヤー]}px」をDOMスタイル設定。
  もし、(サーブ待ち=オン)かつ(サーブ権=プレイヤー)ならば、
    玉セット。     #パドルに玉がくっついて動くようにする。
  ここまで。
ここまで。

スタートボタンをクリックした時には
 もし、(得点[0]≠0)または(得点[1]≠0)ならば、
  URLブラウザ移動。
 違えば、
  スタートボタンの「z-index」に「-1」をDOMスタイル設定。
  「#syohai」の「opacity」に「0」をDOMスタイル設定。
  「#syohai」の「z-index」に「-1」をDOMスタイル設定。
  「#msk」の「z-index」に「3」をDOMスタイル設定。
  オプション無効化。
  サーブ待ち=オン。サーブ権=プレイヤー。
  得点[0]=0。「#Point0」に得点[0]をテキスト設定。
  得点[1]=0。「#Point1」に得点[1]をテキスト設定。
  サーブ。
 ここまで。
ここまで。

「#P1」の「onchange」に「左右変更」をDOMイベント設定。
「#P0」の「onchange」に「左右変更」をDOMイベント設定。
「#SE」の「onchange」に「効果音オフオン」をDOMイベント設定。

●左右変更
 もし、(「#P1」の「checked」をDOM属性取得)=オンならば、プレイヤー=1。
 違えば、プレイヤー=0。
 COM=(プレイヤー+1)%2。
 設定["プレイヤー"]=プレイヤー。
 設定を「ぽんの設定」に保存。
 プレイヤー表示変更。
ここまで。

●効果音オフオン
 もし、(「#SE」の「checked」をDOM属性取得)=オンならばSEオン。
 違えばSEオフ。
 設定["SE"]=SE。
 設定を「ぽんの設定」に保存ここまで。

#-----------------------------------------------------------------------
●サーブ
  COMパドルタイマーIDのタイマー停止。
  ラリー=0。単ラリー=0。
  r=2の乱数もし、r=0ならば、r=-1。
  dx=((30の乱数)+1)/10+2。dy=((20の乱数)+1)/10+2。dy=dy*r。
  玉セット。サーブ待ち=オン。打者=(サーブ権+1)%2。
  もし、打者=0ならば、dx=dx*-1。
  「#ball」の「z-index」に「2」をDOMスタイル設定。
  もし、サーブ権=COMならば、
   サーブ待ち=オフ。
   「玉移動」を1秒後。
  ここまで。
ここまで。

●玉セット
  もし、サーブ権=1ならば、
   玉x=パドルx[1]+パドルw。玉y=パドルy[1]+パドルh/2-玉h/2。
  違えば、
   玉x=パドルx[0]-玉w。玉y=パドルy[0]+パドルh/2-玉h/2。
  ここまで。
  「#ball」の「左」に「{玉x}px」をDOMスタイル設定。
  「#ball」の「top」に「{玉y}px」をDOMスタイル設定。
ここまで。

●玉動作設定
  ラリー=ラリー+1。
  py=y-元y。   //パドルの速さと向き。
  パドル速度=pyの絶対値。
  パドル方向=pyの符号。
  玉速度=dxの絶対値。
  玉角度=dyの絶対値。
  玉x方向=dxの符号。
  玉y方向=dyの符号。
  もし、打者=プレイヤーならば、
    速度補正値=(パドル速度/10)の整数部分。
  ここまで。

  もし、(打者=プレイヤー)かつ(パドル速度=0)ならば、
    単ラリー=単ラリー+1。
  違えばもし、(打者=プレイヤー)かつ(パドル速度≠0)ならば、
    単ラリー=0。
  ここまで。

  #COMの玉動作。
  もし、(打者=COM)ならば、
    もし、玉速度≦4ならば、玉速度=16/玉速度。
    違えばもし、玉速度≧6ならば、玉速度=玉速度/2。
    もし、単ラリー%4=3ならば、玉角度=玉角度-1。
    もし、ラリー%10=9ならば、玉角度=玉角度-1。
    もし、玉角度≦1ならば、
      玉角度=玉角度+2。玉速度=玉速度+3。
    違えばもし、玉角度≧5ならば、
      玉角度=玉角度-2。玉速度=玉速度-1。
    ここまで。
    dx=玉x方向*玉速度*-1。dy=玉y方向*玉角度。
  ここまで。

  #プレイヤーの玉動作。
  もし、(打者=プレイヤー)ならば、
   もし、(玉速度)<3ならば、
    玉速度=10/玉速度。
   ここまで。
   もし、(パドル速度=0)ならば、  #0ならのまま反射。
    dx=玉x方向*玉速度*-1。dy=玉y方向*玉角度。
   違えばもし、(パドル方向=玉y方向)ならば、      #符号が同じならスピードアップ。
    もし、速度補正値≦3ならば、
      dx=玉x方向*(玉速度+速度補正値)*-1。dy=玉y方向*(玉角度+速度補正値+0.5)
    違えば、
      dx=玉x方向*(玉速度+速度補正値/2)*-1。dy=玉y方向*(玉角度+速度補正値/2+1)
    ここまで。
   違えば、                           #符号が逆の時、
    もし、速度補正値≦1ならば、               #パドルが遅ければ減速して角度を少し戻す。
      もし、玉速度>1ならば、
        dx=玉x方向*(玉速度-1)*-1。dy=玉y方向*(玉角度-1.5)
      違えば、
        dx=玉x方向*玉速度*-1。dy=玉y方向*(玉角度-1)    #玉が遅ければ減速しない
      ここまで。
    違えばもし、速度補正値>3ならば、           #早ければ加速して逆向きに反射。
      dx=玉x方向*(玉速度+1)*-1。dy=玉y方向*(玉角度+1.5)*-1
    違えば、                         #こなら、
      dx=玉x方向*玉速度*-1。dy=玉y方向*玉角度*-1。     #逆向きに反射。
    ここまで。
   ここまで。
  ここまで。
  玉速度=dxの絶対値。角度=dyの絶対値ここまで。

#-----------------------------------------------
●絶対値(Aの)
  AのABS戻るここまで。

●符号(Aの)
  AのSIGN戻るここまで。

●整数部分(Aの)
  AのINTここまで。
#-----------------------------------------------

●玉移動
 玉動作設定。
 サーブ権=(サーブ権+1)%2。
 0.01秒タイマー開始した時には(ID)
  玉タイマーID=ID。
  y=パドルy[打者]。

  もし、(玉x+dx<玉w*-1)ならば、0の得点加算。
  もし、(玉x+dx+玉w>画面w+玉w)ならば、1の得点加算。
  もし、((玉x+dx≦パドルx[1]+パドルw)かつ(玉x+dx+玉w>パドルx[1])かつ(玉y+玉h>パドルy[1])かつ(玉y<パドルy[1]+パドルh))ならば、
   もしSE=オンならば、「#se0」に「<audio src="{パドル音}" autoplay></audio>」をDOM_HTML設定。
   玉動作設定。
   打者=(打者+1)%2。
   もし、プレイヤー=1ならば、COMパドル操作。
   違えば、COMパドルタイマーIDのタイマー停止。
  ここまで。
  もし、((玉x+dx+玉w≧パドルx[0])かつ(玉x+dx<パドルx[0]+パドルw)かつ(玉y+玉h>パドルy[0])かつ(玉y<パドルy[0]+パドルh))ならば、
   もしSE=オンならば、「#se0」に「<audio src="{パドル音}" autoplay></audio>」をDOM_HTML設定。
   玉動作設定。
   打者=(打者+1)%2。
   もし、プレイヤー=0ならば、COMパドル操作。
   違えば、COMパドルタイマーIDのタイマー停止。
  ここまで。
  もし、(玉y+dy<0)または(玉y+dy+玉h>画面h)ならば、
    もしSE=オンならば、「#se1」に「<audio src="{側面音}" autoplay></audio>」をDOM_HTML設定。
    dy=dy*-1。
  ここまで。
  玉x=玉x+dx。玉y=玉y+dy。
  「#ball」の「left」に「{玉x}px」をDOMスタイル設定。
  「#ball」の「top」に「{玉y}px」をDOMスタイル設定。
  元y=y。
 ここまで。
ここまで。

●COMパドル操作
 0.01秒タイマー開始した時には(ID)
  COMパドルタイマーID=ID。
  もし、玉y<パドルy[COM]+パドルh/2ならば、cy=-1*COM早さ。
  違えば、cy=COM早さ。
  パドルy[COM]=パドルy[COM]+cy。
  もし、(パドルy[COM]<0)ならば、
    パドルy[COM]=0。
  違えばもし、(パドルy[COM]+50>画面h)ならば、
    パドルy[COM]=画面h-50。      #パドル長さ
  ここまで。
  「#Paddle{COM}」の「top」に「{パドルy[COM]}px」をDOMスタイル設定。
 ここまで。
ここまで。

●得点加算(Pの)
 もしSE=オンならば、
  もし、P=COMならば、「#se2」に「<audio src="{失点音}" autoplay></audio>」をDOM_HTML設定。
  違えば、「#se2」に「<audio src="{得点音}" autoplay></audio>」をDOM_HTML設定。
 ここまで。
 玉タイマーIDのタイマー停止。
 COMパドルタイマーIDのタイマー停止。
 「#ball」の「z-index」に「-1」をDOMスタイル設定。
 得点[P]=得点[P]+1。
 「#Point{P}」に得点[P]をテキスト設定。
 もし、得点[P]=勝点ならば、Pの勝利。
 違えば、「サーブ」を1秒後。
ここまで。

●勝利(Pの)
  「#msk」の「z-index」に「-1」をDOMスタイル設定。
  もし、P=プレイヤーならば、
    「#syohai」に「YOU WIN!」をテキスト設定。
    「#syohai」の「色」に赤色DOMスタイル設定。
  違えば、
    「#syohai」に「YOU LOSE」をテキスト設定。
    「#syohai」の「色」に青色DOMスタイル設定。
  ここまで。
  「#syohai」の「z-index」に「3」をDOMスタイル設定。
  「#syohai」の「opacity」に「1」をDOMスタイル設定。
  「#syohai」の「transform」に「scale(1)」をDOMスタイル設定。
  1秒後には
    スタートボタンに「再戦する?」をテキスト設定。
    スタートボタンの「z-index」に「3」をDOMスタイル設定。
  ここまで。
ここまで。

●プレイヤー表示変更。
 もし、プレイヤー=1ならば、
  「#Player1」の「色」に赤色DOMスタイル設定。
  「#Player1」に「YOU」をテキスト設定。
  「#Player0」の「色」に青色DOMスタイル設定。
  「#Player0」に「COM」をテキスト設定。
 違えば、
  「#Player1」の「色」に青色DOMスタイル設定。
  「#Player1」に「COM」をテキスト設定。
  「#Player0」の「色」に赤色DOMスタイル設定。
  「#Player0」に「YOU」をテキスト設定。
 ここまで。
ここまで。

●オプション無効化
  「#SE」の「disabled」に「disabled」をDOM属性設定。
  「#P1」の「disabled」に「disabled」をDOM属性設定。
  「#P0」の「disabled」に「disabled」をDOM属性設定。
  説明ボタンの「disabled」に「disabled」をDOM属性設定。
ここまで。

●オプション有効化
  「#SE」の「disabled」にDOM属性設定。
  「#P1」の「disabled」にDOM属性設定。
  「#P0」の「disabled」にDOM属性設定。
  説明ボタンの「disabled」にDOM属性設定。
ここまで。
#-----------------------------------------------------------------------

http://snowdrops.starfree.jp/wnako3_test/15_Pong.html

 だいたい、こんな感じだったような?

 こうゆうのが下手なワタシが勝てるくらいのレベルなので、COMは弱いですw


 さて、しかし、問題が一つ発生。

 テキスト読み上げでは、Google ChromeまたはGoogle日本語に悩まされましたが、度はFire foxです。

 どうもね、長くゲームを続けると、効果音が再生されなくなっちゃう。

 しかも、そうなると、Windows Media Playerでもメモリが不足していますか何か言って、再生出来なくなってしまうんだから困ったもんだ。

 単に音を連続再生するだけのプログラムでお試ししたところ、120~130くらいで鳴らなくなっちゃうっぽい。

 ゲームの効果音を鳴らしていたら、のくらいあっというですって;

 しようがないので、1ゲームを5点先取と少なめに設定し、再戦時はページをリロードするようにしてみている。

 ちなみにコレは、chromeIEでは発生しないっぽい。3000くらい鳴らしっぱにしたけど平気だった。


 思うに、音を鳴らすというのは、なでしこの命令には無くて、audioタグをautoplayにして、DOM_HTML設定でぶっ込むという力業で行っています。

 をぶっ込めば音は止まるし、別の音をぶっこめば前の音はキャンセルされて新しい音が鳴るということを利用して音を鳴らしまくってますが、見た目はともかく実際にはどんどん新しいaudio要素を作っちゃってることになるんじゃないですかね?(@_@;

 して、Fire foxの場合はタブを閉じるか再読込するかまで、それがどんどん累されてメモリを解放してくれないんじゃないかとゆう;;;


 むじゅかし過ぎてよく分かんなかったけども、JavaScript的にはaudioやvideoを操作する的な命令もあるみたいなので、なでしこでも出来るようになるといいなぁ・・・

 (それで解決しなかったらもう完全にFire foxのせいなんで、どうしようもないw)

トラックバック - http://nadesiko.g.hatena.ne.jp/snowdrops89/20190507

2019-04-07

祝 新元号発表! で、西暦→元号変換してみる

| 16:36

 マイナビ連載43目は、新元号対応の和暦変換でした。

https://news.mynavi.jp/article/nadeshiko-43/

 これは、このタイミングで絶対出ると思っていましたよ~☆

 ワタシも、和暦変換するのを作ろうと思っていたけど、に合わなんだorz


 記事の最後に、明治以前の和暦にも対応することについて、さらっと触れられていました。

 実は、これは、ガチでやろうとすると本当は、思うほど簡単なことではありません。

 明治六年(1873年)の、グレゴリオ暦導入以前の和暦は旧暦なので、西暦と単純に対応させることが出来ないんですね。

 例えば、なでしこ3にはまだありませんが、なでしこ1には「和暦変換」とゆう命令があり、「1868/01/01」までの西暦を変換してくれることになっていますが、旧暦には対応していないため『「1868/01/01」を和暦変換して表示』とすると、『明治元年1月1日』と返ってきますが、実際には『慶応3年12月7日』です。

 まあ、明治までなら、こうゆう仕様ですと言い張ることも可能かと思いますが、有効な日付を「日本でグレゴリオ暦が採用された明治6年1月1日(1873/01/01)以降」、とするのが本当であろうかとも思われます。

 して、明治以前にも対応するとなると、ちょっとそう言うわけには行かないです。

 日付まで対応しようとすると、改元日のデータと、さらには旧暦のデータも必要になってくる。

(グレゴリオ暦導入後ならば、改元日が無くても、の年の1/1に遡って新元号とする立年改元としても良いのですが、旧暦の場合、の立年改元で遡るべき1/1自体が西暦とは一致ないので)

 してさらに、西暦にグレゴリオ暦が採用される以前の西暦は、ユリウス暦ということにするのかグレゴリオ暦のまま遡るのか、とゆう問題にも直面する。

 あー、アタマ痛い(@_@)

 てゆうかもう、具合わるい(´д`)


 さてさてそれでは、日付のことは考えずざっくりと、西暦年を入れたら元号年に変換するだけならば、元号の開始年と終了年を「大化」から「令和」まで全て用意すれば、マイナビの記事のとうりで、すんなりとできるでしょうか?

 答えは、否です。

 例えば、安政は1855年~1860年なのですが、かの桜田門外の変が安政7年3月3日であることで分かるように、7年まであります

 ところが、単純に当てはめていくと・・・

1855 嘉永7年/安政元年
1856 安政2年
1867 安政3年
1868 安政4年
1859 安政5年
1860 安政6年/万延元年

 ・・・あれ、いっこ足りない?! となります。

 これは、安政への改元が、和暦では年明け前、西暦では年明け後の嘉永7年11月27日(1855/01/15)に行われたために起こります。安政元年は1ヶ月ちょいしかありません。

 西暦1855年は、1/14までは嘉永7年、1/15~2/16のだけ安政元年、2/17以降は安政2年なんですよ~ん。

1854 嘉永7年
1855 嘉永7年/安政元年/安政2年
1856 安政3年
1867 安政4年
1868 安政5年
1859 安政6年
1860 安政7年/万延元年

 どうすりゃいいんだ?

 やっぱ、1860年=安政7年=万延元年とするためには、1855年=安政2年とゆうことにして帳尻を合わせるしか無い。

 しかし、1854年は嘉永7年で、嘉永最後の年だけど安政元年では無いので、安政元年は存在し無いコトになっちゃうけど、仕方がない!・・・のか?

 このような元号が、12個もあります


 プログラム的には?

 どーすりゃいいんだ??

 単純に、こうなっちゃう元号の場合にだけ、Vをさらに+1にする・・・?

 あと、1年続かず年内に改元となった元号が3つありますが、それも無かったことになっちゃいますが、コレもどうしようもない・・・のか?


 考え方としては、指定された西暦年の最終日、12/31時点での元号を、の年の元号と見なして表示する・・・的なことになりますかね?

 南北朝時代は、正統とされる南朝側の元号を表示することにする。

 ・・・でっ、こんな感じ?

#---宣言----------
元号一覧URL=「gengo_s.csv」
時代区分URL=「jidai.csv」
和暦表=配列。特殊元号1=。特殊元号2=。
西暦年=今年。西暦年エディタ。
時代一覧=配列。
時代区分URLへGET送信した時には
  対象CSV取得し、それを時代一覧へ代入ここまで。
元号一覧URLへGET送信した時には
  対象CSV取得し、それを和暦表へ代入。
  和暦表を反復
   もし対象[1]=対象[2]ならば、特殊元号1=特殊元号1「・」対象[0]。ここまで。
   もし、(対象[3]の1だけ文字左部分)=「*」ならば、特殊元号2=特殊元号2「・」対象[0]。ここまで。
  ここまで。
  特殊元号1=特殊元号1の1から1だけ文字削除。特殊元号2=特殊元号2の1から1だけ文字削除。

    #---GUI作成----------
    HTML = 「
    <div class="nako3">
    指定された西暦年を元号年に変換します。<BR>
    1年続かず年内に改元した元号は無視されます。({特殊元号1})<BR>
    西暦では年が明け、和暦では年明け前に改元が行われた元号では、元年と2年が同じ年になるため、元年が表示されません。<BR>
    ({特殊元号2})<BR>
    南北朝時代は南朝側の元号を使用。<BR>
    時代区分は『広辞苑第七版付録 西暦・和暦対照表』による。<BR>
      <p><div id="gui"></div></p>
      <p><div id="result"> </div></p>
    </div>
    」
    「#nako3_div_1」にHTMLHTML設定。
    「#result」に{
      "padding": "16px",
      "border": "1px solid #FF7979",
      "背景色": "#FFF4F4"
    }をDOMスタイル一括設定。

    「#gui」にDOM親要素設定。
    改行作成。
    「西暦 」のラベル作成。
    西暦年のエディタ作成して、西暦年エディタ代入。
    「年」のラベル作成。
    改行作成改行作成。
    「西暦和暦変換処理」のボタン作成して、変換ボタン代入。
    「 」のラベル作成。
    「クリア」のボタン作成して、クリアボタン代入。
    西暦年エディタの「幅」に「80px」をDOMスタイル設定。

    変換ボタンをクリックした時には
     西暦年=西暦年エディタからテキスト取得。
     西暦年=西暦年を英数半角変換。
     和暦年=西暦年を西暦和暦変換処理。
     年干支=西暦年の年干支取得。
     時代区分=西暦年の時代区分取得。
     「#result」に「{和暦年} {年干支} {時代区分}」をテキスト設定。
    ここまで。

    クリアボタンをクリックした時には、
    西暦年エディタをテキスト設定。
    ここまで。
ここまで。

●(西暦年を)西暦和暦変換処理とは
  もし、西暦年<645ならば、「元号制定以前」で戻る。
  違えば、
   和暦表を反復
    # 表から値を取り出す
    和暦名=それ[0]
    開始年=それ[1]
    終了年=それ[2]
    改元日=それ[3]
    # 指定した西暦に該当するか調べる
    もし(開始年≦西暦年)かつ(西暦年<終了年)ならば、
      和暦年=西暦年-開始年+1。
      もし、(改元日の1だけ文字左部分)=「*」ならば、和暦年=和暦年+1。
      もし、和暦年=1ならば、和暦年=「元」。
      「{和暦名}{和暦年}年」で戻る。
    ここまで。
   ここまで
  ここまで。
  「不明」で戻るここまで。

●(西暦年の)年干支取得
 十二支=「子丑寅卯辰巳午未申酉戌亥」を文字列分解。
 十干=「甲乙丙丁戊己庚辛壬癸」を文字列分解。
 干支は配列。
 60
  C=回数-1
  干支[C]=「{十干[C%10]}{十二支[C%12]}」
 ここまで。
 干支No=西暦年%60-4。
 もし、干支No<0ならば、干支No=干支No+60。
 干支[干支No]で戻るここまで。

●(西暦年の)時代区分取得
 時代一覧を反復
  もし対象[2]≧西暦年ならば対象[0]で戻るここまで。
 ここまで。
ここまで。

http://snowdrops.starfree.jp/wnako3_test/17_gengo.html

 タブン合っていると思うんだけど・・・

 干支と時代区分も表示してみたケド、よく考えたら、こんな風に表示するなら、の年に含まれる元号を全て併記するようにしても良かったのだ;

 まあめんどーだし、西暦と和暦を1対1で取得したい場合とゆうことで(^▽^;


 本当は、なでしこ1の和暦変換みたいに日付で、改元日も反映させてずっと昔まで変換出来るようにしたいと思うんだけど、カナリ挫折中(+_+)

 も旧暦と一口に言ったって、本当なら幾度も改暦が行われてますけど、こはどーしますか?! などとゆうさらなる問題にも直面したりするわけです。

 うう、それはムリ・・・(>_<;;;



【追記】

 の後ウィキペディアを見たところ、「実際とはずれが生じる」としながらも、「嘉永7年=安政元年=西暦1854年」にしちゃう感じのようでした。

 立年改元(の年の1/1に遡って新元号とする)として考えれば、嘉永7/安政元年の1/1は、西暦では1854/01/29なので、っから安政元年は始まってるのだと言い張ることも可能っちゃ可能。

 いっこいっこ検索する場合ならともかく、一覧で出力した時とか、元年が無いのもかなり違和感があるし、っちのほうがいいかなぁ?

 の場合は、プログラムでどうこうするより、ちょこっとデータを変えちゃった方が、楽だねw

トラックバック - http://nadesiko.g.hatena.ne.jp/snowdrops89/20190407

2019-03-22

テキスト読上げ(青空文庫形式対応)

| 12:49

 なんだかんだで、読上げ自体はわりとすぐに出来るようになりました。

 [# ]で囲まれた註を無視して、前に書いたとうりに漢字部分を読まずにルビの方を読むようにしただけなので。

#------------------------------------------------------------------
# テキスト読上げ
#------------------------------------------------------------------
「Google 日本語」に話者設定。   //ダミー

#---宣言----------
テキスト=。読上中フラグ=オフ行数=-1。細区切=-1。
区切記号=「{CRLF},{CR},{LF}」を「,」で区切る。
息継記号=「 , ,?,!,―,…,{カッコ}」を「,」で区切る。
註記号=「-------------------------------------------------------,-------------------------------------------------------
※[#,]{改行}[#,]」をCSV取得。

#---HTMLの設置----------
HTML=「<div id="main"></div>」
「#nako3_div_1」にHTMLを、DOM_HTML設定。

#---GUI作成----------
「#main」にDOM親要素設定。
のテキストエリア作成し、テキストエリアに代入改行作成。
「読み上げ」のボタン作成し、読上ボタン代入。
「先頭」のボタン作成し、先頭ボタン代入。
「クリア」のボタン作成し、クリアボタン代入改行作成。
「{カッコ}、{カッコ閉じ}でも区切って読む(Google 日本語で止まる場合)」のチェックボックス作成し、細区切チェック代入改行作成。

#---CSS設定----------
読上ボタンの「margin」に「2px 5px」をDOMスタイル設定。
先頭ボタンの「margin」に「2px 5px 2px 50px」をDOMスタイル設定。
先頭ボタンの「disabled」に「disabled」をDOM属性設定。
クリアボタンの「margin」に「2px 5px」をDOMスタイル設定。
細区切チェックの「margin」に「10px」をDOMスタイル設定。
テキストエリアの「rows」に「20」をDOM属性設定。
テキストエリアの「placeholder」に「ここに読上げたいテキストを入力して下さい」をDOM属性設定。

テキストエリアに{
  "幅": "100%",
  "margin": "2px 5px",
  "背景色":"#ffffff",
  "色": "#000000",
}をDOMスタイル一括設定。

#---イベント----------
クリアボタンをクリックした時には、
  「テキストを全てクリアします。{改行}読上げ中の場合は、読み上げも中断します」で二択。
  もしそれはいならば、
    細区切チェックの「disabled」にDOM属性設定。
    テキストエリアにをテキスト設定。
    テキスト=。読上げ中フラグ=オフ行数=-1。
  ここまで。
ここまで。

先頭ボタンをクリックした時には
  「先頭に戻って読み上げを行います。」で二択。
  もしそれはいならば、
    行数=-1。読上開始。
  ここまで。
ここまで。

読上ボタンをクリックした時には
 「Google 日本語」に話者設定。   //Google Chromeでは、Google 日本語で読む。
 もし、読上中フラグ=オフならば、
  読上開始。
 違えばもし、読上中フラグ=オンならば、
  先頭ボタンの「disabled」にDOM属性設定。
  読上中断。
 ここまで。
ここまで。

細区切チェックの「onchange」に「チェック関数」をDOMイベント設定。

●チェック関数
  細区切=細区切*-1。
ここまで。
#------------------------------------------------------------------
●読上テキスト作成
 註記号を反復
   対象[0]から対象[1]を註削除。
 ここまで。
 ルビ反映。
 テキスト=テキストの「》」を置換。
 テキスト=テキストの「|」を置換。
 テキスト=テキストのカッコ閉じを「。」に置換。
 テキスト=テキストの「。」を「。{改行}」に置換。
 もし、細区切=オンならば、
   テキスト=テキストの「、」を「、{改行}」に置換。
 ここまで。
 息継記号を反復
   テキスト=テキストの対象を「、」に置換。
 ここまで。
 区切記号を反復
   テキスト=テキストを対象区切る。
 ここまで。
ここまで。
#------------------------------------------------------------------
●註削除(AからBを)
 検索開始位置=1。
 削除始=テキストで検索開始位置からAを文字検索改。
 もし、削除始=0ならば戻る。
 削除終=テキストで削除始+(Aの文字数)からBを文字検索改。
 もし、削除終=0ならば戻る。
 削除数=削除終-削除始+(Bの文字数)。
 テキスト=テキストの削除始から削除数を文字削除。
 検索開始位置=検索開始位置+削除始
 AからBを註削除。
ここまで。

●ルビ反映
 検索開始位置=1。
 ルビ記号=テキストで検索開始位置から「《」を文字検索改。
 もし、ルビ記号=0ならば戻る。
 ルビ始=ルビ記号-1。
 オン
   仮=テキストでルビ始から1を文字抜出。
   もし、(仮を漢字か判定)=はいならば、
     ルビ始=ルビ始-1。
   違えば、
     ルビ始=ルビ始+1。抜ける。
   ここまで。
 ここまで。
 削除数=ルビ記号-ルビ始+1。
 テキスト=テキストのルビ始から削除数を文字削除。
 検索開始位置=検索開始位置+ルビ記号+1。
 ルビ反映。
ここまで。
#------------------------------------------------------------------
●文字検索改(SでAからBを)
 検索対象=(Sの文字数)+1-A。
 仮=SのAから検索対象を文字抜出。
 数=(仮でBを文字検索)
 もし、数=0ならば、数で戻る。
 違えば、数+A-1で戻る
ここまで。

●漢字か判定(Sが|Sの|Sを)
  Sを「^[\u3005\u3007\u4E00-\u9FFF\uF900-\uFAFF\u3400-\u4DFF]|[\uD840-\uD87F][\uDC00-\uDFFF]」で正規表現マッチ。
  もしそれがnullならばいいえ戻る。
  違えばはい戻るここまで。
#------------------------------------------------------------------
●テキスト読上げ
 もし、読上中フラグ=オンならば、
  行数行数+1。
  もし行数≧(テキストの要素数ならば、
    細区切チェックの「disabled」にDOM属性設定。
    行数=-1。読上中断。戻る。
  ここまで。
  テキスト[行数]を話し終わった時には
    テキスト読上げ。
  ここまで。
 ここまで。
ここまで。
#------------------------------------------------------------------
●読上開始
  テキスト=テキストエリアからテキスト取得。
  もし、テキスト=ならば、
    「テキストエリアに読み上げたい文章を入力して、読み上げボタンを押して下さい。」と言う。
  違えば、
    読上テキスト作成。
    読上ボタンに「一時停止」をテキスト設定。
    読上中フラグ=オン。
    テキストエリアの「disabled」に「disabled」をDOM属性設定。
    先頭ボタンの「disabled」に「disabled」をDOM属性設定。
    クリアボタンの「disabled」に「disabled」をDOM属性設定。
    細区切チェックの「disabled」に「disabled」をDOM属性設定。
    テキスト読上げ。
  ここまで。
ここまで。

●読上中断
  読上ボタンに「読み上げ」をテキスト設定。
  読上中フラグ=オフ。
  テキストエリアの「disabled」にDOM属性設定。
  クリアボタンの「disabled」にDOM属性設定。
ここまで。
#------------------------------------------------------------------

http://snowdrops.starfree.jp/wnako3_test/16_yomiage.html

 がっ・・・

 ぐる子さん(Google日本語)の方が、はるかさんより読み違いが少なくて、多少聞きやすい感じなので、変えれるようにすっかなと思ったんですけど、どうも「話者設定」や、「話者一覧取得」の命令が、初は通らない(?)感じなのです。

話者一覧取得して反復
  F名前=対象["name"]
  F言語=対象["lang"]
  「{F名前}: {F言語}」を表示ここまで

 実行ボタンを押しても出ないんです。

 で、あれ? と思ってもう一押したらちゃんと表示され、の後はタブではずっと動きます。

 だもんで、前に話者変更などを試していた時には気付いてなかったけど、新しく開いた毎目は動かないの。謎すぎ。


 エディタの場合は、実行ボタンを二押せば良いだけなんだけど、HTMLに埋め込んだらそうもいかないですよね。

 一ダミーで話者設定し、ウェイトを入れた後、再設定すると通るので、最初にダミーを設定した後イベントの中で再設定で、出来たことは出来たのですが、無理矢理すぎ;



 あとは、なでしこは関係ないと思われることだけど、chromeさんとは、どうも相性が良くないみたいなんですよねぇ・・・


 ぐる子さんは長文が読めないらしくて、読上げ途中でいきなり止まって、再読み込みではダメで、ブラウザ自体の再起動必要かも知れない感じになる~(´д`)

 長文を読ますような前提じゃないってコトかも知れないし、一度話し始めたら、強制的に中断させるような命令もないのだから、もあんまり長文を一気に話させるのはどうかと思われるところですけど、100文字以下くらいでも余裕で止まることがあるから、改行や「。」ごと区切ったくらいじゃ駄目なことがあって、困ったもんだ。

 これは、chromeがと言うより、Google日本語のことで、chrome+はるかさんなら問題はないFirefoxではもちろん問題が無い。

 読上げエンジンの方の仕様なのかと思われるけど、「、」で区切ると、ちょっと息切れ感が・・・;


 それから、読上げようのテキストが大きいと、「話す」には一行ずつ送ってるにもかかわらず、しばしば止まるんだよね~。大きいったって30kbくらいなんですが。

 いや、のせいかどうかすらもよく分からんけど、元のテキストを半分とかにしたら、ふつーに読めたのです。

 でも、短編の一編くらいは、まるっと最初から最後まで読んで欲しいよね~。むむむ~。

 これは、chrome+はるかさんでも発生し、前のとは違って、一時停止して、もっかい読上げボタン押すと、次を読んだりもする。これFirefoxでは大丈夫。

 場当たり的には出来るようにできそうな気もするけど、原因が確定していない上にワタシが普段メインで使ってるのはFirefoxだから、やる気出ないなぁ;

 なにしろ、どれもこれFirefoxでは無問題なのですよ(?_?)

 お試しとゆうことでこんくらいにしておくか、まちっと研究してみるか、それが問題だw

トラックバック - http://nadesiko.g.hatena.ne.jp/snowdrops89/20190322

2019-03-17

「文字検索」と「漢字か判定」

| 09:50

 マイナビ連載42目は、「再帰処理」についてでした。

https://news.mynavi.jp/article/nadeshiko-42/

 いや~、ワタシは別に、再帰処理につまずいた気はしないですけどね~。

 だって、それ以前に関数がわかんなかったし(爆)

 なでしこのお陰で急に賢くなって以降は、深く考えずに、ふつーに、それっぽいことをしていたように思う。



 それはさておき、「文字検索」です。

 そうは書いてないけど、v1非互換でした。

 なでしこ1の文字検索は、「文字列SでA文字目からBを検索する」とゆう命令でした。

 したがって、先頭の1文字目から検索を始めて、見つかったら「それ+1」文字目から次を検索・・・とゆう手順で、文書内にある全てのBを検索出来ました。(再帰って、こうゆうコトだよね(?))

#なでしこ1
C=1。新聞紙。
●新聞紙
 「しんぶんし」でCから「ん」を文字検索。  //「文字検索」
 もしそれが0ならば、 //ヒットしなかった場合は、
   戻る。       //関数から戻ることを忘れず!
 違えば、
   それ表示。
   C=それ+1。
   新聞紙。      //再帰

 まあ、なんかこんなような。

 ところが!

 なでしこ3の文字検索は、「文字列Sで文字列Aが何文字目あるか調べて返す」とゆうことになっており、検索開始位置の指定が出来ないんですよー。

 これでは、「何文字目」命令と、同じことっぽい。

 しくしくしくしく。どーすりゃいいんだorz


 ・・・・・・とりあえず、こんな感じか?

#なでしこ3
C=1。新聞紙。
●新聞紙
 「しんぶんし」でCから「ん」を文字検索改。
 もしそれが0ならば、
   戻る。
 違えば、
   文字位置=それ
   文字位置を表示。 //「それ表示」だと、v3の場合の後の「それ」が「undefined」になっちゃう
   C=文字位置+1。
   新聞紙。
 ここまで。
ここまで。

#-----------------------------------------------
#文字列SでA文字目からBを検索する
#なでしこ1の「文字検索」互換っぽいの
●文字検索改(SでAからBを)
 検索対象=(Sの文字数)-A+1。 //Aの位置も検索対象に含める
 仮=SのAから検索対象を文字抜出。
 数=(仮でBを文字検索)
 もし、数=0ならば、数で戻る。
 違えば、数+A-1で戻る
ここまで。
#-----------------------------------------------

 タブン、合ってると思うんだけど・・・



 さてさて、次にやりたいことは、指定した文字が漢字かどうかを調べることなんだけど、「文字種類」の中に、漢字か判定は無いので(1にも無い)自前でなんとかしないない

 ユニコードのCJK統合漢字の中に、ふつーに使うほとんどの漢字が含まれているのですが、ウィキペディアさまによると、Unicode 11.0では次のようになってるそうです。

U+4E00~U+9FEA   CJK Unified Ideographs(CJK統合漢字)
U+F900~U+FAFF   CJK Compatibility Ideographs(CJK互換漢字)
U+3400~U+4DFF   CJK Unified Ideographs Extension A(CJK統合漢字拡張A)
U+20000~U+2A6FF  CJK Unified Ideographs Extension B(CJK統合漢字拡張B)
U+2A700~U+2B734  CJK Unified Ideographs Extension C(CJK統合漢字拡張C)
U+2B740~U+2B81F  CJK Unified Ideographs Extension D(CJK統合漢字拡張D)
U+2B820~U+2CEAF  CJK Unified Ideographs Extension E(CJK統合漢字拡張E)
U+2CEB0~U+2EBE0  CJK Unified Ideographs Extension F(CJK統合漢字拡張F)

https://ja.wikipedia.org/wiki/CJK%E7%B5%B1%E5%90%88%E6%BC%A2%E5%AD%97


 とゆうわけで、正規表現で、

「^[\u4E00-\u9FEA\uF900-\uFAFF\u3400-\u4DFF\u20000-\u2EBE0]」で正規表現マッチ

で行けるかと思ったら、行かなかった。

 5桁のユニコードは、なんでもサロゲートペアなるものの対応が必要ラシイ。

https://ja.wikipedia.org/wiki/Unicode#.E3.82.B5.E3.83.AD.E3.82.B2.E3.83.BC.E3.83.88.E3.83.9A.E3.82.A2

 よくわかんないケド、このとうりに計算してエンコードすればいいのだろう。

 あと、ここによると第2面のU+20000~U+2FFFFは漢字専用領域となっているようなので、少なくともこまでは将来的に拡張される可能性があると考えられるので、

[\uD840-\uD87F][\uDC00-\uDFFF]

 こんな感じ?

 CJK統合漢字も、ATOKさまの文字パレットを見るとU+9FFFまで範囲になっているから、キリよくこまで含めとく?

 あと、繰り返しの「々」と漢数字の「〇」も含めておきたい。

U+3005  々(CJKの記号及び句読点:繰返し記号)
U+3007  〇(CJKの記号及び句読点:漢数字ゼロ)

 「〇」は、丸「○」とは別ですよ~。毛筆書体などを適用すると、違いが顕著なのでご注意です。

 でっ、こうなった。

#-----------------------------------------------
#文字列Sの1文字目が漢字か判定
●漢字か判定(Sが|Sの|Sを)
  Sを「^[\u3005\u3007\u4E00-\u9FFF\uF900-\uFAFF\u3400-\u4DFF]|[\uD840-\uD87F][\uDC00-\uDFFF]」で正規表現マッチ。
  もしそれがnullならばいいえ戻る。
  違えばはい戻るここまで。
#-----------------------------------------------
#以下はテスト
「○」が漢字か判定して表示。   //0 丸
「〇」が漢字か判定して表示。   //1 漢数字のゼロ
「一」が漢字か判定して表示。   //1 CJK統合漢字
「1」が漢字か判定して表示。   //0
「豈」が漢字か判定して表示。   //1 CJK互換漢字
「㐀」が漢字か判定して表示。   //1 CJK統合漢字拡張A
「𠀀」が漢字か判定して表示。   //1 CJK統合漢字拡張B

 しかし、頑張って対応させたものの、果たして拡張部分は必要だったのか;

 見たこともないヤツばっかだ;;;

 して、扱おうとしてるテキストは青文庫のなので、文字コードはJIS X 0208 の範囲に限定されていて、それ以外のは註になってるんだよね。

 ウィキペディアさまによると、「IS X 0208のすべての漢字が、UCS/Unicodeの基本多言語面のいずれかの符号位置に対応する」・・・とゆうことらしいから、明らかにいらなかった気が(´・ω・`)

https://ja.wikipedia.org/wiki/JIS_X_0208#ISO/IEC_10646%E3%81%8A%E3%82%88%E3%81%B3Unicode

 まあ、他のことでも使うかもしないし、足りないよりかは網羅している方がいいとゆうことにしようそうしよう。



 んなこんなでやろうとしていたことは、折角なでしこさんがしゃべるようになったので、青文庫でも読み上げさせてみっかなとゆうことで、読み上げにルビを反映させることでした。

 何しろ、のまま読ますと「兎《と》に角《かく》」を「うさぎきごうときごうにかくきごうかくきごう」と読んじゃうんですからねヽ(;´Д`)ノ

 まず「《」を検索して、漢字か判定でルビの付いてる範囲を調べ、それとルビの記号「《》」を消せば(置換)ルビ部分だけが残るって寸法です。

 しかし・・・もはるかさんの読み上げ精度がひどい(「沢山」を「さわやま」と読んじゃうとか!(´д`;)上に、最近Fire7を手に入れたところ、標準でみずきさんがKindleを読み上げてくれるんで、もうなんだかな~;

 まあ、みずきさんもんなに上手に読んでくれるわけじゃないですけどねw

トラックバック - http://nadesiko.g.hatena.ne.jp/snowdrops89/20190317