elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.

 

 


Tema destacado: Tutorial básico de Quickjs


+  Foro de elhacker.net
|-+  Programación
| |-+  Scripting
| | |-+  Conteo continuo con Batch (Ayuda)
0 Usuarios y 1 Visitante están viendo este tema.
Páginas: [1] Ir Abajo Respuesta Imprimir
Autor Tema: Conteo continuo con Batch (Ayuda)  (Leído 1,410 veces)
Mr. Bit

Desconectado Desconectado

Mensajes: 30



Ver Perfil
Conteo continuo con Batch (Ayuda)
« en: 9 Marzo 2024, 17:07 pm »

Buenas, ¿cómo andan?

Tengo una duda acerca de un tema en Batch que la verdad no estoy pudiendo resolver, y que es demasiado específico como para buscar una respuesta general en internet, o por lo menos yo no estoy encontrando ninguna.

Estoy hace un tiempo con un proyecto de un RPG utilizando Batch, por el momento va bastante bien, pero hay algo nuevo que me gustaría implementar y que no estoy pudiendo entender. Voy a ser lo más claro y explicito posible para que se entienda:

Yo quiero que, en mi juego, exista una variable de "tiempo" que vaya corriendo cada segundo. Pero, que mientras esa variable corre (que supongo que sería una especie de bucle), el usuario o jugador pueda realizar otras acciones, ir de menú en menú, y que ese "tiempo" siga corriendo.

Código:
@echo off
set tiempo=0

:tiempo_corriendo
cls
echo Tiempo: %tiempo%
timeout /t 1 /nobreak >nul
set /a tiempo=%tiempo%+1
goto tiempo_corriendo

Ese es un breve ejemplo que hice para este posteo; un bucle de tiempo que cada 1 segundo la variable "tiempo" va aumentando +1. Pero, el usuario en este caso no puede hacer nada. O sea, por ejemplo, si pongo un input como "set /p opcion=" (para que el jugador seleccione algún tipo de opción) antes del "goto tiempo_corriendo" el bucle se congelaría ya que no estaría llegando a analizar la última linea que le dice que vuelva a ":tiempo_corriendo" y se repita el bucle.


No sé si mi duda será clara, espero que sí. Cualquier cosa puedo explicarlo de otra manera.
Desde ya muchas gracias.


En línea

**Aincrad**


Desconectado Desconectado

Mensajes: 668



Ver Perfil WWW
Re: Conteo continuo con Batch (Ayuda)
« Respuesta #1 en: 9 Marzo 2024, 17:18 pm »

Por lo que recuerdo Batch no tiene la capacidad de múltiples hilos , por lo que no creo que puedas hacer eso. con vbs si podrias.

de todos modos, tal vez usando Start llamando a otro .bat cada cierto tiempo , pero de todos modos , no lo creo posible.

otro modo rebuscado tal vez, seria crear un bucle que seria la funcion de renderizado, manejar todo con estados y simular un Timer usando la hora del sistema.


« Última modificación: 9 Marzo 2024, 17:21 pm por **Aincrad** » En línea



Mr. Bit

Desconectado Desconectado

Mensajes: 30



Ver Perfil
Re: Conteo continuo con Batch (Ayuda)
« Respuesta #2 en: 9 Marzo 2024, 17:42 pm »

(Primero que nada, perdón por haber hecho varios posteos, como no los veía en la lista pensé que había un error o exceso de caracteres por eso terminé subiendo tres)

Volviendo al punto, he visto que un chico creó un juego llamado "Gem Miner" utilizando puramente Batch, que basicamente se trata de contratar mineros para que hagan el trabajo. Y cada segundo, se van sumando "gemas", estando dentro del menú y pudiendo seleccionar otras opciones, se nota como se va refrezcando y las gemas se van sumando una por una.
En línea

Eleкtro
Ex-Staff
*
Desconectado Desconectado

Mensajes: 9.822



Ver Perfil
Re: Conteo continuo con Batch (Ayuda)
« Respuesta #3 en: 9 Marzo 2024, 18:24 pm »

Ese es un breve ejemplo que hice
(...)
Pero, el usuario en este caso no puede hacer nada.

