Advertisement
Sabriel

Reversi

Nov 5th, 2012
357
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Perl 9.24 KB | None | 0 0
  1. use Tk;
  2. use strict;
  3. use warnings;
  4. use utf8;
  5.  
  6. my $mw        = MainWindow->new;
  7. my $main_menu = $mw->Menu();
  8. $mw->bind(
  9.     '<Tab>',
  10.     sub {
  11.         $mw->after( 1, sub { $mw->focus } );
  12.     }
  13. );
  14.  
  15. $mw->configure( -menu => $main_menu );
  16.  
  17. my $btn = $main_menu->Menubutton(
  18.     -text      => "File",
  19.     -underline => 0,
  20.     -tearoff   => 0
  21. );
  22. $btn->command(
  23.     -label            => "New Game",
  24.     -activebackground => "orange",
  25.     -foreground       => "green",
  26.     -command          => [ \&start ]
  27. );
  28.  
  29. $btn->command(
  30.     -label            => "Away",
  31.     -activebackground => "red",
  32.     -activeforeground => "black",
  33.     -background       => "blue",
  34.     -foreground       => "white",
  35.     -command          => sub { $mw->messageBox( -message => "Ups" ) }
  36. );
  37.  
  38. $btn->command( -label => "Exit", -command => sub { exit } );
  39.  
  40. my $help = $main_menu->Menubutton(
  41.     -text      => "Help",
  42.     -underline => 0,
  43.     -tearoff   => 0
  44. );
  45. $help->command(
  46.     -label            => "How to play",
  47.     -activebackground => "red",
  48.     -foreground       => "black",
  49.     -command          => \&help
  50. );
  51.  
  52. $help->command(
  53.     -label            => "About author",
  54.     -activebackground => "orange",
  55.     -activeforeground => "black",
  56.     -background       => "yellow",
  57.     -foreground       => "blue",
  58.     -command          => \&myself
  59. );
  60.  
  61. $mw->title('Reversi');
  62. $mw->geometry("545x402");
  63. $mw->resizable( 0, 0 );
  64.  
  65. my $canvas = $mw->Canvas(
  66.     -width      => 380,
  67.     -height     => 380,
  68.     -background => "black",
  69.     -relief     => "groove",
  70.  
  71. )->pack( -side => "left" );
  72. my $frame = $mw->Frame(
  73.     -width  => 112,
  74.     -height => 400
  75. )->pack( -side => "right" );
  76. my $icon = $mw->Photo( -file => '1.bmp' );
  77. $mw->iconimage($icon);
  78.  
  79. my @pole;
  80.  
  81. my @right = ();
  82.  
  83. my $u = 1;
  84.  
  85. my $semafor = 0;
  86.  
  87. my $task;
  88.  
  89. my $x = 12;
  90.  
  91. my $y = 12;
  92.  
  93. for ( $x = 12 ; ( $x + 40 ) < 400 ; $x += 45 ) {
  94.  
  95.     for ( $y = 12 ; ( $y + 40 ) < 400 ; $y += 45 ) {
  96.  
  97.         my $rec = $canvas->createRectangle(
  98.  
  99.             $x, $y, $x + 40, $y + 40,
  100.  
  101.             -fill => "red",
  102.  
  103.             -outline => "orange",
  104.  
  105.             -width => 2.0
  106.  
  107.         );
  108.  
  109.         my $oval = $canvas->createOval(
  110.  
  111.             $x + 2, $y + 2, $x + 38, $y + 38,
  112.  
  113.             -fill => "red",
  114.  
  115.             -outline => "red"
  116.  
  117.         );
  118.  
  119.         $canvas->bind( $oval, '<ButtonPress>' => [ \&callBack, $oval ] );
  120.  
  121.     }
  122.  
  123.     $y = 10;
  124.  
  125. }
  126.  
  127. my $start = $frame->Button(
  128.  
  129.     -text    => 'Start',
  130.     -width   => 18,
  131.     -command => [ \&start ],
  132.  
  133. )->grid( -row => 0, -column => 0, -pady => 10, -padx => 20 );
  134. $canvas->pack;
  135.  
  136. my $type_game = $frame->Button(
  137.     -text    => "Choose type of game",
  138.     -width   => 18,
  139.     -command => \&button1_sub
  140. )->grid( -row => 1, -column => 0, -padx => 20 );
  141.  
  142. my $result     = $frame->Label()->grid( -row => 2, -column => 0 );
  143. my $currentHod = $frame->Label()->grid( -row => 3, -column => 0 );
  144. my $typeGame   = 0;
  145.  
  146. sub myself {
  147.     my $i = $mw->Toplevel;
  148.     $i->geometry("200x150");
  149.     $i->resizable( 0, 0 );
  150.     $i->title("How to play");
  151.     $i->Label( -text => "Was made by Ksenia Panina. All rights reserved" )
  152.       ->pack();
  153.     my $exit = $i->Button(
  154.         -text    => "Exit",
  155.         -command => [ $i => 'destroy' ]
  156.     )->pack();
  157.  
  158. }
  159.  
  160. sub help {
  161.     my $text;
  162.     open( FILE, "htp.txt" ) or die;
  163.  
  164.     close(FILE);
  165.     my $help = $mw->Toplevel;
  166.     $help->geometry("330x430");
  167.     $help->resizable( 0, 0 );
  168.     $help->title("How to play");
  169.     $help->Label( -text => $text )->pack();
  170.     my $exit = $help->Button(
  171.         -text    => "Exit",
  172.         -command => [ $help => 'destroy' ]
  173.     )->pack();
  174.  
  175. }
  176.  
  177. #0- User vs AI
  178. #1- User vs User
  179. #2 AI vs AI
  180.  
  181. sub button1_sub {
  182.     my $game = $mw->Toplevel;
  183.     $game->geometry("300x150");
  184.     $game->title("Choosing type");
  185.  
  186.     my $radio_frame = $game->Frame()->pack();
  187.     $radio_frame->Label( -text => "Type of game:" )->pack();
  188.     my $radio_us_ai = $radio_frame->Radiobutton(
  189.         -text     => "User vs Computer",
  190.         -value    => "0",
  191.         -variable => \$typeGame
  192.     )->pack( -side => "top" );
  193.     my $radio_us_us = $radio_frame->Radiobutton(
  194.         -text     => "User vs User",
  195.         -value    => "1",
  196.         -variable => \$typeGame
  197.     )->pack( -side => "top" );
  198.     my $radio_ai_ai = $radio_frame->Radiobutton(
  199.         -text     => "Computer vs Computer",
  200.         -value    => "2",
  201.         -variable => \$typeGame
  202.     )->pack( -side => "top" );
  203.     my $game_ex = $game->Button(
  204.         -text    => "OK",
  205.         -command => [ $game => 'destroy' ]
  206.     )->pack();
  207. }
  208. MainLoop();
  209.  
  210. sub start {
  211.     $canvas->afterCancel($task);
  212.  
  213.     setUp();
  214.  
  215.     #   $type_game->configure(-state => "disabled" );
  216.     #   $canvas->itemconfigure( $type_game, - => "black" );
  217.     nextUser(1);
  218. }
  219.  
  220. sub setUp {
  221.  
  222.     for ( my $i = 0 ; $i < 8 ; $i++ ) {
  223.  
  224.         for ( my $j = 0 ; $j < 8 ; $j++ ) {
  225.  
  226.             $pole[$i][$j] = 0;
  227.  
  228.         }
  229.  
  230.     }
  231.  
  232.     for ( my $i = 2 ; $i <= 8 * 8 * 2 ; $i += 2 ) {
  233.  
  234.         $canvas->itemconfigure( $i, -fill => "red" );
  235.  
  236.     }
  237.  
  238.     $pole[3][3] = 1;
  239.  
  240.     $pole[4][4] = 1;
  241.  
  242.     $pole[3][4] = 2;
  243.  
  244.     $pole[4][3] = 2;
  245.  
  246.     $u = 2;
  247.  
  248.     push @right, 3, 4, 4, 3;
  249.  
  250.     draw();
  251.  
  252.     $u = 1;
  253.  
  254.     push @right, 3, 3, 4, 4;
  255.  
  256.     draw();
  257.     $result->configure( -text => "Black: 0 White: 0 Free: 64" );
  258. }
  259.  
  260. sub nextUser {
  261.     my $nextUser = $_[0];  #Кому надо будет передать ход
  262.  
  263.     $currentHod->configure(
  264.         -text => "Current: " . ( ( $nextUser == 1 ) ? "Black" : "White" ) );
  265.     if ( $typeGame == 0 || $typeGame == 2 ) {    # если юзер мы АИ
  266.         if ( $nextUser == 2 || $typeGame == 2 ) {    #если ход бота
  267.             $semafor = 0;  #выключаем ходы пользователю
  268.             $task = $canvas->after( 500, \&callAI );  #вызываем бота
  269.         }
  270.         else {    #если ход юзера
  271.             $semafor =
  272.               1;    #включаем ему возможность ходить
  273.         }
  274.     }
  275.     elsif ( $typeGame == 1 ) {
  276.         $semafor = 1;
  277.     }
  278.  
  279. }
  280.  
  281. sub callBack {
  282.  
  283.     my $c;
  284.  
  285.     my $d;
  286.  
  287.     $b = $_[1];
  288.  
  289.     $c = int( ( $b - 2 ) / 16 );
  290.  
  291.     $d = ( ( $b - 2 ) % 16 ) / 2;
  292.  
  293.     if ($semafor) {
  294.  
  295.         if ( hod( $c, $d ) ) {
  296.             nextUser($u);
  297.  
  298.         }
  299.  
  300.     }
  301.  
  302. }
  303.  
  304. sub f {
  305.  
  306.     my $x = shift;    #координаты
  307.  
  308.     my $y = shift;
  309.  
  310.     my $sdvig_x = shift;    # и на сколько мы их сдвигаем
  311.  
  312.     my $sdvig_y = shift;
  313.  
  314.     my @ther = ();
  315.  
  316.     $x += $sdvig_x;
  317.  
  318.     $y += $sdvig_y;
  319.  
  320.     while ( $x < 8 && $x >= 0 && $y < 8 && $y >= 0 )
  321.  
  322.     {                       #цикл начался
  323.  
  324.         if ( $pole[$x][$y] == 0 ) {    #если 0 то выходим
  325.  
  326.             last;
  327.  
  328.         }
  329.  
  330.         if (
  331.  
  332.             $pole[$x][$y] ==
  333.  
  334.             ( $u == 1 ? 2 : 1 )
  335.  
  336.           )                            #если 1 кладём 2 иначе 1
  337.  
  338.         {    # если вражеские то кладём
  339.  
  340.             push @ther, $x, $y;
  341.  
  342.             #print $x, $y, $pole[$x][$y];
  343.  
  344.             $x += $sdvig_x;
  345.  
  346.             $y += $sdvig_y;
  347.  
  348.         }
  349.  
  350.         else {
  351.  
  352.             if ( $pole[$x][$y] == $u ) {
  353.  
  354.                 push @right, @ther;
  355.  
  356.                 last;
  357.  
  358.             }
  359.  
  360.         }
  361.  
  362.     }
  363.  
  364.     #конец цикла
  365.  
  366. }
  367.  
  368. #каждый элимент поля 1 - чёрный,2 - белый,0 - пустой
  369.  
  370. #функция которая говорит сделан ли ход
  371.  
  372. sub hod {
  373.  
  374.     #берем координаты хода
  375.  
  376.     my $a = $_[0];
  377.  
  378.     my $b = $_[1];
  379.  
  380.     #берем флаг count
  381.  
  382.     my $countFlag = $_[2];
  383.  
  384.     if ( $pole[$a][$b] == 0 ) {
  385.  
  386.         #проверка в поисках фишки того же юзера
  387.  
  388.         #проверка по строкам
  389.  
  390.         f( $a, $b, +1, 0 );
  391.  
  392.         f( $a, $b, -1, 0 );
  393.  
  394.         #проверка по столбцам
  395.  
  396.         f( $a, $b, 0, -1 );
  397.  
  398.         f( $a, $b, 0, 1 );
  399.  
  400.         #диагональки
  401.  
  402.         f( $a, $b, -1, -1 );
  403.  
  404.         f( $a, $b, +1, +1 );
  405.  
  406.         f( $a, $b, +1, -1 );
  407.  
  408.         f( $a, $b, -1, +1 );
  409.  
  410.         if ( scalar @right == 0 ) {
  411.  
  412.             return 0;
  413.  
  414.         }
  415.  
  416.         else {
  417.  
  418.             my $rightLen = scalar @right;
  419.  
  420.             if ( !$countFlag ) {
  421.  
  422.                 push @right, $a, $b;
  423.  
  424.                 #print $a, $b;
  425.  
  426.                 for ( my $i = 0 ; $i < ( scalar @right ) ; $i += 2 ) {
  427.  
  428.                     $pole[ $right[$i] ][ $right[ $i + 1 ] ] = $u;
  429.  
  430.                 }    #меняем состояние нужной клетки
  431.  
  432.                 draw();
  433.                 my @res = getResult();
  434.                 $result->configure(
  435.                     -text => "Black: $res[1] White: $res[2] Free: $res[0]" );
  436.                 $u = $u == 1 ? 2 : 1;    #переход хода
  437.  
  438.                 my @hod = getHod($u);
  439.  
  440.                 if ( !$hod[2] ) {
  441.                     @hod = getHod( $u == 1 ? 2 : 1 );
  442.  
  443.                     if ( !$hod[2] ) {
  444.  
  445.                         $semafor = 0;
  446.  
  447.                         $currentHod->configure( -text => "Game over" );
  448.                         return 0;
  449.  
  450.                     }
  451.  
  452.                     $u = $u == 1 ? 2 : 1;
  453.  
  454.                     return 1;
  455.  
  456.                 }
  457.  
  458.             }
  459.  
  460.             @right = ();
  461.  
  462.             return $rightLen;
  463.  
  464.         }
  465.  
  466.     }
  467.  
  468. }
  469.  
  470. sub getHod {
  471.  
  472.     my $buf_u = $u;
  473.  
  474.     $u = $_[0];
  475.  
  476.     my $lenHod = 0;
  477.  
  478.     my $a = 0;
  479.  
  480.     my $b = 0;
  481.  
  482.     for ( $x = 0 ; $x < 8 ; $x++ ) {
  483.  
  484.         for ( $y = 0 ; $y < 8 ; $y++ ) {
  485.  
  486.             if ( hod( $x, $y, 1 ) > $lenHod ) {
  487.  
  488.                 $lenHod = hod( $x, $y, 1 );
  489.  
  490.                 $a = $x;
  491.  
  492.                 $b = $y;
  493.  
  494.             }
  495.  
  496.         }
  497.  
  498.     }
  499.  
  500.     $u = $buf_u;
  501.  
  502.     return ( $a, $b, $lenHod );
  503.  
  504. }
  505.  
  506. sub draw {
  507.  
  508.     for ( my $i = 0 ; $i < ( scalar @right ) ; $i += 2 ) {
  509.  
  510.         my $id = $right[$i] * 16 + $right[ $i + 1 ] * 2 + 2;
  511.  
  512.         if ( $u == 1 ) {
  513.  
  514.             $canvas->itemconfigure( $id, -fill => "black" );
  515.  
  516.         }
  517.  
  518.         else {
  519.  
  520.             $canvas->itemconfigure( $id, -fill => "white" );
  521.  
  522.         }
  523.  
  524.     }
  525.  
  526.     @right = ();
  527.  
  528. }
  529.  
  530. sub getResult {
  531.  
  532.     my @result = ( 0, 0, 0 );
  533.  
  534.     for ( $x = 0 ; $x < 8 ; $x++ ) {
  535.  
  536.         for ( $y = 0 ; $y < 8 ; $y++ ) {
  537.  
  538.             $result[ $pole[$x][$y] ]++;
  539.  
  540.         }
  541.  
  542.     }
  543.  
  544.     print "user: ", $result[1], "; AI: ", $result[2], "\n";
  545.     return @result;
  546. }
  547.  
  548. #AI section
  549.  
  550. sub callAI {
  551.  
  552.     my @hod = getHod($u);
  553.  
  554.     if ( hod( $hod[0], $hod[1] ) ) {
  555.  
  556.         nextUser($u);
  557.     }
  558.  
  559. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement