Как прочитать строку, чтобы получить пользовательский ввод в GNU Guile?

Я пытаюсь сделать игру «Камень, ножницы, бумага», чтобы помочь себе использовать GNU Guile. Я столкнулся с проблемой, когда я получаю пользовательский ввод, выбор игрока в игре. Если я задаю его строкой, то игра работает корректно. Если я использую (read), я возвращаю #f как тип из поиска. Я пробовал форматировать чтение, чтобы попытаться сделать его строкой, но это не сработало.

(define (print a)
  (display a)
  (newline))

(define choices (make-hash-table 3))
(hashq-set! choices "r" "s")
(hashq-set! choices "s" "p")
(hashq-set! choices "p" "r")

(define (cpu-choice) (list-ref (list "r" "p" "s") (random 3)))

(print "You are playing rock paper scissors.")
(print "Type r for rock, p for paper, and s for scissors.")
(define draw
  ;; "s" ; This works as a test.
 (read (open-input-string (read))) ; Can't get user in as string, so the hashq-ref will work.
  )

(define cpu-draw (cpu-choice))

;; debug
(print (format #f "Player enterd ~a" draw))
(print (format #f "Player needs to with ~a" (hashq-ref choices draw))) ; Keeps coming back as #f
(print (format #f "CPU has entered ~a" cpu-draw))

;; norm
(newline)
(when (eq? draw cpu-draw)
  (print "There was a tie")
  (exit))

(when (eq? (hashq-ref choices draw) cpu-draw)
  (print "You have won.")
  (exit))

(print "You have failed. The computer won.")

Как получить строку от пользователя? Может быть, что-то вроде (str (read)) или (read-string) (читается как строка).

$ guile --version
guile (GNU Guile) 2.0.13

Обновлять

Я просто хотел бы отметить, что хотя утвержденный ответ верен, я не понял, как Guile/Scheme обрабатывает строки и символы при написании этого. Единственный способ заставить программу работать — заменить все строки в choices и в списке cpu-choice на символы. Бывший:

(hashq-set! choices 'r 's)
(list 'r 'p 's)

Спасибо, Оскар Лопес, за помощь.


person 9716278    schedule 23.11.2019    source источник


Ответы (1)


Если вы не заключите ввод в двойные кавычки, введенное вами значение будет интерпретировано как символ. Либо попробуйте это:

(define str (read))
> "hello"

Или это:

(define str (symbol->string (read)))
> hello

В любом случае str теперь будет содержать реальную строку:

str
=> "hello"
person Óscar López    schedule 23.11.2019