Esa es la naturaleza de Batch-script. Los archivos por lotes no entienden de conceptos como hilos que trabajen de forma asincrónica realizando tareas en segundo plano sin interrumpir el flujo de la aplicación. Se puede simular algo, pero es muy limitado.

Lo que solicitas hacer, lo podrías hacer perfectamente en otro lenguaje de programación, pero no puedes hacerlo con la precisión necesaria en una herramienta tan limitada como es Batch. Y cualquier cosa que veas similar a lo que solocitas, será una mera simulación imprecisa haciendo saltos "GoTo" o "Call" entre etiquetas u otras formas muy enrevesadas que se me ocurren, por ejemplo, mediante la ejecución de un script adicional que vaya guardando el tiempo transcurrido en segundos en un archivo intermediario de texto plano, y desde el script principal simplemente lees el contenido del archivo intermediario para obtener los segundos transcurridos...

Aquí abajo te muestro un ejemplo de esa metodología.

De esta forma se logra evitar la interrupción de la ejecución del script principal, pero no esperes precisión en términos de mostrar segundo a segundo (1+1) en pantalla. Y además, tiene sus complicaciones, ya que el archivo intermediario puede estar en uso, siendo escrito por el script adicional, al mismo tiempo que se intenta leer desde el script principal, causando errores (que se pueden silenciar) y mayor imprecisión causando 1 segundo de retraso cada vez que no se pueda leer el archivo, o que el archivo contenga el mismo valor por que el script adicional todavía no haya completado el intervalo de 1 segundo (del comando TIMEOUT) para escribir el nuevo valor en el archivo intermediario.

Con el comando SETX para crear variables de entorno y el modificador /F para extraer el valor desde un archivo de texto, también se puede hacer algo parecido, pero sería incluso más enrevesado.

Este tipo de cosas no son para intentar hacerlas en Batch, insisto. Quizás haya una metodología más eficiente que esta, pero no creo que merezca la pena investigar siendo Batch.

Por último, te muestro el ejemplo:

Timer.cmd
Código
  1. @Echo Off
  2.  
  3. (ECHO+)>"%TEMP%\ElapsedSeconds.tmp"
  4. FOR /L %%# IN (1, 1, 9999999) DO (
  5. (
  6. TIMEOUT /T 1 /NOBREAK
  7.     ECHO:%%#>"%TEMP%\ElapsedSeconds.tmp"
  8.    )1>NUL 2>&1
  9. )
  10.  
  11. Exit /B 0

Script Principal.cmd
Código
  1. @Echo Off
  2. SetLocal EnableDelayedExpansion
  3.  
  4. Start /B "" CMD /K "Call Timer.cmd"
  5.  
  6. SET /A "PreviousValue=0"
  7. SET /A "ElapsedSeconds=0"
  8.  
  9. FOR /L %%# IN (0, 1, 9999999) DO (
  10. (
  11. TIMEOUT /T 1 /NOBREAK
  12. FOR /F "UseBackQ Tokens=* Delims=" %%_ IN (
  13. "%TEMP%\ElapsedSeconds.tmp"
  14. ) DO (
  15. SET /A "ElapsedSeconds=%%_"
  16. )
  17. )1>NUL 2>&1
  18.  
  19. If !ElapsedSeconds! NEQ !PreviousValue! (
  20. ECHO:Elapsed Seconds: !ElapsedSeconds!
  21. SET /A "PreviousValue=!ElapsedSeconds!"
  22. )
  23. )
  24.  



Aténtamente,
Elektro.
« Última modificación: 9 Marzo 2024, 18:34 pm por Eleкtro » En línea

Tachikomaia


Desconectado Desconectado

Mensajes: 1.224


Superhacker (es broma xD )


Ver Perfil
Re: Conteo continuo con Batch (Ayuda)
« Respuesta #4 en: 9 Marzo 2024, 18:30 pm »

¿Puedes captar la hora del sistema?

Los RPG son de mis juegos favoritos, pero de batch casi nada sé. Quizá para uno de esos deberías cambiar de lenguaje.

