Ich will ein Random Integer, wie?



  • Guten Abend,

    ich bin gerade dabei, etwas Haskell zu lernen. Ich stehe noch sehr am Anfang und ich komme leider gerade überhaupt nicht auf die Implementation von zufälligen Zahlen in Haskell klar. Ich habe etwas recherchiert, aber überall stehen andere Wege, manche produzieren IO Integer, mit denen ich nichts anfangen kann, etc. Bin gerade etwas hilflos, daher poste ich hier, sorry 😛

    Folgende Sache : Ich will ein ganz simples Spiel programmieren. Ich glaube, dass es dem Spiel Black Jack ähnlich kommt.

    Das Spiel startet, 2 Spieler sind beteiligt. Spieler 1 würfelt sozusagen solange er will, wenn er < 21 bleibt gehts weiter. Wenn er über 21 kommt hat er verloren, wenn er die Eingabe abbricht zählt sein momentaner Punktestand als Endpunktestand.
    Dann ist Spieler 2 dran. Er macht das Gleiche. Am Ende gewinnt der mit der höheren Punktzahl, die gleichzeitig ja <21 sein muss.

    Momentan addiere ich zu Test-Zwecken immer feste Werte, diese wollte ich nun im letzten Schritt durch zufällige ersetzen, ich dachte das sei relativ leicht.
    Da habe ich mich aber wohl deutlich geirrt, ich komme gar nicht mehr weiter.

    Irgendwie bin ich auf die Funktion randomR gekommen, die wohl für Integer aufgerufen, also etwa sowas
    g <- newStdGen
    randomR (1,4) g
    sowas wie ein (Integer, keineAhnungWasDashierGenauIst) zurrück gibt. Da könnte ich ja schonmal mit fst auf diesen Integer kommen. Das wäre schon mal cool!

    Meine main-game Funktion läuft natürlich rekursiv. Jetzt dachte ich, ich übergebe einfach immer wieder einen neuen Wert für das g per newStdGen. Also etwa sowas

    "0" -> theGame 0 (p1 + (fst (randomR (1,4) g))) p2 newStdGen
    

    Kurze Erklärung : 0 -> Dient um festzustellen, welcher Spieler dran ist
    (p1 + (fst (randomR (1,4) g))) -> p1 ist die aktuelle Punkte-Zahl von Spieler 1. Ich dachte ich kann mir jetzt ganz praktisch über die randomR Funktion so ein (Integer,sonstWas) geben lassen, über fst den Integer rausziehen und ihn dann als Erhöhung des Punkte-Standes verwenden.
    p2 -> Punktestand von Spieler 2
    newstdGen -> Dann dachte ich rufe ich diese Funktion wieder auf, damit ich in der nächsten Runde nicht wieder den gleichen random Integer bekomme.

    Das Problem ist, dass das Ganze nicht compilt und ich weiß nicht genau wieso 😕

    No instance for (RandomGen (IO StdGen)) arising from the use of randomR

    Verstehe leider nicht viel davon 😕

    Danke schon mal und sorry falls die Frage arg banal ist !



  • Villeicht macht es Sinn, auch einmal das ganze Programm zu posten ( falls es einer sehen will, um besser helfen zu können ). Natürlich ist es warscheinlich extrem schlecht gecoded, pardon me!

    import System.Random
    main = do
    	putStrLn "Hello and welcome to this game."
    	putStrLn "You will be asked whether or not you want to draw another card. Be careful not to get beyond the 21 mark, as that will make you lose the game!"
    	theGame 0 0 0 newStdGen
    
    theGame :: Int ->Int -> Int -> IO StdGen -> IO ()
    theGame turn p1 p2 g = do
    		if turn == 0 
    			then do
    				putStrLn ("It's player 1's turn. Draw another card(0) or stop(1)? Current score : " ++ show p1)
    				choice <- getLine
    				case choice of
    					"1" -> theGame 1 p1 p2 newStdGen
    					"0" -> theGame 0 (p1 + (fst (randomR (1,4) g))) p2 newStdGen
    			else do
    				putStrLn ("It's player 2's turn. Draw another card(0) or stop(1)? Current score : " ++ show p2)
    				choice <- getLine
    				case choice of
    					"1" -> evaluateWinner p1 p2
    					"0" -> theGame 1 p1 (p2+4) newStdGen
    
    evaluateWinner :: Int -> Int -> IO ()
    evaluateWinner p1 p2 = do 
    			 putStrLn ("Player 1 score : " ++ show p1 ++ ". Player 2 score : " ++ show p2)
    			 if p1 > p2
    				then putStrLn "Player 1 won."
    				else if p1 < p2 then putStrLn "Player 2 won."
    						else putStrLn "It's tied!"
    


  • Mit langer rum-Fieselei bin ich gerade darüber gestolpert, dass das Binden von IO Aktionen an einen Container sozusagen den Typen von IO a, also das a, extrahiert?

    Also

    [code]n <- randomRIO (min,max)[/code liefert mir wohl tatsächlich einen Typ von Integer. Ich dachte n würde trotzdem vom Typ IO Integer bleiben.

    Dann ist wohl die ganze Sache mit den randoms nur so komplex, wenn man sie außerhalb von IO-Aktionen verwenden will?


Log in to reply