FP Domácí úkol 1
Contents
Základní informace
Ve všech zadáních se očekává výstup na obrazovku. Pro něj je možné použít stejný postup jako ve Cvičení 7.
Definujme si typ pro výstup:
type Result = [String]
Nyní, pokud chceme pěkně vypsat takovýto výstup na obrazovku, můžeme použít:
pp :: Result -> IO ()
pp x = putStr (concat (map (++"\n") x))
Příklad - Lodě
Napište funkci ships
, která má dva argumenty. První je seznam řetězců, které reprezentují hrací plochu jednoho hráče po řádcích postupně shora dolů ('o' - políčko obsazené lodí, ' ' - prázdné pole). Druhým argumentem je seznam dvojic souřadnic políček, na které druhý hráč zkoušel střílet. Vykreslete aktuální stav hry tak, že řádky a sloupce budou označeny svým číslem resp. písmenem, 'o' bude dosud nezasažené políčko s lodí, 'x' zasažené políčko s lodí, '.' místo, kam se střílelo, ale nic nezasáhlo, ' ' prázdná a dosud nezasažená políčka. Můžete předpokládat hrací plochu velikosti 10x10.
ships :: Result -> [(Char, Int)] -> Result
sampleInput = [" o o ",
" ooo ",
" oo ",
" ",
" o ",
" o ",
" o ",
" ",
" ",
" oooo "]
Prelude>pp(ships sampleInput [('a',1),('d',1),('d',2),('c',1),('b',1),('e',1),('f',1),('g',1),('c',7),('c',10)])
10 x o
9 ooo
8 oo
7 .
6 o
5 o
4 o
3
2 .
1..xxxx.
abcdefghij
import Data.Char ( ord )
type Result = [String]
pp :: Result -> IO ()
pp x = putStr (concat (map (++"\n") x))
sampleInput :: Result
sampleInput = [" o o ",
" ooo ",
" oo ",
" ",
" o ",
" o ",
" o ",
" ",
" ",
" oooo "]
ships :: Result -> [(Char, Int)] -> Result
ships input coordinates = let
coordinates' = [(ord ch - ord 'a' +1 ,ri) |(ch, ri)<-coordinates]
get x ch | elem x coordinates' = if ch == 'o' then 'x' else '.'
| otherwise = ch
niceShow x = let
number' = show x
in if length number' == 1 then " "++number' else " "++number'
nicePrint result = reverse [niceShow number ++ row|(number,row)<-zip [1..] result] ++ [" abcdefghij"]
in nicePrint ([[get (ci,ri) ch |(ci,ch)<- zip [1..] row ]| (ri,row)<-zip [1..] (reverse input)])
1 - Šachové pozice
Napište funkci chess
, která má 2 argumenty typu [String]
. Řetězce v seznamech obsahují 3 znaky:
- první určuje šachovou figuru ('K' - král, 'D' - dáma, 'V' - věž, 'S' - střelec, 'J' - jezdec, 'P' - pěšec)
- druhý znak určuje sloupec ('a'-'h')
- třetí je číslo řádku ('1'-'8')
První seznam reprezentuje aktuální rozmístění bílých figur a druhý černých. Vypište aktuální pozici tak, že volná políčka budou reprezentována znakem '.', bílé figury svým písmenem velkým a černé figury svým písmenem malým. Řádky i sloupce budou označeny čísly resp. písmeny.
chess :: [String] -> [String] -> Result
Prelude> pp( chess["Ke1","Ra1","Rh1","Pa2","Be5"] ["Ke8","Ra8","Rh8","Pa7","Qd8","Bc8","Nb8"])
8rnbqk..r
7p.......
6........
5....B...
4........
3........
2P.......
1R...K..R
abcdefgh
2 - Ticktacktoe
Napište funkci ticktack
, která má 2 argumenty. První je dvojice přirozených čísel určující počet sloupců a řádků hrací plochy. Souřadnice jsou počítány z levého dolního rohu. Druhý seznam reprezentuje průběh hry piškvorky, kde jsou souřadnice políček, na které střídavě hrál hráč 'x' a hráč 'o'. Vypište aktuální stav hry tak, že hrací pole bude ohraničeno znaky '-' a '|', volné pozice ' ' a znaky 'x' a 'o' budou na pozicích, kam zahráli příslušní hráči.
ticktack::(Int,Int) -> [(Int,Int)] -> Result
Prelude>pp(ticktack (8,8) [(1,1),(8,8),(2,2),(3,3),(4,2),(3,2)])
----------
| o|
| |
| |
| |
| |
| o |
| xox |
|x |
----------
3 - Bludiště
Napište funkci maze
, která má 2 argumenty. Prvním argumentem je seznam řetězců, které reprezentují bludiště po řádcích postupně shora dolů ('*' - stěna, ' ' - průchozí pole, 's' - startovní pozice). Na začátku se nacházíme na pozici 's'. Druhým argumentem je seznam směrů pohybu ('d' - down, 'u' - up, 'l' - left, 'r' - right). Každé písmeno znamená, že se posuneme o 1 buňku daným směrem a na novou pozici umístíme znak '.' Vypište aktuální situaci po provedení všech kroků z druhého seznamu.
maze :: Result -> String -> Result
sampleInput = ["*********",
"*s* * *",
"* * * * *",
"* * * * *",
"* * *",
"******* *",
" *",
"*********"]
Prelude>pp(maze sampleInput "dddrruuurrdddrrddllllll")
*********
*s*...* *
*.*.*.* *
*.*.*.* *
*...*...*
*******.*
.......*
*********
4 - Hledání min
Napište funkci minesweeper
, která má argument typu seznam řetězců. Řetězce reprezentují hrací plochu po řádcích postupně shora dolů ('*' - mina, ' ' - prázdné pole). Vypište hrací pole tak, že miny budou stále reprezentovány '*', ale na každém políčku bez miny bude číslo znamenající celkový počet min, se kterými toto prázdné pole přímo sousedí (sousedit může vodorovně, svisle i šikmo).
minesweeper :: Result -> Result
sampleInput = [" ",
" * ",
" * ",
" * ",
" *",
"*** ",
"* * ",
"*** "]
Prelude>pp(minesweeper sampleInput)
1110000
1*11110
1122*10
001*221
233211*
***2011
*8*3000
***2000
5 - Turtle
Implement a function that will draw the movement of a turtle in a rectangular grid. It will be named draw
and it will have one parameter - a list movements. Our turtle can move only horizontally or vertically. Each movement will be described by a pair (its type will be (Char, Int)
), where the first character denotates a direction of this movement and the second its length. Possible directions are: left, right, up, and down. As the result, function draw
returns a smallest possible rectangle with all turtle's movements. Each block from the grid will be represented with one character. If it was visited by our turtle, then it will be 'X'
, if it was not, then it will be ' '
.
draw :: [(Char, Int)] -> Result
*Main> pp (draw [('u',5),('r',5),('d',5),('l',10),('d',5),('r',5),('u',5)])
XXXXXX
X X
X X
X X
X X
XXXXXXXXXXX
X X
X X
X X
X X
XXXXXX