Solucionado (ver solução)

Importante

Você está vendo a versão anterior da nova experiência da Alura que estamos preparando para você. Em breve, ela ganha uma identidade visual novinha totalmente pensada em potencializar seus estudos!

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.