やねうらおうの定跡ファイルをサイトに使ってみた

ずーっと海外に住んでいて、将棋を指す相手がいなく、ヒカルの碁でネット碁の存在を知り、 こんなものがあるんだ、と検索して、Kurnickというゲームサイトを見つけ、そこでネット将棋を始めてみたら、みんな結構無茶苦茶な指し方をするのにびっくりして、英語の将棋入門サイトを作成したのが、今から17年くらい前、最初は静止画像をべたべたはりつけ、ブログに毛が生えたようなサイトだったが、フラッシュアプリを使った将棋盤というのが世の中にあるのがわかり、これを使って詰将棋やら最初の数手の説明、定跡の説明なんかをしていた。
割と早い段階で、フラッシュが駆逐されそうだということに気が付き、JavaScriptを勉強してフラッシュ無しでも動く将棋盤を自前で作成して自分のサイトで使い始めた。これがもうかれこれ12年以上前。これが幸いしてFlashが完全終息 した際のインパクトは避けることができた。

当時はそれなりに海外の将棋入門者の役にたったのではと思っているのだがそのうちYouTubeにHidetchさんが英語の将棋入門チャンネルを開き、さらに81道場を開設するにいたって、これは時代が変わったと悟った。 今ではほかのリソース、例えばYoutubeに上がる将棋の動画などもさらに充実し、DiscordではカロリーナのShogi Harborなど。 加えて自分もそろそろ終活を考慮しはじめるべき歳なのでこのサイト、もう閉じようかと思ったりするのだが、Statsを見るとまだ世界中からぼちぼちロボットではなく人間のアクセスがある。のでなんとなく続けている。 それにページを更新するごとにPHPの新しい使い方とかTypeScriptの勉強にもなるので、頭の老化防止にもつながっているような気がする。→どちらかというとこれが現在一番のモチベーションになっている。

最近何気にWikipediaの将棋の項目(英語版)を観たら外部リンクのリストの最初に自分のサイトが載っていて驚いた。ますます閉じにくくなった。

このサイトの中で何度か書き直しているページの中に、初めの数手の内容をまとめようとしたページがある。 最初はYamajunさんのサイトにある棋譜にリンクしていた。  しかしながら他のサイトへのリンクというのは実にあてにならないもので、 このリンクを含むリンク先の大部分が2019年時点で消失していた。 2009年当時Webの90%を占めていたFlash Player base のサイトが ほぼ全滅したのが大きいと思われる。
ならば自前でつくろうと考え、やり直しを重ねたこのページ。 一応形にはなったが、これは掘り下げていけばいくほど、もっと広げていきたい衝動に駆られる。

最近 やねうらお さんのGithubでやねうら王に使われている定跡の4年前のレベルのものが公開されているのに気が付いた。 自由にお使いくださいと書いてある。前にNHKの将棋講座の特集でだれかが将棋ソフトの作者さんたちは気前が良すぎるんですと言っていたが、まったくだ。  定跡フォーマットを見るとSFEN + move(s)の繰り返しのテキストファイルだ。 幸いSFENの読み込みと書き出し機能は自作のWeb用将棋盤表示アプリにすでに実装ずみなので、このファイルをそのまま使わせてもらってWebで定跡表示ができるのではないかと思いついた。

遠い昔 やねうらお さんというハンドルネームの方の、将棋界の内情を色々批評していたブログを見ていたようなきがするのだが、同一人物かどうかはさだかではない。 ただ、今や将棋プログラム界のドンとでもいえるような大活躍をされているようである。 5歳のときにTK‐80を使って8080のニーモニックを覚えたと書いているのを見ると、多分 自分より20歳くらい若い働き盛りなのでありましょう。自分がTK-80に触ったのはまだ日本にいたころ、取引先の業者がNECの代理店をやっていて、「遊んでみて」と持ってきたのが最初だ。モニターのルーチンを使ってスクロール表示をくるくる回しただけで満足して 終わったような気がする。

