rm documents to github
[svn42.git] / dart / Dart.pm
index 7352fc2..ac7775d 100644 (file)
@@ -3,6 +3,10 @@ package Dart;
 use strict;
 use base 'Exporter';
 use Clone;
+use POSIX;
+use Term::Cap;
+use FileHandle;
+
 # new Dart(player_names=>[ 'lala', 'popo' ]);
 ## Player, Rank, Active, 
 
@@ -15,26 +19,64 @@ sub new
   die "Missing player_names" if not ref $params{player_names} eq 'ARRAY';
   die "Missing player_names" if not @{$params{player_names}};
   $self->{player}=[];
-  $self->{current_player}=0;
-  my $player_counter=0;
   for my $player_name (@{$params{player_names}}) 
   {
-    $player_counter++;
     $self->add_player(&create_player(name=>$player_name,rank=>undef,active=>1));
   }
-  $self->{active_player_count}=$player_counter;
-  $self->{player_count}=$player_counter;
-  $self->{round}=1;
+  $self->{callbacks}=$params{callbacks};
+
+  open($self->{shout_fifo}, '>>', $params{shout_fifo}) or die $!;
+  $self->{shout_fifo}->autoflush(1);
+
+  my $termios = new POSIX::Termios;
+  $termios->getattr;
+  $self->{term} = Term::Cap->Tgetent( { OSPEED => $termios->getospeed } );
+  $self->init();
+  return $self;
+}
+
+sub trace_shoot
+{
+  my $self=shift;
+  my ($property)=@_;
+  push @{$self->{trace_shoot}},$property;
+}
+
+sub get_color
+{
+  my $self=shift;
+  my ($mul,$zahl)=@_;
+  my @zahlen =  qw/20 1 18 4 13 6 10 15 2 17 3 19 7 16 8 11 14 9 12 5 25/;
+  my $counter=0;
+  $counter++ while($zahl != shift @zahlen and @zahlen);
+  $mul=0 if $mul >1;
+  my $result = ($counter+$mul )%2;
+  return $result;
+}
+
+sub init
+{
+  my $self=shift;
+  $self->{round}=0;
   $self->{max_shoots_per_player}=3;
   $self->{current_shoot_count}=0;
-  $self->{callbacks}=$params{callbacks}; 
+  $self->{current_player}=0;
+  $self->{player_count}=@{$self->{player}};
+  $self->{active_player_count}=$self->{player_count};
+  $self->{trace_shoot_data}={};
   $self->callback('init');
-  return $self;
 }
 
 sub reset_game
 {
   my $self=shift;
+  my @sort_player = sort { $b->{rank} <=> $a->{rank} } @{$self->{player}};
+  $self->{player}=[];
+  for my $player (@sort_player)
+  {
+    $self->add_player(&create_player(name=>$player->{name},rank=>undef,active=>1));
+  }
+  $self->init();
 }
 
 sub callback
@@ -52,23 +94,20 @@ sub callback
 sub run
 {
   my $self=shift;
-  my ($data_in_fh,$sound_out_fh)=@_;
   my @history;
-#  $data_in_fh ||= STDIN;
-#  $sound_out_fh ||= STDOUT;
-  $self->{sound_out_fh}=$sound_out_fh;
 
   push @history, Clone::clone($self);
+  my $STDOUT = new FileHandle '>-';
+  $self->{term}->Tputs('cl', 1, $STDOUT);
   $self->callback('before_shoot');
-  #while ( my $shoot_data = <$data_in_fh>)
   while ( my $shoot_data = <STDIN>)
   {
-    #print STDERR $schuss;
     my ($mult,$number) = split /\s+/, $shoot_data;
 
     if ($mult =~/^\d$/)
     {
       die "Unexpected input" if not $number=~/^\d+$/;
+      next if not $self->{current_shoot_count} < $self->{max_shoots_per_player};
       $self->shoot($mult,$number);
     } elsif ($mult eq 'btn') {
       $self->next_player();
@@ -76,8 +115,16 @@ sub run
       pop @history;
       $self= pop @history;
       $self->callback('undo');
+    } elsif ($mult eq 'reset') {
+      $self->reset_game();
+    } elsif ($mult eq 'quit') {
+      return;
+    } else {
+      # shitty input
+      next;
     }
     push @history, Clone::clone($self);
+    $self->{term}->Tputs('cl', 1, $STDOUT);
     $self->callback('before_shoot');
   }
 }
