突发奇想要用dot语言来画围棋棋谱。
代码实现
测试了一下,交叉点用 point,棋子用 circle并fillcolor,可以完成棋谱的绘制。然而一个个点的画当然不现实,首先想到的就是将sgf棋谱转换为dot语言。用shell脚本实现,首先设置所有的点为point,然后重定义有棋子的点为circle。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
|
#!/bin/bash [ $# -lt 1 ] && echo "args error" && exit 1 sgf=$1 echo >$sgf.gv cat >$sgf.gv << EOF graph go { size=15; bgcolor="lightgoldenrod3"; node [shape="point", fontsize=27, fontname="SimHei"]; EOF play=`grep ";B\ [" $sgf |tr -d ' \n)' |tr -s ';' ' '` #\ [直接本没有空格,跟latex插件冲突。。臃肿难用,想放弃WordPress了。。 function sgf() { i=1 for id in $play; do color=`echo $id | awk -F "[" '{print $1}'` point=`echo $id |awk -F "[" '{print $2}' |tr -d ']'` [ $i -lt 10 ] && num=" $i" [ $i -lt 100 ] && num=" $i" [ $i -gt 99 ] && num=$i if [ $color == B ]; then echo "$point [label=\"$num\", width=\"0.9\", fontcolor=\"cornsilk\", shape=\"circle\", style=\"filled\", fillcolor=\"black\"];" >>$sgf.gv elif [ $color == W ]; then echo "$point [label=\"$num\", width=\"0.9\", shape=\"circle\", style=\"filled\", fillcolor=\"cornsilk\"];" >>$sgf.gv fi let i+=1 done } sgf |
功能是实现了,然而速度非常慢。
棋子画好了,接下来是连线。连线比较固定,可以生成一次以后直接用。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
|
arr=(a b c d e f g h i j k l m n o p q r s) function a2d() { offset=96 hex=`printf "%s" "'$1"` #注意:$1前有个单引号 ret=`echo "$hex $offset" | awk '{print $1-$2}'` return $ret } function d2a { echo "${arr[$1]}${arr[$2]}" } function draw() { for x in {0..18}; do for y in {0..18}; do point=`d2a $x $y` l=`echo $x |awk '{print $1-1}'` r=`echo $x |awk '{print $1+1}'` u=`echo $y |awk '{print $1-1}'` d=`echo $y |awk '{print $1+1}'` left=`d2a $l $y` right=`d2a $r $y` up=`d2a $x $u` down=`d2a $x $d` if [ $r -lt 19 ]; then echo "$point -- $right;" >> $sgf.gv fi if [ $d -lt 19 ]; then echo "$point -- $down;" >> $sgf.gv fi done done echo "}" >>$sgf.gv } |
这里涉及到数字和字母的对照,a2d是字母转数字,这个比较通用,然而在这里并没有什么卵用,用数字计算点的边比较方便,所以需要数字转字母。找不到现成的通用函数,只好自己写了个d2a函数,只能处理特定字母和数字。
接下来,sgf函数生成棋子,然后将draw函数生成的文本追加到dot源码中,最后的dot源码片段示例:
|
graph go { size=15; bgcolor="lightgoldenrod3"; node [shape="point", fontsize=27, fontname="SimHei"]; pd [label=" 1", width="0.9", fontcolor="cornsilk", shape="circle", style="filled", fillcolor="black"]; dp [label=" 2", width="0.9", shape="circle", style="filled", fillcolor="cornsilk"]; pq [label=" 3", width="0.9", fontcolor="cornsilk", shape="circle", style="filled", fillcolor="black"]; ... aa -- ba; ab -- ac; ac -- bc; ... } |
GraphViz各种引擎生成的棋谱
neato引擎,就这个最靠谱
dot
twopi,放射状
fdp,变形的棋盘
参考资料
|
[1]. http://www.graphviz.org/content/attrs [2]. http://www.graphviz.org/content/node-shapes [3]. http://www.graphviz.org/content/color-names |
Pingback: Discuz插件处理大型dot源码 | 知行近思