GUIのフロントエンドから、コアとなるCUIプログラムを制御して、GUIでオセロロジックを動かしてみます。

マウスをクリックしたら、GUIフロントエンドは、CUIプログラムへ標準入力でコマンドを送ります。
CUIプログラムは受け取った座標を判定し、GUIフロントエンドへ石の表示コマンドを送ります。

Tcl/Tkで作られたフロントエンドからCUIプログラムへは、標準入出力でやりとりするため、openコマンドで、パイプをオープンします。
set pipe [open “| ./a.out” r+]
オープン後getsコマンドを使い、CUIプログラムからの文字列を一行ずつ読みこみます。
gets $pipe 受け取った文字列
CUIプログラムへ文字列を送信するには、putsコマンドで行います。
puts $pipe 送る文字列
では、「tcl/tkで黒と白」で作成したGUIプログラムを改造したソースです。
CUIプログラムから結果を受け取ると、update_borad関数でオセロボードの更新を行います。
first_char==”Y”という判定がありますが、CUIプログラムの、YOUという催促の、最初の文字Yで、結果通知の完了トリガとしています。
1 proc update_board { pipe } {
2 while {[gets $pipe str] >= 0} {
3 set first_char [string range $str 0 0]
4
5 if { $first_char == "Y" } { ;# Y in YOU
6 break
7 }
8
9 set dst [split $str ","]
10 set xy [lindex $dst 0]
11 set bw [lindex $dst 1]
12 if {$bw == "B"} {
13 .b$xy configure -text "●" -fg black
14 } else {
15 .b$xy configure -text "●" -fg white
16 }
17 }
18 }
19
20 set pipe [open "| ./a.out" r+]
21
22 set turnsw 0
23 for {set i 1} {$i <= 8} {incr i} {
24 for {set j 1} {$j <= 8} {incr j} {
25 button .b$i$j -font {FreeMono 40 bold} -bg green -activebackground yellow -activeforeground red
26 grid .b$i$j -in . -row $i -column $j -sticky nsew
27 grid columnconfigure . {1 2 3 4 5 6 7 8} -weight 1 -minsize 60
28 grid rowconfigure . {1 2 3 4 5 6 7 8} -weight 1 -minsize 60
29
30 bind .b$i$j <Enter> {
31 %W configure -bg red
32 }
33 bind .b$i$j <Leave> {
34 %W configure -bg green
35 }
36 bind .b$i$j <Button> {
37 set x [string range %W 2 2]
38 set y [string range %W 3 3]
39 puts $pipe "$x,$y\n";flush $pipe
40
41 update_board $pipe
42
43 set turnsw [expr 1 - $turnsw]
44 }
45 }
46 }
47
48 update_board $pipe
実行してみましょう。
takk@deb83:~$ git clone https://github.com/takkete/scrap.git takk@deb83:~$ cd scrap takk@deb83:~$ cd scrap takk@deb83:~/scrap$ gcc reversi.c takk@deb83:~/scrap$ wish reversi.tcl
下のような緑のマトリクスが表示されて、マウスクリックした箇所に白と黒を交互に置石できると思います。


コメント
[…] 「GUIプログラムからCUIプログラムを使う(標準入出力)」で作ったオセロのGUIフロントエンドを、将棋でも使えるように変更してみます。 shogi.tclではなく、gameboard.tclとしたのは、マス目がある他のゲームにも対応するためです。 […]