2012-06-21 20 views
10

Póster por primera vez y perl noobie a tiempo parcial.Cómo detener la entrada en Perl?

Estoy haciendo un juego de reflejos. Aquí está la salida -

__________________________________________________________________________ 
Reflex game initiated. Press ENTER to begin the game, and then press ENTER 
after the asterisks are printed to measure your reflexes!. 


************************* 

Your result: 0.285606 seconds. 
logout 

[Process completed] 
__________________________________________________________________________ 

Hay un pequeño problema, aunque - No es 0-10 segundos (basado en una variable aleatoria) después de pulsar ENTER para iniciar el juego y antes de la impresión de las estrellas. Durante ese tiempo, si el jugador presiona ENTRAR, se registra como su tiempo reflejo. Así que necesito una forma de evitar que mi código lea su botón ENTER antes de que se impriman las estrellas. El código -

#!/usr/bin/perl 

use Time::HiRes qw(sleep); 
use Time::HiRes qw(gettimeofday); 

#random delay variable 
$random_number = rand(); 

print "Reflex game initiated. Press ENTER to begin the game, and then press ENTER after   the asterisks are printed to measure your reflexes!.\n"; 

#begin button 
$begin = <>; 

#waits x milliseconds 
sleep(10*$random_number); 

#pre-game 
$start = [ Time::HiRes::gettimeofday() ]; 

print "\n****************************\n"; 

#user presses enter 
$stop = <>; 

#post game 
$elapsed = Time::HiRes::tv_interval($start); 

#delay time print 
print "Your result: ".$elapsed." seconds.\n"; 
+0

las estrellas no se imprimieron en la salida, lo siento. están justo entre 'tus relexes' e 'impreso para medir tus reflejos'. – user1472747

+0

posible duplicado de [Flushing Perl STDIN buffer] (http://stackoverflow.com/questions/7602861/flushing-perl-stdin-buffer) – pilcrow

Respuesta

4

La repetición de la original answer por CanSpice:

Parece que Term::ReadKey puede ayudar.

#!perl 

use strict; 
use warnings; 
use 5.010; 

use Term::ReadKey; 

say "I'm starting to sleep..."; 
ReadMode 2; 
sleep(10); 
ReadMode 3; 
my $key; 
while(defined($key = ReadKey(-1))) {} 
ReadMode 0; 
say "Enter something:"; 
chomp(my $input = <STDIN>); 
say "You entered '$input'"; 

Esto es lo que sucede:

  • ReadMode 2 significa "poner el modo de entrada en el modo normal, pero apagar el eco". Esto significa que cualquier golpeteo del teclado que haga el usuario mientras se encuentre en su código computacionalmente caro no se reflejará en la pantalla. Todavía se entró en búfer STDIN 's aunque, por lo ...
  • ReadMode 3 convierte STDIN en modo cbreak, lo que significa STDIN tipo de personal se van después de cada pulsación de tecla. Es por eso que ...
  • while(defined($key = ReadKey(-1))) {} sucede. Esto está eliminando los caracteres que el usuario ingresó durante el código de costo computacional. Luego ...
  • ReadMode 0 restablece STDIN, y puede leer en STDIN como si el usuario no hubiera golpeado el teclado.

Cuando ejecuto este código y explosión en el teclado durante la sleep(10), a continuación, introduzca un texto diferente después del indicador, sólo se imprime el texto que he escrito después de la pronta aparición.

Estrictamente hablando, el ReadMode 2 no es necesario, pero lo coloco allí para que la pantalla no se sature con el texto cuando el usuario golpea el teclado.

+3

Alguna explicación sería agradable. – TLP

+0

Explicación Agregado. – ZnArK

+0

Esta respuesta (código y explicación) se copia literal de la "Respuesta original", excepto por la cita de introducción y la edición/enlace. ¿Tal vez en lugar de duplicar respuestas deberíamos cerrar la pregunta como un dúo? – pilcrow

Cuestiones relacionadas