免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
123下一页
最近访问板块 发新帖
查看: 9077 | 回复: 21
打印 上一主题 下一主题

初学练习,用perl写的命令行五子棋 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2009-11-28 01:48 |只看该作者 |倒序浏览
刚刚起步,可能有些地方还残留着其他语言的痕迹。如果有什么更好的写法请大家不吝赐教。
  1. #!perl

  2. use 5.010;
  3. use strict;
  4. use utf8;
  5. binmode(STDIN, ':encoding(utf8)');
  6. binmode(STDOUT, ':encoding(utf8)');
  7. binmode(STDERR, ':encoding(utf8)');

  8. my $cell=16;
  9. my $cell_char="+";
  10. my $turn = 1;
  11. my (@cells, @line, @rows, $point, $msg);

  12. &init;
  13. while(1) {
  14.     system "cls";
  15.     &printCells;
  16.     if(&checkWin) {
  17.         say "[".(!$turn ? "Black" : "White")."] is win!";
  18.         last;
  19.     }
  20.     say $msg if ($msg);
  21.     $msg = undef;
  22.     say "[".($turn ? "Black" : "White")."] side turn...";
  23.     chomp($point = <STDIN>);
  24.     unless ($point =~ s/([a-p]{2})/\L\1/i) {
  25.         $msg = "Invalid input or out of range. \nPlease enter two character in a-z.";
  26.         redo;
  27.     }
  28.     if (&downChess) {
  29.         $turn = !$turn;
  30.     } else {
  31.         $msg = "Pieces already exist, can not be repeated. \nTry again!";
  32.         redo;
  33.     }
  34. }

  35. #初始化游戏二维数组
  36. sub init {
  37.     for(1..$cell) {
  38.         my @line = split(/ /, "$cell_char " x $cell);
  39.         push @cells, \@line;
  40.     }
  41.     @rows = 'a'..'p';
  42. }

  43. #打印游戏当前棋盘
  44. sub printCells {
  45.     say "  @rows";
  46.     for(0..$cell-1){
  47.         @line = @{$cells[$_]};
  48.         say "$rows[$_] @line";
  49.     }
  50. }

  51. #落子
  52. sub downChess {
  53.     #解析
  54.     my $rowNum = &index(substr $point, 0, 1);
  55.     my $colNum = &index(substr $point, 1, 1);
  56.     #验证
  57.     #return 0 if (!&isInRange($rowNum) or !&isInRange($colNum));
  58.     return 0 unless ($cells[$rowNum]->[$colNum] eq $cell_char);
  59.     #落子
  60.     $cells[$rowNum]->[$colNum] = &turnChar($turn);
  61.     return 1;
  62. }

  63. #当前棋子样式
  64. sub turnChar {
  65.     return $_[0] ? '@' : 'o';
  66. }

  67. sub isInRange {
  68.     return $_[0] >= 0 and $_[0] <= $cell;
  69. }

  70. #传入char,返回与'a'的差
  71. sub index {
  72.     ord($_[0]) - ord('a');
  73. }

  74. #判断是否胜利
  75. sub checkWin {
  76.     return (&checkVerticalWin or &checkTraverseWin or &checkLeftCantWin);
  77. }

  78. #判断纵向胜利
  79. sub checkVerticalWin {
  80.     for my $index (0..$#cells) {
  81.         my $time;
  82.         for my $line (@cells) {
  83.             if(@{$line}[$index] eq &turnChar(!$turn)) {
  84.                 $time++;
  85.             } else {
  86.                 $time = 0;
  87.             }
  88.             if($time == 5) {
  89.                 return 1;
  90.             }
  91.         }
  92.     }
  93.     return 0;
  94. }

  95. #判断横向胜利
  96. sub checkTraverseWin {
  97.     for(@cells) {#0..$#cells) {
  98.         my $time;
  99.         for my $chess (@{$_}) {#$cells[$_]}) {
  100.             if($chess eq &turnChar(!$turn)) {
  101.                 $time++;
  102.             } else {
  103.                 $time = 0;
  104.             }
  105.             #say $time if($time != 0);
  106.             if($time == 5) {
  107.                 return 1;
  108.             }
  109.         }
  110.     }
  111.     return 0;
  112. }

  113. #判断向左倾斜
  114. sub checkLeftCantWin {
  115.     for my $index (0..$#cells) {
  116.         my ($time_right, $time_left, $temp_index);
  117.         $temp_index = $index;
  118.         for my $line (@cells) {
  119.             #左上到右下,上半部分
  120.             if(@{$line}[$temp_index] eq &turnChar(!$turn)) {
  121.                 $time_right++;
  122.             } else {
  123.                 $time_right = 0;
  124.             }
  125.             #右上到左下,上半部分
  126.             if(@{$line}[$#line-$temp_index] eq &turnChar(!$turn)) {
  127.                 $time_left++;
  128.             } else {
  129.                 $time_left = 0;
  130.             }
  131.             $temp_index--;
  132.             #say $time if ($time != 0);
  133.             return 1 if($time_right == 5 or $time_left == 5);
  134.             last if($temp_index < 0);
  135.         }
  136.         $time_right = 0;
  137.         $time_left = 0;
  138.         for my $line(reverse @cells) {
  139.             #左上到右下,下半部分
  140.             if(@{$line}[$#line-$index] eq &turnChar(!$turn)) {
  141.                 $time_right++;
  142.             } else {
  143.                 $time_right = 0;
  144.             }
  145.             #右上到左下,下半部分
  146.             if(@{$line}[$index] eq &turnChar(!$turn)) {
  147.                 $time_left++;
  148.             } else {
  149.                 $time_left = 0;
  150.             }
  151.             $index--;
  152.             #say $time if ($time != 0);
  153.             return 1 if($time_right == 5 or $time_left == 5);
  154.             last if($#line == $index);
  155.         }
  156.     }
  157.     return 0;
  158. }
复制代码

评分

参与人数 1可用积分 +3 收起 理由
兰花仙子 + 3 我很赞同

查看全部评分

论坛徽章:
0
2 [报告]
发表于 2009-11-28 12:49 |只看该作者
请大家帮忙看看,给点意见。看看有什么地方需要改进?

论坛徽章:
0
3 [报告]
发表于 2009-11-28 12:50 |只看该作者
牛X

论坛徽章:
0
4 [报告]
发表于 2009-11-28 15:29 |只看该作者
这就是 5.10 的新语法了吧,记得看过一些介绍的,确实不习惯啊,Perl6似乎也这样子了,不过应该是没有放弃以前的语法吧,考虑是不是得花时间关注下才是~

看了lz的代码了,提个需求:平时的 棋类游戏 很少有敲坐标下子的,一般都是一个光标移到后,空格确认后落子,这样子更人性化一点
不过这个需求会很麻烦就是了,readline 就不行了, readkey 如果要处理 方向键更麻烦,当然 wasd 四个键替代也不错,期待lz的下一个版本~

论坛徽章:
0
5 [报告]
发表于 2009-11-30 01:02 |只看该作者
原帖由 dugu072_cu 于 2009-11-28 15:29 发表
这就是 5.10 的新语法了吧,记得看过一些介绍的,确实不习惯啊,Perl6似乎也这样子了,不过应该是没有放弃以前的语法吧,考虑是不是得花时间关注下才是~

看了lz的代码了,提个需求:平时的 棋类游戏 很少有 ...

感谢您的意见。不过从命令行中获取光标这种事不知道 perl 能否做到?

论坛徽章:
0
6 [报告]
发表于 2009-11-30 08:11 |只看该作者
windows 有 Win32::Console
其他平台 有 Term::ANSIScreen

论坛徽章:
0
7 [报告]
发表于 2009-12-01 16:49 |只看该作者
超级牛x的‘小白菜’呀。。。。

-_-|||

论坛徽章:
0
8 [报告]
发表于 2010-01-25 21:09 |只看该作者
呵呵,有意思的,下了一盘很不错。

论坛徽章:
0
9 [报告]
发表于 2010-01-26 09:13 |只看该作者
赞一个,这哪是初学水平啊。

建议用GUI界面,PERL是能做到的!

论坛徽章:
0
10 [报告]
发表于 2010-01-26 09:30 |只看该作者
同样是新手,差距就这么大呢
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP