Solucionado (ver solução)
Solucionado
(ver solução)
15
respostas

Dúvida no Ex. 2 da Aula 4 - Lendo do teclado e Relacionamento entre Funções

Oi gente! Tenho o seguinte codigo clojure, não compila. Definitivamente não entendo porquê? Parece esta todo como mandam as regras!

    (def total-de-vidas 6)
    (defn perdeu [] (print "voce perdeu! "))
    (defn ganhou [] (print "voce ganhou! "))
    (defn letras-faltantes [palavra acertos]
        (remove (fn [letra] (contains? acertos (str letra))) palavra)
    )

    (defn acertou-a-palavra-toda? [palavra acertos] 
        (empty? (letras-faltantes palavra acertos))
    )

    (defn le-letra! [] (read-line))
    (defn acertou? [chute palavra] (.contains palavra chute))

    (defn avalia-chute [chute vidas palavra acertos]
        (if 
            (acertou? chute palavra)
            (jogo vidas palavra (conj acertos chute))
            (jogo (dec vidas) palavra acertos)
        )
    )

    (defn jogo [vidas palavra acertos]
        (if (= vidas 0)
            (perdeu) 

            (if (acertou-a-palavra-toda? palavra acertos)    
                (ganhou)
                (avalia-chute (le-letra!) vidas palavra acertos)

            )
        )

    )

Lanca a seguinte exception:

      Exception in thread "main" java.lang.RuntimeException: Unable to resolve symbol: jogo in this context, compiling:(forca/core.clj:21)

aqui continua a pilha de exceptions....

       Caused by: java.lang.RuntimeException: Unable to resolve symbol: jogo in this context
        at clojure.lang.Util.runtimeException(Util.java:170)

Continuam mais linhas de exceptions...

15 respostas

Cremildo , Boa Tarde !

seu código está certo , mas vou pedir para fazer a seguinte modificação , que lembro que comigo deu certo !!

coloque a função avalia-chute abaixo da função jogo !

assim ele seu código irá rodar , o que está acontecendo , parece que ele não está reconhecendo o chamada da função jogo dentro do avalia chute .

faça isso e teste , acredito que dará certo .

poste o resultado aqui por gentileza

Bons estudos

Oi celso!

tentei por a função avalia-chute abaixo da funcao jogo, mas mesmo assim as duas funcoes continuavam a não se echergarem, até parece que tem modificador private em classes separadas! kikiki..!

Ao inves disso coloquei a função avalia-chute dentro do escopo da função jogo, assim funcionou, compilou, testei o jogo de todas as formas e funciona como se espera!

O mais estranho é que quando fiz o primeiro teste compilou e tudo correu bem! so que atualizei o leinigen, a partir dai comecou a lancar uma pilha de exceptions!

Aqui esta o código modificado (para não dizer corrigido!)


    (def total-de-vidas 6)
    (defn perdeu [] (print "voce perdeu! "))
    (defn ganhou [] (print "voce ganhou! "))
    (defn letras-faltantes [palavra acertos]
        (remove (fn [letra] (contains? acertos (str letra))) palavra)
    )

    (defn acertou-a-palavra-toda? [palavra acertos] 
        (empty? (letras-faltantes palavra acertos))
    )

    (defn le-letra! [] (read-line))
    (defn acertou? [chute palavra] (.contains palavra chute))

    (defn jogo [vidas palavra acertos]

        (defn avalia-chute [chute vidas palavra acertos]
            (if 
                (acertou? chute palavra)
                (jogo vidas palavra (conj acertos chute))
                (jogo (dec vidas) palavra acertos)
            )
        )

        (if (= vidas 0)
            (perdeu) 

            (if (acertou-a-palavra-toda? palavra acertos)    
                (ganhou)
                (avalia-chute (le-letra!) vidas palavra acertos)

               )
           )

       )

Oi celso!

tentei por a função avalia-chute abaixo da funcao jogo, mas mesmo assim as duas funcoes continuavam a não se echergarem, até parece que tem modificador private em classes separadas! kikiki..!

Ao inves disso coloquei a função avalia-chute dentro do escopo da função jogo, assim funcionou, compilou, testei o jogo de todas as formas e funciona como se espera!

O mais estranho é que quando fiz o primeiro teste compilou e tudo correu bem! so que atualizei o leinigen, a partir dai comecou a lancar uma pilha de exceptions!

