(2019-11-10 2:00頃 Git hub)
「 連珠では アゲハマ とか使わないだろ☆
欄の表示、非表示は どういうコマンドにしよかな……☆」
「 コンピューター囲碁をベースにするの?
何もない床をベースにするの?」
set w-hama.visibility = visible
set w-hama.value = 14
「 ↑例えば こう書くなら一貫性があるが、打鍵が めんどくさい☆」
「 こんな くそGUI の仕様に そんなにガチにならんでも……☆」
widget w-hama.visible = true
Name | Description |
---|---|
value | set b-name = kifuwarabe みたいな働き。 |
visible | true : 表示。 false : 非表示。 |
「 ↑visible
だけでいい気がするぜ☆ ガチにやりだしたら結局 CSS が欲しくなるだろ☆」
Name | Description |
---|---|
ply | 何手目 |
move | 最後の着手 |
b-name | 先手(黒番)の氏名 |
b-time | 黒の持ち時間 |
b-hama | 黒のアゲハマ |
w-name | 後手(白番)の氏名 |
w-time | 白の持ち時間 |
w-hama | 白のアゲハマ |
komi | 白のコミ |
MainController.cs
case "widget":
{
var args = (WidgetInstructionArgument)instruction.Argument;
switch (args.Name)
{
case "ply":
switch (args.Property)
{
case "visible":
switch (args.Property)
{
case "true":
view.plyCanvas.Visibility = Visibility.Visible;
break;
case "false":
view.plyCanvas.Visibility = Visibility.Hidden;
break;
}
break;
}
break;
「 ↑雰囲気的には こういうのを書いていけばいいんだろ☆ 一般化できんかなあ……☆」
MainController.cs
private static void ChangeCanvasProperty(Canvas canvas, WidgetInstructionArgument args)
{
switch (args.Property)
{
case "visible":
switch (args.Value)
{
case "true":
canvas.Visibility = Visibility.Visible;
break;
case "false":
canvas.Visibility = Visibility.Hidden;
break;
}
break;
}
}
「 ↑Canvas をいじる部分を 関数に切りだして……☆」
MainController.cs
case "widget":
{
var args = (WidgetInstructionArgument)instruction.Argument;
switch (args.Name)
{
case "ply":
ChangeCanvasProperty(view.plyCanvas, args);
break;
case "move":
ChangeCanvasProperty(view.lastMoveCanvas, args);
break;
case "b-name":
ChangeCanvasProperty(view.blackNameCanvas, args);
break;
case "b-time":
ChangeCanvasProperty(view.blackTimeCanvas, args);
break;
case "b-hama":
ChangeCanvasProperty(view.blackAgehamaCanvas, args);
break;
case "w-name":
ChangeCanvasProperty(view.whiteNameCanvas, args);
break;
case "w-time":
ChangeCanvasProperty(view.whiteTimeCanvas, args);
break;
case "w-hama":
ChangeCanvasProperty(view.whiteAgehamaCanvas, args);
break;
case "komi":
ChangeCanvasProperty(view.komiCanvas, args);
break;
}
}
break;
「 ↑とりあえず 簡素ながら アゲハマと コミを非表示にできるようにしたぜ☆」
widget column-numbers.value = A,B,C,D,E,F,G,H,J,K,L,M,N,O,P
「 はぁ~あ☆(/_\)なんで国際囲碁は 特別仕様なんだぜ☆」
「 カンマ区切りにするのか☆? 他のは スペース区切りなのに☆?」
BoardModel.cs
public BoardModel()
{
this.Stones = new List<Stone>();
for (int i = 0; i < this.GetCellCount(); i++)
{
// 初期値は 空点 で☆(^~^)
this.Stones.Add(Stone.None);
}
// 1桁の数は、文字位置の調整がうまく行かないので勘で調整☆(^~^)
this.RowNumbers = new List<string>()
{
" 1", " 2", " 3", " 4", " 5", " 6", " 7", " 8", " 9", "10",
"11", "12", "13", "14", "15", "16", "17", "18", "19"
};
// I列がない☆(^~^)棋譜に I1 I11 I17 とか書かれたら字が汚くて読めなくなるのだろう☆(^~^)
this.ColumnNumbers = new List<string>()
{
"A", "B", "C", "D", "E", "F", "G", "H", "J", "K",
"L", "M", "N", "O", "P", "Q", "R", "S", "T"
};
}
「 可変盤はつらいよな☆ こういう変更に対応する作りにしないといけない☆」
「 位置調整のために 半角空白まで入れるなんて……☆ いつの時代だぜ☆」
widget row-numbers.value = " 1", " 2", " 3", " 4", " 5", " 6", " 7", " 8", " 9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19"
# 国際式の囲碁。19列。I列がない。
widget row-numbers.value = "19", "18", "17", "16", "15", "14", "13", "12", "11", "10", " 9", " 8", " 7", " 6", " 5", " 4", " 3", " 2", " 1"
widget column-numbers.value = "A", "B", "C", "D", "E", "F", "G", "H", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T"
# 連珠。15列。
widget row-numbers.value = "15", "14", "13", "12", "11", "10", " 9", " 8", " 7", " 6", " 5", " 4", " 3", " 2", " 1"
widget column-numbers.value = "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o"
「 表示は 連珠盤 に近づいてきたが、 i11
という入力はできないぜ☆
囲碁盤に i列 は無いからな☆」
「 列番号の表示は ただのラベルだからな……☆ コマンド入力を ラベルに対応づけるのは むずかしいが
やらなければ 入力で混乱する……☆」
「 アルファベット1文字と、数字2文字 という構造なんだが……☆ こんなんエディットできないぜ☆」
「 内部も、入力系も、最初に国際式の囲碁をベースにしたのが 全部 ダメの原因だぜ……☆
それをキャンセルして白紙状態に戻さないと 他に変換できないのが 無駄……☆」
「 ↑星の位置も、国際囲碁式なのか、連珠式なのか どちらで指定するのか はっきりさせないといけない☆」
# 国際式の囲碁。19路盤。I列がない。
widget stars.value = "D16", "K16", "Q16", "D10", "K10", "Q10", "D4", "K4", "Q4"
# 13路盤
widget stars.value = "D4", "G7", "K4", "D10", "K10"
# 9路盤
widget stars.value = "E5"
# 10路盤。将棋盤☆(^~^)
widget stars.value = "D4", "G4", "D7", "G7"
# 連珠。15列。
widget stars.value = "d4", "l4", "h8", "d12", "l12"
board wwwww/bbbbb/...../wbwbw
「 ↑例えば 白石が w で、黒石が b で、スペースを .
にするのよ」
board 9 wwwww
board 8 bbbbb
board 7 .....
board 6 wbwbw
「 行番号が分かったら、どうやって セルのインデックスを取得するんだっけ☆?」
「 CellAddress
クラスになんかいいメソッド作ってないのかだぜ☆?」
board 19 bbbbbwwwww.....bbbb
「 output.json
は JSONファイルなのに 入力はなんで input.txt
の独自コマンドなんだぜ☆?
JSON で入力させろだぜ☆」
output.txt:
{"board":{"rowSize":19,"columnSize":19,"stones":[1,1,1,1,1,2,2,2,2,2,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"rowNumbers":["19","18","17","16","15","14","13","12","11","10","9","8","7","6","5","4","3","2","1"],"columnNumbers":["A","B","C","D","E","F","G","H","J","K","L","M","N","O","P","Q","R","S","T"],"starCellAddresses":["D16","K16","Q16","D10","K10","Q10","D4","K4","Q4"]},"state":{"intervalMsec":2000,"ply":0,"lastMoveIndex":-1,"blackName":"","blackTime":"","blackHama":0,"whiteName":"","whiteTime":"","whiteHama":0,"komi":0,"info":""}}
「 確かに これを そのまま デシリアライズ できればお得だが、そんなデータ構造してないしな☆」
「 設計のレベルから大改造だな……☆
ApplicationDataModel
とかいうクラス名で この構造を作るかだぜ☆」
「 JSONは Java Script Object Notation だろ☆ 合わせるなら ApplicationObjectModel
の方が近くないか☆?」
「 もともと State
と BoardModel
しかないコードなんで なんとかなりそうだが……☆」
「 ほとんどのメソッドが グローバル変数を引数で渡されるという とんでもない作りになったが まあいいだろう☆」
JSON {ここにJSON}
「 まあ いいだろう、こんな くそGUI の仕様に こだわらなくても☆」
「 JSON をごそっと差し替えても、再描画が対応してない……☆
どこが変わったのか 部分ごとに 再描画しないといけないぜ☆」
The New JSON Serializer In .NET Core 3
「 完全に復元するには、白アゲハマ・ウィジェットの visible とかも JSON に出しておかないといけないのか……☆」
「 ヌル例外が出て スタック・トレースが無い……☆
何かを 数分かけて ダウンロードしたら 出るようになったが……☆ 今日は終わり☆」
「 UIウィジェットは 画面上にずっと表示されっぱなしだから
リペイント・メソッドなんか 作ってないんだよな☆」
「 気に入らねぇ☆! 表示されているものを 表示しようぜ☆!」
「 ウィジェットを プログラムで付けたIDではなく、ユーザーが付けた名前で検索できる方法が必要だぜ☆
例えば……☆」
var widget = FindWidget("黒アゲハマ");
「 しかし JSON では お父んが付けた b-hama
がウィジェット名になっているぜ☆?」
「 Git hub でソースコード見て 名前を調べて
狙い撃ちで 開発者の想定しない操作を されてしまう☆」
CanvasWidgetController.cs:
private static Dictionary<string, string> nameDictionary = new Dictionary<string, string>()
{
{ "ply", "plyCanvas" },
{ "move", "lastMoveCanvas" },
{ "b-name", "blackNameCanvas" },
{ "b-time", "blackTimeCanvas" },
{ "b-hama", "blackAgehamaCanvas" },
{ "w-name", "whiteNameCanvas" },
{ "w-time", "whiteTimeCanvas" },
{ "w-hama", "whiteAgehamaCanvas" },
{ "komi", "komiCanvas" },
{ "info", "infoCanvas" },
};
public static string GetNameBy(string widgetName)
{
if (nameDictionary.ContainsKey(widgetName))
{
return nameDictionary[widgetName];
}
return string.Empty;
}
「 if文や switch文に頼って キータイピングしまくるのは 悪いコーディングだぜ☆
↑このように データは 構造に入れるのが マスト だぜ☆」
「 その name の使い道は オブジェクトを探して取ってくることしか無いんだから、
直接 オブジェクトを検索して返すところまで やったら?」
「 1時間遅刻したかと思ったんだが、23時間 早かったようだぜ☆」
「 ちょっとべつのブログを書くぜ☆(^~^)休憩☆(^~^)」
widget row-numbers.value = "15", "14", "13", "12", "11"
set row-numbers = "15", "14", "13", "12", "11"
「 プロパティの値の書式は プログラム側がよろしく判定するということか☆ 自動推論かだぜ☆」
「 行番号は Board
に、 プレイヤー名は State
に、と分けているんだが、
これを Widgets
に統一したいと思うんだぜ☆」
「 name, value, visible の3属性をもつ構造体のことかだぜ☆」
「 混乱しない用語とか 無いもんな……☆ Properties
にするぜ☆」
set row-numbers = '15', '14', '13', '12', '11'
「 C# で開発していると ダブル・クォーテーションのエスケープがめんどくさいんで、
スクリプトは シングル・クォーテーション にしたらどうだぜ☆?」
"intervalMsec":{"name":"interval-msec","value":"2000","visible":true}
「 ↑ name
の内容を2回打ち込むのも イケてなくないか☆?」
「 JSON にも 数値型と 論理型があるだろ☆
全部 文字列型にしてしまうのは イケてないのでは☆?」
"column-numbers":{"value":"\u0022a\u0022, \u0022b\u0022, \u0022c\u0022, ...(omitted)
「 string型のリストをシリアライズ、デシリアライズできないのかだぜ☆?」
output.json:
"column-numbers":{"value":["a","b","c","d","e","f","g","h","i","j","k","l","m","n","o"],"visible":true},
「 List<string>
型もデシリアライズしてくれた……☆ ラッキー☆」
「 行番号に位置調整のために半角空白が入っていて、これをトリムしてはいけないというのが つらい……☆」
output.json:
,"rowNumbersTrimed":["15","14","13","12","11","10","9","8","7","6","5","4","3","2","1"]
「 ↑こういう隠しデータまで JSON に出てしまうの なんとかならないの☆?」
「 プロパティーになってるんだろ☆ ゲッター・メソッドにしようぜ☆?」
output.json:
{"board":{"rowSize":15,"columnSize":15,"stones":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]},"properties":{"column-numbers":{"value":["a","b","c","d","e","f","g","h","i","j","k","l","m","n","o"],"visible":true},"row-numbers":{"value":["15","14","13","12","11","10"," 9"," 8"," 7"," 6"," 5"," 4"," 3"," 2"," 1"],"visible":true},"stars":{"value":["d4","l4","h8","d12","l12"],"visible":true},"interval-msec":{"value":2000,"visible":true},"ply":{"value":0,"visible":true},"move":{"value":0,"visible":true},"b-name":{"value":"Kifuwarabe","visible":true},"b-time":{"value":"00:00","visible":true},"b-hama":{"value":0,"visible":false},"w-name":{"value":"Warabemoti","visible":true},"w-time":{"value":"00:00","visible":true},"w-hama":{"value":0,"visible":false},"komi":{"value":6.5,"visible":false},"info":{"value":"","visible":true}}}
「 "visible":false
はデフォルトにして、JSONに出力しないようにできないの?」
Hiding C# properties when serialize with JSON.NET
「 ↑常時隠すのは あるのかも知れないが、ゲッター・メソッドでも できるしな☆」
How to serialize and deserialize JSON in .NET
Reducing Serialized JSON Size
DefaultValueAttribute Class
[DefaultValue(0.0)]
「 black
も white
も小文字なのに、 JSON
だけ 大文字なのは やはり 気にかかるぜ☆」
「 .ToString()
が付け加えられて暗黙の文字列変換がされてしまうのは 困りものだぜ☆」
「 列番号を変更するのと、black
で黒石を置くのを 同じテキストで実行すると 古い列番号で置かれてしまう☆」
set b-hama = 3
widget b-hama.visible = false
「 set
構文と widget
構文の2つあるの大変なんで……☆、」
set b-hama = 3
set b-hama.value = 3
set b-hama.visible = false
「 set
構文に統一しようぜ☆? .
が無ければ .value
が補完されるということで☆」
「 関数型プログラミングで if 分岐したあとの return 書くとき 頭が沸騰するぜ☆」
「 パーサーを ラムダ式計算に書き換えたんで
set
構文と widget
構文の統一をやってみるぜ☆」
「 石と、ウィジェットが 異なるコードで 同じ命令でも異なる働きをするんだよな☆(^~^)」
「 1行ずつ分けてループで回しながらパースするように変更☆
コマンドを分けないと実行できなかったバグが取れたぜ☆」
「 見た目は変わっていないが、バグが取れたぜ☆(^~^)
C#で ラムダ計算風に書いたプログラムのサンプルとしても使えるだろう☆」
{"board":{"rowSize":15,"columnSize":15,"stones":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,1,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]},"properties":{"column-numbers":{"value":["a","b","c","d","e","f","g","h","i","j","k","l","m","n","o"],"visible":true},"row-numbers":{"value":["15","14","13","12","11","10"," 9"," 8"," 7"," 6"," 5"," 4"," 3"," 2"," 1"],"visible":true},"stars":{"value":["d4","l4","h8","d12","l12"],"visible":true},"interval-msec":{"value":2000,"visible":true},"ply":{"value":0,"visible":true},"move":{"value":"g9","visible":true},"b-name":{"value":"Kifuwarabe","visible":true},"b-time":{"value":"00:00","visible":true},"b-hama":{"value":0,"visible":false},"w-name":{"value":"Warabemoti","visible":true},"w-time":{"value":"00:00","visible":true},"w-hama":{"value":0,"visible":false},"komi":{"value":6.5,"visible":false},"info":{"value":"","visible":true}}}
<書きかけ>
Crieitは個人で開発中です。
興味がある方は是非記事の投稿をお願いします! どんな軽い内容でも嬉しいです。
なぜCrieitを作ろうと思ったか
また、「こんな記事が読みたいけど見つからない!」という方は是非記事投稿リクエストボードへ!
こじんまりと作業ログやメモ、進捗を書き残しておきたい方はボード機能をご利用ください!