@@ -90,12 +137,34 @@ sub shoot
   {
     $self->{current_shoot}={mult=>$mult,number=>$number};
     $self->{current_shoot_count}++;
-    return $self->callback('shoot',$mult,$number);
+    my $result = $self->callback('shoot',$mult,$number);
+    for my $trace_prop ( @{$self->{trace_shoot}})
+    {
+      push @{$self->{trace_shoot_data}{$self->{current_player}}},$self->get_current_player()->{$trace_prop};
+    }
+    return $result;
   } else {
     return 0;
   }
 }
 
+sub plot_trace_shoot
+{
+  my $self=shift;
+  my $datastr;
+  for my $player_num (keys %{$self->{trace_shoot_data}})
+  {
+    $datastr.=$self->get_player($player_num)->{name}.':';
+    $datastr.= join ',',@{$self->{trace_shoot_data}{$player_num}};
+    $datastr.="\n";
+  }
+  chomp $datastr;
+  my $plotter;
+  open($plotter,"|./plot.py") or return;
+  print $plotter $datastr;
+  close $plotter;
+}
+
 sub shout_last_shoot
 {
   my $self=shift;
@@ -115,14 +184,13 @@ sub shout
 {
   my $self=shift;
   my ($what)=@_;
-  my $fh = $self->{sound_out_fh};
+  my $fh = $self->{shout_fifo};
   if ($what eq 25)
   {
-    print "bull\n";
+    print $fh "bull\n";
   } else {
-    print "$what\n";
+    print $fh "$what\n";
   }
-#print $fh "$what\n";
 }
 
 sub get_current_player
@@ -144,7 +212,7 @@ sub next_player
   my $self=shift;
   $self->callback('before_next_player');
   $self->{current_shoot_count}=0;
-  ($self->{current_player},my $new_round)=get_next_active_player($self->{player},$self->{current_player});
+  ($self->{current_player},my $new_round)=$self->get_next_active_player();
   $self->shout("player");
   $self->shout($self->get_current_player()->{name});
   $self->next_round() if $new_round;
@@ -153,7 +221,9 @@ sub next_player
 
 sub get_next_active_player
 {
-  my ($players_ref,$current_player)=@_;
+  my $self=shift;
+  my $players_ref = $self->{player};
+  my $current_player = $self->{current_player};
   my $num_players=@$players_ref;
   my $new_round=0;
   do
@@ -161,15 +231,21 @@ sub get_next_active_player
     $current_player++;
     if($current_player>=$num_players)
     {
-      die "Error no remaining active players" if $new_round;
+      $self->reset_game() if $new_round;
       $current_player=0;
       $new_round=1;
     }
   }
-  while (not $players_ref->[$current_player]{active});
+  while (not $self->{player}->[$current_player]{active});
   return ($current_player,$new_round);
 }
 
+sub finish_player_round
+{
+  my $self=shift;
+  $self->{current_shoot_count} = $self->{max_shoots_per_player};
+}
+
 sub next_round
 {
   my $self=shift;
@@ -180,28 +256,26 @@ sub next_round
 sub win
 {
   my $self=shift;
-  $self->deactivate_current_player($self->{player_count}-$self->{active_player_count}+1);
   $self->shout('win');
+  $self->deactivate_current_player($self->{player_count}-$self->{active_player_count}+1);
   if ($self->{active_player_count}==1)
   {
     $self->next_player();
-    $self->lose();
-  } elsif (not $self->{active_player_count}) {
-    $self->end_game();
+    $self->shout('lose');
+    $self->deactivate_current_player($self->{player_count}-$self->{active_player_count}+1);
   }
 }
 
 sub lose
 {
   my $self=shift;
-  $self->deactivate_current_player($self->{active_player_count});
   $self->shout('lose');
+  $self->deactivate_current_player($self->{active_player_count});
   if ($self->{active_player_count}==1)
   {
     $self->next_player();
-    $self->win();
-  } elsif (not $self->{active_player_count}) {
-    $self->end_game();
+    $self->shout('win');
+    $self->deactivate_current_player($self->{active_player_count});
   }
 }