#User Input during a time.sleep (RAW)

11 messages · Page 1 of 1 (latest)

torn loom
#

Yes, the title isn't very good. Let me explain.
In my hangman game, I want to add a bonus that indicates the time you have to print a letter. The time is set to 10sec. The problem is that I'm having trouble displaying the remaining time in real time on the terminal (like Time remaining 10s, Time remaining 9s ect (with time.sleep ect)) and asking the user for their opinion. So I used mouse cursor movement to move from line 0 to line 1 and get user input while displaying time remaining. The funny thing is that I don't know how to make a proper user input that allows the user to print a letter and not instantly exit the program after a user input. If you don't understand what I'm saying, I can try to explain it again.

#

Here is my actual CODE :

package main

import (
    "fmt"
    "os"
    "time"

    "golang.org/x/term"
)

func main() {
    done := make(chan bool)
    go waitForInput(done)
    startTime := time.Now()
    duration := 10 * time.Second
    ticker := time.NewTicker(500 * time.Millisecond)
    isTimeRemaining := true
    for {
        select {
        case <-ticker.C:
            if isTimeRemaining {
                elapsed := time.Since(startTime)
                remaining := duration - elapsed
                if remaining <= 0 {
                    remaining = 0
                    os.Exit(0)
                }
                moveCursorToLine(0)
                fmt.Printf("\033[2K\rTemps restant: %s", remaining.Round(time.Second))
            } else {
                moveCursorToLine(1)
                fmt.Printf("\033[2K\rEntrez quelque chose: ")
            }
            isTimeRemaining = !isTimeRemaining
        case <-done:
            ticker.Stop()
            fmt.Println("\nSaisie utilisateur détectée.")
            return
        case <-time.After(duration):
            ticker.Stop()
            fmt.Println("\nTemps écoulé sans saisie.")
            return
        }
    }
}

func waitForInput(done chan<- bool) {
    oldState, err := term.MakeRaw(int(os.Stdin.Fd()))
    if err != nil {
        fmt.Println("Impossible de passer en mode raw:", err)
        return
    }
    defer term.Restore(int(os.Stdin.Fd()), oldState)
    var buf [1]byte
    for {
        _, err := os.Stdin.Read(buf[:])
        if err != nil {
            fmt.Println("Erreur de lecture de l'entrée:", err)
            return
        }
        done <- true
        break
    }
}

func moveCursorToLine(line int) {
    fmt.Printf("\033[%d;0H", line+1)
}
snow oasis
#

use chan byte, and pass your byte though the channel

#

you don't need done in this case

#

and don't break your loop

torn loom
#

Yeah that's what I was thinking

#

I mean, the byte

#

imma try that

#

alr that work

#

Now, it doesn't like, keep the letter on the line

#

SO maybe I should do a if or a case that'll keep the letter and show it on another line ?