2013年1月6日星期日

复杂的问题和简单的解法

看到一个视频:Twining motion of vines。看完很震惊,藤类缠绕策略这么简单!!!。于是在反思。假如有这样一个情况,上帝给我一段代码,是关于一种叫“藤”的植物的,让我增加借助其它物品缠绕向上爬的特性。相信这种情况下,我会开始这么想:

  1. 藤要想缠住其它物品,首先得知道其它物品在哪里
  2. 知道物品在哪里以后,需要向那个物品靠近
  3. 接触到物品后可以做缠绕动作

最难的问题是第一个。怎么知道物品在哪里。植物跟动物不一样,上帝给的代码里没有感知物品位置的功能。看看上帝的代码里都有实现了哪些传感器,看看有没有能用得上的。有一段感知光的代码,有一段感知土地养料指数的代码,有一段感知水分指数的代码。如果周围有物品的话,尤其是像树这样高大的,都会把光遮住,所以光少的地方就有可能有可以缠绕的物品。而土地养料和水分比较充足的地方,比较容易长其它植物,所以也可以尝试。经过一番思索,决定把逻辑定成这样:

void twine_object()
{
    while (!reach) {
        if (pos = get_sunshine_pos() && pos = invert(pos)) {
            stretchto(pos);
        }
        else if (pos = get_most_fertile()) {
            stretchto(pos);
        }
        else if (pos = get_most_water()) {
            stretchto(pos);
        }
        else {
            grow_up();
        }
    }
    twining();
}

第二个问题,stretchto有点难实现,因为植物没有神经系统的代码。那只好用生长素浓度等等tricky的办法实现了。虽然这么写代码恶心一点,但情况特殊,没有办法做到simple和stupid了。

第三个问题,实现缠绕动作:twine。这个太简单了。

void twning()
{
    while (grow_up() && turn_left()) ;
}

想了半个多小时,各种边边角角的细节都考虑到了。相信这个解决方案是比较好的,因为都想了这么久,技术难点都过了一遍,各种细节也都覆盖了。于是花了几个小时甚至更多时间去实现。写完会自恋地看一下那几块tricky的代码,沾沾自喜一下。

这样的代码交上去,肯定各种用户投诉:

为什么我家的藤插竹子在旁边却不向上长?
做的什么东西,为什么我种的藤会朝石缝里钻?
你这藤是怎么回事,怎么光缠着粪长?
这藤是水仙藤还是自杀藤,怎么就往池塘里跳?

看着投诉,我认为没有别的办法,只好跟上帝要求要给藤加上神经系统和运动系统,考虑到能量会消耗得比以前多,还要加上消化系统。最后上帝受不了了,把我的代码全删,只剩twining函数,并写下这样的代码

void twine_object()
{
    while (twining()) ;
}

世界清静了。

解决复杂的问题也可以用很简单的方法。

没有评论:

发表评论