Aqui esta o código modificado (para não dizer corrigido!)


    (def total-de-vidas 6)
    (defn perdeu [] (print "voce perdeu! "))
    (defn ganhou [] (print "voce ganhou! "))
    (defn letras-faltantes [palavra acertos]
        (remove (fn [letra] (contains? acertos (str letra))) palavra)
    )

    (defn acertou-a-palavra-toda? [palavra acertos] 
        (empty? (letras-faltantes palavra acertos))
    )

    (defn le-letra! [] (read-line))
    (defn acertou? [chute palavra] (.contains palavra chute))

    (defn jogo [vidas palavra acertos]

        (defn avalia-chute [chute vidas palavra acertos]
            (if 
                (acertou? chute palavra)
                (jogo vidas palavra (conj acertos chute))
                (jogo (dec vidas) palavra acertos)
            )
        )

        (if (= vidas 0)
            (perdeu) 

            (if (acertou-a-palavra-toda? palavra acertos)    
                (ganhou)
                (avalia-chute (le-letra!) vidas palavra acertos)

               )
           )

       )

Cremildo ,

estranho isso , comparei seu código com o meu está correto a diferença que a função avalia chuta está abaixo de jogo , segue meu código para comparação :

(ns forca.core
  (:gen-class))

(def total-de-vidas 6)

(defn perdeu [] (print "Voce Perdeu !!"))
(defn ganhou [] (print "Voce Ganhou !!"))

(defn letras-faltantes [palavra acertos]
    (remove (fn [letra] (contains? acertos (str letra))) palavra)
)

(defn acertou-a-palavra-toda? [palavra acertos] 
    (empty? (letras-faltantes palavra acertos))
)

(defn le-letra! [] (read-line))

(defn acertou? [chute palavra] (.contains palavra chute))


(defn jogo [vidas palavra acertos] 
    (if (= vidas 0) 
        (perdeu) 
        (if (acertou-a-palavra-toda? palavra acertos)
            (ganhou)
            (avalia-chute (le-letra!) vidas palavra acertos)
        )

    )
)

(defn avalia-chute [chute vidas palavra acertos]
    (if (acertou? chute palavra)
        (jogo vidas palavra (conj acertos chute))
        (jogo (dec vidas) palavra acertos)
    )
)

(defn -main
  "I don't do a whole lot ... yet."
  [& args]
  (println "Hello, World!")
)

espero ter ajudado , Bons estudos

solução!

O Celso!

Eu também tentei fazer o mesmo! Não importa se está antes ou depois da função jogo, desde que esteja fora dela, as duas funções não se enxergam uma a outra, e não sei porquê?

Talvez haja um modificador "private" omisso! Hahaha..! Brincadeira. O importaante é que conseguimos uma solução, embora diferente, mas resolve o problema.

Oi pessoal,

o problema aqui é que temos uma chamada circular de funções, f1 que chama f2 que chama f1.

O fato da função acertou-chute? chamar a função jogo, que por sua vez chama a função acertou-chute? de novo, confunde o compilador além de deixar o código um quanto confuso.

Talvez uma alternativa seria a função acertou-chute? ter uma responsabilidade única, como retornar um boolean e deixar para seu "chamador" tomar decisão em cima disso.

Segue meu código:

(def total-de-vidas 3)

(defn ganhou [] (print "ganhou"))

(defn letras-faltantes [palavra acertos]
  (remove (fn [letra]
            (contains? acertos (str letra))) palavra))

(defn acertou-a-palavra-toda? [palavra acertos]
  (empty? (letras-faltantes palavra acertos)))

(defn le-letra! [] (read-line))

(defn acertou-chute? [letra palavra]
  (.contains palavra letra))

(defn jogo [vidas palavra acertos]
  (if (= vidas 0)
    (print "perdeu...")
    (if (acertou-a-palavra-toda? palavra acertos)
      (ganhou)
      (do
        (def letra (le-letra!))
        (if (acertou-chute? letra palavra)
          (jogo vidas palavra (conj acertos letra))
          (jogo (dec vidas) palavra acertos))))))

To com o mesmo problema. Estranho ter compilado normalmente na vídeo-aula.

Aqui pra mim deu problema de compilação também. Estou usando a versão Windows. Utilizei a solução do Celso e deu certo. Deixei como backup a solução anterior para tentar mais tarde.

A única solução que encontrei foi a do Cremildo.

E mesmo que seja private (o que não é, já que defn por default é public) deveria ter acesso, certo? Afinal é o mesmo arquivo...

Alguns detalhes: Java 1.8.0_60; Clojure: 1.7.0.

