www.jammni.de

Logo - Kleiner Drache
Login
Username:

Passwort:

Daten merken
Auto-Login
Registrieren
 
Online
niemand
 
Forumsuche
Suche nach:

Logo - DracheHaskell-Forum

XeZZ

Gepostet:
01.04.2010 14:39

Tic Tac Toe bräucht bischen Hilfe  
Hiho,

um mal meine derzeitigen Kentnisse zu checken hab ich mir überlegt eifnach mal Tic Tac Toe zu basteln. Nun hab ich nen Problem bei meiner Ausgabefunktion was ich nicht verstehe :)

printField (x:y:z:_) = do
putStrLn "______"
printLine x
printLine y
printLine z
putStrLn "______"
where printLine (a:b:c:_) = putStrLn ("|" ++ a ++ "|" ++ b ++ "|" ++ c ++ "|")


Aufruf: printField ["123", "456", "789"]
Erwartete Ausgabe:
______
|1|2|3|
|4|5|6|
|7|8|9|
______

Bekomme aber nen Typfehler:
<interactive>:1:12:
Couldn't match expected type `[Char]' against inferred type `Char'
Expected type: [[Char]]
Inferred type: [Char]
In the expression: "123"
In the first argument of `printField', namely
`["123", "456", "789"]'

Hab mir auch mal mithilfe von :t den Typ der Funktion ausgeben lassen und der ist nicht das was ich erwartet habe und da liegt denke ich auch mein Problem.
Erwartet habe ich printField :: [[Char]] -> IO ()
gekommen ist printField :: [[[Char]]] -> IO ()

Warum istd as so und wie behebe ich das :)?

mfg

Zum Seitenanfang ICQ    
 
Siracusa

Gepostet:
01.04.2010 15:22

   
Hallo,

x, y, z sind bei dir Strings, d.h. printLine bekommt immer einen String übergeben. Der wird durch Musteranpassung wieder zerlegt in a, b, c, die nun jeweils Chars sind. Auf der rechten Seite versuchst du dann also immer abwechselnd String mit Char mit String mit Char etc. zu verknüfen. (++) ist aber nur für die Verknüpfung von String mit String vorgesehen. Die Lösung ist also die Chars a, b, c auf der rechten Seite jeweils wieder in einen String umzuwandeln, und zwar durch eckige Klammern darum, also bspw. [a].


Viele Grüße,

Siracusa
Zum Seitenanfang    
 
XeZZ

Gepostet:
01.04.2010 15:44

   
So ich habs nach einigen weiteren Problemen geschafft :) Danke für deine Hilfe und ich hätte noch eine Bitte... Könnte da evtl. wer gegenlesen und mir nen paar Tipps geben was man im allgemeinen besser lösen könnte und halt so Stilkritik.

module TicTacToe where

import IO
import Data.List (transpose)

--starts the Game and Loops until quit
startGame :: IO ()
startGame = do
putStrLn "Welcome please select an option"
putStrLn "[1] to start a new Game"
putStrLn "[2] to exit"
opt <- getLine
case read opt of
1 -> do newGame
startGame
2 -> return ()
_ -> do putStrLn "Invalid Input"
startGame

--initialises a new Gamefield and sets first Player to 'X'
newGame :: IO ()
newGame = do
let field = ["123","456","789"]
printField field
playGame field 'X' 0

--Loops while a Game is active
playGame :: (Num a) => [[Char]] -> Char -> a -> IO ()
playGame field player count = do
--check if field is full
case (count /= 9) of
True -> do --get Input
putStrLn ("Player " ++ show player ++ " make your turn!")
opt <- getLine
--Check if Turn is valid
case checkValid opt field of
True -> do let newField = updateField (head opt) player field
printField newField
--Check if last turn lead to a Winsituation
case checkWin newField of
True -> putStrLn ("Player " ++ show player ++ " Wins!")
--change Player and loop
False -> do let nextPlayer = changePlayer player
playGame newField nextPlayer (count+1)
--Invalid Turn -> Loop
False -> do putStrLn "Invalid Input - Try again!"
playGame field player count
--Field is full -> Draw
False -> putStrLn "Draw!"


printField :: [[Char]] -> IO ()
printField (x:y:z:_) = do
putStrLn "______"
printLine x
printLine y
printLine z
where printLine (a:b:c:_) = putStrLn ("|" ++ [a] ++ "|" ++ ++ "|" ++ [c] ++ "|")

checkWin :: [[Char]] -> Bool
checkWin field
| "XXX" `elem` field = True
| "OOO" `elem` field = True
| "XXX" `elem` field' = True
| "OOO" `elem` field' = True
| "XXX" `elem` field'' = True
| "OOO" `elem` field'' = True
| otherwise = False
where field' = transpose field --rebuild for vertical check
--The field will be rebuild to ["159", "357"] to check diagonal
field'' = [[(!! 0)((!!0) field)]++[(!! 1)((!!1) field)]++[(!! 2)((!!2) field)]
,[(!! 0)((!!2) field)]++[(!! 1)((!!1) field)]++[(!! 2)((!!0) field)]]

changePlayer :: Char -> Char
changePlayer player
| player == 'X' = 'O'
| player == 'O' = 'X'

checkValid :: [Char] -> [[Char]] -> Bool
checkValid [] _ = False
checkValid _ [] = False
checkValid opt (x:xs)
| (head opt) `elem` "XO" = False
| (head opt) `elem` x = True
| otherwise = checkValid opt xs

updateField :: (Eq a) => a -> a -> [[a]] -> [[a]]
updateField opt player field =
map (replace opt player) field
where replace _ _ [] = []
replace opt player (t:ts)
| t == opt = player:replace opt player ts
| otherwise = t:replace opt player ts

Zum Seitenanfang ICQ