#!/usr/bin/perl -w use strict; use Tk; use Tk::LabEntry; use Time::HiRes; my $mw = MainWindow->new(-title=>"Kettenreaktion"); my $width = $mw->screenwidth; my $height = $mw->screenheight-200; $mw->geometry($width.'x'.($height+200)); my $frame1 = $mw->Frame(-height=>40)->pack(-side=>'bottom', -fill=>'both', -expand=>1); my $frame2 = $mw->Frame(-height=>40)->pack(-side=>'bottom', -fill=>'both', -expand=>1); my $bt_beenden = $frame1->Button(-text=>"Beenden", -command=>sub{exit})->pack(-side=>'left', -padx=>5); my $bt_reset = $frame1->Button(-text=>"Reset", -command=>\&feld_zeichnen)->pack(-side=>'left', -padx=>5); my $LE_feld = $frame2->LabEntry(-label=>"Breite (4-10)", -labelPack=>[-side=>'right'], -width=>4, -text=>"5")->pack(-side=>'left', -padx=>20, -pady=>5); $LE_feld->bind( '', \&feld_zeichnen); my $LE_spieler = $frame2->LabEntry(-label=>"Spieler (2-6)", -labelPack=>[-side=>'right'], -width=>4, -text=>"2")->pack(-side=>'left', -padx=>20, -pady=>5); $LE_spieler->bind( '', \&feld_zeichnen); my $LE_aktueller_spieler = $frame2->LabEntry(-label=>"aktueller Spieler", -labelPack=>[-side=>'right'], -width=>4, -text=>"1")->pack(-side=>'left', -padx=>20, -pady=>5); my $LE_sieger = $frame2->LabEntry(-label=>"Sieger", -labelPack=>[-side=>'right'], -width=>4, -text=>"")->pack(-side=>'left', -padx=>20, -pady=>5); my $breite_feld = 80; my $c = $mw->Canvas(-width=>800, -height=>800, -bg=>'white')->pack(-side=>'top'); $c->CanvasBind(''=>[\&mausdown,Ev('x'),Ev('y'),$breite_feld]); my %feld; my $anzahl_feld = 5; my $anzahl_spieler = 2; &feld_zeichnen; my $counter = 0; my $spieler = 1; my $sieger; MainLoop; sub feld_zeichnen{ $c->delete('all'); $anzahl_feld = $LE_feld->get; $anzahl_spieler = $LE_spieler->get; if (($anzahl_feld >= 4)&&($anzahl_feld <= 10)){ for my $i(0..$anzahl_feld){ $c->createLine($i*$breite_feld+1, 1, $i*$breite_feld+1, $anzahl_feld*$breite_feld+1); $c->createLine(1, $i*$breite_feld+1, $anzahl_feld*$breite_feld+1, $i*$breite_feld+1); } } &init($anzahl_feld); } sub init{ my $anzahl_feld = $_[0]; $spieler = 1; $LE_aktueller_spieler->configure(-text=>$spieler); $sieger = 0; $LE_sieger->configure(-text=>" "); ########## limit setzen ########## for my $i(2..($anzahl_feld-1)){ for my $j(2..($anzahl_feld-1)){ $feld{$i}->{$j}->{limit} = 4; } } for my $i(2..($anzahl_feld-1)){ $feld{$i}->{1}->{limit} = 3; $feld{$i}->{$anzahl_feld}->{limit} = 3; $feld{1}->{$i}->{limit} = 3; $feld{$anzahl_feld}->{$i}->{limit} = 3; } $feld{1}->{1}->{limit} = 2; $feld{$anzahl_feld}->{1}->{limit} = 2; $feld{$anzahl_feld}->{$anzahl_feld}->{limit} = 2; $feld{1}->{$anzahl_feld}->{limit} = 2; for my $i(0..($anzahl_feld+1)){ $feld{0}->{0}->{limit} = 0; $feld{$anzahl_feld+1}->{0}->{limit} = 0; $feld{$anzahl_feld+1}->{$anzahl_feld+1}->{limit} = 0; $feld{0}->{$anzahl_feld+1}->{limit} = 0; } ########## anzahl und besitzer nullen ########## for my $i(1..$anzahl_feld){ for my $j(1..$anzahl_feld){ $feld{$i}->{$j}->{anzahl} = 0; $feld{$i}->{$j}->{spieler} = 0; } } } sub mausdown{ my ($canvas, $x, $y, $breite_feld) = @_; my $feld_x = int($x/$breite_feld)+1; my $feld_y = int($y/$breite_feld)+1; if (($feld_x <= $anzahl_feld)&&($feld_y <= $anzahl_feld)){ &setzen($feld_x,$feld_y); if (($feld{$feld_x}->{$feld_y}->{spieler} == $spieler)||($feld{$feld_x}->{$feld_y}->{spieler} == 0)){ do{ if ($spieler < $anzahl_spieler){$spieler++;} else{$spieler = 1;} $LE_aktueller_spieler->configure(-text=>$spieler); }while(&freies_feld($spieler) == 0); } &farbig_hinterlegen; } } sub freies_feld{ my $frei = 0; for my $i(1..$anzahl_feld){ for my $j(1..$anzahl_feld){ $frei = 1 if (($feld{$i}->{$j}->{spieler} == $spieler)||($feld{$i}->{$j}->{spieler} == 0)); } } return $frei; } sub setzen{ $counter = 0; my ($X, $Y) = @_; if (($feld{$X}->{$Y}->{spieler} == $spieler)||($feld{$X}->{$Y}->{spieler} == 0)){ $feld{$X}->{$Y}->{anzahl} += 1; $feld{$X}->{$Y}->{spieler} = $spieler; &check($X,$Y); } } sub check{ if (++$counter < 10000){ my ($X, $Y) = @_; if ($feld{$X}->{$Y}->{anzahl} == $feld{$X}->{$Y}->{limit}){ $feld{$X}->{$Y}->{anzahl} = 0; $feld{$X}->{$Y}->{spieler} = 0; $feld{$X+1}->{$Y}->{anzahl} += 1; $feld{$X+1}->{$Y}->{spieler} = $spieler; &check($X+1,$Y); $feld{$X-1}->{$Y}->{anzahl} += 1; $feld{$X-1}->{$Y}->{spieler} = $spieler; &check($X-1,$Y); $feld{$X}->{$Y+1}->{anzahl} += 1; $feld{$X}->{$Y+1}->{spieler} = $spieler; &check($X,$Y+1); $feld{$X}->{$Y-1}->{anzahl} += 1; $feld{$X}->{$Y-1}->{spieler} = $spieler; &check($X,$Y-1); } } else{ $sieger = $spieler; $LE_sieger->configure(-text=>$spieler); } } sub farbig_hinterlegen{ for my $X(1..$anzahl_feld){ for my $Y(1..$anzahl_feld){ my ($farbe, $hintergrund); $farbe = 'red' if ($feld{$X}->{$Y}->{spieler} == 1); $farbe = 'blue' if ($feld{$X}->{$Y}->{spieler} == 2); $farbe = 'green' if ($feld{$X}->{$Y}->{spieler} == 3); $farbe = 'yellow' if ($feld{$X}->{$Y}->{spieler} == 4); $farbe = 'black' if ($feld{$X}->{$Y}->{spieler} == 5); $farbe = 'brown' if ($feld{$X}->{$Y}->{spieler} == 6); $hintergrund = 'white' if ($feld{$X}->{$Y}->{spieler} != $spieler); $hintergrund = 'cyan' if ($feld{$X}->{$Y}->{spieler} == $spieler); if ($feld{$X}->{$Y}->{anzahl} == 0){ $c->createRectangle(($X-1)*$breite_feld+1,($Y-1)*$breite_feld+1,$X*$breite_feld+1,$Y*$breite_feld+1, -fill=>$hintergrund); } if ($feld{$X}->{$Y}->{anzahl} == 1){ $c->createRectangle(($X-1)*$breite_feld+1,($Y-1)*$breite_feld+1,$X*$breite_feld+1,$Y*$breite_feld+1, -fill=>$hintergrund); $c->createOval(($X-1)*$breite_feld+int($breite_feld/2)-15,($Y-1)*$breite_feld+int($breite_feld/2)-15,($X-1)*$breite_feld+int($breite_feld/2)+15,($Y-1)*$breite_feld+int($breite_feld/2)+15, -fill=>$farbe); } if ($feld{$X}->{$Y}->{anzahl} == 2){ $c->createRectangle(($X-1)*$breite_feld+1,($Y-1)*$breite_feld+1,$X*$breite_feld+1,$Y*$breite_feld+1, -fill=>$hintergrund); $c->createOval(($X-1)*$breite_feld+int($breite_feld/2)-22,($Y-1)*$breite_feld+int($breite_feld/2)-22,($X-1)*$breite_feld+int($breite_feld/2)+8,($Y-1)*$breite_feld+int($breite_feld/2)+8, -fill=>$farbe); $c->createOval(($X-1)*$breite_feld+int($breite_feld/2)-8,($Y-1)*$breite_feld+int($breite_feld/2)-8,($X-1)*$breite_feld+int($breite_feld/2)+22,($Y-1)*$breite_feld+int($breite_feld/2)+22, -fill=>$farbe); } if ($feld{$X}->{$Y}->{anzahl} == 3){ $c->createRectangle(($X-1)*$breite_feld+1,($Y-1)*$breite_feld+1,$X*$breite_feld+1,$Y*$breite_feld+1, -fill=>$hintergrund); $c->createOval(($X-1)*$breite_feld+int($breite_feld/2)-30,($Y-1)*$breite_feld+int($breite_feld/2)-22,($X-1)*$breite_feld+int($breite_feld/2)+0,($Y-1)*$breite_feld+int($breite_feld/2)+8, -fill=>$farbe); $c->createOval(($X-1)*$breite_feld+int($breite_feld/2)-15,($Y-1)*$breite_feld+int($breite_feld/2)+5,($X-1)*$breite_feld+int($breite_feld/2)+15,($Y-1)*$breite_feld+int($breite_feld/2)+35, -fill=>$farbe); $c->createOval(($X-1)*$breite_feld+int($breite_feld/2)-0,($Y-1)*$breite_feld+int($breite_feld/2)-22,($X-1)*$breite_feld+int($breite_feld/2)+30,($Y-1)*$breite_feld+int($breite_feld/2)+8, -fill=>$farbe); } } } }