ともあれ、定跡ファイルをばらしてMySqlデータベースに落とし込んでみた。Pythonを覚える良い機会と思ったがコマンドラインでもPHPが使えることを思い出し、コードもあっさりかけてしまったので、Pythonの学習はまたもやお預けだ。(ファイルサイズが87メガバイトの大定跡ファイルは、MySQLに落とし込むのにPHPをコマンドラインで実行させて4~5時間ほどかかった。 専用サーバーではなく、他の業務と兼用なので、こんなものなのかもしれない)

局面数指し手数
やねうら王定跡(2016)130,182155,443
やねうら王大定跡(2016)428,2442,433,672
やねうら王テラショック【WCSC29】285,463512,860
各定跡ファイルの持つ局面数と指し手数

Web ServerにSFEN文字列を送るとと候補手のアレィをリスポンスとして返してくれるようなAPIを作成し、ページを追加してみた

我ながら GUI デザインのセンスが無いなあと思うのは毎度のことだが、 面白いなとおもったのは最初の定跡(説明によるとFloodGateで収集した棋譜を24手まで統計的にまとめたもの)の初手の頻度が人間の指す初手の頻度とほぼ一致していた点。2016年当時ということもあるのだろうが、ソフトというのは、もっと自由な手を指すのかと思っていた。この統計頻度の高い指し手を選び続けて行くと先手左美濃対後手四間飛車になる。 こういう風に指すんですねえ。
一方局面評価をしまくって精選したという100Tera Shock定跡なるデータファイルのほうでは評価値が高い指し手を選び続けると横歩取りに誘導される。

大定跡は一番充実しているはずなのだが、評価値の高い指し手を選んでいってもはやばやと定跡から外れるケースが多い。 原因は Mysqlへの落とし込みに失敗しているか、最初から定跡ファイルがそういう作りになっているかのどちらかだがよくわからない。ただ、下の表に示したように、初期局面1にたいし、二番目の(一手目)局面が14種類、三番目の局面(2手目)が56種類 と多くなっていくものの局面数が、指数関数的には広がっていないので結構枝をはらっているのはわかる。でも第一候補の次の指し手が無いというのはなんかおかしい。 暇ができたら見直してみます。

11
214
356
4135
5323
6678
71289
81922
92714
103623
114812
125995
137181
148407
159741
1611136
1712492
1814160
1915731
2017425
2118979
2220500
2321883
2423224
2524374
2625479
2726567
2827704
2928792
3029952
3131001
3231954

これだけの局面数と指し手を評価して枝をはらっていくというのは相当にリソースと時間が必要になると思うのだけど、それをgithub上にポンと公開してくれているのは 大丈夫ですか、と思ってしまう。恩恵にあずかっているわけですが。

Python Generator

>>> def make_counter(x):
	print('entering make_counter')
	while True:
		yield x
		print('incrementing x')
		x = x + 1

		
>>> counter = make_counter(2)
>>> counter

>>> next(counter)
entering make_counter
2
>>> next(counter)
incrementing x
3
>>> next(counter)
incrementing x
4
>>> next(counter)
incrementing x
5
>>> def fib(max):
	a,b = 0,1
	while a < max: yield a a,b = b, a + b >>> for n in fib(1000):
	print(n,end = ' ')

	
0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 
>>> list(fib(1000))
[0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987]
>>> 

Python Generator の話

React Revisited after version 16.8

React というのは DOMの内容を簡単に操作しようという JavaScriptのライブラリーの一つだが、Shadow DOMという概念を導入し、JQueryのようにコマンドごとの実行でDOMを書き換えることはせず、Shadow DOMにある程度書き込んでおいてから描画する直前にまとめてDOMに書き込む。なので軽快に動作する、というのが売り。

数年前に覚えようとしたのだが、 二点腑に落ちないところがあって、結局、Vue.jsという他のLibraryを愛用(溺愛)するに至った。

その二点というのが

1.JSXという新しい概念の導入。 一見するとHTMLなのだがHTMLではなく、XML書式をJavaScriptで理解できるようにしたプリプロセッサ。この一見HTMLというのがくせもので、class= はJSの予約用語ゆえに使えずclassName=にしなければならないなど、細かいところで違っていて気持ちがわるい。(これに比べてVueのTemplateはまごうことなきHTMLの拡張)