ChatGPT:
Citar
En Batch, puedes utilizar el comando `timeout` para realizar una espera durante un período de tiempo determinado. Sin embargo, Batch no permite la interacción directa con el usuario mientras se ejecuta un comando de tiempo de espera. Por lo tanto, no es posible tener un código Batch que cuente el tiempo y permita que un usuario realice acciones simultáneamente.

Si necesitas una solución que cuente el tiempo y permita la interacción del usuario al mismo tiempo, sería más apropiado utilizar un lenguaje de programación más avanzado como Python, Java o C#. Estos lenguajes ofrecen bibliotecas y funcionalidades para gestionar el tiempo y la interacción con los usuarios de manera simultánea.

Aquí tienes un ejemplo en Python que cuenta el tiempo y permite que el usuario realice acciones al mismo tiempo:

```python
import time

# Definir el tiempo límite en segundos
tiempo_limite = 60

# Obtener el tiempo de inicio
inicio = time.time()

# Bucle principal
while True:
    # Obtener el tiempo actual
    tiempo_actual = time.time()
    
    # Calcular el tiempo transcurrido
    tiempo_transcurrido = tiempo_actual - inicio
    
    # Verificar si se ha alcanzado el tiempo límite
    if tiempo_transcurrido >= tiempo_limite:
        print("Tiempo límite alcanzado.")
        break
    
    # Realizar acciones del usuario
    accion = input("Ingresa una acción: ")
    print("Realizando la acción:", accion)
```

Este código utiliza la biblioteca `time` de Python para calcular el tiempo transcurrido y establece un tiempo límite de 60 segundos. El bucle principal permite que el usuario realice acciones ingresando datos a través de `input()`. El programa seguirá ejecutándose hasta que se alcance el tiempo límite o el usuario decida salir del bucle.

Recuerda que este es solo un ejemplo básico y puedes adaptarlo según tus necesidades específicas.

¿hay algún modo de captar la hora del sistema y restarle la hora inicial?

Citar
Sí, en Batch puedes utilizar el comando `wmic` para obtener la fecha y hora actual del sistema. Luego, puedes realizar la resta con la hora inicial para obtener la diferencia en tiempo transcurrido. Aquí tienes un ejemplo de cómo hacerlo:

```batch
@echo off

REM Obtener la hora inicial
for /F "tokens=1-3 delims=:." %%a in ("%time%") do (
    set /A "hora_inicial=%%a*3600 + %%b*60 + %%c"
)

REM Bucle principal
:loop
REM Obtener la hora actual
for /F "skip=1 delims=" %%a in ('wmic path win32_localtime get Hour,Minute,Second /format:list') do (
    for /F "tokens=2 delims==" %%b in ("%%a") do set "hora_actual=%%b"
)

REM Calcular la diferencia
for /F "tokens=1-3 delims=:." %%a in ("%hora_actual%") do (
    set /A "hora_actual=%%a*3600 + %%b*60 + %%c"
)

REM Restar la hora inicial a la hora actual
set /A "diferencia=hora_actual - hora_inicial"

REM Mostrar la diferencia en tiempo transcurrido
echo Tiempo transcurrido: %diferencia% segundos

REM Esperar un segundo antes de verificar nuevamente
ping -n 2 127.0.0.1 >nul

REM Volver al inicio del bucle
goto loop
```

En este código, se utiliza un bucle infinito (`:loop`) para obtener continuamente la hora actual del sistema utilizando el comando `wmic`. Luego, se convierte la hora inicial y la hora actual en segundos para realizar la resta y obtener la diferencia en tiempo transcurrido. Esta diferencia se muestra en la consola.

El comando `ping -n 2 127.0.0.1 >nul` se utiliza para introducir una pausa de 1 segundo antes de obtener la hora actual nuevamente. Puedes ajustar este valor si deseas una frecuencia de actualización diferente.

Recuerda que Batch no es el lenguaje más adecuado para este tipo de tareas, ya que su capacidad de manejar el tiempo y la interacción con el usuario es limitada. Si necesitas una solución más robusta, te recomendaría utilizar un lenguaje de programación más avanzado como Python, como se mencionó anteriormente.
Si logras que se actualicen los segundos podría haber una simulación de que el tiempo pasa, pero como comentaste parece que para hacer eso tendrías que estar en un bucle constante chequeando si el tiempo cambió o no.

