LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
查看: 2501|回复: 2

用perl写的一段小游戏(转贴)

[复制链接]
发表于 2003-8-20 11:54:31 | 显示全部楼层 |阅读模式
转自http://www.ilcatperl.org/

  1. #!/usr/bin/perl -w
  2. #!/usr/local/bin/perl -w

  3. use strict;
  4. use diagnostics;
  5. use Tk;
  6. use Tk::Dialog;
  7. use Tk::After;
  8. use Tk::ProgressBar;
  9. #use Tk::Photo;

  10. my $colorAvail = 0;

  11. if (eval "require Tk::ColourChooser") {
  12.   $colorAvail = 1;
  13. }

  14. # Constants
  15. # 排行榜最大值
  16. use constant MAXHIGH       => 11;
  17. # 排行榜里名字的最大长度
  18. use constant NAMECHARSMAX  => 20;
  19. # 排行榜文件路径和名字
  20. use constant HIGHSCOREFILE => "C:\\.cascadixHigh";

  21. # 全局变量
  22. my $rows                  = 8;  # ! 8  means 0 .. 8  = 9  rows   !
  23. my $cols                  = 24; # ! 24 means 0 .. 24 = 25 columns!
  24. my $offset                = 4;
  25. my $colors                = 3;
  26. my $searchMax             = 40;
  27. my @cpreset1              = ( "tomato2", "LightGoldenrod2", "DeepSkyBlue1");
  28. my @cpreset2              = ( "gray10", "gray50", "gray90");
  29. my @cpreset3              = ( "blue", "green", "red");
  30. my @color                 = @cpreset1;
  31. my $sizeOfItems           = 15;
  32. my $distanceBetweenItems  = 5;
  33. my $form                  = 'rectangle';            #'oval';
  34. my $highscorefile         = tilde(HIGHSCOREFILE);
  35. my $points                = 0;
  36. my $undopoints            = 0;
  37. my $i                     = 1;
  38. my $name;
  39. if ($^O =~ m/Win/) {
  40.   $name = "HansWurst";
  41. }
  42. else {
  43.   $name = getpwuid($<);
  44. }
  45. my $delta;
  46. my $gameSizex;
  47. my $gameSizey;
  48. my $markcolor;

  49. # widgets
  50. my $top;
  51. my $highW;
  52. my $canvas;
  53. my $cProgBar0;
  54. my $cProgBar1;
  55. my $cProgBar2;
  56. my $undoB;

  57. my $marked;
  58. my $x;
  59. my $y;
  60. my $n;
  61. my $j;

  62. # 数组的数组:这是包含条目的二维数组
  63. my @lol;
  64. # 为了取消删除@lol的一个拷贝
  65. my @lolcopy;

  66. my @colorlist;
  67. my $nrcolor0;
  68. my $nrcolor1;
  69. my $nrcolor2;
  70. my $cmax;
  71. my $cmin;

  72. # 散列的数组
  73. my @highscore;

  74. # 主程序

  75. fillLol();

  76. mainWin();

  77. readHigh();

  78. paintItems();

  79. $top->MainLoop;

  80. # 子程序

  81. my $rep = 0;
  82. sub fillLol {

  83.   $rep = 0;
  84.   while (1) {
  85.     @lol = ();
  86.     my $color;

  87.     @colorlist = ();
  88.     for (0 .. 2) { $colorlist[$_] = 0; }

  89.     for $x (0 .. $cols) {
  90.       for $y (0 .. $rows) {
  91.         # 选择一个任意颜色
  92.         $color = int(rand 3) + 1;
  93.         # fill the two dimensional array with the color
  94.         $lol[$x][$y] = $color;
  95.         # increase the counter for this color
  96.         $colorlist[$color - 1]++;
  97.       }
  98.     }

  99.     $cmin = 20;
  100.     $cmax = 60;

  101.     # number of blocks
  102.     my $blocks = ($cols + 1)*($rows + 1);

  103.     # round and calculate the percentage of the colors
  104.     $nrcolor0 = sprintf "%.0f", $colorlist[0]/$blocks*100;
  105.     $nrcolor1 = sprintf "%.0f", $colorlist[1]/$blocks*100;
  106.     $nrcolor2 = sprintf "%.0f", $colorlist[2]/$blocks*100;

  107.     # exit loop when a criteria is met
  108.     last if ($nrcolor0 >= $searchMax or
  109.              $nrcolor1 >= $searchMax or
  110.              $nrcolor2 >= $searchMax or
  111.              $rep >= 1000);

  112.     $rep++;
  113.   }
  114.   #print "searched $rep times\n";
  115. }

  116. # sub printlol {
  117. #   my $text = shift;
  118. #   my $listRef = shift;
  119. #   print "$rows $cols $text ------------------------\n";
  120. #   for ($x = $rows; $x >= 0; $x--) {
  121. #     for $y ( 0 .. $cols) {
  122. #       if ( $$listRef[$y][$x] ) {
  123. #         if ( $$listRef[$y][$x] == $markcolor) {
  124. #           print "* ";
  125. #         } else {
  126. #           print $$listRef[$y][$x]," ";
  127. #         }
  128. #       } else {
  129. #         print "- ";
  130. #       }
  131. #     }
  132. #     print "\n";
  133. #   }
  134. #   print "------------------------\n";
  135. # }

  136. # sub printcolor {

  137. #   print "------------------------\n";
  138. #   for ($x = 0; $x <= 2; $x++) {
  139. #     print "$x $color[$x] $colorlist[$x]\n";
  140. #   }
  141. #   print "------------------------\n";
  142. # }

  143. sub markIt {
  144.   my $x     = shift;
  145.   my $y     = shift;
  146.   my $color = shift;

  147.   # mark this item with the markcolor
  148.   $lol[$x][$y] = $markcolor;
  149.   # count the marked items
  150.   $marked++;

  151.   plopItem($x, $y);

  152.   # look top
  153.   if ($y < $rows) {
  154.     if ($lol[$x][$y+1]) {
  155.       if ($lol[$x][$y+1] == $color) {
  156.         markIt($x, $y+1, $color);
  157.       }
  158.     }
  159.   }
  160.   # look right
  161.   if ($x < $cols) {
  162.     if ($lol[$x+1][$y]) {
  163.       if ($lol[$x+1][$y] == $color) {
  164.         markIt($x+1, $y, $color);
  165.       }
  166.     }
  167.   }
  168.   # look down
  169.   if ($y > 0) {
  170.     if ($lol[$x][$y-1]) {
  171.       if ($lol[$x][$y-1] == $color) {
  172.         markIt($x, $y-1, $color);
  173.       }
  174.     }
  175.   }
  176.   # look left
  177.   if ($x > 0) {
  178.     if ($lol[$x-1][$y]) {
  179.       if ($lol[$x-1][$y] == $color) {
  180.         markIt($x-1, $y, $color);
  181.       }
  182.     }
  183.   }

  184. }

  185. sub removeMarked {

  186.   my $i;
  187.   my $j;
  188.   my $aref;

  189.   # from left to right
  190.   for $i ( 0 .. $cols) {
  191.     # and top down
  192.     for ($j = $rows; $j >= 0; $j-- ) {
  193.       if ($lol[$i][$j]) {        # if element exists
  194.         if ($lol[$i][$j] == $markcolor) { # and its marked
  195.           splice @{ $lol[$i] }, $j, 1; # cut it out
  196.         }
  197.       }
  198.     }
  199.   }

  200.   # from right to left
  201.   for ($i = $cols; $i >= 0; $i--) {
  202.     my @array = @{ $lol[$i] };    # @array is a colunm of @lol
  203.     my $sum = 0;
  204.     foreach (@array) {
  205.       $sum += $_ if (defined($_));
  206.     }                            # buid the sum of all elements in col $i
  207.     if ($sum <= 0) {            # if this col is empty
  208.       splice @lol, $i, 1;        # cut it out of @lol
  209.     }
  210.   }
  211. }

  212. sub paintItems {

  213.   my ($x, $y, $col, $id);
  214.   removeMarked();
  215.   $canvas->delete('all');
  216.   for $x (0 .. $cols) {
  217.     for $y (0 .. $rows) {
  218.       if ($lol[$x][$y]) {
  219.         if ($lol[$x][$y] > 0) {
  220.           my $col = $color[$lol[$x][$y]-1];
  221.           #my $tag = "item-$x-$y";
  222.           my $id = $canvas->create($form,
  223.                                    ($x*$delta + $offset),
  224.                                    ($gameSizey - ($y*$delta)),
  225.                                    ($x*$delta + $sizeOfItems + $offset),
  226.                                    ($gameSizey - ($y*$delta + $sizeOfItems)),
  227.                                    -fill => $col,
  228.                                   );

  229.           $canvas->bind($id,'<Button-1>',
  230.                         sub {
  231.                           my $i;
  232.                           my @coor = $canvas->coords($id);
  233.                           my $indexx = int($coor[0]/$delta);
  234.                           my $indexy = $rows - int($coor[1]/$delta);
  235.                           $marked = 0;

  236.                           # remember the color
  237.                           my $color = $lol[$indexx][$indexy];

  238.                           # remember the array for undo action
  239.                           copyArray(\@lol, \@lolcopy);
  240.                           $undoB->configure(-state => "normal");
  241.                           markIt($indexx, $indexy, $color);
  242.                           # if just found one, give him the color back and redraw all items
  243.                           if ($marked <= 1) {
  244.                             $lol[$indexx][$indexy] = $color;
  245.                             paintItems();
  246.                             return;
  247.                           }
  248.                           my $newPoints = 0;
  249.                           for ($i = 1; $i <= $marked; $i++) {
  250.                             $newPoints = $newPoints + $i;
  251.                           }
  252.                           $points = $points + $newPoints;
  253.                           # remember the additional point for a undo move
  254.                           $undopoints = $newPoints;
  255.                           #removeMarked();
  256.                           paintItems();
  257.                           if (reachedEnd()) {
  258.                             eog();
  259.                           }
  260.                         });
  261.         }
  262.       }
  263.     }
  264.   }

  265. }

  266. sub reachedEnd {

  267.   my ($x, $y, $found);

  268.   if (!$lol[0][0]) {
  269.     # cleaned everything up!
  270.     my $dialog =
  271.       $top->Dialog(-title => "Bonus",
  272.                    -text => "太棒了!\n你清理干净了所有的目标!\n 奖励 500 点!",
  273.                    -buttons => ["OK"]);
  274.     $dialog->Show();
  275.     $points = $points + 500;
  276.     return 1;
  277.   }

  278.   $found = 0;
  279.   for $x (0 .. $cols) {
  280.     for $y (0 .. $rows) {
  281.       if ($lol[$x][$y]) {
  282.         if ($lol[$x][$y] > 0 && $lol[$x][$y] < $markcolor) {
  283.           if (countIt($x, $y, $lol[$x][$y])) {
  284.             $found++;
  285.             last;
  286.           }
  287.         }
  288.       } else {
  289.         # we are searching bottom-up,
  290.         # if there is nothing here there can`t be anything
  291.         # in the higher positions
  292.         #print "... is empty\n";
  293.         last;
  294.       }
  295.       last if ($found > 0);
  296.     }
  297.     last if ($found > 0);
  298.   }

  299.   if ($found == 0) {
  300.     return 1;
  301.   } else {
  302.     return 0;
  303.   }
  304. }

  305. sub countIt {
  306.   my $x     = shift;
  307.   my $y     = shift;
  308.   my $color = shift;

  309.   # look top
  310.   if ($y < $rows) {
  311.     if ($lol[$x][$y+1]) {
  312.       if ($lol[$x][$y+1] == $color) {
  313.         return 1;
  314.       }
  315.     }
  316.   }
  317.   # look right
  318.   if ($x < $cols) {
  319.     if ($lol[$x+1][$y]) {
  320.       if ($lol[$x+1][$y] == $color) {
  321.         return 1;
  322.       }
  323.     }
  324.   }
  325.   # look down
  326.   if ($y > 0) {
  327.     if ($lol[$x][$y-1]) {
  328.       if ($lol[$x][$y-1] == $color) {
  329.         return 1;
  330.       }
  331.     }
  332.   }
  333.   # look left
  334.   if ($x > 0) {
  335.     if ($lol[$x-1][$y]) {
  336.       if ($lol[$x-1][$y] == $color) {
  337.         return 1;
  338.       }
  339.     }
  340.   }
  341.   return 0;
  342. }

  343. sub resetHigh {

  344.   my $i;

  345.   # reset highscore
  346.   @highscore = ();

  347.   # fill with default values
  348.   for ($i = 0; $i < MAXHIGH; $i++) {
  349.     my$rec = {};
  350.     my $name = "John Doe";
  351.     my $points = 0;
  352.     $rec->{"name"} = $name;
  353.     $rec->{"points"} = $points;
  354.     push @highscore, $rec;
  355.   }

  356.   showHigh();
  357. }

  358. # sub printHigh {

  359. #   my $i;
  360. #   foreach (@highscore) {
  361. #     $i++;
  362. #     if ($_->{'name'}) {
  363. #       print "$i ".$_->{'name'}." ".$_->{'points'}."\n";
  364. #     }
  365. #   }

  366. # }

  367. sub showHigh {

  368.   my $select = shift;
  369.   $select = $select + 3 if $select;
  370.   my $i;

  371.   if (Exists($highW)) {
  372.     $highW->withdraw();
  373.   }

  374.   # open window
  375.   $highW = $top->Toplevel();

  376.   $highW->title("Cascadix 排行榜");

  377.   my $highlist =
  378.     $highW->Scrolled("Listbox",
  379.                      -scrollbars => 'osoe',
  380.                      -selectmode => 'single',
  381.                      -width => 36,
  382.                      -height => 15)->pack(-expand => 1,
  383.                                           -fill =>'both',
  384.                                           -padx => 3,
  385.                                           -pady => 3);

  386.   my $OKB =
  387.     $highW->Button(-text => "确定",
  388.                    -command => sub {
  389.                      $highW->withdraw();
  390.                      return;
  391.                    })->pack(-side => 'top',
  392.                             -fill => 'x',
  393.                             -padx => 3,
  394.                             -pady => 3);

  395.   $OKB->bind('<Return>',
  396.              sub {
  397.                $OKB->invoke;
  398.              }
  399.             );

  400.   $highlist->insert('end', "");
  401.   $highlist->insert('end', "排名     名字                点数");
  402.   $highlist->insert('end', "");

  403.   foreach (@highscore) {
  404.     $i++;
  405.     if ($_->{'name'}) {
  406.       # the * is the placeholder for NAMECHARSMAX
  407.       my $line = sprintf " %3d. %-*s %6d", $i, NAMECHARSMAX, $_->{'name'}, $_->{'points'};
  408.       $highlist->insert('end', $line);
  409.     }
  410.   }

  411.   if ($select) {
  412.     $highlist->selectionSet($select);
  413.     $highlist->see(0);
  414.     $highlist->see($select);
  415.   }

  416.   $highW->waitWindow;

  417. }

  418. sub eog {

  419.   # cut list to maxHigh
  420.   splice @highscore, (MAXHIGH - 1);

  421.   my $i = 0;
  422.   my $inHigh = 0;

  423.   foreach (@highscore) {
  424.     if ($points > $_->{'points'}) {
  425.       $inHigh = 1;
  426.       last;
  427.     }
  428.     $i++;
  429.   }

  430.   if ($inHigh or ($i < MAXHIGH)) {
  431.     insertPlayer($i);
  432.   } else {
  433.     my $dialog =
  434.       $top->Dialog(-title => "EOG: 游戏结束",
  435.                    -text => "游戏结束\n$points 点.\n  这个成绩太差劲了.",
  436.                    -buttons => ["再来一次!"]);
  437.     $dialog->Show();
  438.   }

  439.   saveHigh();
  440.   showHigh($i-1);
  441. }


  442. sub    insertPlayer {

  443.   my $i =shift;

  444.   my $rc = getName($i+1);
  445.   if ($rc eq "OK") {
  446.     checkName(\$name);
  447.     # cut off the second part and store it in highscoreTmp
  448.     my @highscoreTmp = splice @highscore, $i;

  449.     # insert a new DS
  450.     my $rec = {};                # record zuruecksetzten
  451.     $rec->{'name'} = $name;
  452.     $rec->{'points'} = $points;
  453.     push @highscore, $rec;

  454.     # add the highscoreTmp to highscore
  455.     push @highscore, @highscoreTmp;
  456.   }
  457. }

  458. sub readHigh {

  459.   my ($field, $key, $value);

  460.   if (! -f $highscorefile) {
  461.     warn "readHigh: $highscorefile not found";
  462.     resetHigh();
  463.     #saveHigh();
  464.     return;
  465.   }

  466.   if (!open(DATEI, "<$highscorefile")) {
  467.     warn "readHigh: Can't open $highscorefile: $!\n";
  468.     resetHigh();
  469.     return;
  470.   }

  471.   # reset highscore list
  472.   @highscore = ();

  473. LINE: while (<DATEI>) {
  474.     next LINE if /^$/;            # Leerzeilen ueberspringen
  475.     next LINE if /^#/;           # Kommentarzeilen ueberspringen
  476.     my $rec;                    # record zuruecksetzten
  477.     chomp;                        # removes the newlines from $_
  478.   FIELD: for $field ( split /,/) {
  479.       ($key, $value) = split /=/, $field; # key und value trennen (=-Zeichen)

  480.       if ($rec->{$key}) {
  481.         warn "$highscorefile Zeile: $.: Der key ($key) ist mehrfach vorhanden!";
  482.       }
  483.       $rec->{$key} = $value;
  484.     }

  485.     push @highscore, $rec;
  486.   }

  487.   close(DATEI);

  488. }

  489. sub saveHigh {

  490.   if (!open(SAVEFILE, ">$highscorefile")) {
  491.     warn "Can't open $highscorefile for write: $!\n";
  492.     return 0;
  493.   }

  494.   #my $i;
  495.   foreach ( @highscore ) {
  496.     for my $key ( sort keys %{ $_ } ) {
  497.       print SAVEFILE "$key=$_->{$key},";
  498.     }
  499.     # Zeilenumbruch am Ende eines Datensatzes
  500.     print SAVEFILE "\n";
  501.   }

  502.   if (!close(SAVEFILE)) {
  503.     warn "error closing $highscorefile: $!\n";
  504.     return 0;
  505.   }
  506.   return 1;
  507. }

  508. sub getName {

  509.   my $p = shift;
  510.   my $rc;

  511.   # open window
  512.   my $myDiag = $top->Toplevel();
  513.   $myDiag->title("Game over");

  514.   $myDiag->Label(-text => "你获得了 $points 点.\n恭喜你!\n你在排行榜里排名第 $p !\n请输入你的名字:",
  515.                 )->pack(-side => 'top',
  516.                         -fill => 'x',
  517.                         -padx => 3,
  518.                         -pady => 3);

  519.   my $entry =
  520.     $myDiag->Entry(-textvariable => \$name,
  521.                    -width => 80,
  522.                   )->pack(-side => 'top',
  523.                           -fill => 'x',
  524.                           -padx => 3,
  525.                           -pady => 3);


  526.   my $ButF =
  527.     $myDiag->Frame()->pack(-fill =>'x',
  528.                            -padx => 3,
  529.                            -pady => 3);

  530.   my $OKB =
  531.     $ButF->Button(-text => "确定",
  532.                   -command => sub {
  533.                     $rc = "OK";
  534.                     $myDiag->destroy();
  535.                     return "OK";
  536.                   })->pack(-side => 'left',
  537.                            -expand => 1,
  538.                            -fill => 'x',
  539.                            -padx => 3,
  540.                            -pady => 3);

  541.   $entry->bind('<Return>',
  542.                sub {
  543.                  $OKB->invoke;
  544.                }
  545.               );

  546.   $ButF->Button(-text => "取消",
  547.                 -command => sub {
  548.                   $rc = "Cancel";
  549.                   $myDiag->destroy();
  550.                   return "Cancel";
  551.                 }
  552.                )->pack(-side => 'left',
  553.                        -expand => 1,
  554.                        -fill => 'x',
  555.                        -padx => 3,
  556.                        -pady => 3);

  557.   $myDiag->waitWindow;
  558.   return $rc;

  559. }

  560. ##############################################################
  561. #
  562. # tilde
  563. #
  564. ##############################################################

  565. sub tilde {

  566.   my $name = shift;

  567.   return $name if ($^O =~ m/Win/);
  568.   $name =~ s{ ^ ~ ( [^/]* ) }
  569.     { $1
  570.         ? (getpwnam($1))[7]
  571.           : ( $ENV{HOME} || $ENV{LOGDIR}
  572.               || (getpwuid($<))[7]
  573.             )
  574.         }ex;

  575.   return $name;
  576. }

  577. sub display {

  578.   my $distcopy   = $distanceBetweenItems;
  579.   my $distcancel = $distanceBetweenItems;
  580.   my $sizecopy   = $sizeOfItems;
  581.   my $sizecancel = $sizeOfItems;
  582.   my $formcopy   = $form;
  583.   my $formcancel = $form;

  584.   # open window
  585.   my $displayW = $top->Toplevel();
  586.   $displayW->title("显示选项");

  587.   $displayW->Label(-text => "目标尺寸",
  588.                   )->pack(-fill => 'x');

  589.   $displayW->Scale(-variable => \$sizecopy,
  590.                    -orient => 'horizontal',
  591.                    -from => 5,
  592.                    -to => 40,
  593.                    -relief => 'raised'
  594.                   )->pack(-fill   =>'x',
  595.                           -expand => 1);

  596.   $displayW->Label(-text => "目标间距",
  597.                   )->pack(-fill => 'x');

  598.   $displayW->Scale(-variable => \$distcopy,
  599.                    -orient => 'horizontal',
  600.                    -from => 1,
  601.                    -to => 10,
  602.                    -relief => 'raised'
  603.                   )->pack(-fill   =>'x',
  604.                           -expand => 1);

  605.   $displayW->Label(-text => "目标形状",
  606.                   )->pack(-fill => 'x');

  607.   $displayW->Radiobutton(-text => "圆形",
  608.                          -variable => \$formcopy,
  609.                          -value => "oval")->pack(-fill =>'x');
  610.   $displayW->Radiobutton(-text => "矩形",
  611.                          -variable => \$formcopy,
  612.                          -value => "rectangle")->pack(-fill =>'x');


  613.   my $butF =
  614.     $displayW->Frame(-relief => 'raised',
  615.                      -borderwidth => 2)->pack(-side => 'left',
  616.                                               -fill => 'x');

  617.   $butF->Button(-text => "确定",
  618.                 -command => sub {
  619.                   $distanceBetweenItems = $distcopy;
  620.                   $form = $formcopy;
  621.                   $sizeOfItems = $sizecopy;
  622.                   mainWin();
  623.                   paintItems();
  624.                   $displayW->withdraw();
  625.                 }
  626.                )->pack(-side=>'left',
  627.                        -fill =>'both');

  628.   $butF->Button(-text => "应用",
  629.                 -command => sub {
  630.                   $distanceBetweenItems = $distcopy;
  631.                   $sizeOfItems = $sizecopy;
  632.                   $form = $formcopy;
  633.                   mainWin();
  634.                   paintItems();
  635.                 }
  636.                )->pack(-side=>'left',
  637.                        -fill =>'both');

  638.   $butF->Button(-text => "取消",
  639.                 -command => sub {
  640.                   $distanceBetweenItems = $distcancel;
  641.                   $sizeOfItems = $sizecancel;
  642.                   $form = $formcancel;
  643.                   mainWin();
  644.                   paintItems();
  645.                   $displayW->withdraw();
  646.                 }
  647.                )->pack(-side=>'right',
  648.                        -fill =>'both');
  649. }

  650. sub gameSize {

  651.   my $rowscopy   = $rows + 1;
  652.   my $colscopy   = $cols + 1;
  653.   my $rowscancel = $rows;
  654.   my $colscancel = $cols;

  655.   # open window
  656.   my $gameSizeW = $top->Toplevel();
  657.   $gameSizeW->title("游戏尺寸");

  658.   $gameSizeW->Label(-text => "行数:",
  659.                    )->pack(-fill => 'x');

  660.   $gameSizeW->Scale(-variable => \$rowscopy,
  661.                     -orient => 'horizontal',
  662.                     -from => 3,
  663.                     -to => 9,
  664.                     -relief => 'raised'
  665.                    )->pack(-fill   =>'x',
  666.                            -expand => 1);

  667.   $gameSizeW->Label(-text => "列数:",
  668.                    )->pack(-fill => 'x');

  669.   $gameSizeW->Scale(-variable => \$colscopy,
  670.                     -orient => 'horizontal',
  671.                     -from => 3,
  672.                     -to => 25,
  673.                     -relief => 'raised'
  674.                    )->pack(-fill   =>'x',
  675.                            -expand => 1);

  676.   my $butF =
  677.     $gameSizeW->Frame(-relief => 'raised',
  678.                       -borderwidth => 2)->pack(-side => 'left',
  679.                                                -fill => 'x');

  680.   $butF->Button(-text => "确定",
  681.                 -command => sub {
  682.                   if ($rows != ($rowscopy - 1) or $cols != ($colscopy - 1)) {
  683.                     $rows = $rowscopy - 1;
  684.                     $cols = $colscopy - 1;
  685.                     fillLol();
  686.                     $points = 0;
  687.                     mainWin();
  688.                     paintItems();
  689.                   }
  690.                   $gameSizeW->withdraw();
  691.                 }
  692.                )->pack(-side=>'left',
  693.                        -fill =>'both');

  694.   $butF->Button(-text => "应用",
  695.                 -command => sub {
  696.                   if ($rows != ($rowscopy - 1) or $cols != ($colscopy - 1)) {
  697.                     $rows = $rowscopy - 1;
  698.                     $cols = $colscopy - 1;
  699.                     fillLol();
  700.                     $points = 0;
  701.                     mainWin();
  702.                     paintItems();
  703.                   }
  704.                 }
  705.                )->pack(-side=>'left',
  706.                        -fill =>'both');

  707.   $butF->Button(-text => "取消",
  708.                 -command => sub {
  709.                   if ($rows != $rowscancel or $cols != $colscancel) {
  710.                     $rows = $rowscancel;
  711.                     $cols = $colscancel;
  712.                     fillLol();
  713.                     $points = 0;
  714.                     mainWin();
  715.                     paintItems();
  716.                   }
  717.                   $gameSizeW->withdraw();
  718.                 }
  719.                )->pack(-side=>'right',
  720.                        -fill =>'both');
  721. }


  722. sub mainWin {

  723.   $delta = $sizeOfItems + $distanceBetweenItems;
  724.   $gameSizex = ($cols + 1) * ($delta);
  725.   $gameSizey = ($rows +1) * ($delta);
  726.   $markcolor = $colors + 1;

  727.   if (Exists($top)) {
  728.     $top->withdraw();
  729.   }

  730.   my @cascadixRCSVersion = split / /, '$Revision: 1.4 $';
  731.   my $cascadixVersion = "0.".$cascadixRCSVersion[1];

  732.   $top = MainWindow->new;
  733.   $top->title("Cascadix $cascadixVersion");

  734.   # create the menu
  735.   my $menu = $top->Frame(-relief => 'raised',
  736.                          -borderwidth => 2)->pack(-fill => 'x');

  737.   $menu->Menubutton(-text => "选项",
  738.                     -menuitems => [
  739.                                    [ 'command' => "显示设置",
  740.                                      -command => \&display ],
  741.                                    [ 'command' => "游戏尺寸",
  742.                                      -command => \&gameSize ],
  743.                                    [ 'command' => "颜色设置",
  744.                                      -command => \&color ],
  745.                                   ]
  746.                    )->pack(-side => 'left');

  747.   my $gameF = $top->Frame(-relief => 'raised',
  748.                           -borderwidth => 2)->pack(-side => 'left',
  749.                                                    -fill => 'x');
  750.   my $butF = $top->Frame(-relief => 'raised',
  751.                          -borderwidth => 2)->pack(-side => 'right',
  752.                                                   -fill => 'both');

  753.   # point
  754.   $butF->Label(-textvariable => \$points,
  755.               )->pack(-side => 'top',
  756.                       -fill => 'both');

  757.   $canvas = $gameF->Canvas(-width => $gameSizex,
  758.                            -height => $gameSizey,
  759.                            -relief => 'sunken',
  760.                            -bd =>2)->pack(-side=>'top',
  761.                                           -fill =>'both');;

  762.   my $newGame =
  763.     $butF->Button(-text => "新游戏",
  764.                   -command => sub {
  765.                     if (Exists($highW)) {
  766.                       $highW->withdraw();
  767.                     }
  768.                     $canvas->delete('all');
  769.                     fillLol();
  770.                     $points = 0;
  771.                     paintItems();
  772.                     $undoB->configure(-state => "disabled");
  773.                   }
  774.                  )->pack(-side=>'top',
  775.                          -fill =>'both');

  776.   $newGame->bind('<Return>',
  777.                  sub {
  778.                    $newGame->invoke;
  779.                  }
  780.                 );

  781.   $undoB =
  782.     $butF->Button(-text => "撤消",
  783.                   -state => "disabled",
  784.                   -command => sub {
  785.                     copyArray(\@lolcopy, \@lol);
  786.                     paintItems();
  787.                     $points -= $undopoints;
  788.                     $undoB->configure(-state => "disabled");
  789.                   }
  790.                  )->pack(-side=>'top',
  791.                          -fill =>'both');


  792.   $butF->Button(-text => "排行榜",
  793.                 -command => sub {
  794.                   showHigh();
  795.                 }
  796.                )->pack(-side=>'top',
  797.                        -fill =>'both');

  798.   # quit button
  799.   $butF->Button(-text => "退出",
  800.                 -command => sub {
  801.                   exit;
  802.                 }
  803.                )->pack(-side=>'top',
  804.                        -fill =>'both');

  805.   my $cF0 = $butF->Frame(-relief => 'raised',
  806.                          -borderwidth => 2)->pack(-side => 'top',
  807.                                                   -fill => 'x');
  808.   $cProgBar0 =
  809.     $cF0->ProgressBar(
  810.                       -borderwidth => 1,
  811.                       -relief => 'sunken',
  812.                       -width => 9,
  813.                       -length => 70,
  814.                       -padx => 1,
  815.                       -pady => 1,
  816.                       -variable => \$nrcolor0,
  817.                       -colors => [0 => $color[0]],
  818.                       -troughcolor => 'grey80',
  819.                       -resolution => 1,
  820.                       -blocks => 1,
  821.                       -anchor => 'n',
  822.                       -from => $cmin,
  823.                       -to => $cmax
  824.                      )->pack(-side => 'left',
  825.                              -fill => 'x',
  826.                              -padx => 3,
  827.                              -pady => 0);

  828.   $cF0->Label(-text => "%")->pack(-side => 'right', -fill => 'both');
  829.   $cF0->Label(-textvariable => \$nrcolor0,
  830.              )->pack(-side => 'right',
  831.                      -fill => 'both');

  832.   my $cF1 = $butF->Frame(-relief => 'raised',
  833.                          -borderwidth => 2)->pack(-side => 'top',
  834.                                                   -fill => 'x');
  835.   $cProgBar1 =
  836.     $cF1->ProgressBar(
  837.                       -borderwidth => 1,
  838.                       -relief => 'sunken',
  839.                       -width => 9,
  840.                       -length => 70,
  841.                       -padx => 1,
  842.                       -pady => 1,
  843.                       -variable => \$nrcolor1,
  844.                       -colors => [0 => $color[1]],
  845.                       -troughcolor => 'grey80',
  846.                       -resolution => 1,
  847.                       -blocks => 1,
  848.                       -anchor => 'n',
  849.                       -from => $cmin,
  850.                       -to => $cmax
  851.                      )->pack(-side => 'left',
  852.                              -fill => 'x',
  853.                              -padx => 3,
  854.                              -pady => 0);

  855.   $cF1->Label(-text => "%")->pack(-side => 'right', -fill => 'both');
  856.   $cF1->Label(-textvariable => \$nrcolor1,
  857.              )->pack(-side => 'right',
  858.                      -fill => 'both');

  859.   my $cF2 = $butF->Frame(-relief => 'raised',
  860.                          -borderwidth => 2)->pack(-side => 'top',
  861.                                                   -fill => 'x');
  862.   $cProgBar2 =
  863.     $cF2->ProgressBar(
  864.                       -borderwidth => 1,
  865.                       -relief => 'sunken',
  866.                       -width => 9,
  867.                       -length => 70,
  868.                       -padx => 1,
  869.                       -pady => 1,
  870.                       -variable => \$nrcolor2,
  871.                       -colors => [0 => $color[2]],
  872.                       -troughcolor => 'grey80',
  873.                       -resolution => 1,
  874.                       -blocks => 1,
  875.                       -anchor => 'n',
  876.                       -from => $cmin,
  877.                       -to => $cmax
  878.                      )->pack(-side => 'left',
  879.                              -fill => 'x',
  880.                              -padx => 3,
  881.                              -pady => 0);

  882.   $cF2->Label(-text => "%")->pack(-side => 'right', -fill => 'both');
  883.   $cF2->Label(-textvariable => \$nrcolor2,
  884.              )->pack(-side => 'right',
  885.                      -fill => 'both');


  886. }

  887. sub color {

  888.   my @colorcopy = @color;
  889.   my @colorcancel = @color;

  890.   my @cbut;

  891.   # 打开窗口
  892.   my $colorW = $top->Toplevel();
  893.   $colorW->title("游戏尺寸");

  894.   if ($colorAvail) {
  895.     $colorW->Label(-text => "颜色",
  896.                   )->pack(-fill => 'x');

  897.     my $cbutF =
  898.       $colorW->Frame(-relief => 'raised',
  899.                      -borderwidth => 2)->pack(-fill => 'x');

  900.     my $activec;
  901.     my $i = 0;

  902.     foreach $activec (@colorcopy) {

  903.       $cbut[$i] =
  904.         $cbutF->Button(-text => $activec,
  905.                        -background => $activec,
  906.                        -command => sub {
  907.                          my $colorD =
  908.                            $top->ColourChooser(-colour => $activec);
  909.                          my $col = $colorD->Show;
  910.                          $activec = $col if ($col);
  911.                          for (my $j = 0; $j <= $#colorcopy; $j++) {
  912.                            $cbut[$j]->configure(-text => $colorcopy[$j]);
  913.                            $cbut[$j]->configure(-background => $colorcopy[$j]);
  914.                          }
  915.                        }
  916.                       )->pack(-side => 'left');
  917.       $i++;
  918.     }
  919.   } else {
  920.     $colorW->Label(-text => "对不起, 模块Tk::ColourChooser 不可用!",
  921.                   )->pack(-fill => 'x');
  922.   }

  923.   $colorW->Label(-text => "预设颜色",
  924.                 )->pack(-fill => 'x');

  925.   my $csbutF =
  926.     $colorW->Frame(-relief => 'raised',
  927.                    -borderwidth => 2)->pack(-fill => 'x');

  928.   $csbutF->Button(-text => "预设颜色1",
  929.                   -background => $cpreset1[0],
  930.                   -command => sub {
  931.                     @colorcopy = @cpreset1;
  932.                     my $i = 0;
  933.                     foreach (@cbut) {
  934.                       $_->configure(-background => $colorcopy[$i]);
  935.                       $_->configure(-text => $colorcopy[$i]);
  936.                       $i++;
  937.                     }
  938.                   }
  939.                  )->pack(-side=>'left',
  940.                          -expand => 1,
  941.                          -fill =>'both');

  942.   $csbutF->Button(-text => "预设颜色2",
  943.                   -background => $cpreset2[0],
  944.                   -command => sub {
  945.                     @colorcopy = @cpreset2;
  946.                     my $i = 0;
  947.                     foreach (@cbut) {
  948.                       $_->configure(-background => $colorcopy[$i]);
  949.                       $_->configure(-text => $colorcopy[$i]);
  950.                       $i++;
  951.                     }
  952.                   }
  953.                  )->pack(-side=>'left',
  954.                          -expand => 1,
  955.                          -fill =>'both');

  956.   $csbutF->Button(-text => "预设颜色3",
  957.                   -background => $cpreset3[0],
  958.                   -command => sub {
  959.                     @colorcopy = @cpreset3;
  960.                     my $i = 0;
  961.                     foreach (@cbut) {
  962.                       $_->configure(-background => $colorcopy[$i]);
  963.                       $_->configure(-text => $colorcopy[$i]);
  964.                       $i++;
  965.                     }
  966.                   }
  967.                  )->pack(-side=>'left',
  968.                          -expand => 1,
  969.                          -fill =>'both');

  970.   my $butF =
  971.     $colorW->Frame(-relief => 'raised',
  972.                    -borderwidth => 2)->pack(-fill => 'x');

  973.   $butF->Button(-text => "确定",
  974.                 -command => sub {
  975.                   @color = @colorcopy;
  976.                   paintItems();
  977.                   $colorW->withdraw();
  978.                 }
  979.                )->pack(-side=>'left',
  980.                        -expand => 1,
  981.                        -fill =>'both');

  982.   $butF->Button(-text => "应用",
  983.                 -command => sub {
  984.                   @color = @colorcopy;
  985.                   paintItems();
  986.                 }
  987.                )->pack(-side=>'left',
  988.                        -fill =>'both');

  989.   $butF->Button(-text => "取消",
  990.                 -command => sub {
  991.                   @color = @colorcancel;
  992.                   paintItems();
  993.                   $colorW->withdraw();
  994.                 }
  995.                )->pack(-side=>'right',
  996.                        -fill =>'both');

  997. }

  998. sub plopItem {

  999.     my $x = shift;
  1000.     my $y = shift;

  1001.     if ($lol[$x][$y] != $markcolor) {
  1002.       warn "plopItem: $x $y is not $markcolor!";
  1003.       return;
  1004.     }

  1005.     my $bgc = $canvas->cget(-background);

  1006.     my $item = $canvas->find('closest', ($x*$delta + $offset), ($gameSizey - ($y*$delta)));
  1007.     $canvas->delete($item);

  1008.     createDelete($x, $y, ($sizeOfItems+8), ($offset-4), "red");
  1009.     createDelete($x, $y, ($sizeOfItems-4), ($offset+2), "blue");
  1010.     return;

  1011.   }

  1012. sub createDelete {

  1013.   my $x = shift;
  1014.   my $y = shift;
  1015.   my $sizeOfItems = shift;
  1016.   my $offset = shift;
  1017.   my $color = shift;

  1018.   my $id = $canvas->create($form,
  1019.                            ($x*$delta + $offset),
  1020.                            ($gameSizey - ($y*$delta)),
  1021.                            ($x*$delta + $sizeOfItems + $offset),
  1022.                            ($gameSizey - ($y*$delta + $sizeOfItems)),
  1023.                            -fill => $color,
  1024.                           );
  1025.   $top->update();
  1026.   $top->after(3);
  1027.   $canvas->delete($id);
  1028.   $top->update();
  1029.   $top->after(3);

  1030. }


  1031. sub copyArray {

  1032.   my $arrayARef = shift;
  1033.   my $arrayBRef = shift;
  1034.   my $x;
  1035.   my $y;
  1036.   for $x (0 .. $cols) {
  1037.     for $y (0 .. $rows) {
  1038.       $$arrayBRef[$x][$y] = $$arrayARef[$x][$y];
  1039.     }
  1040.   }
  1041. }

  1042. sub checkName {
  1043.   my $nameR = shift;

  1044.   if (!$$nameR or $$nameR eq "") {
  1045.     $$nameR = "A. Nonym";
  1046.   }
  1047.   # cut to max length if necessary
  1048.   if (length($$nameR) > NAMECHARSMAX) {
  1049.     $$nameR = substr($$nameR,0,NAMECHARSMAX);
  1050.   }

  1051.   # replace , by ;
  1052.   $$nameR =~ s/,/;/;
  1053. }

复制代码


大家可以下下去玩玩,很有意思的。不过需要tk的支持。
发表于 2003-8-20 15:47:29 | 显示全部楼层
我不太懂perl,但也感兴趣,下载,帮忙顶一下
下次要改成C的哦;)
 楼主| 发表于 2003-8-20 15:48:58 | 显示全部楼层
为什么要改成C的呢?
呵呵,程序设计没有说一定要用C呀。
在很多方面C开发效率比不上其它的。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表