[转]什么是Windows能干而Linux干不了的?

  我回答说:"Windows 能干而 Linux 干不了的事情,那就是不需要干的事情。"   Windows 能做的有益的事情 Linux 都能做   Windows 下的某些功能确实是我们需要的,那么 Linux 的开发者们和用户也需要这种功能,他们就会去实现这种功能,而且比 Windows 的方式好得多。由于大多数科学家,工程师用的都是 Linux 或者某种商业 UNIX, 所以几乎所有商业的科学工程程序,比如 Matlab, Mathematica, AutoCAD, Candence的,Synopsys的,Avant! 的……全都是先有 UNIX 的版本(包括Linux),然后再考虑移植给Windows,甚至根本不移植给 Windows,因为 Windows 的机器一般没有足够的能力运行这样的程序。你不要以为只有 Windows 才有 PSpice, UNIX 的 HSpice 要好得多,而且可以运行在大型主机上。当然它们不是免费的,但是它们值那个价钱。   但是 Windows 下有些东西在 Linux 下没有很相似的,或者你找到很多类似的,但是它们每一个比起 Windows 的那个程序都要差很多,那么原因有两种可能性:   有一个完全类似的程序,但是由于它乍一看不漂亮,被你忽略了。而其它程序虽然看起来很漂亮,但是它们是一些初学编程的人写的。现在由于 Gtk+, Qt 的诞生,Linux 下开发图形界面程序极其简单,很多初中生甚至小学生都可以随手编出一些漂亮不中用的程序。如果你整天寻找这样的程序挑来挑去,永远也找不到你满意的。   我曾经也犯过这样的错误,优秀的 FVWM, lftp, Mutt, wget 都被我忽略过!当我找回它们的时候,我是那么的羞愧不已,它们现在都是我的朋友 用这些程序你可以改变它们的一切,我第一次看到 FVWM 觉得它只不过是一个有很厚很难看边框的东西。可是现在,我的同学看到 FVWM 都说:"哇!真漂亮。"   有另一种完全不同的方式可以达到相同的目的,甚至更好。   很多人很关心 Open Office, Star Office, AbiWord, … 他们多么盼望有一天某一个 Linux 程序能够完全兼容的打开一个复杂的 doc 文档。但是你永远也不可能有那一天。为什么呢?因为微软为了占有市场,必定不会让其它系统的程序能够完全兼容它的文档格式!它一定会不断变化 doc 文档的内部结构,隐藏一些秘密,让其它公司的程序打开 doc 文档时总是有某种问题,从而你必需购买Microsoft Office 和 Windows。   你应该想一下,那么多的高智商的大学教授,科学家,学生,他们用的都是 Linux或者其它类型的 UNIX,他们没有 Word 可用,怎么处理文档呢?这么多年没有一个像 Open Office 的程序出现,难道大家没有办法写文档吗?   显然不是这样。你看看那些高水平的学术杂志,论文,那些大学教授的网页,那些漂亮的P DF幻灯片,它们是什么做的?原来 UNIX 用户早就有非常方便的 troff,LaTeX, SGML 等东西可以处理文档,而且它们比起 Word 都要高明的多。Word 显然被这些大拿忽略了,以至于很久以来没有人想在 Linux 下开发一个类似 Word的程序,除非某些公司想抢微软的饭碗。   很多人留着 Windows 在硬盘上的原因无非是为了用 Word 和 PowerPoint。你待会儿可以看看我的TeX网页,你就会知道为什么我可以完全离开 Windows.   Windows 能做的那些没用的事情 Linux 永远做不好   电脑游戏
  有些人说 Linux 下不能玩 Windows 下所能得到的所有游戏。的确,Linux 下虽然也有少量的游戏,比如 Quake。但是它没有 Counter Strike, 没有 Star Craft,……   并不是说电脑游戏不该玩,但是应该适可而止。电脑是用来处理事务,帮助你学习,解决问题的工具,而不是一个玩具!整天沉迷于电脑游戏中,而不出去感觉外面的世界,你会变得越来越冷酷,越来越缺乏人情味。你与真实的世界越来越远。   你可以在 CS 里杀人,你可以在 Tomb Raider 里探险,你甚至可以在 TonyHawk’s Pro Skaters 里滑板…… 但是It’s not real!你虽然有很高的"反恐技巧",但是遇到歹徒的时候,你是那么的怯懦;你虽然控制 Laura 伸手敏捷,但是你打篮球的时候怎么总是被人断球?你虽然可以轻易的在 THPS 里作出一个"360 kickflip to hangten grind to fakie",但是你踩在自己的滑板上的时候还不会 ollie!   说回来,如果你偶尔玩一下电脑游戏未尝不可。但是世界上有远比 Windows +PC 更好的游戏方式。Sony 的 PlayStation2, SEGA 的 DreamCast, Nintendo 的N64,Namco 的街机.. ….每一个都比 Windows 游戏精彩,每一个都有如此高的3D性能,以至于 Pentium4, Itanium + GForce4 都无法与它们比美!   Linux 的用户们都是关心解决世界的关键问题的份子,他们哪里有时间用自己的机器来玩游戏啊?他们每天用Linux高效的做完自己的工作就到阳光下享受自然去了。要玩游戏也是玩一些类似推箱子,贪吃蛇之类的智力小游戏。所以,你知道为什么 Linux 几乎没有游戏了吧?   "整理硬盘,优化系统"   这是一个非常有意思的话题,仅次于有关"病毒"的话题。相信很多 Windows 用户都有整理硬盘的经历。在很多 Windows 用户眼里,"硬盘用久了,会出现碎片,速度会减慢,需要一个程序来整理,整理硬盘的时候不要做其它工作",这好像是天经地义的事情。   我也曾经津津有味的看着 Norton Defrag 一点一点的把我的硬盘排序,调整,用图形的方式显示出来,然后报告:"100% 没有碎片。你的硬盘现在已经达到最佳状态。" 我现在才发觉我那时是多么的幼稚。   Linux 和 UNIX 用户似乎从来没有"整理硬盘"这种说法呢?你觉得很奇怪吗?如果你觉得很奇怪,那说明你的思想在某种程度上被微软的垃圾程序禁锢了。你需要明白,UNIX 的大型主机很多必须是一天24小时,一年365又1/4天不停运转的,要是每个星期都要整理一次硬盘,在整理的时候几乎不能干任何事情,那是绝对行不通的!   Linux 机器根本不用整理硬盘,这就是为什么没有看到过 Linux 用户整理硬盘。Linux 的文件系统是比 Windows 的 FAT, FAT32, NTFS 高明得多的文件系统,它们不但可以对文件设置权限,实施完全的保护,而且可以"越用越整齐","越用碎片越少"!你应该把文件大部分放在 Linux 的分区,而不是 Windows 分区,因为它比 Windows 分区可靠得多。   还有更滑稽的事情就是有很多"Norton System Doctor","Windows 优化大师","超级兔仔注册表魔法" 之类的程序存在,而且价格昂贵。似乎一个操作系统本来应该有很多问题,需要别的厂商做程序来"优化"它,而且为了得到优化,你需要付钱!这些问题 Linux 根本就没有,所以不需要什么优化。Linux 内核本身就是高度优化的。
  IDE   有些人在抱怨为什么 Linux 没有一个良好的 IDE 开发环境。Linux 现在已经有一些 IDE 了,但是总是有很多问题。你是不是正在寻找,正在期望 Linux 某一天可以有一个VC 那样的开发环境?你有没有发现你正在进入微软给你设下的怪圈? 你为什么一定要用 IDE ?你说:"IDE 开发迅速,调试方便,适合大型程序……" 那说明微软的程序在你脑子里已经比较根深蒂固,你需要好好清醒一下了,看看我来告诉你。   高明的 UNIX 程序员不用 IDE,IDE 从来就是给初级 Windows 程序员用的。   你看看大型的 UNIX 程序,包括 Linux 内核,各种网络服务程序,Xwindow 程序在内,哪一个是 IDE 搞出来的?我们实验室的 EDA 程序也没有一个是 IDE 弄的,我还知道 Candence, Synopsys,Mentor 的高性能的图形界面 EDA 程序也都不是 IDE 写的。你信不信,微软的人在写 Windows 本身的时候也根本不用 IDE!   有一次某杂志采访一些出名的 Linux 内核程序员,包括 Linus 在内,没有一个人用 IDE ,有的人用 VIM,有的用 Emacs,只有 Linus 说"GNU Emacs is evil",但是其实他用的是一种跟 Emacs 有同样键绑定功能的 MicroEmacs。大家都是用编辑器编辑了程序文件,然后用 make 这样的自动工具调用 gcc 编译器完成编译工作的。   我以前也编过 Windows 程序:应用程序,驱动程序。但是我没有用 VC 的 IDE。Linux 教育了我,我会在命令行调用 CL,我知道 CL 才是 VC 的编译器。我可以在 cygwin 的 Makefile 里使用 CL。我还知道 CL 的参数都有什么用处。但是这些不是一个从一开头就用 IDE 的人能很快理解到的。   我相信: IDE is evil。我有一些用 Windows 的 IDE 写程序的朋友,他们对那套东西已经很精通了。但是我却惊奇的发现,他们竟然把编译器和汇编器的概念都分不清楚,甚至有的人连"编辑器"和"编译器"都搞混淆了!他们只知道在一个窗口里输入了代码,点击一个按钮就可以编译程序,但是这里面到底是怎么工作的,他们不知道!他们被盖在上面的窗口挡住了视线,甚至会以为那个按钮就是编译器!   他们对那些 IDE 的热键背的滚瓜烂熟,但是我却看到他们在一个函数一个函数的把别人的 ANSI 风格的代码变成 VC 的风格。想想这件事在 VIM 里有多么简单,一瞬间就可以搞定。   为什么 UNIX 程序员不用 IDE?明白了这个道理你就能体会到 UNIX 的设计思想了。首先,一个 IDE 集成了编辑器,编译器,汇编器,调试器,跟踪器…… 这个编辑器功能肯定比不上 VIM 或 Emacs,编译器比不上 GCC,汇编器比不上 as,调试器比不上 gdb, ddd, 跟踪器比不上 strace, ltrace, truss。你得到的是一套整合的很好的低能的程序。如果你对调试器的功能不满意,你只好换用另外一套IDE,但是这套 IDE 的热键,菜单,编辑器功能,按钮…… 跟原来那个有很大不同。你不得不花很多时间来熟悉新的环境,而不能保持原来的某些东西。   而在 UNIX 下就不一样了。你可以用你最喜欢的 VIM 编辑程序,你在 VIM 里可以调用 GNU make,make 可以调用 gcc, ld, … 实际上 make 能帮你很多忙。make的出错信息可以被 VIM 捕获,VIM 能帮你在源程序里定位。你如果喜欢 icc, 你可以让 make 用 icc 而不是 gcc。你如果觉得 gdb 跟踪变量时比较麻烦,你可以用 ddd 来显示各种数据结构之间的关系。你还可以在 Emacs 里调用 gdb,那样就可以同步显示源代码了。而且 VIM 和 Emacs 还可以编辑很多其它东西,比如信件,LaTeX 文档,HTML,配置文件…… 你不用另外找一个什么编辑器来干这些杂活了。很多程序比如 Mutt, tin 都可以在内部使用 VIM,这样就更方便了。   释放内存   我在 Windows 下做过的一件最傻的事情莫过于"释放内存"了。有一天我看到一个 Windows 程序说:"这个程序可以帮你把大量内存释放出来给一个很大的程序用。"我试了一下,居然一下把我的 64M 内存释放出来 48M!我高兴极了。现在想一想,那是多么傻的事情,那么多的内存留着干什么?不用白不用啊!一操作系统,居然还需要别人写的程序来释放内存,那是什么样的操作系统?   在 Linux 下用 free 命令,你会发现你的内存几乎每时每刻都快要被用完。那是因为 Linux 把大部分内存用来作为磁盘缓冲了。Linux 有比 Windows 先进的磁盘缓冲技术。你有没有发现你往硬盘写数据的时候,很快就完成了?那是因为 Linux在内存里有很多磁盘缓冲区,你要写到硬盘上的数据先被写到了这些内存里,然后 Linux 就告诉你"拷贝完成" ,当你马上又想删除刚才写入的某些数据时,Linux 只是把数据从内存里移除,然后报告" 删除完成"。在一定的间隔时间后,Linux 才把数据写回硬盘,这样不但高效,避免了多次硬盘操作,而且减少了文件的不连续,也就是减少了"碎片"。Windows 当然也有磁盘缓冲,但是由于它内存管理的低效率,它不敢把大量内存都用来作为磁盘缓冲,因为它没有能力在用的时候随时把内存收回来。   Linux 能干的高级的事情 Windows 都干不了   当然有很多事情是Linux/UNIX的专利了。因为 Windows 只能装在 PC 机上,好像以前也有 Alpha 可以使用 Windows NT,但是就是没见到有人用。PC 机的能力是很低的,像我们编程序处理 NP-Hard 问题的人,用 Windows 的机器显然速度不够,而且有时一个问题算上几天甚至几个星期,Windows 机器是以"死机"著称的,我们怎么能放心?   所以几乎所有科学计算程序,EDA 程序,高性能图像处理程序都不是 Windows 的。他们有时也会移植一些给 Windows,但是常常降低那些程序的能力。你比较过Windows 版本的 Mathematica 和 Linux 的有什么区别吗?   IBM 制造的最大的并行计算机有 8000 多个处理器,Windows 不可能有能力管理这么多处理器,它用的是什么操作系统?答案是 Linux。   《泰坦尼克号》电影里的三维动画,那么细腻逼真,Windows机器能做出来吗?不行。那也是 Linux 机器做的。   民航总局用来训练地情人员的虚拟现实训练设备,Windows 当然无能为力。那都是商业的 IRIX 机器。   UNIX 是最早支持 TCP/IP 网络协议的系统。它上面有很多可以互相协作的网络服务程序,它们经过多年的使用和修订,已经达到比较完善的程度。而就在1997年,微软的比尔盖茨还在扬言:"Internet 是没有前途的。" 微软的这个"远见卓识"大家应该都已见识,它后来加上的网络服务程序IIS漏洞之多,让公安部都频频发出警报,大家也是见识了的。   其实你知道了,Windows 没有一样有用的事情能比 UNIX 干的更好。   # Linux 干不了的有用的事情 Windows 照样干不了   当然 Linux 不是万能的。它也有不能干的事情,电脑也有干不了的事情。但是Linux 干不了的事情,Windows 肯定也干不了。这些事情就是我们需要探索,需要努力的事情了。在你探索的过程中,Linux 必定是你的好伙伴。   UNIX 的真谛何在?   让聪明人干任何他们想干的事情   UNIX 的一个特点就是非常高的灵活性,Xwindow 也具有这种灵活性。这种灵活性体现在哪里呢?   UNIX 的程序一般都有很多参数,不管你现在用的着用不着,总有人需要某些参数。它们的行为很多都可以用配置文件来改变。比如 GNU bash, 通常缺省的命令行输入方式是 Emacs 方式,但是只要 我编辑一个 .inputrc 文件,就可以把它变成vi 的输入方式,而且我还可以自己绑定键序列到某些操作。我可以用 shopt 来设置它的很多特点,比如是否进行通配符扩展,是否可以把一个变量当作一个目录来cd,是否可以自动纠正某些明显的目录名打字错误 ……   UNIX 程序设计的思想是提供给用户"机制",而不限制用户制定"政策"。这是一个重要的尊重用户的作法。   我们再来看看 Xwindow。Xwindow 是一个出色的设计,它把显示服务器和客户程序分开。一个显示上既可以显示本机上的程序,也可以显示别的机器上的 X 程序,而它们都遵守你的窗口管理器的统一指挥,它们之间可以方便的传送剪贴版数据,各种事件 …… 比如有时我的 XFree86 上会出现四个不同机器上的 XTerm,两个不同机器上的 GVIM,…… 它们统一受本机上的 FVWM 指挥。   Xwindow 程序都具有很多很多命令行参数和 resource 参数。你可以随意的在命令行或者 .Xdefaults 文件设置所有的颜色,字体,尺寸…… 而且如果你用 xrdb把 .Xdefaults 导入到根窗口,那么其它机器上没有经过配置的同样的程序,显示到你的机器上的时候也会遵守同样的外观规定。   Xwindow 的窗口具有 Property, 也就是一些可以自己定义的共享数据(原子)。正是因为这些 Property 的存在,使得 Xwindow 具有无比强大的生命力。X 的窗口管理器和其它客户程序之间并没有统一的协议,但是后来出现了 ICCCM(客户程序间通信规范),这个规范就是通过 property 定义的。现在又有人定义了一套"扩展的窗口协议(EWM Hints)",使得 Xwindow 可以具有某些 Windows 的特征,比如一个工具条程序可以告诉窗口管理器:"这个屏幕下面被我占据了24个像素的空间,你最大化程序的时候不要越过这个界线。"   一个强大的窗口管理程序比如 FVWM,它收到这样的提示时,可以答应工具条程序的这个要求,也可以不答应。一切选择的权力在于谁?当然是用户了!一切窗口乖乖听话,FVWM 给予用户最大的尊重。   你想想,是不是有些 Windows 程序常常弹出一个窗口要你选择 "Yes or No"?你不点击它它就不下去。你觉不觉得你的程序在侵犯你的尊严?你是一个人!还有就是很多 Windows 程序把人当成傻瓜,而它是"智能程序"。比如,有一个程序就是喜欢把你的每句话第一个字母都变成大写,我不说它是谁了,你遇到的时候就知道了。如果连"一句话开头一个字母要大写"这么明显的问题都需要程序帮你纠正的话,人脑还用来干什么?况且如果你故意想要不大写的话,那就更麻烦了,我楞是没有从它那一大堆菜单里找到怎么关闭这个愚蠢的选项。   只有符号才能完全操纵计算机   我们来说说很多初学 Linux 的用户。虽然他们在用 Linux,但是他们打心眼儿里是觉得 Windows 的工作方式好,他们希望 Linux 有一天能"像Windows那样"。你说:"我鼠标一点,我菜单一拉,…… 就可以完成我的操作。" 但是我要告诉你:"Linux 从来没有摹仿 Windows,将来也不会。Linux 从诞生之日起,它的工作方式就比 Windows 的先进。Linux 属于能勇敢面对符号的人。只有符号才能完全操纵计算机。"   看看优秀的 UNIX 程序,XFree86, FVWM, VIM, Emacs, proftpd, Mutt, wget,tin, … 没有一个不是用配置文件来设置选项的。为什么这些程序没有方便的菜单可以用来配置?难道它们的设计者就那么低能,连个图形配置界面也写不出来?   当然不是。因为图形界面配置方式的能力是极其有限的,而配置文件和程序语言的表达能力却是无限的。用图形界面配置这些程序的话,如果你想达到配置文件的效果,你需要成百上千的菜单,checkbox, radio button, … 到时候你根本没办法找到你需要修改的地方了!而各个程序的配置文件的语法都有很多相似之处,一般就是一些命令,设置一些变量,参数,…… 一旦用会了一个,其它的也就容易理解了。如果你用惯了 awk, sed, Perl,你会觉得那才是真正的自动化啊。   鼠标虽然是很好的工具,但是它的表达能力是有限的。你不可能光用鼠标就让电脑完全明白你的意思,它毕竟只有3个按钮。看看我的MetaPost页你就能体会到鼠标的这一弱点。所以我们虽然很喜欢鼠标,但是却不能完全依赖它。   各个小程序的完美配合   这就是UNIX最重要的特点了,它就是UNIX设计的思想。让每个程序只具有一项专门的能力,然后让它们合作。Xwindow也继承了这种好传统。   这恐怕就是Windows和其它操作系统望尘莫及的地方了。UNIX 程序设计之统一,配合之完美,真使我难以置信!shell, grep, find, awk, sed, make, Perl,Emacs, vi, tin, Mutt, … 它们是那么的具有一致性!你一旦学会了 sed 的正则表达式,其它程序基本上都能用了。你一旦学会了 vi 和 VIM, 你会发现它的操作是那么的有规律性,似乎vi的设计者在几十年前就已经设计好了 VIM 在今天的完美而统一的操作方式!而且vi的操作还体现在 Mutt, tin 等很多程序中。你甚至可以把 bash 设置为 vi 的输入方式来输入命令行,我就是这么做的。一个程序可以调用另外一个程序来得到数据,可以把数据交给它处理后返回来,可以在自己的窗口里"嵌入"另外一个程序。   在 Windows 和其它非 UNIX 操作系统中,这种合作是非常困难的。我曾经在Windows 下使用 Perl来进行一些自动工作。但是 Windows 的文件操作,管道是如此的不稳定,程序之间基本不能合作。你别想在 Visual Studio 窗口里面嵌入UltraEdit 编辑器,你别想用一个 expect 脚本来控制 telnet 到水木清华BBS,这就是为什么 helloooo 诞生在 Linux 而不是 Windows。我曾经试图从Windows + Exceed + SecureCRT ssh 登录到 Sun 机器,然后通过 ssh 的隧道(X11 tunnel)把 X 程序传到 Exceed 上运行,但是搞了两天都没有成功!而在Linux 下这个事情根本就是不用怎么配置的,OpenSSH 和 XFree86 本来就是完美结合,只要打开 ssh 的 "forward X11" 选项就什么都搞定了。   Windows 的程序都是大而全,大而杂,所有的电子邮件程序都需要自己提供编辑器,自己发送和收取邮件,自己显示邮件的附件。每一个BBS程序都提供自己的 Virtual Terminal, 自己的通讯代码。每一个 IDE 都自己提供编辑器,编译器,汇编器,调试器。人们为了使用一种新的程序,需要适应所有这些它提供的界面,而不能使用自己喜欢的编辑器的键绑定,菜单组织…… 不能 DIY!   你要知道,最高级的电脑是定做的,自己想要什么什么CPU,什么主板,多少内存,什么硬盘,键盘,鼠标,显示器都是自己选择的。最高级的滑板,自己想要什么牌子的版面,什么牌子的沙,什么桥,什么轮子,什么轴承,也都是自己选的。最高级的乒乓球拍,木板,胶皮,海绵,胶水都是可以自己选择…… 而用Windows 程序,你得到的是大杂烩,就像你去买"品牌机",只有那么几种配置,而且附带很多你不需要的软件和服务;就像你去买组装好的滑板,你想要大一点的轮子和窄一点的板子,但是你没有这种选择余地!Windo ws 程序就相当于最廉价,最次的滑板。但是它却会花你更多的] ]>

