Lego MindStorms NXT 井字棋机器人算法讨论

来源:互联网 发布:淘宝用户名能改吗 编辑:程序博客网 时间:2024/04/30 03:23

written by flexitime
最近在搞这套Lego的玩具,大家可以看一下照片


(

以下是一些有关这个机械人的录像:

 

1.最终修正版本,算法现在按正统的方式修改了,聪明了很多
http://www.tudou.com/programs/view/c7Msf-Ol0VE/ 

 

2.第一次修正的方案,改进了运行的算法,下棋会快一些。但算法有点问题,所以有点笨~~
http://www.tudou.com/programs/view/R8rrNXcO02o/

 

3.最初的版本
http://www.tudou.com/programs/view/KK1PEY78u1w/

)

这个玩具其实是Lego公司推出的一套机器人套装玩具,里面有一个32位的电脑(单片机),3个伺服电机,光感,声感,超声波等的传感器,使用这些传感器可以搭建出很多不同类型的机器人。在这里我就不讨论这个井字棋机器人如何搭建了(我对精巧的机械设计很感兴趣,但对机械的理解及运用能力毕竟不在行,这个机械人花了我两周的时间才搞好)
现在我们来讨论一下有关井字棋算法的实现:
在讨论算法之前,我先来介绍一下有关NXT机器人的一些问题,NXT机器人是一个电脑(单片机),Lego公司为这个机器人配套了一种名为NXT-G的语言,这是一种图形语言,用户可以通过鼠标选择一个个节点图标来描述程序,简单易懂,十分适合儿童去学习。但NXT除了支持NXT-G之外还支持汇编及其它一些高级语言,例如我将会用到的NXC(Not Exactly C)。
NXC是一种与C语言十分类似的语言,它的编译器是开源的,这种语言的语法与C语言相差无几,但它有不少的限制,例如不支持函数的递归调用。

井字棋很多人都懂得,规则是双方在一个9个格子的棋盘上轮流下棋,如果某一方首先能在纵、横、斜等方向上连成一线的,就赢得一局,如图所示一样。


现在我们要实现一个人机对奕的程序,按照一般棋类博奕程序的写法,我们首先完成的是‘规则’的函数,这个规则的函数也比较简单,我们可以写出以下的代码:
......
int chess_win [24] ={
      1,2,3,
      1,5,9,
      1,4,7,
      2,5,8,
      3,5,7,
      3,6,9,
      4,5,6,
      7,8,9
     }; //赢棋规则

int check_win_chess(int flag) //输入:棋子的代码,1为人,2为电脑;输出:1为赢, 0为非赢
{
 int i, j, result, k;
 for (i = 0 ; i < 8; i++)
 {
  result = 1;
  for (j = 0; j < 3; j++)
  {
   k = chess_win[i * 3 + j];
   k = chess_ary[k];
   if (k != flag)
   {
    result = 0;
    break;
   }
  }
  if (result == 1) {return result; }
 }
 return 0;
}
......
我在这里定义了一个全局的数组(NXC的程序一般都不复杂,定义一个全局数组有利于运算速度的提高),这个数组的作用是保存了所有可以赢棋的组合,另外,我当时写这个程序时不清楚NXC支不支持多维的数组,所以我在这里使用的是一个一维的数组,通过一些映射的运算来模拟二维数组。
接着下面编写的那个chess_win函数的作用是用来判断棋局的输赢情况。参数flag是表明传入的是那方的标识(在这里1代表的是人所执的棋子,2代表的是机器所执的棋子)。函数有两个返回值,如果返回是1表是传入标识的这种棋子赢了,如果是0则表示没有赢。

未完,待续....

原创粉丝点击