Thread komischer fehler aber wo?
(7 answers)
Opened by conray at 2010-04-22 21:31
Hm.. also erstmal würde ich sagen, der Spieler sollte sehen, welche Indizes zu den jeweiligen Zellen gehören. Außerdem wird das erste Element in einem Array per default mit 0 indiziert, aber das ist nur eine Kleinigkeit.
Ich finde ein paar Dinge sollten in eigene Funktionen gepackt werden, wie bspw. das Ausgeben des Spielfeldes oder das Überprüfen ob jemand gewonnen hat. Damit nicht mehr so viele Variablen gebraucht und getauscht werden müssen, würde ich mir merken, wer gerade an der Reihe ist: 1 = Spieler 1, 0 = Spieler 2, oder umgekehrt. Der Spielstein und Spielername ergibt sich dann daraus. Außerdem sollte ein getätigter Zug aus den möglichen gelöscht werden. Ansonsten finde ich das system('clear') nicht so toll und würde stattdessen entweder je nach Betriebssystem etwas anderes tun, oder eine bestimmte Anzahl an Leerzeilen ausgeben (sollte für den Effekt genügen). Hier ein alternativer Vorschlag: Code (perl): (dl
)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 #!/usr/bin/perl use 5.010; use strict; use warnings; # spielernamen: print "Player 1: "; chomp( my $player1 = <STDIN> ); $player1 =~ s/^\s*$/Player1/; print "Player 2: "; chomp( my $player2 = <STDIN> ); $player2 =~ s/^\s*$/Player2/; $player2 .= '2' if $player2 eq $player1; my @board; # spielfeld my $winner; # gewinner my $color = 1; # 1 = X, 0 = O # hauptschleife: while ( not defined $winner and scalar( grep defined, @board ) != 9 ) { draw_board(); handle_input(); check_winner(); } # while # ausgabe des gewinners: if ( defined $winner ) { draw_board(); say "\nCongratulations ". ($winner eq 'X' ? $player1 : $player2) ."!"; say "You are the winner!"; } # if else { draw_board(); say "\nDraw."; } # else # spielfeld zeichnen: sub draw_board { print "\n" x 24; # bildschirm "loeschen" (edit) say " A | B | C\n -----------"; printf( "%s: %s | %s | %s\n". ($_ == 2 ? '' : " ---+---+---\n"), $_ + 1, $board[3*$_ ] // ' ',#/ $board[3*$_+1] // ' ',#/ $board[3*$_+2] // ' ',#/ ) for 0 .. 2; } # draw_board # eingabe entgegennehmen und behandeln: sub handle_input { my( $name, $sym ) = $color ? ($player1, 'X') : ($player2, 'O'); print "\nIt's your turn, $name ($sym): "; chomp( my $cell = <STDIN> ); if ( $cell =~ /([abcABC])([123])/ ) { my( $x, $y ) = ( $1, $2 - 1 ); $x = { 'a' => 0, 'b' => 1, 'c' => 2 }->{ lc $x }; if ( defined $board[3*$y+$x] ) { say "This cell is already taken."; <STDIN>; } # if else { $board[3*$y+$x] = $sym; $color = !$color; # naechster spieler } # else } # if else { say "I'd appreciate something like A1 or b3."; <STDIN>; } # else } # handle_input # ueberpruefen ob jemand gewonnen hat: sub check_winner { my $eq = sub { # edit: diese routine stände wohl besser in einem my $cmp = my $r = $board[shift]; # scope neben check_winner $r &&= $cmp eq $board[$_] for @_; return $r; }; # $eq # horizontal, vertikal, diagonal: for ( 0, 3, 6 ) { return $winner = $board[$_] if $eq->($_, $_+1, $_+2) } for ( 0, 1, 2 ) { return $winner = $board[$_] if $eq->($_, $_+3, $_+6) } $winner = $board[4] if $eq->(0, 4, 8) or $eq->(6, 4, 2); } # check_winner __END__ Last edited: 2010-04-22 23:44:41 +0200 (CEST) perl -E'*==*",s;;%ENV=~m,..$,,$&+42;e,$==f;$"++for+ab..an;@"=qw,u t,,print+chr;sub f{split}say"@{=} me"'
|