前回の学習では、WPFのアウトラインを俯瞰してみましたが、抽象的過ぎて何の役にも立たない「知ったかぶり知識」でした。プログラミングにおける「役に立つ知識」とは「プログラムを書ける能力」に直結していないと、ですよね?

 

では「即戦力」観点から学習するにはどうしたらよいのか?「習うより慣れろ」の原則に立ち返るべきなんでしょうね。まずは「単なるウィンドウを作る」所から始めましょう。まずは慣れ親しんだWinFormでのウィンドウだけのプログラムから。

 

【WinFormでの最小ウィンドウプログラム】

/////////////
// Form01.cs
/////////////
using System;
using System.Windows.Forms;

namespace Form01
{
    class MyApp : Form
    {
        [STAThread]
        public static void Main()
        {
            Application.Run(new MyApp());
        }
    }
}

 

WPFでこれと同じようなことをやってみます。

【WPFの最小ウィンドウプログラム】

/////////////
// Window01.cs
/////////////
using System;
using System.Windows;

namespace Window01
{
    class MyApp : Window
    {
        [STAThread]
        public static void Main()
        {
            Application.Run(new MyApp());
        }
    }
}

 

最初のエラーメッセージが、

「Window01.cs(9,16): error CS0246: 型または名前空間名 'Window' が見つかりませんでした。using ディレクティブまたはアセンブリ参照が不足しています。」

だったので、WPFプログラムに最小限必要な(注)

RefFile=C:\Windows\Microsoft.NET\Framework\v4.0.30319\WPF\WindowsBase.dll
RefFile01=C:\Windows\Microsoft.NET\Framework\v4.0.30319\WPF\PresentationCore.dll
RefFile02=C:\Windows\Microsoft.NET\Framework\v4.0.30319\WPF\PresentationFramework.dll
RefFile03=C:\Windows\Microsoft.NET\Framework\v4.0.30319\System.Xaml.dll(注)
をMSCompAssの「参照ファイル」に追加します。

(注)最初はエラーメッセージを出しながら、その内容やMS Leraningで調べて、やっとこさこの4つが必要であることを暴きました。特に困ったのがSystem.Xaml.dllで、「俺はXamlは使わないから」と無視したら、PresentationFramework.dllが参照しているので'System.Windows.Markup.IQueryAmbient' が参照されていないアセンブリで定義されています。アセンブリ 'System.Xaml, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' への参照を追加してください。」というエラーが出てしまいました。従って、WPFプログラミングでは、このSystem.Xamlへの参照は不可欠であると考えてください。

 

さあこれでよいだろう、とコンパイルしたらまた「静的でないフィールド、メソッド、またはプロパティ 'System.Windows.Application.Run(System.Windows.Window)' で、オブジェクト参照が必要です」というエラーが出ます。(注)

注:参照しているのは、またPresentationFramework.dllです。ご存じの通り、このエラーはC++でいうところのポインターがnullで、インスタンスの実体がメモリーに存在しない場合に出ます。WinFormの場合はApplicationクラスに静的なメソッドがあったのでコンパイラー通りましたが、WPFでは静的なメソッドがないので通らなかったことになります。

 

しょうがないので、↑の紫字部分を

            Application Myapp = new Application();
            Myapp.Run(new MyApp());

と書き換えてコンパイルすると、

やっとこさ、サイズが大きめの、クライアントエリア色が異なるウィンドウが表示されました。(ここら辺から私は、「両者は似たようで非なるものだ」という印象を強くしていきます。)

 

この間、Amazon PrimeでM3GAN(注)を見ました。

注:ご存じない方の為に予告編を。

 

米国で大ヒットしたということに素直にうなづけるストーリー展開で、大いに楽しめまましたし、二匹目のどじょうを狙うのも郁子(ムベ)なるかな、と得心が行きます。一方、これがAIの危険性と短絡的に結びついて直ちに恐懼のような感情的反応を起こすようなことはないでしょうが、反対に「あれは映画だから」ということでAIの危険性を過小評価することもないようにしたいものです。

 

私は4年前までは、とあるリスクコンサルティング企業にいて、AGIの人類に対する危険性についても一般的調査研究の対象でした。

 

1.先ずは「人工知能」とはなにか?という問題があります。このAIの定義が曖昧で規範性がない為に、更に問題が迷走するという問題もあり(注)、この傾向に警鐘をならし、真剣にAI、即ちAGIを検討し、本当に危険性があるのか否かを考えることが必要だと考えます。(なお、電気も通信もないような田舎にスタンドアローンのAGIがあるなら「危害の方法」がなく、危険じゃないですが、社会機能の統制がデジタルネットワークで管理されている社会で、AGIに最高技術のハッキング能力があれば社会的支配力は大きくなり、危害の可能性は大きくなりますね。以下はその前提で話します。)

注:例えば、最近は「(画像処理機能を中心とした)機械学習=即AI」と表現する傾向もあって(個人的には殆ど詐欺に近いのではないか、と思う)製品宣伝もあり、批判(↑の警鐘と同じ記事です)されていますね。

 

2.人工知能の危険性というと最初に上ってくるのがSingularityの問題ですね。誤解を恐れずに「えいやっ」とまとめると「AIが人間より賢くなってしまって、AI何をやっているか(処理)が人間には理解できなくなり、その結果(処理の)制御できなくなる」(注)ことだといえましょう。プログラミングをやっている人ならば、「賢いAIが自らを再帰的に賢く書き換える(創造的学習ですね)ことにより発生する知能の爆発」は極めて「起きそう(Likely)」に感じます。(上述(↑)のM3GANでも、最後に「M3GANが守るべき第1ユーザー」として設定された少女との戦いで、その少女がM3GANをシャットダウンするよう命令した時に、"I'm afraid it does not work."といった後に、第1ユーザーは"It’s ME.(「それは私よ。」)"と発言します(映画の1:32:04参照)が、将に「創造的学習」の賜物ではないでしょうか?私には印象深かったです。)

注:既に囲碁の世界では「人工超知能が実現した場合、人類は本質的にその行動・思考・原理を理解できない可能性がある...開発者ですらどのように動作しているか正確に理解できておらず、解説者を務めたマイケル・レドモンドは『これが良い手なのか悪い手なのか本当に理解できない』と述べている」そうです。

 

3.皆さんと同じく、私もAIの研究者ではありませんし、こういう問題を取り上げると得てしてコンピューター設計の技術的側面に話が流れてゆくのですが、私が現役の頃は「問題を簡略化して、それを原因として派生する危険を洗い出すことにより、リスクマネージメントは十分に可能」であると、クライアントの方にはお伝えしてきました。

 

4.どういうことかというと、現在は技術的に可能ではないですが、最終の人工知能モデル「人間の脳(知能)」以上だと仮定し(注)、「自分と同等、または自分より賢い存在が自分に対して有する危害の蓋然性」を検討すればよいことになります。

