#!/usr/bin/perl
use strict;
##

my $perg = 5;

# $perg -> quantas possibilidades em cada round... isto deverá ser gerado automaticamente (ou aliás, retirado de algures...)

my ($t1,$t2) = (5,50);

# $t1 -> segundos entre duas rondas consecutivas (tempo de espera)
# $t2 -> segundos que dura uma ronda

#my ($p1,$p2,$p3,$p4) = (5,2,6,2);
my ($p1,$p2,$p3,$p4) = (10,10,10,10);

# $p1 -> pontos por cada resposta acertada
# $p2 -> bónus por todas as respostas dadas
# $p3 -> penalização por usar ajuda
# $p4 -> bónus por nenhuma resposta incorrecta

my $r1 = 5;

# $r1 -> de quantas em quantas rondas se dá o bónus de permanência (de 1 ponto)

##

#undef $/;

#my (%topicos1,%topicos2);
#my (@temas1,@temas2);
#carrega();

#print "\n" x 7;
#for (1..2) {
#  print "\n=====\n\n";
#  print topico();
#}
#
#exit 1;

my %comandos = (
  'ajuda' => "mostra uma possível resposta (-$p3 pontos)",
  'help' => "imprime este texto",
  'last' => "faz com esta seja a última ronda",
  'keep' => "anula o comando 'last'",
  'next' => "termina imediatamente esta ronda",
  'scoring' => "exibe o mecanismo de pontuação",
  'stop' => "termina o jogo imediatamente",
);

my $help = "\nComandos disponíveis:\n\n";
for(sort keys %comandos){$help.="  $_ -\t$comandos{$_}\n"}
$help .= "\n";

my $scoring = "
  Por cada resposta acertada -		+$p1
  Por todas as respostas acertadas -	+$p2
  Se usar ajuda -			-$p3
  Se não der respostas incorrectas -	+$p4
  Por cada $r1 rondas -			+1

";

my %num = qw(1 Uma 2 Duas 3 Três 4 Quatro 5 Cinco 6 Seis 7 Sete 8 Oito 9 Nove 10 Dez);

$SIG{ALRM} = \&time_out;

###