¿Seguro que lo hizo en Batch?
En línea

Eleкtro
Ex-Staff
*
Desconectado Desconectado

Mensajes: 9.822



Ver Perfil
Re: Conteo continuo con Batch (Ayuda)
« Respuesta #5 en: 9 Marzo 2024, 18:51 pm »

he visto que un chico creó un juego llamado "Gem Miner" utilizando puramente Batch

Sin más información, cabe la posibilidad de que parte del código esté escrito en Batch-Script, y parte en otros lenguajes, es decir un código híbrido, para sortear las limitaciones del primero.

También cabe la posibilidad de que el juego dependa del uso de "comados externos" (aplicaciones de terceros por línea de comandos) para llevar a cabo esas tareas limitadas en Batch-Script.

Si no te importase emplear lenguajes adicionales en tu proyecto de Batch para "hibridarlo", entonces te sugiero usar PowerShell para llevar a cabo de forma más fácil y sofisticada lo que quieras hacer.



¿Puedes captar la hora del sistema?

La cuestión no parece ser como asignar la hora actual del sistema a una variable, ni como realizar operaciones aritméticas con los segundos, sino hacerlo con un mínimo de precisión sin interrumpir la ejecución del script.

De todas formas, y para aclarar tu duda, sí, la hora actual del sistema se puede obtener mediante el valor de la variable dinámica %TIME%, y se puede asignar los segundos actuales (00~59) a una variable local.



¿hay algún modo de captar la hora del sistema y restarle la hora inicial?

Veo que ChatGPT es extremadamente inútil hasta para intentar resolver cuestiones básicas de programación por lotes con Batch-Script. Como para confiar en sus afirmaciones y en sus códigos al formularle preguntas sobre lenguajes de programación que no se limiten al uso de treinta comandos contados, documentados y exprimidos al máximo durante décadas. Vaya una IA, ¡no sabe hacer nada de forma óptima!.

Realizar una llamada a las clases de la infrastructura WMI mediante wmic.exe supone una ralentización elevada e innecesaria en el tiempo de respuesta de cualquier aplicación. Supone una interrupción bastante medible (a veces puede tardar hasta 2-3 segundos. Depende de cómo se realice la solicitud a WMI, qué clase y que propiedades), y no hay necesidad de ello pudiendo obtener le hora actual de forma inmediata mediante el valor expuesto a través de la variable dinámica %TIME% como ya expliqué.

Pero estas cosas no son para hacerlas en Batch-script, insisto una vez más, no es la forma óptima, ni tampoco la más sencilla. Sus limitaciones implican recurrir al ingenio para acabar sorteando dichas limtiaciones mediante la creació de algoritmos tediosos (y feos, e imprecisos) que en muchos casos incluso podrían ser simplificados en una sola línea de código en otros lenguajes de programación.
« Última modificación: 9 Marzo 2024, 20:01 pm por Eleкtro » En línea

**Aincrad**


Desconectado Desconectado

Mensajes: 668



Ver Perfil WWW
Re: Conteo continuo con Batch (Ayuda)
« Respuesta #6 en: 9 Marzo 2024, 19:41 pm »

Esa es la naturaleza de Batch-script. Los archivos por lotes no entienden de conceptos como hilos que trabajen de forma asincrónica realizando tareas en segundo plano sin interrumpir el flujo de la aplicación. Se puede simular algo, pero es muy limitado.

Lo que solicitas hacer, lo podrías hacer perfectamente en otro lenguaje de programación, pero no puedes hacerlo con la precisión necesaria en una herramienta tan limitada como es Batch. Y cualquier cosa que veas similar a lo que solocitas, será una mera simulación imprecisa haciendo saltos "GoTo" o "Call" entre etiquetas u otras formas muy enrevesadas que se me ocurren, por ejemplo, mediante la ejecución de un script adicional que vaya guardando el tiempo transcurrido en segundos en un archivo intermediario de texto plano, y desde el script principal simplemente lees el contenido del archivo intermediario para obtener los segundos transcurridos...

Aquí abajo te muestro un ejemplo de esa metodología.