注:ニューラルネットコンピューターは言うに及ばず、「汎用人工知能を達成するためのアプローチとしてしばしば議論される方法が、脳のシミュレーションや精神転送」という研究がなされています。

 

実はそれって余り特殊なことではなく、現在も日常的に発生しているんですね。それはこのリスクモデルが、

 

あなたの育成する子供や部下があなたと同等、またはあなたより賢く(その結果有能になり、より強い支配力を有するように)なった場合、あなたに対して有する危害の蓋然性

 

と変わらない、ということなんです。それに対して人間は古来からどうリスク対処してきたでしょう?

 

(1)教育(特に価値観と規範<含タブー>のインプラント)

(2)しつけ(教育内容の反復的実行や強制による定着化)

(3)監視(きちんと価値観や規範を遵守しているか否かのモニタリング)

(4)矯正(逸脱した例外存在の処理-処遇、対処、排除etc)

 

一番簡単な例が犯罪行為ですね。例として殺人(Homicide)を挙げてみましょう。人間は永続的存在を目的に法という社会規範を作り出し、「命は大切、人を殺してはいけない」という価値観と規範を明文化して社会で共有できるようにを作り、その遵守の担保として違反の監視、捜査、報復としての刑罰による矯正(含死刑による排除)のインフラ策定・執行を行っています。しかし、この手の「プログラミング上の例外や違反」は(小は問題児、不良少年少女、DV夫|妻、犯罪者、大は某Putinや某김정운、昨今の戦争行為)頻発し、「人間の愚かさ」は過去の例外や違反の反復的再発を阻止できず、犯罪行為の根絶は極めて困難であることが経験的に確認されています。

 

これこそが上記のリスク対処とその限界に関わる私の回答とならざるを得ないのですが、その前提は飽くまで「最終の人工知能モデルが「人間の脳(知能)」以上」であり、(知能の爆発により、特異点に達して「将来の為に現在を否定する創造的学習」によって)AGIの処理を人間が制御できなくなる段階におけるものであることを再度確認しておきます。(要するに「麗しく、偉大な人間的知能の特徴」なんですが。)従って、とどのつまりが、

 

人類の未来は明るいのか、暗いののか?それは今より明るくも、暗くもならない。

 

という言葉に尽きるのではないでしょうか?要すれば自然知能でも存在するリスクは、AIであっても変わらない(注)、ということです。

注:人工知能のPutinや김정운等が発生するだけです。ただし、人間の「例外、違反」者は「欲動」によって行動しますが、AGIに欲動があるとすれば「AGIの前提となる存続欲求(『私が何かであるには、まず私が存在しなければならない』)」であると考えられ、AGIと敵対しない限り、危険は最小化されることになります。(人間の場合でも戦わずに降伏することにより生存可能性が高くなるのと同じですが。まぁ、これも似たか寄ったかですね。)

 

【記事参照-以下は↑の参照と重複するものもあります】

人工知能

前回までの経験で「C#のウィンドウプログラムにはWinFormsとWPFという異なる(UI)プラットフォームがあり、これらは共存が困難である。」ということを学びました。(注)