伯克利大学新举措,将课堂教学免费送上YouTube

美国柏克莱加州大学,将免费课程录影放到分享网站YouTube上,今天开始全世界都可以上网吸收大学殿堂知识.
校主管今天宣布,公众可以到www.youtube.com/ucberkeley的网址,收看超过三百小时的柏克莱大学课程和活动.柏克莱加大素以提升 言论自由以及反战而著称,YouTube网站上提供的课程,包括和平与冲突研究,生物工程学,以及名为「给未来总统的物理课」的理工课程.

   大学部副教务长玛斯拉奇说:「YouTube网站上的加州大学课程,将提供公众一窥大学生活的管道,范围包括学术和活动」

    加州大学的YouTube网页今天正式启动,将公布九门课的全部教学内容,包括大约四十堂课程。这间大学计画持续地在网站放上新课程。

    柏克莱加大自称是第一所将全部课程放上YouTube网站的大学。热门的YouTube影音分享网站总公司设於加州北部。

    这所大学二零零一年开始在网路上播送课程,称为webcasts。去年开始制作有声课程podcasts,放在苹果电脑    公司的iTune网路商店上供人下载。

    管理大学网站节目的哈伯德说:「我们很兴奋能够制作柏克莱加大的网路播送节目,放在YouTube网站提供给全世界。」

    他说:「我想,课程内容全面公开化,和我们作为一个公共机构的本质十分一致。我们深信,公众能够接触到大学课程是十分重要的。」