Não faz 1 mês que fiz atualizações dos mesmos.

O meu aconteceu a mesma coisa. A única forma de rodar foi passar a função 'avalia-chute' para antes da verificação de vidas = 0. Na verdade eu não entendi muito bem a razão de esta modificação ter resultado em uma compilação adequada. De qualquer forma vou colocar meu código aqui para caso alguém tenha problemas também.

(ns forca.core
  (:gen-class))

(def total-de-vidas 6)

(defn perdeu [] (print "Voce Perdeu !!"))
(defn ganhou [] (print "Voce Ganhou !!"))

(defn letras-faltantes [palavra acertos]
    (remove (fn [letra] (contains? acertos (str letra))) palavra)
)

(defn acertou-a-palavra-toda? [palavra acertos] 
    (empty? (letras-faltantes palavra acertos))
)

(defn le-letra! [] (read-line))

(defn acertou? [chute palavra] (.contains palavra chute))


(defn jogo [vidas palavra acertos] 
    (defn avalia-chute [chute vidas palavra acertos]
    (if (acertou? chute palavra)
        (jogo vidas palavra (conj acertos chute))
        (jogo (dec vidas) palavra acertos)
    )
)
    (if (= vidas 0) 
        (perdeu) 
        (if (acertou-a-palavra-toda? palavra acertos)
            (ganhou)
            (avalia-chute (le-letra!) vidas palavra acertos)
        )

    )
)


(defn -main
  "I don't do a whole lot ... yet."
  [& args]
  (println "Hello, World!")
)

Olá Pessoal, também passei pelo mesmo problema e somente aplicando a solução do Cremildo funcionou.

Pessoal também tive o mesmo problema, uma outra solução que encontrei foi apenas adicionar o código da função 'avalia-chute' dentro da função 'jogo', utilizando o operador 'let' (http://clojuredocs.org/clojure.core/let) para armazenar o 'chute' e poder reutilizá-lo. Acho que fica menos estranho do que definir uma função dentro de outra:

(ns forca.core
  (:gen-class))

(def total-de-vidas 6)

(defn perdeu [] (println "Você perdeu!"))
(defn ganhou [] (println "Você ganhou!"))

(defn letras-restantes [palavra acertos]
  (remove #(contains? acertos (str %)) palavra))

(defn acertou-a-palavra-toda? [palavra acertos]
  (empty? (letras-restantes palavra acertos)))

(defn acertou-chute? [chute palavra]
  (.contains palavra chute))

(defn le-chute! []
  (read-line))

(defn jogo [vidas palavra acertos]
  (if (= vidas 0)
    (perdeu)
    (if (acertou-a-palavra-toda? palavra acertos)
      (ganhou)
      (let [chute (le-chute!)]
        (if (acertou-chute? chute palavra)
          (jogo vidas palavra (conj acertos chute))
          (jogo (dec vidas) palavra acertos))))))

(defn -main
  "Start..."
  [& args]
  (println "Hello world!"))

Uma alternativa seria no topo do código inserir a declaração da função jogo: (declare jogo)

Completo ficaria:



(ns forca.core
  (:gen-class))

(declare jogo)

(def total-de-vidas 6)

(defn perdeu [] (print "Você perdeu"))
(defn ganhou [] (print "Você ganhou!"))

(defn letras-faltantes [palavra acertos]
    (remove (fn [letra] (contains? acertos (str letra))) palavra))

(defn acertou-a-palavra-toda? [palavra acertos] 
    (empty? (letras-faltantes palavra acertos))
)

(defn le-letra! [] (read-line))

(defn acertou? [chute palavra] (.contains palavra chute))


(defn avalia-chute [chute vidas palavra acertos]
    (if (acertou? chute palavra)
        (jogo vidas palavra (conj acertos chute))
        (jogo (dec vidas) palavra acertos)
    )

)


(defn jogo [vidas palavra acertos]
    (if (= vidas 0) 
        (perdeu)
        (if (acertou-a-palavra-toda? palavra acertos)
            (ganhou)
            (avalia-chute (le-letra!) vidas palavra acertos)
        )
    )
)


(defn -main
  "I don't do a whole lot ... yet."
  [& args]
  (println "Hello, World!"))

Acho que todos vamos ter o mesmo problema. Achei ótima essa solução de declarar a função Guilherme.

Gostei da solução do Guilherme, só queria entender o que mudou da versão que foi gravado o video para as versões posteriores que nao permiti que o código compile.