这是一个林老师在2011年春节编写的LOGO游戏程序。在多数人没有参透取胜的技巧之前,你与计算机的对弈比赛十次,恐怕全部都要输给计算机!程序是按照必胜的策略来编程的,所以计算机得胜的概率非常大。当年编写的版本是PCLogo的。现在(2023年春节)MSWLogo-FMSLogo版本也编写出来了。只要你把程序粘贴在LOGO程序编辑窗口中,保存起来,再调用出来,然后运行程序就行了。两种版本的程序大家自己比较一下。博客的内容较多分为MSWLogo-FMSLogo版本、PCLogo版本两次发表,第三次是专门讲取胜的诀窍及算法的供大家参考。
游戏规定显示100根火彩,人或计算机每次可以任意取1-10根,游戏中人总是先取。最先把火柴取光的一方得胜。还没有取走的火柴是彩色的,已经取走的是灰色的。程序有友好的提示界面,提示你取火柴,最后还告诉你谁取胜了。所有的提示文字在“作图窗口”和“文本窗口”中都显示得清清楚楚。如果你有把握取胜的话,就试一试。还可以把这个文件拷贝给其他人共享。
学计算机编程只是做书本中出的题目、做老师给的考卷试题是不够的。林老师见过许多现在都是编程高手的人,他们除了能够轻松应对所有现成的“试题”外,往往热衷于自己编写程序——但是这些编程高手往往不玩现成的计算机游戏程序(觉得玩“游戏”浪费时间,缺少技术含量)——觉得只有自己编写游戏程序才是最好玩的。然后编写好、反复修改以后,就心满意足地给大家分享、接着就“扔掉”,再编下一个新的玩意。有些学习者竟然有耐心花一整个暑假将近60天的时间编写一个很大、很长的游戏程序。编写游戏程序的感觉和做试题的感觉是完全不一样的:因为自编游戏题目是自己选定的、游戏的“脚本”要自己构思,计算机人工智能的“算法”要反复琢磨,游戏程序中需要考虑的问题非常多……编写较大型的游戏程序和计算机专业工作者完成一个“课题”研究的过程在本质上是一样的。所以有经过这样磨炼的人,后来个个都成了编程高手。
这个程序是林老师的戏作,并没有花太多的时间进行“优化”,大家玩了以后多提宝贵意见。但是林老师的实践证明,LOGO语言编写游戏程序是可能的。
如果大家也有类似自编的人机对弈游戏程序的话
欢迎进行交流!
下面是玩这个游戏时在“文本窗口”同步显示的人机对话文本。
qhc
现在的火柴根数是:100
请输入取几根并按回车键!
你取走的火柴数是:3
现在的火柴根数是:97
请输入取几根并按回车键!
计算机取走的火柴数是:9
现在的火柴根数是:88
请输入取几根并按回车键!
你取走的火柴数是:9
现在的火柴根数是:79
请输入取几根并按回车键!
计算机取走的火柴数是:2
现在的火柴根数是:77
请输入取几根并按回车键!
你取走的火柴数是:4
现在的火柴根数是:73
请输入取几根并按回车键!
计算机取走的火柴数是:7
现在的火柴根数是:66
请输入取几根并按回车键!
你取走的火柴数是:7
现在的火柴根数是:59
请输入取几根并按回车键!
计算机取走的火柴数是:4
现在的火柴根数是:55
请输入取几根并按回车键!
你取走的火柴数是:3
现在的火柴根数是:52
请输入取几根并按回车键!
计算机取走的火柴数是:8
现在的火柴根数是:44
请输入取几根并按回车键!
你取走的火柴数是:9
现在的火柴根数是:35
请输入取几根并按回车键!
计算机取走的火柴数是:2
现在的火柴根数是:33
请输入取几根并按回车键!
你取走的火柴数是:10
现在的火柴根数是:23
请输入取几根并按回车键!
计算机取走的火柴数是:1
现在的火柴根数是:22
请输入取几根并按回车键!
你取走的火柴数是:5
现在的火柴根数是:17
请输入取几根并按回车键!
计算机取走的火柴数是:6
现在的火柴根数是:11
请输入取几根并按回车键!
你取走的火柴数是:7
现在的火柴根数是:4
请输入取几根并按回车键!
计算机取走的火柴数是:4
火柴已取光!计算机获胜!游戏结束!
FMSLogo-MSWLogo源程序
to qhc ;取火柴游戏
cs
ht
make "n 100
;游戏开始时火柴数
make "qq
0 ;从对话窗口输入的人取火柴数(字符)
限1-10
make "q
0
;变换后成为数字的人取火柴数
make "j
0
;计算机决策取火柴数
make "nj
" ;谁获胜的字符
hc 1 :n 14 4
;画初始火柴 淡黄杆 红头
setpc 4
setlabelfont [[黑体] 40 20] ;写屏标题头
pu setxy -110 200
pd seth 90 label "取火柴游戏 seth 0
setpc 1
setlabelfont [[楷体] 25 10] pu setxy -270 150 pd
;所有其他字体
pu setxy -185
-194 pd ;写底部游戏规则
seth 90
label[每次只能取1~10根火柴。先取完者为胜。] seth 0
sx1
sx2
aaa
;取火柴博弈计算入口
end
to
aaa ;取火柴博弈入口
;==============人取火柴程序段===============
make "q
rw
;从对话窗口输入字符取火柴数
if (or
:q<1 :q>10 :q>int :q)[make"q rw]
;剔除负数、大于10、小数)
pr (word
"你取走的火柴数是 char 58 :q)
make "n
:n-:q
if
:n>0[
hc 1 :n 14 4 hc :n+1 100 15 15 sx1
sx2]
if
:n=0[ ;人已经取胜的条件
hc 1 100 15 15
make "j 0 sx1 sx2
make "nj "你 sx3
stop]
;===========计算机取火柴程序段==============
ifelse
(0=remainder :n 11)[
;计算机取胜的核心算法
make "j 1+random 10][
make "j
:n-11*(int(:n/11))]
pr (word
"计算机取走的火柴数是 char 58 :j)
make "n
:n-:j
if
:n>0[
hc 1 :n 14 4 hc :n+1 100 15 15 sx1
sx2]
if
:n=0[
;计算机已经取胜的条件
hc 1 100 15 15
sx1 sx2
make "nj "计算机 sx3
stop]
aaa ;尾递归形成反复循环
替代PCLogo中的GO-LABEL循环
end
to hc :a :b :y1
:y2 ;画所有火柴的子程序
for[i :a-1
:b-1][
pu setxy
(remainder :i 25)*19-230 80-(int(:i/25)+1)*64
pd
setpc :y1
setpensize 6 fd 47
setpensize
10 setxy xcor ycor setpc :y2 fd 1 bk 1]
end
to sx1
;对第一行提示的刷新
setpensize 30 setpc 7 pu
setxy -210 128 pd setx
270
make "xs (word "现在的火柴根数是 char
58 :n char 32 char 32 "请输入取几根并按回车键! )
if :n>0[pr
:xs]
pu setxy -210 138 pd setpc
1
seth 90 label :xs seth
0
end
to sx2
;对第二行提示的刷新
setpensize 30 setpc 7 pu
setxy -210 95 pd setx 270
make "xs (word "你取走的火柴数是 char
58 :q char 32 char 32 "计算机取走的根数 char 58 :J)
pu setxy -210 105 pd setpc
1
seth 90 label :xs seth
0
end
to sx3
make "xs (word "火柴已取光! :nj
"获胜!游戏结束!)
pr
:xs
setpc 1 setlabelfont [[黑体] 35
14]pu setxy -230 -10
pd seth 90 label
:xs
end