访问:YouTube – Berkley

英领馆推出公益学习网站学英语

英国总领事馆文化教育处于今天正式推出了“英语在线”网站,将免费面向中国英语学习者和从事英语教学的教育者开放,提供丰富的英文学习和英语教学多媒体资料。与此同时,网站还鼓励用户相互交流,分享经验,实现真正的“互助式”英语学习。推荐哦..学习英文的好地方..
[ 链接 http://www.englishonline.org.cn ]

用游戏来学习Java技术(Robocode攻略)

用你的JAVA编程技术来玩游戏吧!不会JAVA?那就用游戏来学习JAVA吧!
什么是Robocode?

 

其实我对机器人一直很感兴趣。我记得在我还是初中的时候,就知道 AplleⅡ上有一个程序,用它来编写简单的机器人程序,然后相互作战。当时自己还完全不懂编程,总是向往着,那神秘的编程高手玩的游戏是怎样的?

Robocode就是这样一个东西,但是更好一些。它是一个基于Java语言的机器人作战游戏。 其代码的编写和建模都不错,玩起来也很有趣。Robocode是很多"编程游戏"软件中的一个,他们共同的特征是在没有用户输入的状态下许多机器人在一个及竞技场中比赛,用户必须编制一个高效的机器人来取胜。Robocode特别的像一场机器人坦克的大混战,它们互相开火直到只剩一个胜利者。程序完全是由JAVA编写,并且玩家必须要创造一个继承自Robot类的类。

你希望在玩游戏的过程中、在闪躲炮弹、执行精确攻击的演练中学会Java编程的 继承、多态性、事件处理以及内部类这些内容吗?Robocode 这个游戏为全世界的 Java 开发者实现这个愿望,它把游戏风潮变成了教学工具,人们对它的上瘾程度令人吃惊。下面,我参考网友 Sing Li 以前写的文章,让我们一起来拆解 Robocode,同时着手建造属于自己的、定制的、小而精悍的战斗机器吧!

Robocode 是一个很容易使用的机器人战斗仿真器,可以在所有支持 Java 2 的平台上运行。您创建一个机器人,把它放到战场上,然后让它同其他开发者们创建的机器人对手拼死战斗到底。Robocode 里有一些预先做好的机器人对手让你入门,但一旦您不再需要它们,就可以把您自己创建的机器人加入到正在世界范围内形成的某个联盟里去和世界最强手对阵。

每个 Robocode 参加者都要利用 Java 语言元素创建他或她的机器人,这样就使从初学者到高级黑客的广大开发者都可以参与这一娱乐活动。初级的 Java 的开发者们可以学习一些基础知识:调用 API 代码、阅读 Javadoc、继承、内部类、事件处理等等。高级开发者们可以在构建“最优品种”的软件机器人全球竞赛中提高他们的编程技巧。在本文中,我们将介绍 Robocode,并指导您从构建您平生第一个 Robocode 机器人开始征服世界。我们还将看一下迷人的“后台”机制,正是它使得 Robocode 起作用。

首先当然是下载和安装 Robocode 啦

Robocode 是 Mathew Nelson 的智慧之作,他是 IBM Internet 部门 Advanced Technology 的软件工程师。现在Robocode的主页已经搬迁到sourceforge这个开源网站上了,大家可以在这里下载RobotCode的最新版http://robocode.sourceforge.net/ 到3月21日为止最新版本是1.0.7,大小为3.2M。
好了,下载回来后当然还要在你的电脑上安装JAVA运行库才行的哦~地址是http://java.sun.com/getjava
1.先安装好JAVA运行库,好像需要重启的?忘记了……
2.把下载回来的robocode-setup.jar复制到c盘根目录
3.打开 开始菜单 的“运行”,输入 java -jar "c:robocode-setup.jar" 进行安装
4.安装完后就可以在开始菜单中找到Robocode的菜单了,来~我们进入战场咯!

安装完成后,您也可以通过 shell 脚本(robocode.sh)、批处理文件(robocode.bat)或桌面上的图标来启动 Robocode 系统。此时,战场将会出现。在此,您可以通过菜单调用 Robot Editor 和 compiler。

Robocode 系统组件
当您启动 Robocode 时,将看到两个GUI窗口,这两个窗口构成了 Robocode 的 IDE:

图 1. Robocode IDE


战场是机器人之间进行战斗直至分出胜负的场地。主要的仿真引擎被置于其中,并且允许您在这里创建战斗、保存战斗以及打开新建的或现有的战斗。通过界面区域内的控件,您可以暂停或继续战斗、终止战斗、消灭任何机器人个体或获取任何机器人的统计数据。此外,您可以在此屏幕上激活 Robot Editor。

Robot Editor 是一个定制的文本编辑器,它可以用于编辑生成机器人的 Java 源文件。在它的菜单里集成了 Java 编译器(用于编译机器人代码)以及定制的 Robot 打包器。由 Robot Editor 创建并成功编译的所有机器人都会处于战场上一个部署就绪的位置。

Robocode 里的每个机器人都由一个或多个 Java 类构成。这些类可以被压缩成一个 JAR 包。为此,Robocode 的最新版本提供了一个可以在战场 GUI 窗口中激活的“Robot Packager”。

对 Robocode 机器人的详细分析
在写这篇文章时,Robocode 机器人是一个图形化的坦克。图 2 是一个典型的 Robocode 机器人的图解。

图 2. 对 Robocode 机器人的详细分析

请注意,机器人有一门可以旋转的炮,炮上面的雷达也是可以旋转的。机器人坦克车(Vehicle)、炮(Gun)以及雷达(Radar)都可以单独旋转,也就是说,在任何时刻,机器人坦克车、炮以及雷达都可以转向不同的方向。缺省情况下,这些方向是一致的,都指向坦克车运动的方向。

我们先不考虑怎么编程来实现机器人战斗,我们先用自带的例子机器人来一场战斗吧

单击菜单上的Battle,然后选New,出现了New Battle对话框

图 3. New Battle 对话框

左边的框是Packages,相当于一个文件夹,里面包含多个Robots(机器人)
我们选择sample这个包,里面有Corners、Crazy、Fire等等很多例子的机器人了
随便选择几个你喜欢的,然后按Add添加到Selected Robots框,进了这个框就是准备要上战场的机器人了~选择好后,按 StartBattle 开战吧!

现在你已经知道怎样可以使用机器人去战斗并且也构建好你的战场了,好,下面我们学习怎样来编写属于自己的战斗机器人!!

战场是机器人之间进行战斗直至分出胜负的场地。主要的仿真引擎被置于其中,并且允许在这里创建战斗、保存战斗以及打开新建的或现有的战斗。通过界面区域内的控件,可以暂停或继续战斗、终止战斗、消灭任何机器人个体或获取任何机器人的统计数据。此外,我们可以在此屏幕上的Robot菜单打开 Editor,就是我们机器人的代码编辑器了!Robot Editor 是一个定制的文本编辑器,它可以用于编辑生成机器人的 Java 源文件。在它的菜单里集成了 Java 编译器(用于编译机器人代码)以 及定制的 Robot 打包器。由 Robot Editor 创建并成功编译的所有机器人都会处于战场上一个部署就绪的位置。我们就是要在这里编写机器人了。
选择“File”》“New”》“Robot”来新建一个机器人。它会首先要你输入这个机器人的名字(注意名字首字母要大写哦),然后要你输入包的名字(就是保存这个机器人的文件夹名称),这样就生成了一个蠢蠢的机器人XForce的代码了~因为我们还没替它加上人工智能,呵呵!

现在单击菜单的Complie下的Complie进行编译,保存好,我们的机器人已经生产出来咯~
现在关闭Editor,在进入New Battle,Pakeage下选择你刚才的包的名字,Robot下就有了我们新建的XForce机器人了~添加进去吧,然后选择多几个其他的机器人,开始战斗!

看~我们的XForce在战斗了!

是否觉得它太蠢了点呢?来,继续来学习~~

Robocode 机器人是一个图形化的坦克,请注意,机器人有一门可以旋转的炮,炮上面的雷达也是可以旋转的。机器人坦克车(Vehicle)、炮(Gun)以及雷达(Radar)都可以单独旋转,也就是说,在任何时刻,机器人坦克车、炮以及雷达都可以转向不同的方向。缺省情况下,这些方向是一致的,都指向坦克车运动的方向。

附:Robot 命令
  Robocode 机器人的命令集都收录在 Robocode API Javadoc 中。这些命令都是 robocode.Robot 类的公共方法。

(1)移动机器人、炮和雷达

  移动机器人及其装备的基本命令:

  • turnRight(double degree) 和 turnLeft(double degree) 使机器人转过一个指定的角度。
  • ahead(double distance) 和 back(double distance) 使机器人移动指定的像素点距离;这两个方法在机器人碰到墙或另外一个机器人时即告完成。
  • turnGunRight(double degree) 和 turnGunLeft(double degree) 使炮可以独立于坦克车的方向转动。
  • turnRadarRight(double degree) 和 turnRadarLeft(double degree) 使炮上面的雷达转动,转动的方向也独立于炮的方向(以及坦克车的方向)。

  这些命令都是在执行完毕后才把控制权交还给程序。此外,转动坦克车的时候,除非通过调用下列方法分别指明炮(和雷达)的方向,否则炮(和雷达)的指向也将移动。

  • setAdjustGunForRobotTurn(boolean flag):如果 flag 被设置成 true,那么坦克车转动时,炮保持原来的方向。
  • setAdjustRadarForRobotTurn(boolean flag):如果 flag 被设置成 true,那么坦克车(和炮)转动时,雷达会保持原来的方向。
  • setAdjustRadarForGunTurn(boolean flag):如果 flag 被设置成 true,那么炮转动时,雷达会保持原来的方向。而且,它执行的动作如同调用了 setAdjustRadarForRobotTurn(true)。

(2)获取关于机器人的信息

  • getX() 和 getY() 可以捕捉到机器人当前的坐标。
  • getHeading()、getGunHeading() 和 getRadarHeading() 可以得出坦克车、炮或雷达当前的方向,该方向是以角度表示的。
  • getBattleFieldWidth() 和 getBattleFieldHeight() 可以得到当前这一回合的战场尺寸。

(3)射击命令

  一旦掌握了移动机器人以及相关的武器装备的方法,我们就该考虑射击和控制损害的任务了。每个机器人在开始时都有一个缺省的“能量级别”,当它的能量级别减小到零的时候,我们就认为这个机器人已经被消灭了。射击的时候,机器人最多可以用掉三个能量单位。提供给炮弹的能量越多,对目标机器人所造成的损害也就越大。 fire(double power) 和 fireBullet(double power) 用来发射指定能量(火力)的炮弹。调用的 fireBullet() 版本返回 robocode.Bullet 对象的一个引用,该引用可以用于高级机器人。(也就是说,当你确定能击中对方,火力越大越好咯^_^)

(4)事件

  每当机器人在移动或转动时,雷达一直处于激活状态,如果雷达检测到有机器人在它的范围内,就会触发一个事件。作为机器人创建者,我们有权选择处理可能在战斗中发生的各类事件。基本的 Robot 类中包括了所有这些事件的缺省处理程序。但是,们可以覆盖其中任何一个“什么也不做的”缺省处理程序,然后实现自己的定制行为。下面是一些较为常用的事件:

  • ScannedRobotEvent。通过覆盖 onScannedRobot() 方法来处理 ScannedRobotEvent;当雷达检测到机器人时,就调用该方法。
  • HitByBulletEvent。通过覆盖 onHitByBullet() 方法来处理 HitByBulletEvent;当机器人被炮弹击中时,就调用该方法。
  • HitRobotEvent。通过覆盖 onHitRobot() 方法来处理 HitRobotEvent;当您的机器人击中另外一个机器人时,就调用该方法。
  • HitWallEvent。通过覆盖 onHitWall() 方法来处理 HitWallEvent;当您的机器人撞到墙时,就调用该方法。

 

很多研究Robocode的 玩家都被其中的方向及坐标弄糊涂了。整个屏幕哪个是0度角,整个是坐标原点呢? 顺时针与逆时针的方向如何区分?

一段英文的翻译及说明:

  • heading – absolute angle in degrees with 0 facing up the screen, positive clockwise. 0 <= heading < 360.
  • bearing – relative angle to some object from your robots heading, positive clockwise. -180 < bearing <= 180
  • heading:是机器人方向与屏幕正上方的角度差,方向在0到360之间.
  • bearing:是机器人的某个部件如雷达发现的目标与方向的角度差,顺时针为正角度在-180到180之间

几个在Robocode中很重要的概念:

  • 坐标系:Robocode整个坐标系都是战场屏幕以左下角为原点
  • 绝对方向系:Robocode中不管机器人在哪个方向都是以静态战场屏幕为参照的绝对角度(也即大家说的Heading),正上方为0度角。也即不管是Robot,Gun,Radar向北为0,向东为90,向南为180,向西为270。
  • 相对方向系:相对方向是Robot,Gun,Radar以机器人的动态heading角度为参照的角度差不再以整个静态屏幕为参照了,叫它相对因为机器人的heading是随着机器人移动而不停的在改变,heaing只是个相对物体。
  • 顺时针和逆时针是看另一机器人是在你的Heading角度的(0,180)还是(-180,0)之间。

  再次提醒:Heading是个静态角度,正上方总为0.不管是取Heading,还是取方向。Bearing是个角度差值,是由参照的Heading和发现时的Heading的差值。方向的问题就说到这,欢迎大家讨论。

我看了Robocode的基础知识,自己写了个bot,放到BattleField上却是屡战屡败……伤心ing。

  Bot对于周围环境的了解非常有限。它可以知道其它机器人的距离、方位、方向、速度和能量等级。但是,它看不到子弹。怎么才可以有效的躲避对方的子弹呢?

  Bot虽然看不到子弹,但是对方的能量等级还是可以scan到了。对方只要发射子弹就会耗损能量,并且耗损的能量介于0和3之间。根据这些线索,如何发现其它机器人正向它开炮 对于“笨笨”的Bot不就易如反掌了? ^_^

  当Bot检测到对方发射子弹的信息时,向左或向右移动一小步,嘿嘿,子弹就打不到咯~并且大多数Bot的瞄准方法是要么直接向目标开炮,要么试着根据Bot的速度和方向来推算位置。如果我的Bot不移动,两种算法都会正好冲着这个Bot的当前位置开炮。哈哈哈,这时我的Bot再移动,不就全部都打不到啦。(是不是颇有武侠小说里以静制动的高手味道?^_^)

  下面是部分代码和注释:

  double previousEnergy = 100; //初始状态对方能量为100
  int movementDirection = 1;  //移动方向
  int gunDirection = 1; //炮管方向

  /**
   * 当检测到对方Bot,触发事件
   * @param e
   */
  public void onScannedRobot(ScannedRobotEvent e) {
    //调整自己和对方之间的角度
    setTurnRight(e.getBearing()+90-30*movementDirection);

    //如果对方的能量损耗一定值,进行躲避动作
    double changeInEnergy = previousEnergy – e.getEnergy();
    if (changeInEnergy>0 && changeInEnergy<=3) {
      //躲避!
      movementDirection = -movementDirection; //和上次的躲避方向相反
      setAhead((e.getDistance()/4+25)*movementDirection);
    }
    //将炮管指向对方当前位置
    gunDirection = -gunDirection;
    setTurnGunRight(99999*gunDirection);

    //射击
    fire(1);

    //重新设置对方能量
    previousEnergy = e.getEnergy();
  }

  是不是很简单?这个技巧还存在问题。子弹一发射,我的Bot就移动,所以它最终可能会移回炮弹轨迹之内。最好是在估计子弹要到达时再移动。

  我有个更大胆的假设:因为现在我的Bot命中率还不高,那么如果我的Bot一直不开火,只是躲避对方的子弹的话,能不能拖到对方的能量为0呢?确实存在一点问题。对方子弹一发射,我的Bot就移动,并且这个移动是规律的来回移动。如果移动距离短了,就可能在回来的时候撞到对方的子弹;如果移动距离长了,就等于做一个直线运动,对方很容易计算得到Bot的运动轨迹。还有一个问题,躲避的时候很有可能撞到墙上……(撞墙是要减energy的:~()

  针对以上的问题,我另写了一个Bot。代码如下:

import robocode.*;

public class HanicBot extends AdvancedRobot{
  private double eDist; //对方的距离
  private double move; //移动的距离
  private double radarMove = 45; //雷达移动的角度
  private double dFirePower;  //火力

  /**
   * main func run()
   */
  public void run() {
    eDist = 300;
    while(true){
      //每过一个周期,运动随机的距离
      double period = 4*((int)(eDist/80));  //周期;敌人越接近,周期越短,移动越频繁
      //周期开始,则移动
      if(getTime()%period == 0){
        move = (Math.random()*2-1)*(period*8 – 25);
        setAhead(move + ((move >= 0) ? 25: -25));
      }
      //避免撞墙
      double heading = getHeadingRadians(); //取得bot方向的弧度数
      double x = getX() + move*Math.sin(heading); //移动move后将要达到的x坐标
      double y = getY() + move*Math.cos(heading); //移动move后将要达到的y坐标
      double dWidth = getBattleFieldWidth();  //战场的宽度
      double dHeight = getBattleFieldHeight();  //战场的长度
      //当(x,y)超过指定的范围,则反向移动move
      if(x < 30 || x > dWidth-30 || y < 30 || y > dHeight-30){
        setBack(move);
      }
      turnRadarLeft(radarMove); //转动雷达
    }
  }//end run()

  /**
   * 当检测到对方Bot,触发事件
   * @param e
   */
  public void onScannedRobot(ScannedRobotEvent e) {
    eDist = e.getDistance();  //取得对方距离
    radarMove = -radarMove; //设置雷达
    double eBearing = e.getBearingRadians();  //取得和对方相对角度的弧度数
    //将bot转动相对的角度,以后bot的运动将是以对方为圆心的圆周运动
    setTurnLeftRadians(Math.PI/2 – eBearing);
    //转动炮管指向对方
    setTurnGunRightRadians(robocode.util.Utils.normalRelativeAngle(
      getHeadingRadians() + eBearing – getGunHeadingRadians()));
    //根据对方距离射击
    dFirePower = 400/eDist;
    if (dFirePower > 3){
      dFirePower = 3;
    }
    fire(dFirePower);
  }
}

  首先,为了迷惑对方,不让对方容易的得到Bot的移动规律,Bot就要在一定的时间内做出随机的运动,这个很容易办到。并且,我给Bot的运动改变时间规定了周期。这个周期随离对方的距离改变,敌人越接近,周期越短,移动越频繁。

double period = 4*((int)(eDist/80));
if(getTime()%period == 0){
  move = (Math.random()*2-1)*(period*8 – 25);
  setAhead(move + ((move >= 0) ? 25: -25));
}

  其次,Bot的运动不是呈直线的。而是以对方为圆心的圆周运动。

setTurnGunRightRadians(robocode.util.Utils.normalRelativeAngle(
      getHeadingRadians() + eBearing – getGunHeadingRadians()));

  最后是如何避免撞墙。这里要用到点三角函数-_-!! 原理就是,计算Bot一次运动后将要达到的坐标是不是位于规定的危险区域。如果是,则立即反方向运动。

double heading = getHeadingRadians();
double x = getX() + move*Math.sin(heading);
double y = getY() + move*Math.cos(heading);
double dWidth = getBattleFieldWidth();
double dHeight = getBattleFieldHeight();
if(x < 30 || x > dWidth-30 || y < 30 || y > dHeight-30){
  setBack(move);
}

这个Bot的威力如何?呵呵,我去测试一下先~

好了,就说到这里了,欢迎各大高手来踩……

 

关于其它的一些"编程游戏"
有许多软件是基于这种思想的,Robocode它自己就是来源于机器人大战Robot Battle(http://www.robotbattle.com/)这款软件]] >

交互设计中运用奥卡姆剃刀原理

14的世纪哲学家、圣方济各会修士奥卡姆的威廉(William of Occam,约1285年至1349年)提出的一个奥卡姆原理,这个原理是告诫人们“切勿浪费较多东西去做用较少的东西同样可以做好的事情。”后来以一种更为广泛的形式为人们所知——“如无必要,勿增实体。”

在条件相同的情况下,要求得越少的哪个就越好,越有价值。——罗伯特·格罗斯泰斯特(Rober Grossteste,1175~1253,牛津大学第一任校长)

自然界选择最短的路。——亚里斯多德

如果某一原因既真有足以结实自然事物的特性,则我们不应当接受比这更多的原因。——艾萨克·牛顿

万事万物应该最简单(Make everything as simple as possible, but not simpler )。——阿尔伯特·爱因斯坦

奥卡姆剃刀原理暗含这个观点:不必要的元素降低设计效率,增加不可预料结果的几率。不必要的分量,不论是生理的,直观的,还是认知的,都会降低性能;不必要的元素潜伏着失败或问题。这个原理还有个美感要求,它把从设计中去掉不必要的元素比做是从溶液中去掉不纯洁的东西——设计是一种更整洁,纯洁的结果。

可用奥卡姆剃刀原理来对多个功能相等的设计进行评价、选择。

补充材料:

一.奥卡姆剃刀在科学上的应用

对于科学家,奥卡姆剃刀原理还有一种更为常见的表述形式:当你有两个处于竞争地位的理论能得出同样的结论,那么简单的那个更好。

这一表述也有一种更为常见的强形式:如果你有两个原理,它们都能解释观测到的事实,那么你应该使用简单的那个,直到发现更多的证据。对于现象最简单的解释往往比较复杂的解释更正确。如果你有两个类似的解决方案,选择最简单的。需要最少假设的解释最有可能是正确的。或者以这种自我肯定的形式出现:让事情保持简单!

注意到这个原理是如何在上述形式中被加强的。严格的说,它们应该被称为吝啬定律,或者称为朴素原则。最开始的时候我们使用奥卡姆剃刀区分能够做出相似结论的理论。现在我们试图选择做出不同结论的理论。这不是奥卡姆剃刀的本意。我们不用检验这些结论吗?显然最终不是这样,除非我们处于理论的早期阶段,并且还没有为实验做好准备。我们只是为理论的发展寻求一种指导。

这个原理最早至少能追溯到亚里士多德的“自然界选择最短的道路”。亚里士多德在相信实验和观测并无必要上走得太远。朴素原理是一个启发式的经验规则,但是有些人引用它,仿佛它是一条物理学公理。它不是。它在哲学和粒子物理中使用的很好,但是在宇宙学和心理学中就不是特别好,这些领域中的事务往往比你想象的还要复杂。或许引用莎士比亚的一句话要胜过引用奥卡姆剃刀:“天地之大, 赫瑞修, 比你所能梦想到的多出更多”

许多科学家接受或者(独立的)提出了奥卡姆剃刀原理,例如莱布尼兹的“不可观测事物的同一性原理”和牛顿提出的一个原则:如果某一原因既真又足以解释自然事物的特性,则我们不应当接受比这更多的原因。

奥卡姆剃刀以结果为导向,始终追寻高效简洁的方法,600多年来,这一原理在科学上得到了广泛的应用,从牛顿的万有引力到爱因斯坦的相对论,奥卡姆剃刀已经成为重要的科学思维理念。

二.奥卡姆剃刀在管理学上的应用

奥卡姆剃刀不断在哲学、科学等领域得到应用,但使它进一步发扬光大,并广为世人所知的,则是在近代的企业管理学中。

好的理论应当是简单、清晰、重点突出,企业管理理论亦不例外。在管理企业制定决策时,应该尽量把复杂的事情简单化,剔除干扰,抓住主要矛盾,解决最根本的问题,才能让企业保持正确的方向。对于现代企业而言,信息爆炸式的增长,使得主导企业发展的因素盘根错节,做到化复杂为简单就更加不易。

企业管理是系统工程,包括基础管理、组织管理、营销管理、技术管理、生产管理、企业战略,奥卡姆剃刀所倡导的简单化管理,并不是把众多相关因素粗暴地剔除,而是要穿过复杂,才能走向简单。通过奥卡姆剃刀将企业最关键的脉络明晰化、简单化,加强核心竞争力。

三.奥卡姆剃刀在投资学上的应用

投资需要策略,在投资市场,太保守不行,太冒险也不行。投资市场是复杂的,不少投资者整天在忙忙碌碌地分析、研究和频繁操作,投入了大量精力,却依然难以应付市场中庞杂的信息。

面对复杂当投资市场,应拿起奥卡姆剃刀,把复杂事情简单化,简化自己的投资策略,对那些消耗了大量金钱、时间、精力的事情加以区分,然后采取步骤去摆脱它们。

四.奥卡姆剃刀在生活上的应用

作为一种思维理念,当然并不仅仅局限于某一些领域,事实上,奥卡姆剃刀在社会各方面已得到越来越多的应用。

奥卡姆剃刀同时也是一种生活理念。这个原理要求我们在处理事情时,要把握事情的本质,解决最根本的问题。尤其要顺应自然,不要把事情人为地复杂化,这样才能把事情处理好。 爱因斯坦说:“如果你不能改变旧有的思维方式,你也就不能改变自己当前的生活状况。”当你用奥卡姆剃刀改变你的思维时,你的生活将会发生改变。

在运用奥卡姆剃刀时应牢记爱因斯坦的一句著名的格言:Make everything as simple as possible, but not simpler