2.コンポーネントで操作できる変数(State)を使うためにはコンポーネントをClass表記してsetState()という関数を使って管理しなければならない。

というもの。

その後 「JSXは単なるJavaScriptの関数表現」という開発チームの解説をYoutubeでみて ストンと納得できるものがあったものの、 二つ目のJavaScriptにClassが必要というのがなんとも納得いかない(個人の意見です)身としては今いち手が出せずにいた。 Class表記をするあまり、 thisの多用を行い、しかもそのContextを明示するためにClass Constructorに this.function=this.function.bind(this) を書きまくるというのがなんとも切ない。

しかしながら、 Reactの勢いは侮りがたいものがある。 特にMicrosoftのOffice開発系の方たちは Office UI GraphicsのComponentに「Reactは正義!」という感じで使いまくっている。 SharePoinitの JavaScript Frame workも Reactびいきがすごい。

で、最近React-client-appというCLIでReactのScaffoldingが簡単にできます、という記事をよく見るので、実際どれくらい簡単なんだいと試してみたら、 生成されるScaffoldingのComponentがClass表記ではなくfunction表記になっている。 あれ、これって、Stateful Componentは Class表記しなければいけないんじゃなかったっけ、と思ったが、 実はReactも進化していた。

Version 16.8から Hooksという機能が追加されて Functional ComponentでもStateの管理ができるようになっていた。 そして今まで、 Functional Component = Stateless Component, Class Componnet=Stateful Componentとなっていたものが、 どちらを使ってもよいようになっている。 Reactのサイトにも将来の開発にはFunctional Componentを使うのがおすすめと書いてある。 なので、React-client-appもDefaultで生成するコードはクラスレスになっていたわけだ。

紹介ページ https://reactjs.org/docs/hooks-intro.html にあるコードをみれば一目瞭然だが、クラス表記のようなConstructorもなければ、this. でメンバー指定をすることもない。 非常に簡単。 ただ、このHookを使ったクラスレスのステートフルコンポーネントの作り方、オフィシャルサイト以外で解説しているサイトはまだ少ない。

この

const [ var1, setVar1]=useState('this is variable one');

で気をつけなければいけないのは Var1が複数メンバーから構成されるオブジェクトだった場合、

const [obj1,setObj1]=useState({member1:"this is member 1", member2:"this is member 2"})

のように Obj1を宣言したときに、

setObj1({member2:"this is member 2 modified"})

とやってもsetState()と違って、オブジェクトの他のメンバー(Key)とマージしてくれない。上の例ではmember1が消えてしまう。

セット関数には元のstateがパラメータとして渡されているのを利用して、

setObj1(s=>({ ...s, member2:"this is member 2 modified"}))

とスプレッド表記を使ってマージしてあげる必要がある。(上のサイトにはObject.createを使うのも可と書いてある)

また、いわゆる ComponentWillMountなどのLife Cycle hookの代わりには描画毎に発火するuseEffect()を使えと書いてある。 このHookは発火を限定するために二つ目のパラメータ―で発火する条件を指定できる。 ファイルデータを読み込むなど、あるいはイベントリスナーを設定するなど、一回だけ発火させたい場合、 このパラメーターを空のアレイで渡してあげることで実現できる。(なんとなくハックっぽいが)

useEffect(()=>{Data を読み込む云々}, [])

他にも何種類かのHooksが用意されているが、 演習用にアプリを書いてみると、上の二つのHookだけで、それなりのものができる。

すでにJSXへのアレルギーはなくなっているので、クラスを使わなくてよいReactという選択は結構魅力的です。

すべてにVue.jsを使いたいのはやまやまなれど、SharePoint関連においてMicroSoft が Reactありきの開発を推しているというのはやはり大きい。

Using Vue with WebPack

I wanted to transfer my existing script to WebPack bundle.  The application is a simple page that uses  Vue.js.   Note that I only read Introduction part of Vue and started using it.  At that time, I did not even know the concept of Vue component files .  Thus my application was entirely in one JavaScript file.

I rewrote it using typescript.   WebPack bundling was necessary to make it work.

I had to decipher minor (but important) detail on NPM’s Vue  module that should be used along with WebPack. 