De esta forma se logra evitar la interrupción de la ejecución del script principal, pero no esperes precisión en términos de mostrar segundo a segundo (1+1) en pantalla. Y además, tiene sus complicaciones, ya que el archivo intermediario puede estar en uso, siendo escrito por el script adicional, al mismo tiempo que se intenta leer desde el script principal, causando errores (que se pueden silenciar) y mayor imprecisión causando 1 segundo de retraso cada vez que no se pueda leer el archivo, o que el archivo contenga el mismo valor por que el script adicional todavía no haya completado el intervalo de 1 segundo (del comando TIMEOUT) para escribir el nuevo valor en el archivo intermediario.

Con el comando SETX para crear variables de entorno y el modificador /F para extraer el valor desde un archivo de texto, también se puede hacer algo parecido, pero sería incluso más enrevesado.

Este tipo de cosas no son para intentar hacerlas en Batch, insisto. Quizás haya una metodología más eficiente que esta, pero no creo que merezca la pena investigar siendo Batch.

Por último, te muestro el ejemplo:

Timer.cmd
Código
  1. @Echo Off
  2.  
  3. (ECHO+)>"%TEMP%\ElapsedSeconds.tmp"
  4. FOR /L %%# IN (1, 1, 9999999) DO (
  5. (
  6. TIMEOUT /T 1 /NOBREAK
  7.     ECHO:%%#>"%TEMP%\ElapsedSeconds.tmp"
  8.    )1>NUL 2>&1
  9. )
  10.  
  11. Exit /B 0

Script Principal.cmd
Código
  1. @Echo Off
  2. SetLocal EnableDelayedExpansion
  3.  
  4. Start /B "" CMD /K "Call Timer.cmd"
  5.  
  6. SET /A "PreviousValue=0"
  7. SET /A "ElapsedSeconds=0"
  8.  
  9. FOR /L %%# IN (0, 1, 9999999) DO (
  10. (
  11. TIMEOUT /T 1 /NOBREAK
  12. FOR /F "UseBackQ Tokens=* Delims=" %%_ IN (
  13. "%TEMP%\ElapsedSeconds.tmp"
  14. ) DO (
  15. SET /A "ElapsedSeconds=%%_"
  16. )
  17. )1>NUL 2>&1
  18.  
  19. If !ElapsedSeconds! NEQ !PreviousValue! (
  20. ECHO:Elapsed Seconds: !ElapsedSeconds!
  21. SET /A "PreviousValue=!ElapsedSeconds!"
  22. )
  23. )
  24.  



Aténtamente,
Elektro.


algo como eso es exactamente lo que tenia en mente, sin embargo es extremadamente ineficiente , para realizar un juego como un RPG, definitivamente será necesario correr código de forma asincrónica ... pero bueno... ya se le advirtió.

En línea



Tachikomaia


Desconectado Desconectado

Mensajes: 1.224


Superhacker (es broma xD )


Ver Perfil
Re: Conteo continuo con Batch (Ayuda)
« Respuesta #7 en: 9 Marzo 2024, 20:48 pm »

¿No se puede hacer algo como:
Código:
Repetir:
  Actualizar el tiempo.
  Si el jugador presiona tecla:
    Hacer tarea.
mientras...
?
En línea

Páginas: [1] Ir Arriba Respuesta Imprimir 

Ir a:  

Mensajes similares
Asunto Iniciado por Respuestas Vistas Último mensaje
Ayuda - Burlar pagina de conteo « 1 2 »
Seguridad
leogtz 12 7,244 Último mensaje 19 Agosto 2010, 00:28 am
por cgvwzq
Ayuda con conteo de registros en php y mysql « 1 2 »
PHP
RedZer 13 9,372 Último mensaje 5 Diciembre 2010, 20:28 pm
por RedZer
Conteo
Programación C/C++
Ander123 9 4,064 Último mensaje 29 Agosto 2012, 18:48 pm
por leosansan
conteo de lineas en c
Programación C/C++
nietsnie 2 1,534 Último mensaje 17 Octubre 2015, 00:05 am
por DarK_FirefoX
Ayuda con conteo en tiempo real
Scripting
Mr. Bit 0 258 Último mensaje 9 Marzo 2024, 17:18 pm
por Mr. Bit
WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines