Lazarus - Relógio para jogar Xadrez

Para os aficcionados do milenar jogo de Xadrez que não querem ou não podem pagar por um relógio, estou disponibilizando um programa bem simples que simula um relógio, cujo executável pode ser baixado aqui. O programa não requer instalação, podendo inclusive ser executado em um pendrive. Ele foi desenvolvido usando a fantástica ferramenta Lazarus/FreePascal e substitui com eficiência os relógios de mesa. Além disso, aqueles que estão dando os primeiros passos em Lazarus encontrarão um exmplo de programa que usa bastante componentes e código para seus exercícios.
Antes de mostrar o código vou mostrar a interface e explicar o funcionamento do relógio.

A interface


Na parte superior do relógio está a configuração do tempo que será usado na partida. Há três caixas de texto (TEdit). Uma para hora, a segunda para minutos e a terceira para segundos. À direita encontram-se três botões (TButton). O primeiro para iniciar o relógio, o segundo para reset e o terceiro para pausar.
Abaixo temos mais dois TButton que servirão para simular o pressionamento do botão do relógio de cada jogador. Mais abaixo tem-se dois TGroupBox com TLabel dentro deles. Os rótulos são usados para mostrar o tempo de reflexão de cada jogador. E, finalmente, dois TProgressBar para mostrar visualmente o progresso do tempo das brancas e das pretas. As barras de progresso também ficam dentro de TGroupBox.
Além dos componentes visuais são usados dois TTimer, usados para controlar o tempo de cada jogador.

O funcionamento

Para iniciar uma partida, inicialmente definimos o tempo da partida. Certamente o tempo é o mesmo, tanto para as brancas quanto para as pretas. Definido o tempo, pressiona-se o botão iniciar. Imediatamente o tempo das brancas começa a correr, habilitando-se o TTimer das brancas. As brancas fazem sua jogada e pressionam qualquer tecla do teclado que possa ser detectada pelo evento OnKeyPress. Nesse momento o TTimer das pretas é habilitado e o das brancas é desabilitado. O processo continua até que um dos jogadores estoure o tempo ou a partida seja encerrada. Se o botão Pausar for pressionado, os dois TTimer são desabilitados e o rótulo dele muda para Continuar. Pressionando-se o botão novamente a partida prossegue do ponto onde parou.
O componente TTimer dispara um evento a determinados intervalos definidos na propriedade Interval. O valor informado em Interval é em milissegundos. Deixamos a propriedade com o valor padrão 1000 milissegundos. Ou seja, o evento OnTimer irá acontecer a cada segundo.

O código

Grande parte do código é bem simples e não merece maiores explicações. Vou apresentar o método do evento OnClick do botão Pausar/Continuar. Para o funcionamento correto, declarei duas variáveis boolean globais: blPausa, que define se o relógio está em pausa ou em andamento, e blBrancas, que define de quem é o relógio que está em andamento.

procedure TfrmRelogio.btPausarClick(Sender: TObject);
begin
   if not blPausa then
   begin
      if blBrancas then
         timBrancas.Enabled := false
      else
         timPretas.Enabled := false;
      btParar.Enabled := false;
      blPausa := true;
      btPausar.Caption := 'Continuar';
   end
   else
   begin
      if blBrancas then
      begin
         timBrancas.Enabled := true;
         btBrancas.SetFocus;
      end
      else
      begin
         timPretas.Enabled := true;
         btPretas.SetFocus;
      end;
      blPausa := false;
      btParar.Enabled := true;
      btPausar.Caption := 'Pausar';
   end
end;

De acordo com o estado de blPausa, habilita-se/desabilita-se o TTimer correspondente e ora o botão das brancas recebe o foco, ora o botão das pretas é quem recebe o foco. Nesse evento muda-se o rótulo do botão, alternando-se entre Pausar e Continuar.

Os eventos OnTimer tanto das brancas quanto das pretas são similares. Mostro apenas o método referente às brancas.

procedure TfrmRelogio.timBrancasTimer(Sender: TObject);
var
  bTotal, bParcial: integer;
begin
  bSeg := bSeg + 1;
  if bSeg > 59 then
  begin
     bSeg := 0;
     bMin := bMin + 1;
     if bMin > 59 then
     begin
        bMin := 0;
        bHor := bHor + 1;
     end
  end;
  lbBrancas.Caption := StrZero(bHor, 2, 0) + ':' + StrZero(bMin, 2, 0)+':'+StrZero(bSeg, 2, 0);
  bTotal := StrToInt(edHora.Text) * 3600 + StrToInt(edMinuto.Text) * 60 + StrToInt(edSegundo.Text);
  bParcial := bHor * 3600 + bMin * 60 + bSeg;
  pbBrancas.Position := (100 * bParcial div bTotal);
  if (StrZero(bHor, 2, 0) >= edHora.Text) and (StrZero(bMin, 2, 0) >= edMinuto.Text) and (StrZero(bSeg, 2, 0) >= edSegundo.Text) then
  begin
      timBrancas.Enabled := false;
      ShowMessage('As brancas estouraram o tempo');
  end;
end;          

Nas linhas de 5 a 15, o tempo é incrementado. Observe que temos uma variável para hora, minutos e segundos. Em seguida o tempo é mostrado no rótulo correspondente ao display do relógio, na linha 16. Nas linhas de 17 a 19, é calculado o percentual de tempo decorrido e esse valor é mostrado no TProgressBar. Finalmente, é verificado se o tempo limite foi atingido. Caso positivo, o relógio é parado e a mensagem de estouro de tempo é mostrado.
A função StrZero() foi criada para preencher um número inteiro com zeros à esquerda. O código pode ser encontrado no download.
Baixe o programa completo aqui e divirta-se jogando Xadrez e aprendendo mais um pouco sobre Lazarus/FreePascal.

Nenhum comentário:

Django - Composição de queries brutas (raw queries)

Django Rest Framework (DRF) é uma poderosa ferramenta para criar Web APIs. Ele requer o uso de Python e do framework Django. Mesmo o Django...