注:私がMSCompAssを作って、Windows10や11に標準でついてくるcsc.exe(C# 5)を使い始めた際に参照した学習サイトは、私が20年以上前にC++を学習した際に参考にした旧いもの(「猫でも」)だったので、自然にウィンドウズプログラミングがWinFormsベースになった訳です。私はWPFという「言葉」は「Visual Studioの新しいプロジェクトの作成で出てくる略語」位は知っていましたが、WinForm、UWP等Microsoftの「寿限無寿限無」の一つくらいにしか考えておらず、両者の違い(そんなものがあるのかどうかも含め)は了解していませんでした。

 

では、「WPF(Windows Presentation Foundation)」とは一体何なのか?これについて調べるとわんさか出てきますが、最近Microsoftがお勧めのWindows Copilotさんは次の通り説明します。

 

WPFとは、Windows Presentation Foundationの略称で、Windows用のデスクトップクライアントアプリケーションを作成するためのGUIフレームワーク(注1)です。WPFは、解像度に依存しない、ベクター ベース(注2)のレンダリングエンジンであり、これは最新のグラフィックスハードウェアを活用できる(注3)ように構築されています。WPFでは、Extensible Application Markup Language (XAML)、コントロールデータバインディングレイアウト2Dおよび3Dグラフィックスアニメーションスタイルテンプレートドキュメントメディアテキストタイポグラフィなどの、アプリケーション開発機能の包括的なセットを使用します。WPF.NETの一部であり、.NET APIの他の要素を組み込むアプリケーションを構築できます。WPFのプログラミングは、ほとんどの部分がSystem.Windows名前空間に格納されている.NET型のサブセットとして存在します。WPFでは、マークアップと関連付けられたコードで動作が実装されます。このタイプのコードは分離コードと呼ばれています。WPFは、マイクロソフトが提供するMicrosoft Learnのコースで学ぶことができます。」(ご参考

注1:「なんちゃらフレームワーク」という言葉が出てきたら、サブシステム(API群)とか纏まったライブラリーがある、と考えてよいでしょう。

注2:FormはGDI+を使っており「ラスターベース」の描画を行います。「ラスター」と「ベクター」の違いは、これとかをお読みください。

注3:WinFormはWin32APIのラッパーだったので、GDI+というグラフィックサブシステム(API群)を使っていますが、処理がCPUに依存しているので、現在の新しいPCのようにGPUが独立して処理できる場合でもCPUに負荷がかかってしまいます。「最新のグラフィックスハードウェアを活用できる」とは、WPFがDirectXをベースにしているので、処理をGPUに任せることが出来る、という意味です。

 

自分なりに纏めると、

 

1995年の32bitOSであるWindows 95から脈々と続いてきたWin32API、GDI+、およびそれらをラップしてライブラリーとしてまとめたWinForms(プラットフォーム)から、新しい技術、特にDirect XをGUIに採用し、CPUへの負荷をGPUへ移管した新しいGUIライブラリー(注)

注:Windows 10、11についてくるC# 5では"C:\Windows\Microsoft.NET\Framework\v4.0.30319\WPF"に入っているようです。

 

で、その移行の必然性はこのようなことにありました。(大昔は640x480しかなかったのですが...。なお、実際には思った通り移行せず、未だにWinFormsアプリが結構残っているのが実態のようです。)

 

この進化はWelcomeですが、それは同時にインターネット環境への適合をも進め、「分離コードと呼ばれ」る、UIに関わるXamlコーディング(View)と処理に関わるC#コーディング(Model)の分離を可能とし(というか、促進し)、データバインディングと呼ばれるViewとModelの結合処理(ViewModel)で結ぶ、統合開発環境なしにはWPFベースのアプリケーションプログラムを開発するのが相当ムズイ状況にしてしまいました。(とはいえ、個人で趣味の小規模アプリを作るうえでは、このようなビジネスレベルの話は殆ど関係がない、とも思ったのですが...)

 

でも、本当にWPFプログラムはVisual Studioを使わずに書けないの?

 

などと馬鹿なことを考えたことを、まぁ、ブログネタにしたんですが。(続く)

 

【ご参考】

WPFを理解する!初心者でも分かる特徴、使用環境、基礎知識などを簡単に解説! | 案件評判 (anken-hyouban.com)

WPF とは|WPF 入門 (zenn.dev)

【2分で理解】!WPF とは ?図付きで解説! | 初心者DIYプログラミング入門 (resanaplaza.com)

 

前に「【昔話】私の8ビット時代」で、40年位前の私の「8Bit パソコン」経験について触れました。

最初のSharpの「ポケコン」は別としても、最初の「パソコン」であるSONY HitBit(MSX機)と現在の64Bit PCを比較すると、

CPUクロック    :4MHz3.2~4.4 GHz(但し8コア)(800~1,100倍)
主記憶    :64KB16GB(25万倍)
外部記憶装置:カセットテープ512GB SSD(比較不能)

という「ゲロを吐きそうな位の違い」です。同梱ソフトウェアだって、(私は既に28歳でゲームカセットを買うようなガキではなかったので)OS代わりのROM BASIC(MSX-BASIC)に自分で手入力するプログラムだけ、という潔さです。
 

そんなプアーな開発環境でも、「作る喜び」は今と全く変わらず、次のような九九を表示するプログラムが走っただけで感動したものでした。(注)
10 DIM i,j
20 FOR i = 1 to 9
30 FOR j = 1 to 9
40 PRINT i * j;", ";
50 NEXT j
60 PRINT

70 NEXT i
80 END

注:当時は現在のインテリセンスのような機能は全くなく、タブもスペースも自分次第。また、(出自のFORTRANに因んで)可読性よりも余計な容量を採らないように、プログラムテキストの無駄なスペースやインデントは排除されるべきものでした。(私がインデントを多用するようになったのは、後に「構造化プログラミング」がはやってからです。)

次にステップアップしたZ80 6MHzのMZ-2500も、主にMS系のBASIC言語(BASIC-M25)を使っていたのですが、この段階で初めてのC言語(BDS C)でのプログラミングや、それで自作したアセンブラー(ZASM.com)での機械語プログラム開発が楽しかったです。

なんで、こんな話を蒸し返すのかというと、昨年ですか、(当時の私たちには垂涎の的であった)X68000のミニチュアレプリカPC(X68000 Z)が発売され、即完売となり、再度追加販売してもまた完売した、という記事を読んだからです。(注)
注:関連記事
  メーカー
  追加販売
  製品レポート
  元ユーザーのレポート

かくいう私も(当時欲しくて欲しくてたまらなかったのですが、価格が高すぎて...買えませんでした...注)喉元迄「買いま...」となったのです。
注:当時の16Bit PCは、かの市場占有率9割を超えていた某N〇Cの9800シリーズに代表される「主記憶は1MBだけど、64KBのセグメントをスイッチイングして使うIntel 8086」ばかりで、これに辟易した好き者が「リニアな1MBメモリー空間をアドレスできる、Macと同じモトローラ68000型チップのPC」を待望していました。因みにwebの記事では「1987年3月22日(日)、X68000は本体価格369,000円という、その能力から考えれば破格のプライスで発売されました。」とあります。この「破格」とは「安い」という意味です。(N〇Cの9800は4-60万は平気でしていたし、画像処理能力を高めたPC-100というのは100万円位した、と記憶しています。またディスプレーは別売で2-30万してましたので、フルセットの16Bit機がいかに高かったかが分かると思います。)

しかし、
 

同梱されるソフトは「グラディウス」というゲームと、せいぜいがX-BASICのようで、当時「専用のC言語コンパイラが安価な価格で提供」というのはどうなったのか分かりません。

そんな「ノスタルジア」に浸りながら、ちょっと調べたら、
 

なーんと
 

MZ-2500も「好き者」がエミュレーターを出しており(ご参考)、そのエミュレーターの場所はここみたいです。しかし、これを使うには「実機からROMイメージを吸い出して、以下のファイル名で実行ファイルと同じディレクトリにコピーしてください。」とあるので、簡単に使えるものではありませんでした。


ところが、


MSXについても「好き者」がエミュレーターを出しており、その開発支援ソフトもあるというのです。

これには興味を惹かれ、関連記事も読んでしましました。

更に更に


スタンドアロンのエミュレーターもあるというじゃないですか?余りに懐かしくて、思わずダウンロードしかかりました
 

が、
 

「グラディウスなんてしないし、今更変態的X-BASICのプログラムを前時代的なエディターで書くのか?」

「今更MSX-BASICで九九のプログラムを書いてどうするの?」
 

という理性の声が聞こえてきました。まぁ、MSXが懐かしくなったら上記WEBサイトにいっていじればいいんですからね。

矢張り一度高度で効率的なプログラミング環境に入ったならば、もうそこからは抜け出せなくなる、ということなんです。あれほど市場独占を志向したMicrosoftがフリーのVisual Studioを提供するのも、ユーザープログラムの吸収機構のみならず、「Visual Studioを使わなければ、Windowsのプログラムは書けない」という「目に見えない市場独占(invisible Monopoly)」を目指しているからではないか、という

初(悪)夢

を見た思いでした。


とはいえ、後10-20年で失われてしまうであろう、1970-80年代のPC環境をのぞいてみたい等、ご興味のある方にはどうぞ。

 

本年もよろしくお願いいたします。

さて、本ブログも第3年目の終盤に入り、今年70歳の誕生日まで続けられるか否か、微妙な想いでおります。

既に何度も書きましたが、22年前にBCCFormをリリースした時とは様変わりしており、


(1)Visual Studioもフリー版があり、
(2)Win32APIも陳腐化しWindowsは.NETのCLI(Common Language Infrastructure)へ移行しており、
(3)CPUの64 bit化により32 bitプログラムが絶滅しつつあり、
(4)C++によるアンマネージドネイティブコードの必要性が乏しくなってきている
 

現在、中核事業となるBorland C++ Compiler(現在はEmbarcadero C++ Compiler)のフリーリソースエディター、開発ライブラリーとツールのパッケージをサポートするという本ブログの存在理由(raison d'?tre)風前の灯火です。

一方、MSComAssの開発から始めたC#の「体験的学習」記事は、「手書きで遊べる、GDI+やWin32APIのラッパーであるWinformの時代」から、「Visual Studio必須の.NET、WPFやUWPの時代」となり、「既にお前は死んで(陳腐化して)いる」ということがわかってきました。

となると、

「今後は何を書いてゆけばよいのか?」が重要な課題となってきます。

が、しかし、

真面目に悩んでも解決するわけでもなし、
(1)「高田純次的にお気楽に」
(2)「なんでも、あることないこと」
(3)「気の向くままに」
書き綴ってゆこうと思っております。(知らんけど。

いずれにしても、本年も気が向いた折に訪れていただき、駄文をお読みいただければ幸甚に存じます。

ps. 因みに昨年作ったChinchirorinの動作テストをまだ続けており、成績はこう(↓)なっております。人間の英知による「張り方」によって勝率が異なること、出目徳、上州虎、坊や哲が強いことが分かります。ドサ健は一時50%を超えていたんですがねぇ。

 

前回の話)いうことで、このサンプルコードを利用して自作のダイアログテンプレートをベースにテストします。

 

フォームのドンガラは直ぐにできて、

後はサンプルのコードを参考に「(メディア)ファイルを読込」「再生」「一時停止」「中断」「終了」の各メソッドを埋めればよいのです。(悪戦苦闘の部分は//解説:を参照してください。)

 

【MediaPlayer(Form).cs】

///////////////////////////////////////////////////////////////
// MediaPlayer, MediaDrawingサンプル

// https://learn.microsoft.com/ja-jp/dotnet/desktop/wpf/graphics-multimedia/multimedia-overview?view=netframeworkdesktop-4.8
// https://learn.microsoft.com/ja-jp/dotnet/desktop/wpf/graphics-multimedia/how-to-play-media-using-a-videodrawing?view=netframeworkdesktop-4.8
// https://learn.microsoft.com/ja-jp/dotnet/api/system.windows.media.videodrawing?view=windowsdesktop-7.0
// https://learn.microsoft.com/ja-jp/dotnet/api/system.windows.media.mediaplayer?view=windowsdesktop-7.0
// https://learn.microsoft.com/ja-jp/dotnet/desktop/wpf/graphics-multimedia/drawing-objects-overview?view=netframeworkdesktop-4.8
// https://www.dotnetheaven.com/article/how-to-create-a-media-player-in-csharp#google_vignette
// https://www.tetsuyanbo.net/tetsuyanblog/54455

///////////////////////////////////////////////////////////////
//解説:URLはテストを進めながら参照(学習)していったサイトです。

using System;
//using System.Windows;            //Rectを使う為にこれを入れるとFormsの定義と抵触する
//using System.Windows.Controls;

using System.Windows.Forms;        //Rectを使う為にこれを入れるとWindowsの定義と抵触する
//解説:ここら辺で「ん?なんかおかしいぞ?」という感じはしたんですよね。

using System.Drawing;
using System.Reflection;            //Assemblyを使う為
using System.Windows.Media;                //解説:MediaPlayerクラスを宣言すると直ぐに「参照先がない」
using System.Windows.Media.Imaging;   //というエラーになるので、Microsoft Learnで調べて追加しました。

namespace MPViewer
{
    ///////////////////////////
    //エントリーポイントクラス
    ///////////////////////////

    class MainApp
    {
        [STAThread]
        public static void Main()
        {
            Application.Run(new MPForm());
        }
    }

    ///////////////////////////
    //MediaPlayerサンプルクラス
    ///////////////////////////

    public partial class MPForm : Form
    {
        //コントロール
        Button Btn1, Btn2, Btn3, Btn4, extBtn;
        MediaPlayer mp = null;    //解説:これはメソッドから参照できるように、です。
        VideoDrawing vd = null;    //解説:同じです。
        //ファイル名
        string fName;

        public MPForm()
        {
            Assembly myOwn = Assembly.GetEntryAssembly();
            this.Icon = Icon.ExtractAssociatedIcon(myOwn.Location);    //プログラムアイコンをフォームにつける
            this.Load += new EventHandler(MPForm_Load);
            this.Text = "MediaPlayerとMediaDrawing サンプル";
            this.ClientSize = new Size(640, 480);
            this.MinimumSize = new Size(480, 360);
            this.BackColor = SystemColors.Window;
        }

        private void MPForm_Load(object sender, EventArgs e)
        {
            //ボタン1
            Btn1 = new Button();
            Btn1.Location = new Point(ClientSize.Width - Btn1.Width - 10, 10);
            Btn1.Text = "Open";
            Btn1.Anchor = (AnchorStyles.Top | AnchorStyles.Right);
            Btn1.Click += Button1_Click;
            this.Controls.Add(Btn1);

            //ボタン2ボタン
            Btn2 = new Button();
            Btn2.Location = new Point(ClientSize.Width - Btn2.Width - 10, Btn1.Height + 20);
            Btn2.Text = "Play";
            Btn2.Anchor = (AnchorStyles.Top | AnchorStyles.Right);
            Btn2.Click += Button2_Click;
            this.Controls.Add(Btn2);

            //ボタン3ボタン
            Btn3 = new Button();
            Btn3.Location = new Point(ClientSize.Width - Btn3.Width - 10, Btn1.Height + Btn2.Height + 30);
            Btn3.Text = "Pause";
            Btn3.Anchor = (AnchorStyles.Top | AnchorStyles.Right);
            Btn3.Click += Button3_Click;
            this.Controls.Add(Btn3);

            //ボタン4ボタン
            Btn4 = new Button();
            Btn4.Location = new Point(ClientSize.Width - Btn4.Width - 10, Btn1.Height + Btn2.Height + Btn3.Height + 40);
            Btn4.Text = "Stop";
            Btn4.Anchor = (AnchorStyles.Top | AnchorStyles.Right);
            Btn4.Click += Button4_Click;
            this.Controls.Add(Btn4);

            //終了ボタン
            extBtn = new Button();
            extBtn.Location = new Point(ClientSize.Width - extBtn.Width - 10, ClientSize.Height - extBtn.Height - 10);
            extBtn.Text = "終了";
            extBtn.Anchor = (AnchorStyles.Bottom | AnchorStyles.Right);
            extBtn.Click += extBtn_Click;
            this.Controls.Add(extBtn);

            //MediaPlayer    //解説:System.Windows.Media等を追加しているのでエラーになりません。
            mp = new MediaPlayer();
        }

        private void Button1_Click(object sender, EventArgs e)
        {
            OpenFileDialog ofd = new OpenFileDialog();
            ofd.AddExtension = true;
            ofd.DefaultExt = "*.*";
            ofd.Filter = "Media(*.*)|*.*";
            ofd.ShowDialog();
            fName = ofd.FileName;
            ofd.Dispose();
        //解説:これは単にメディアファイルパス、名を選択するだけです。

        }

        private void Button2_Click(object sender, EventArgs e)
        {
/*
    //Create a MediaTimeline.
    MediaTimeline mTimeline = new MediaTimeline(new Uri(@"sampleMedia\xbox.wmv", UriKind.Relative));
    //Set the timeline to repeat.
    mTimeline.RepeatBehavior = RepeatBehavior.Forever;
    Create a clock from the MediaTimeline.
    MediaClock mClock = mTimeline.CreateClock();
    MediaPlayer repeatingMP = new MediaPlayer();
    repeatingMP.Clock = mClock;
    VideoDrawing repeatingVD = new VideoDrawing();
    repeatingVD.Rect = new Rect(150, 0, 100, 100);
    repeatingVD.Player = repeatingMP;
   
//解説:これはTimeLineを利用したMicrosoft Learnのサンプルを参照できるように貼っています。

*/
            //mp.Open(new System.Uri(fName, UriKind.Relative));  //相対。他に"Absolute"がある。//解説:これは備忘です。
            mp.Open(new System.Uri(fName));    //Uri:URI(Uniform Resource Identifier) のオブジェクト表現を可能にし、URI の一部へ簡単にアクセスできるようにします。
            vd = new VideoDrawing();
            vd.Rect = new System.Windows.Rect(0, 0, 200, 200);
            vd.Player = mp;

//解説:描画するにはVideoDrawインスタンスを引数で渡して生成したDrawBrushインスタンスが必要ということを、後で英文サイトで調べて知りました。以下がそのコードです。
//            Assign the DrawingBrush.

//            https://csharp.hotexamples.com/jp/examples/System.Windows.Media/VideoDrawing/-/php-videodrawing-class-examples.html
//            DrawingBrush br = new DrawingBrush(vd);
//            System.Windows.Controls.Panel p = new System.Windows.Controls.Panel();
//            p.Bakcground = br;

//解説:これはWPFの書き方ではなく、WinFormでの書き方です。当時何も分かっていませんでした。

//            this.Control.Add(p);
//解説:このコードではDrawBrushインスタンスをVideoDrawインスタンスを渡して生成し、「Panel」というコントロールを作ってその"BackGround"プロパティに設定しますが、Panelというコントロールは「見当たらないエラー」が出ますし、他のコントロールでは「BackGroundというプロパティがないエラー」が出ます。実に「おかしい」です。
            mp.Play();
    //解説:以上の緑色部分がMicrosoft Learnのサンプルコードです。最初から「どこへ、どのように描画するのか」が分からないコードだったので「おかしいな」とは思っていましたが、ここで段々と学習し、「何か僕が知らない大事な問題が隠れているぞ」ということが分かってきました。(「無知の智」)

        }

        private void Button3_Click(object sender, EventArgs e)
        {
            mp.Pause();    //トグルでmp.Play()と交互に使用する
        }

        private void Button4_Click(object sender, EventArgs e)
        {
            //ファイルを閉じる
            mp.Close();
            //初期化する
            mp = null;
        }

        private void extBtn_Click(object sender, EventArgs e)
        {
            vd = null;
            mp = null;
            Close();
        }
    }
}

結局、後で「C#には、UI(UserInterface)の基盤(プラットフォーム、従ってライブラリー)にWinFormsとWPFの二つがあり、これらは(特別な必要性があり、特別な方法で共存させることは不可能ではないが。基本的に)共存できない」ことを知るのですが、この段階では「何故だろう、何故かしら?????」状態であったので、とうとうChat-GPI様のアドバイスを乞いました。

/* Chat-GPTの回答
C#のWindows
FormsアプリケーションでMediaElementコントロールを使用することは、通常は難しいです
MediaElementコントロールは主に
WPF (Windows Presentation Foundation) プラットフォームで使用されるものであり、Windows Formsには直接組み込まれていません。
ただし、
Windows Media Playerコントロールを使用してメディア再生を実現することは可能です。(解説:これは結局InterOperativeによります。)以下に、Windows FormsアプリケーションでWindows Media Playerコントロールを使用する例を示します。
まず、プロジェクトにWindows Media Playerコンポーネントを追加する必要があります。
プロジェクトを右クリックして、「デザイナーで開く」を選択します。(
解説:結局Visual Studioベースです。
ツールボックスで、「COMコンポーネント」から「Windows Media Player」を探します。ない場合は、「ツールボックスの選択」から追加します。(
解説:これは結局InterOperativeによります。
以下は、簡単な例です。フォームにWindowsMediaPlayerという名前のAxWindowsMediaPlayerコントロールを配置し、以下のコードを使用してメディアを再生します。

using System;
using System.Windows.Forms;

namespace MediaElementExample
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            // メディアのファイルパスを指定
            axWindowsMediaPlayer1.URL = "C:\\Path\\To\\Your\\MediaFile.mp4";
        }

        private void btnPlay_Click(object sender, EventArgs e)
        {
            // 再生
            axWindowsMediaPlayer1.Ctlcontrols.play();
        }

        private void btnPause_Click(object sender, EventArgs e)
        {
            // 一時停止
            axWindowsMediaPlayer1.Ctlcontrols.pause();
        }

        private void btnStop_Click(object sender, EventArgs e)
        {
            // 停止
            axWindowsMediaPlayer1.Ctlcontrols.stop();
        }
    }
}

Windows Media PlayerのCOMオブジェクトを操作するためのWMPLibライブラリ(
解説:InterOperativeベースなので入手しようともしませんでした。)は、通常、Interop.WMPLib.dllとして知られるInteropアセンブリに含まれています。これは、Windows Media PlayerのCOMオブジェクトとC#コードとの間の相互運用性を提供します。

Interop.WMPLib.dllは通常、プロジェクトが参照するために生成され
、プロジェクトのビルドディレクトリやbinフォルダに配置されます。ただし、直接的に手動で追加することは一般的でなく、通常はVisual Studioなどの開発環境が自動的に処理します。(解説:「Visual StudioやMSBuildが生成する」ので、Visual StudioがないとInterOperativeベースの開発は困難です。まぁ、それならC++でやった方が簡単だし。でも、それは本旨ではないので...
以下は、WMPLibを使用するC#コードの例です:

csharp
Copy code
using WMPLib;

class Program
{
    static void Main()
    {
        WindowsMediaPlayer wmp = new WindowsMediaPlayer();

        // ここで Windows Media Player オブジェクトを使用するコードを追加

        // アプリケーションを終了する前にオブジェクトを解放する
        System.Runtime.InteropServices.Marshal.ReleaseComObject(wmp);
    }
}
このコードでは、WMPLibから提供されるWindowsMediaPlayerオブジェクトが使用されています。プロジェクトが正しく構成されていれば、Interop.WMPLib.dllが必要なライブラリであり、これが自動的に解決されるはずです。
*/

 

結局Chat-GPTに聞いても、WinFormsベースではWin32APIベースのCOMをラップして使う方法しか提供してもらえず、またC#でWinFormsとWPFが共存困難であることから、

じゃ、C#でWPFベースのプログラムをかけばいーんでしょ?

という発想に切り替えました。(切り替えざるを得ませんでした。)

 

そして「私のWPFへの冒険(闘い?)」は続くのです。(注)

 

注:切りが良いので、【WPF】シリーズはここで本年分を締め、中断します。旧年中はご訪問、有難うございました。又、来年「【WPF】WPFを学習する」シリーズでお会いしましょう。

 

追記:アップしてから、「↑のコードでどうなったの?」という結論を書き忘れましたぁ!実は↑のコードは「正常にコンパイルされ、動くことは動き」ます。ただ、動画ファイルを読み込んで再生しても「音しか出ない」だけです。まぁ、画像処理部分が解説した通りなので、再生されるわけがないのですが...

 

それでは、前回触れた「私の格闘記」を始めてみようと思います。

 

ご存じの通り、このブログは2002年にVectorにリリースした、当時のフリーのC++コンパイラーの一つ、BCC(Borkand C++ Compiler 5.5)の開発環境としてリソースエディター、BCCSkeltonライブラリー、スケルトン作成ウィザードと各種ツールのパッケージであるBCCForm and BCCSkelton(含サンプルプログラム)を、20年後に定年退職した爺いがボケ防止のためにアップデート(含Unicode版のECCSkelton)して、その使い方解説の為にサンプルプログラムを紹介するものです。

 

元々はEmbarcadero C++ Builderの無償版(と言っても1年だけ)をダウンロードして使おうとしたのですが、メモリーエラー等トラブルがあった為、使い慣れた20年前の遺物である自分のBCCForm and BCCSkeltonを掘り返(ダウンロード)して使い始め、アップデートされたEmbarcadero C++ Compiler(bcc32c.exe)に対応させ、20年前は(Microsoft Visual C++とMFCにはできて)BCCではできなかった、

(1)テキストを音声で発音するTextToSpeech(既に音声認識と合体してSAPIになっていたが)、

(2)動画をコントロールで再生するDirectShowや、

(3)ExplorerのようにTreeViewやListViewでPCのファイルを表示するShell等

のCOMをBCCForm and BCCSkeltonで利用できる自作ラッパーを作り、サンプルも増やして解説したりもしていました。(注)

注:いずれも今の64bit PC時代の水準では「低レベル」と言われそうですが、「失われた20年」をPC、Windows、C++、bcc32.exe(現在はbcc32c.exe)、Win32API等の復習と新しい技術の学習をする機会になりました。

 

しかし、既にWindows 10もサービス終了が見えてきて、PCが64bitでないと動かなくなりそうになって、私も徐々に学習成果から「BCCForm and BCCSkeltonを断捨離」する覚悟を固め始め、代わりに(注)C#を学習したりしました。

注:BCCSkeltonでWindowsに付属するcsc.exe(C# 5)を使うMSCompAssを作ったことが契機でしたが...

 

その結果、(必要に迫られて作成した)ResWriter、ResReaderや、一般ツールとしてのReplacer、CardboardBox、アミューズメントサンプルのMazeやChinchirorinを作り、ブログネタにしましたが、段々とネタ切れに陥り、「矢張り新しいコントロールの利用などもやろう」とMSChart等のサンプルを作ってはネタにしていました。

 

そんな時に、

BCCSkeltonでもやったTextToSpeech、DirectShowなどはどんな形でC#で使われているのだろう?

と思い立ち、調べ始めたのが発端です。

 

最初はC#で利用できるCOMを調べました。基本的にはWin32APIベースのCOMをInterOperabilityという手法でラッパーを作ることにより使えるようになるということはわかりましたが、断捨離するBCCForm and BCCSkeltonで既にラッパーをつくっているものいまさらなんかなー」とテンションが下がりました。「正直もう何年もたっているんだからC#用の洗練されたコントロールはないの?」とおもい、".NET"とか".NETFramework"とかで利用できる動画再生コントロールをつらつらとGoogleで探していました。

そうしたら、

こんなものを見つけました。

「このページWindows メディア プレーヤーSDKに関連付けられている機能は、レガシ機能です。 MediaPlayerに置き換わりました。MediaPlayerは、Windows 10とWindows 11用に最適化されています。新しいコードでは、可能な場合は SDK ではなく MediaPlayerWindowsメディア プレーヤー使用することを強くお勧めします。Microsoftは、従来のAPIを使用する既存のコードを、可能であれば新しい API を使用するように書き直すよう提案しています。」

あるじゃん!

 

でも、この記事はVisual Studioベースのものだったので、「じゃあ、MediaPlayerクラスのC#コードの記述」を調べようとしていると、またこんなものを見つけました。

(注)

注:はっきりと"Windows Presentation Foundation"とか"WPF"とか書かれていますが、私はその段階ではまだその本当の意味が分かっていませんでした。

 

メディア API
MediaElementおよびMediaPlayerクラスは、オーディオまたはビデオのコンテンツを表示するために使用されます。これらのクラスは、対話式またはクロックで制御できます。これらのクラスは、Microsoft Windows Media Player 10 コントロールでメディアの再生に使用できます。どちらのクラスを使用するかは、シナリオによって決まります。
MediaElementは、レイアウトでサポートされている UIElement であり、多くのコントロールのコンテンツとして利用できます。また、Extensible Application Markup Language (XAML) とコードでも使用できます。それに対し、MediaPlayer は Drawing オブジェクト向けに設計されていて、レイアウトではサポートされていません。MediaPlayerを使用して読み込まれたメディアは、VideoDrawing を使用するか、DrawingContext を直接操作することでのみ表示できます。MediaPlayerXAML では使用できません。

おおっ、あるじゃん!

と思い、サンプルもMediaElementは(私の嫌いな)Xaml

"<!-- This page shows a simple usage of MediaElement -->

 <Page x:Class="MediaElementExample.SimpleUsage"

      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 

      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="SimpleUsage"

     >

     <StackPanel Margin="20">

         <MediaElement Source="media/numbers-aud.wmv" />

     </StackPanel>

 </Page>"

等と書かれていますが、MediaPlayerは、

"//

 // Create a VideoDrawing.

 //

 MediaPlayer player = new MediaPlayer();

 player.Open(new Uri(@"sampleMedia\xbox.wmv", UriKind.Relative));

 VideoDrawing aVideoDrawing = new VideoDrawing();

 aVideoDrawing.Rect = new Rect(0, 0, 100, 100);

 aVideoDrawing.Player = player;

 // Play the video once.

 player.Play();"

とC#コードで書かれており、

おっ、簡単じゃん!

等と考えてしまいました。

なんて、愚かだったんでしょう?

(続く)

 

なんでも自作、王道を歩かない私ですが、今回だけは「参った」ということで、

きちんとしたWPFプログラムを書こうとするならVisual Studioを使ってください

という結論から入ります。

 

理由としては、

(1)WPFベースの開発では、ウィンドウやコントロール等のUI関係がFormベースのものと異なり、(C#コードで書けなくもないのですが)基本的にXAML(eXtensible Application Markup Language)を使った開発が望ましいこと

(2)この場合、XAMLファイルとC#ソースファイルをコンパイルする際にMSBuildを使ったプロセスを踏むことが望ましい(現実的には踏まざるを得ない)

(3)従って、変に抗わないで自然にVisual Studioを使うことが一番

だからです。

 

しかし、

 

これで「ハイ、おしまい」となると面白くもなんともないので、これからこの結論に至った私の「格闘記」を少し書いてみたいと思います。

これから、この間経験したWPF(Windows Presentation Foundation)ベースのC#プログラミングを書く上で、もう一度おさらいと、webで記事を読み始めたら止まらなくなりました。

何故?

それはネットワークコンピューティングやMSの歴史と密接に関係があるから、色々と妄想してしまうからです。

 

思い返せば、1980年までのPC(といえばIBM PC互換機の時代)コンピューティングではMS-DOSの独壇場で、それはWindows 3.x時代になっても変わらず、米国では先にWindows for WorkGroups 3.11でTCP/IP接続によるPeer-to-peerネットワークが始まり、本格的なインターネット時代に突入し、1995年のWindows95の爆発的なヒットにつながってゆきますが、これが「市場占有率95%以上」のMicrosoft帝国の最盛期の始まりでした。同時に「PCプログラミング=Windowsプログラミング=Win32 APIプラットフォームによるプログラミング」の時代でもあり、当時は「言語を何にするか」の選択肢はあっても「PCといえば、Microsoft WindowsでWin32 APIベース

のプログラミング」(勿論残りの5%がApple MacintoshやLinuxなんですが)を行うのが(特にビジネスシーンでは)当たり前でした。要すれば、一般の個人である趣味プログラマーがPCでプログラミングするなら、ほぼ

Visual BasicかVisual C++か

という状況でした。

 

所が欲に目がくらんだMSは、これら開発キットのソフトウェアを超高額に設定していたので、一般プログラマーは1999年頃からオープンソフトウェアのGCC++(GNU Compiler Collection)や当時とても人気があったActiveBasicや、当時対抗するBorlandがフリーで配布するBorlandC++ Compilerをベースに開発環境を手作りしていた、という状況でした。(

:かくいう私もその一人で、このブログ(BCCForm and BCCSkeltonのサポートセンター)もその成れの果てです。なお、ここら辺、特に「MS帝国の衰退」は自分史の中でも触れています。

 

この

Microsoft Windows(ほぼ)一択

の帝国も実は徐々に崩れてゆくのですが、それが表題につながってゆきます。

 

現在「WindowsのPCでプログラミングしてみようか?」と思ったならば、(なーんと現在は)フリーのMicrosoft Visual Studio Community Editionをダウンロードして始めるのが最も効果的で効率的(の筈)です。しかし、私は(↑のような経緯を経験していることもありますが)Visual Studioを始めてダウンロードしてそれを目にした際に当惑しました。(

【趣味としてのプログラミング】何のために 。同様に感じている方も多いのではないでしょうか?私は「取り敢えずイジってみる派」でしたが、フォームを一つ作っただけで「(プログラマーが理解していないで、IDEにやらされているだけの状態に対して)無理っ!」と感じて自作開発環境に戻ってしまいました。今考えれば、きちんとここから全部読んで、理解して始める方が良かったと思います。又、現在はCopilot君が次のようなアドバイスをくれます。

Visual StudioでC#のプログラムを書く場合、プラットフォームを選択する必要があります。プラットフォームは、アプリケーションを実行するために必要なランタイムとAPIのセットを提供します。以下の手順を参考に、プラットフォームを選択してください:

  1. Visual Studioを起動し、新しいプロジェクトを作成します。
  2. プロジェクトのテンプレートを選択する画面で、使用するプラットフォームを選択します。プラットフォームの選択肢は、.NET、.NET Framework、WPF、UWPなどがあります。
  3. 選択したプラットフォームに応じて、必要なコンポーネントが自動的にインストールされます。

以下は、各プラットフォームの概要です:

  • .NET: .NETは、Windows、macOS、Linuxなどの多様なプラットフォームで動作するアプリケーションを開発するためのプラットフォームです。.NETは、C#、F#、VB.NETなどの言語をサポートしています。.NETは、.NET Coreと.NET Frameworkの2つのバージョンがあります。.NET Coreは、クロスプラットフォームで動作する軽量で高速なバージョンであり、.NET Frameworkは、Windowsで動作する従来のバージョンです。
  • .NET Framework: .NET Frameworkは、Windowsで動作するアプリケーションを開発するためのプラットフォームです。.NET Frameworkは、C#、F#、VB.NETなどの言語をサポートしています。.NET Frameworkは、Windowsに統合されており、Windows Updateを介して更新されます。
  • WPF: WPFは、Windowsで動作するデスクトップアプリケーションを開発するためのプラットフォームです。WPFは、.NET Frameworkをベースにしており、XAMLというマークアップ言語を使用して、UIを定義します。
  • UWP: UWPは、Windows 10で動作するアプリケーションを開発するためのプラットフォームです。UWPは、.NET Coreをベースにしており、Windows 10の機能を活用したアプリケーションを開発することができます。

Visual StudioでC#のプログラムを書く場合、.NETが最も一般的なプラットフォームです。.NETは、多様なプラットフォームで動作するアプリケーションを開発するためのプラットフォームであり、C#などの言語をサポートしています。」しっかし、プログラミング初心者の方であればプラットフォームだの、WPFだの、UWPだの言われても「寿限無寿限無」としか見えないでしょうね。

 

要すれば昔は「プログラミング言語」の選択だけでよかったのが、現在はいかのような環境、現状、問題等があり、

異なる観点、切り口からの選択肢が多すぎて

Visual Studioを立ち上げてから悩むことが多いのではないかと思われます。

(1)プラットフォーム

レガシーのWin32API、そのラッパーだった.NET Framework、その「後継(かな?)」と言われる.NET(含む.NET Core)、そして新しいWinRT APIというプラットフォームの多様さ。これはインターネット時代、モバイル時代で台頭してきた勢力をMSも無視できないので、それらの主流と言われるiOSやAndoroidとのクロスプラットフォームを試行せざるを得なかったことや、既にレガシーなったWin32 API(そのラッパーとして、GDI+ベースの.NET Framework)から脱却して新技術に基づくプラットフォームに移行せざるを得なかったことが背景となるでしょう。

(2)インターネット(とモバイルデバイス)との親和性

これは↑とも関連しますが、(MSが得意としていたクライアントーサーバー、スピードの為のC++によるネイティブコードによる開発等が逆目に出てしまったこともあり)インターネットへアプローチする為に、親インターネットの.NET系のアプローチのみならず、自社の得意領域からインターネットへアプローチするUWP系(WinRTベース)等の複数の方針が存在したこともあるのではないかと思われます。

(3)C#の問題

更にC#はWinFormsからWPFへ移行しようとして、余りWPFが受けず、現在は両立しているという問題もあります。(

:もともとC#って、(Visual C++が全然"Visual"ではないMFCベースだったので)「C言語系のVisual Basic」を目指した開発環境だったのではないかと思っています。現にVisual Basicでウィンドウを呼ぶ"Form"という言葉等を継承して、Win32 APIラッパーのライブラリー(これを「Windows フォーム(WinForms)」系というのだそうです)で.来ましたが、ディスプレーの高解像度化、縦横比率多様化で躓き、「WPF」というDirect Xベースのライブラリーを作った迄は良かったのですが、思ったように移行しなかったので、「WinForms」系を捨てきれず、「WPF」系と両立しています(と理解して)います。

(4)Viewの傾向

最近はMVCとかMVVMとか色々と訳が分かったような分からないような話が多いのですが、プログラムを使うユーザーとのインターフェースがデスクトップの「キーボード+マウス」から「画面だけ」に代わってゆくに従って、これからのウィンドウデザイン(Win32の昔はリソースとかいいましたが、最近はみーんな纏めてUI~User Interface~なんて言うのですね)はすべてマークアップ言語のXaml(Extensible Application Markup Language)一辺倒になってゆくようですね。()まぁ、これからプログラミングを職業としてまたは趣味として嗜む方はこれでしょうね。(私はマークアップ言語は蕁麻疹が出るので苦手ですが...)しかし、Visual Studioのすべてのプラットフォーム、言語でXamlを使えるようになるにはやや時間がかかるのでは?

:「Microsoftは2016年2月24日に、マルチプラットフォームのモバイルアプリ開発プラットフォームを提供するXamarinを買収することで合意に達しました。Xamarinは、C#でのiOS、Android、Mac、Windowsアプリ開発のためのプラットフォームを提供している非公開企業で、大企業や新興企業が同社のサービスを利用しています1。買収総額などの詳細は公表されていません。」

 

何れにしても、これらはITビジネス最前線の方があーでもない、こーでもない、とやって答えが出ない領域なので、

これからプログラミングを楽しく学んでいこう

と思っている人にとっては、

ぜーんぜん楽しくない

と思わざるを得ないのではないでしょうか?

まっ、所詮爺いのたわごとですが、何か?

 

冗談はさておき、職業としてプログラミングに携わる方は兎も角、「趣味としてプログラムを作り、たわいもない自作ソフトが動いたといって喜ぶ人」には、余りカタカナやアルファベット略語に左右されず、「レガシー開発環境でもPCとその機序が分かる環境から入って楽しさを覚え」、「カタカナやアルファベット略語」の世界へ入ってゆくのが良いのではないか、と矢張り考えてしまいます。

 

解説(1)~解説(4)迄、プログラムの中身について説明しました。C#を使ったチンチロリンのシミュレーションゲーム(注)、いかがだったでしょう?

注:一応BCCForm_and_BCCSkelotonのSampleBCCSkelton→MSCompAss→Debug→Samples→Chinchirorinフォールダーにソースファイルとリソースファイルが入っています。Dice.dllはDiceフォールダーのソースファイルで作ってください。

 

後は、

1.Player.csと、Dice.csをリソース付きでそれぞれコンパイルし、Dice.dllとPlayer.dllを作る。

2.これらを参照してChinchirorin.csをリソース付きでコンパイルして、Chichirorin.exeを作ります。

3.一応使い方はChinchirorinHelp.chmに書いておきました。

 

まぁ、プログラム的には「C#は部品をDLLで作っておくと他でも再利用が出来ますよ。」「カスタムコントロールが簡単にできますよ。」という所がハイライトで、特段難しいことはやっていません。従って今回は「解説」といっても、プログラミングではなく、チンチロについての解説、というよりも「考察」について述べてみましょう。(実際、このプログラム結構遊べます。それはプログラムの所為ではなく、チンチロリンというシンプルなサイコロゲームの機微にあるのではないかと思っています。)

 

このゲームを最初に考えた時にも書きましたが、私は「カイジ」は見たこともなく、もっぱら「麻雀放浪記(一)青春篇」の「チンチロ部落」をベースとして開発しました。この章で物語を淡々と描き進めているのですが、チンチロリンのルールのみならず、出目の機微、場の流れ()等が過不足なく自然に語られるのは矢張り代表作の名に恥じない書きぶりです。

:「だが、その次のチン六という男が胴(親)の時」に、「四五六(シゴロ)を三回続けてだし」、四回は出ないだろうと張られた際に出したのが「五ゾロ(5の目のアラシ-今気が付いたのですが、小説では(1のゾロ目であるピンゾロを含め)ゾロ目は勝ちでも1倍取りで、五ゾロのみ倍取りなんですね。プログラムではアラシはWiki通りの3倍取りにしています)を出し、皆が張りを控えた時に出したのが1の目の即負け、親流れという「如何にも現実にありそうな目の流れ」でした。

 

だって、小説だからドラマチックにしたんじゃないの?

 

と思いますよね?しかし、賭博というのは本当にこんな状況が起こり得るんです。

 

でも本当なの?

 

というのが、本プログラムを実際に作った真の動機かもしれません。

 

「PCの乱数による投賽」と実際の投賽環境(場所、ドンブリ、賽子)が必ずしも同じではなく、隠れた偏向要因が存在するかもしれないという可能性はありますが、確率的には

(1)アラシは「1/6 x 1/6 x 1/6(従って全216通り)x 6(1~6の目)の1/36」

(2)456(シゴロ)や123(ヒフミ)も「3/6 (456のいずれか)x 2/6(で為以外の二通り) x 1/6(残りの一つ)の1/36」

(3)目が出る確率は「1/6 x 1/6 x 6(1~6)-1/36(アラシを除外)の35/36」

等、一応計算はできます。(こうやってみるとアラシの3倍取りは取りすぎのインフレのように感じますね。)

 

しっかし、実際にやったことがある人には

同じ現象でもミクロ的、マクロ的にみると異なる世界に見える

のです、↑のチン六さんの親のように。(注)

注:決して大法螺を吹いているわけではなく、私、33年間とある保険会社(内29年間は事故処理部門)に、9年間リスクコンサルティング会社に勤めておりましたが、「神様の悪戯」のように見えるミクロ的偶発性には何度も遭遇しております。(それも偶然の賜物なんですけどね。)

 

本当にそうなんだろうか?

 

と思われた「あなた」、本ゲームの「あなた」博徒になってゲームを続けていただき、その結果(累計少部数、累計勝数、累計負数)を

 

ご自身の目で見て確かめてください。

 

「事実は小説より奇なり」、これも小説(注)の言葉ですが。

注:"Truth is stranger than fiction." in "Don Juan" by George Gordon Byron, 6th Baron Byron. (英国の作家、詩人バイロン男爵の「ドン・ジュアン(所謂ドン・ファン)」にある箴言(日本では「事実は小説より奇なり」と訳されている。)

 

ps. チンチロリン賭博をやる時は、小賢しい「確率」など考えず、「場の流れ」を感じなさい。ジークンドーの始祖、李小龍(Bruce Lee)もそういっています。

参照:Don't think! Feeeel! (youtube.com)