my ($pont,$round,$stop,@topicos) = (0,0);
my @topicos = topicos();
print "\nJogo iniciado com ".($#topicos+1)." tópicos.\n";

while (!$stop)
{
  $round++;
  print "\n\t========== Ronda $round ==========\n";

  my ($tema,$topico,@resp) = split(/\n/,$topicos[int rand($#topicos)]);
  my $exemplo = $resp[int rand($#resp)];

  my %poss;
  for (@resp) {$poss{$1} = 1 if /^(.*?)( \(.*\))?$/}

  my (%valores,%temp,%respostas);
  for (0..$#resp) {$temp{$_} = $resp[$_]}
  my $tenho = $#resp + 1;
  for (1..$perg)
  {
    my $a = int rand($tenho--);
    my $b = $temp{$a};
    $b =~ /^(.*?)( \(.*\))?$/;
    $valores{$1} = $b;
    $temp{$a} = $temp{$tenho};
    delete $temp{$tenho};
  }

  for (keys %valores) {$respostas{$_}=1}

  print "\nCategoria '$tema' dentro de $t1 segundos...\n\n";
  sleep($t1);
  print "$topico ($t2 segundos)\n\n";

  my ($cons,$keep,$ajuda,$ninc,$tentou,$faltam);
  eval {
    alarm($t2);
    $faltam = $perg;
    $keep = $ninc = 1;
    $ajuda = $tentou = 0;
    while ($keep)
    {
      chomp (my $a = <>);
#print "\nDEBUG 1:respostas{$a} $respostas{$a} cons $cons keep $keep help $ajuda ninc $ninc tentou $tentou stop $stop:\n";
#print "DEBUG 1:$respostas{$a}-$cons-$keep-$ajuda-$ninc-$tentou-$stop:\n";
      is_cmd($a) || (!$a) || ($tentou = 1);
      $poss{$a} || is_cmd($a) || (!$a) || ($ninc = 0);
      if ($respostas{$a}) {$respostas{$a}=0;$faltam--;print "Resposta acertada: $valores{$a} (+$p1 pontos)\n"}
      if (!$faltam) {$keep=0;print "\nTodas as respostas correctas!\n"}
      if ($a eq 'ajuda') {print "Por exemplo: $exemplo".($ajuda?"":" (-$p3 pontos)")."\n";$ajuda=1}
      if ($a eq 'help') {print $help}
      if ($a eq 'scoring') {print $scoring}
      if ($a eq 'last') {$stop=1;print "\nEsta será a última ronda.\n\n"}
      if ($a eq 'keep') {$stop=0;print "\nO jogo vai continuar.\n\n"}
      if ($a eq 'next') {$keep=0}
      if ($a eq 'stop') {$stop=1;$keep=0}
      $cons = 1;
      for (values %respostas) {$cons = 0 if $_}
#print "\nDEBUG 2:respostas{$a} $respostas{$a} cons $cons keep $keep help $ajuda ninc $ninc tentou $tentou stop $stop:\n";
#print "DEBUG 2:$respostas{$a}-$cons-$keep-$ajuda-$ninc-$tentou-$stop:\n";
    }
    alarm(0);
  };

  print "\nAcabou o tempo.\n\n" unless ($stop || !$keep);
  for (sort keys %respostas) {print ">> $valores{$_}".($respostas{$_}?"":" -> +$p1 pontos")."\n"}
  print "\nPontuação anterior:\t\t\t$pont pontos\n\n";
  $pont += $p1*($perg-$faltam);
  if ($ninc && $tentou) {$pont+=$p4;print "Nenhuma resposta incorrecta -\t\t+$p4\n"}
  if ($faltam < $perg) {print ($num{$perg-$faltam}." resposta(s) correctas -\t\t+".($p1*($perg-$faltam))."\n")}
  if ($cons) {$pont+=$p2;print "Todas as respostas correctas -\t\t+$p2\n"}
  if ($ajuda) {$pont-=$p3;print "Precisou de ajuda -\t\t\t-$p3\n"}
  if (($round / $r1) == int ($round / $r1)) {$pont+=1;print "Bónus de permanência por $round rondas -\t+1\n"}
  print "\nPontuação actual:\t\t\t$pont pontos\n" unless $stop;
}

show_scores();

###

sub show_scores {
  print "\nPontuação final:\t\t\t$pont (podia ter feito ".max_score().")\n";
  print "\nRanking:\t\t\t\t".rank()." (de ".min_rank()." a ".max_rank().")\n\n";
}

#sub carrega {
#  open (I,"index") || die "could not open 'index': $! (try running 'make' first)\n";
#  my @temas = split /\n/,<I>;
##  while(<I>) {chomp;push @temas, $_}
#  close (I);
#
#  my %topicos;
#  for my $t (@temas)
#  {
##print "estou a carregar '$t'\n";
#    open (F,$t) || die "could not open '$t': $!\n";
#    my @t = map {"$t\n$_"} (split /\n%\n/,<F>);
#    $topicos{$t} = \@t;#(map {"$t\n$_"} (split(/\n%\n/,<F>)));
##print join(",",@{$topicos{$t}}).".\n";
#    close (F);
#  }
#
#  my $n = min(5,$#temas-1/2);
#  my %temp;
#  while(keys %temp<$n) {$temp{int rand($#temas)} = 1}
#  for (0..$#temas) {$temp{$_} ? push @temas1,$temas[$_] : push @temas2,$temas[$_]}
##print">>@temas1\n";
##print">}@temas2\n";
#  for my $k (keys %topicos)
#  {
#    my $n = min(200,scalar(@{topicos{$k}})/2);
#    my %temp;
#    while((scalar keys %temp)<$n) {$temp{int rand(scalar(@{topicos{$k}}))} = 1}
#    for (0..scalar(@{topicos{$_}})+1) {$temp{$_} ? push(@{$topicos1{$k}},$topicos[$_]) : push(@{$topicos2{$k}},$topicos[$_])}
#  }
#}

#sub topico {
#  my $t = int rand($#temas1);
##print ">Temas 1 -> $#temas1\n";
##print ">T Random-> $t\n";
#  chomp (my $tema = $temas1[$t]);
##print ">Temas   -> ".join(",",@temas1)."\n";
##print ">Tema Ran-> $tema\n";
#  push @temas2, $tema;
#  $temas1[$t] = shift @temas2;
##print ">T1      -> ".%topicos1."\n";
##print ">Tóps 1  -> ".(keys %topicos1)."\n";
##for ($topicos1{$tema}) {print " >>>'$_'\n"}
#  $t = int rand(scalar @{$topicos1{$tema}} + 1) if defined @{$topicos1{$tema}}; # este if não deveria ser necessário
##print ">T Random-> $t\n";
#  my $topico = ${$topicos1{$tema}}[$t];
##print "'$topico'\n";
#  push @{$topicos2{$tema}}, $topico;
#  ${$topicos1{$tema}}[$t] = shift @{$topicos2{$tema}};
#  return $topico
#}

#sub min {my $a = shift;for (@_) {$a = $_ if $_ < $a};$a}

sub topicos {
  my $t = $/;
  undef $/;
  open (I,"index") || die "could not open 'index': $! (try running 'make' first)\n";
  my (@index,@topicos) = split(/\n/,<I>);
  close (I);
  for my $f (@index)
  {
    open (F,$f) || die "could not open '$f': $!\n";
    push @topicos, map {"$f\n$_"} (split(/\n%\n/,<F>));
    close (F);
  }
  $/ = $t;
  @topicos
}

sub rank {int ($pont/$round) + $p3}

sub min_rank {0}

sub max_rank {$perg*$p1+$p2+$p4+1+$p3}

sub max_score {$round*($perg*$p1+$p2+$p4)+1}

sub is_cmd {for (keys %comandos) {return 1 if $_[0] eq $_} return 0}

sub time_out {die}