If I were to use a Vue package from node_modules/ and bundle it with WebPack, then the default module that will be used is Runtime-only ES module build (vue.runtime.esm.js.)

Now this verbiage is coming from VueJs.org V2 guide
https://vuejs.org/v2/guide/installation.html#Terms


” If you need to compile templates on the client (e.g. passing a string to the template option, or mounting to an element using its in-DOM HTML as the template), you will need the compiler and thus the full build:”

This applies to ‘getting started example’ code where  you use template directly on target html file, such as 

<div id="app"> {{message}} </div>

According to Vue documentation, runtime only module is 30% lighter and when I write my code in such a way that it utilize component file (*.vue), then  using vue-loader will precompile all the templates into render function (for those within component file)  so the default settings wil be not an issue.   Issue is when I create a new instance  of the view . 
Again, according to the guide

// this requires the compiler
new Vue({
template: '{{ hi }}'
})

// this does not
new Vue({
render (h) {
return h('div', this.hi)
}
})


If I use the first method but did not configure webpack to use full version of Vue module, resulting bundle file  is missing template compiler and I will be staring at the blank page.  In this situation,  looking into  source with F12 looks something like this

<body><!-- function(a,b,c,d) {.......} --></body>


Then how do I configure Webpack  so that it knows to bundle the full version of vue module instead of runtime-only module?  It was spelled right in the guide above.

module.exports = {
          // ...
          resolve: 
                {
                   //.....,
               alias: {'vue$': 'vue/dist/vue.esm.js' }
               //.......
      }

I needed to add  ‘alias’ clause to  the ‘resolve’ section of module.exports.  (for webpack v2 and above)
WebPack will then bundle full version of Vue module(vue.esm.js). 

Since I didn’t use .vue files for this project and put everything in a single html file, I did not  need to use ‘vue-loader’ either.
So this is a minimal requirement for Vue to work with WebPack.

Vue.js has a very detailed documentation which is good. All I needed was to read it through and understand the meaning of it (lol).  

By the way, another way to make it work is not tell WebPack about Vue at all.

  1. add script tag in your HTML writeup pointing to Vue CDN
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>


    2. Then tell Typescript  that ‘Vue’ is a global object

declare let Vue:any

Yes, use the bundler but not bundle the module. It sounds strange but it works

String.replaceで知らなかった件

User がノート欄にやたら長いリンク先をそのまま張り付けて、SharePointのリストの表示が著しく損なわれるという現象が自分の管理するサイトコレクションで何件か発生している。 ユーザー教育を行ってリンクの説明を別途短文入力してください、というのは簡単だが、だまって従ってくれるような従業員ばかりではない。 そこで長いリンクを見つけたら強制的に短い文字列に置き換えてしまう、という仕掛けをJavaScriptで書いてしまえばよいのだと思いつき、 試してみた。 結果、以下のような関数を記述し、これを描画時に呼び出す形で解決した。

function shortenAnchor(text) {

    if (text===null) {
        return "";
    }
    let testPattern = /(<a.*?href=.+?>)(.*?)(<\/a?>)/g;

    function replacer(match, p1, p2, p3) {
        if((p2.length)>30) {
            p2 = p2.slice(0, 25) + '...';
        }
        return [p1, p2, p3].join('');
    }

    return text.replace(testPattern, replacer);
}

このコードで何をやっているか。 まずtestPatternを正規表現(RegExp)で記述する。 RegExpで a tag elements をグローバルにトラップする。トラップしたエレメントはタグの前の部分、中身のテキスト部分、タグの後ろの部分にグループわけされ、それぞれの文字列は$1,$2,$3として利用可能になる。( a tag element 全体のマッチは$&)。 そして、あとは String.replaceを使ってマジックをおこすわけだが、Implementationを試行錯誤している最中に 二つ目のパラメーターが実は関数でもよいのだ、というのを本日初めて知ったわけで、それを使ってうまく書くことができた。 ここに関数を使うと、以下の引数が この順番で使えるようになる。 まずは TestPatternそのもののマッチ $&, それぞれグループ分けした部分のマッチ $1,$2,$3。 よって match,p1,p2,p3として利用可能にしておく。実はこの後ろにIndexなどのパラメーターも続くのが、今回は必要がないので無視。 
この replacer という関数ではこの中身の文字列$2(p2)の長さが30文字以上あった場合、最初の25文字以下を切り捨て点三つ…を最後に追加するというもの。 この関数自体を二つ目の引数として使う。 Testしてみたら一発で完動したので感動(おやじギャグです)

普通はString.replaceというと

"this is a pen".replace("this","that") //=>"that is a pen"

という簡単な使い方は知っていたし、 最初のパラメーターを正規表現にすれば $& $1 etc., などのパラメーターを使ってかなり柔軟な置き換えなどができることも知っていて使ってはいたのだが、まさか関数まで使えるとは思っていなかった。 これは素晴らしい、と思った次第

TypeScript その2

年末の休暇を利用してtypeScriptの演習を続行中。 現在まで理解できたところをとりあえず列挙。
nodejs が導入されている必要あり。

npm install typescript -g

これで tscコマンドが使えるようになる。

tsc example.ts

そして、これでexample.ts から example.jsがトランスパイルされる。

プロジェクトフォルダー内で

 tsc init

とやると、コンパイラー設定用のtsconfig.jsonが作成され規定値が設定される。例えば、出力のJavaScriptのレベルが

<pre>”target”:”es5″</pre>

などと記述されている。またコードをトランスパイルしたときのエラーの出力設定などもできる。今のところ全く変更の必要のないレベルでトライアル中。

TypeScript は 基本的には JavaScriptのsuper setなのだが、 ’let’, ‘const’, ‘arrow function ()=>’, ‘ … spread operator’,’Template strings’ などes2015の書式が既にサポートされている。 なのでexample.tsではこれらの言語機能を使ってプログラムを書き、tscでトランスパイルすると、これらの表記をまだサポートしていない現行のブラウザでも動くようなJavaScriptに書き換えてくれる。上のConfig例ではes5レベルのコードに置き換わる。 つまりBabelと同じような使い方ができる、。

type safeなので 異なったタイプの変数へのアサインは論外としてもその可能性が生じそうなコードにはエラー表示が鬼のようにでる。例外処理とか、Interface定義を記述して対処すると満足して何も言わなくなってくれるので、バグの可能性のあるコードを書く可能性が低くなる。

TypeScript 入門

TypeScriptのイントロがDev.office.comにあるので眺めてみた。

tsとして以下の例が載っている。

class Student {
    fullName: string;
    constructor( public firstName, public middleInitial, public lastName){
        this.fullName = firstName + " "+ middleInitial + " " + lastName;
    }
}
interface Person {
    firstName: string;
    lastName : string;
}

function greeter(person: Person){
    return "Hello, "+ person.firstName + " " + person.lastName;

}

let user =new Student("Jane","G.","Doe");

document.body.innerHTML=greeter(user);

これをJSにコンパイルするとこうなる(WebStormはプラグインが動いてダイナミックに自動生成する)

var Student = (function () {
    function Student(firstName, middleInitial, lastName) {
        this.firstName = firstName;
        this.middleInitial = middleInitial;
        this.lastName = lastName;
        this.fullName = firstName + " " + middleInitial + " " + lastName;
    }
    return Student;
}());
function greeter(person) {
    return "Hello, " + person.firstName + " " + person.lastName;
}
var user = new Student("Jane", "G.", "Doe");
document.body.innerHTML = greeter(user);

うむむむむ。JSのほうがパターンに親近感があって読みやすいんですけど。でもそういうことじゃなくてTypeやクラスの定義がしっかりできて、あとあとの管理が楽、ということなんだろうな。

SharePoint Framework

去年の暮れぐらいだったか、MSのお知らせでSharePoint Frameworkという新しい開発環境を使った SharePoint SiteのCustomizationが可能になりました。という連絡があった。  自分がやりたいSPサイトのCustomizationは 基本的にJavaScriptをページに埋め込むJavaScript Injectionという手法だ。 これでクライエントサイドの描画をコントロールするCSRフックとかリストやファイルのアイテムをAjaxで読み書きするREST APIなどを使ってカスタムページを作るという方法で用が足りてしまうので、あまり気にしていなかったのだが、この方法、最近、その進化が目立つModern view  pageでは使えない。 これは開発するのにVisual Studioが必須であるSharePoint Add-Inでも同じ様で、 どうも今の時点でModern Look componentのCustomizationをサポートしているのはSharePoint Frameworkのみのようなのだ。

で、Dev.Office.comのDocumentationを眺めてみると、なんとこれ、 Node.JS上で全部動いているのだ。

NPMで yo,  gulpと @microsoft/generator-sharepoint を導入し Project folderを作って以下を実行

yo @microsoft/sharepoint

これで必要なファイル群がフォルダーにインストールされる。 hello worldのテンプレートになっているので、これでもうnode.js 上のローカルPCで動くSharePointのページを模したWorkbench上での実行が可能(下記コマンドでDefaultブラウザが勝手に立ち上がる)

gulp trust-dev-center

gulp serve

ここまで、SharePointサイトにアクセスする必要すらない。 Step by Stepはdev.office.comに詳しいので割愛 (Build your first SharePoint client-side web part (Hello World part1)

SharePointのサイトでもすでにDevelopper siteが例えば”https://mysite.com/sites/dev”などとして設定されているなら、 ”https://mysite.com/sites/dev/_layouts/workbench.aspx” にアクセスすると、開発中のwebPart のWorkbenchがSharePoint上で作動する。

そしてこのTool Chainによる開発、Visual Studioが必要ない、というか使えない。dev.office.comのお勧めEditorはVS Code. IDEの例としてJetBrainのWebStormがあげられているなどVisual Studioへの依存性が一切ない。(C#もドットnetも使わないなら当たり前というべきか)

ただ、使われているコードが通常のJavaScriptではなく、TypeScriptなのだ。 TypeScriptのコードは実行時にはJavaScriptにばらされるのでそんなに大きなLearning Curveにはならない、と予測はしているのだが、これは学習する必要があるんだろう。

Node.jsは言語というより開発環境のベースとして使われるので、これ自体を学ぶ必要はない。

VSで使っていたNugetだとかMS buildーtoolなどのツールが、下のようにNode.JS上で動くツールにおきかわっているわけで、今わかっている範囲でまとめると

  1. Node.js: Install するだけ、普通のJavaScriptの知識で十分のはず。
  2. NPM :DependencyのUpdateなど、使い方は学んだほうがよさそう。yarnでもいいのかな
  3. yeoman(yo):Install するだけ、学習の必要性はなさそう
  4. gulp: コマンドをいくつか覚えるだけで学習の必要性はなさそう
  5. typescript: 学習の要あり
  6. webpack:@microsoft モジュールを導入したときに含まれている。さわらなくてよい。何本ものファイルを、一本に圧縮する、というような作業をやっているらしい。
  7. VS CodeまたはWebStorm:Dev.office.comはVS Codeを使った用例を挙げているが、自分は従来からつかっているWebStormを使う。

というわけで、なんと開発環境的には、2,3,4,5,6は1のNodeJSが動けば動くのでなんでもよく、VS codeもWebStormもマルチOS環境で動くので 要するに Linux上で開発できてしまうのだ。

というわけで、javaScriptをかじっている人間にはハードルが低そうな予感。 Linux環境でぼちぼちやってみようかな?

constructing long string with Javascript

There is a time you need to construct a string (for instance, to create a html block) in your code.

In the simpliest approach, youcan constract the string variable  like so

var html='<head><body>’+contentVariable+’more stuff’ + ‘</body></head>’;

this becomes very messy quickly once more variables, more nested construction is needed.

I used to keep concatinating the string, like so

var html='<head></body>’;

html +=  contentVariable;

html += ‘ more Stuff’;

html += ‘</body></head>’;

 

 

Then I saw a pattern in the couple of codes from internet;

var h=[‘<head><body’];

h.push(contentVariable);

h.push(‘more Stuff’);

h.push(‘</head></body>’);

var html=h.join(”);

The More concatenation needed, the more convinient the last method becomes. Key is to join the array element with null delimiter.