“Connect Four”

Használható segédanyagok: Haskell könyvtárainak dokumentációja, Hoogle, a tárgy honlapja és a BE-AD rendszerbe feltöltött beadandók. Ha bármilyen kérdés, észrevétel felmerül, azt a felügyelőknek kell jelezni, NEM a diáktársaknak!

A feladat összefoglaló leírása

Egy “Connect four” játékot kell készíteni. A játékot egy megadott szélességű és magasságú rácson játszhatja 2 személy adott számú korongokkal. A játékosok felváltva dobnak be egy korongot a saját színükből a rács valamelyik oszlopába. A korong le fog csúszni az oszlop aljára vagy az oszlopban található legfelső korongig. A játék célja, hogy elhelyezzünk a rácson bizonyos számú ugyanolyan színű korongot úgy, hogy azok sor- vagy oszlopfolytonosak, illetve átlósan szomszédosak legyenek. Az ellenfelet pedig ugyanebben kell megadályozni.

Vizuálisan (az illusztráció a Wikipediáról származik):

Connect Four
Connect Four

A rács méreteit a következő konstansok jelölik: rows a sorok száma, columns az oszlopok száma.

(rows,columns) = (7 :: Int, 6 :: Int)

A győzelemhez szükséges szomszédos korongok számát a winning konstans adja meg:

winning = 4 :: Int

Az egyik játékos korongjai pirosak, a másiké sárgák. Az egyszerűség kedvéért a korongokat ábrázoljuk egész számokkal: 0 és 1. A piros korongok legyen red (= 0), a sárga korong pedig yellow (= 1).

[red,yellow] = [0,1]

A rácsot listák listájával fogjunk ábrázolni, ahol a belső listák mindig az oszlopokat adják meg.

Például:

grid = [[],[red,yellow,red],[red],[yellow],[],[]]

A fenti rács egy 7 sorból, 6 oszlopból álló rács, amelynek az 1. oszlopa üres, a 2. oszlopában 3 korong található egymáson (lentről felfelé - piros, sárga, piros), a 3. oszlopában csak egy sárga, míg a 4. oszlopban csak egy piros korong található legalul. A utolsó 2 oszlopa pedig üres.

Továbbá adott egy üres rács és néhány tesztállás is:

grid0 :: [[Int]]
grid0 = [[],[],[],[],[],[]]
grid1 :: [[Int]]
grid1 =
  [ [yellow,red,yellow,red]
  , []
  , [red,red,red,yellow]
  , []
  , []
  , [yellow,yellow,yellow,red,yellow,red,red]
  ]
grid2 :: [[Int]]
grid2 =
  [ [yellow,red,yellow,red]
  , [red,red,yellow,red]
  , [yellow,yellow,yellow]
  , [red,red,yellow,yellow]
  , [red]
  , [red,yellow,red,yellow]
  ]
grid3 :: [[Int]]
grid3 =
  [ [yellow,yellow, yellow]
  , [red,yellow,red]
  , [red,red,yellow,yellow]
  , [yellow,red,red,red]
  , [yellow,yellow,red,yellow]
  , [red,red,yellow,red]
  ]

Üres oszlopok egy rácsban (1 pont)

Hány üres oszlopa van a megadott rácsnak?

emptyColumns :: [[Int]] -> Int

Test>
6 :: Int
Test>
3 :: Int
Test>
0 :: Int
Test>
0 :: Int

Korongok száma egy rácsban (1 pont)

Hány korong található a rácsban?

numOfPieces :: [[Int]] -> Int

Test>
0 :: Int
Test>
15 :: Int
Test>
20 :: Int
Test>
22 :: Int

Üres sorok száma egy rácsban (2 pont)

Hány üres sor van egy rácsban?

emptyRows :: [[Int]] -> Int

Test>
7 :: Int
Test>
0 :: Int
Test>
3 :: Int
Test>
3 :: Int

Korong elhelyezése a rácsban (2 pont)

Készítsünk egy függvényt, amellyel el tudunk helyezni egy korongot egy rácsban!

Az első paraméter az oszlopszám (ahova dobni szeretnénk), a második paraméter adja meg a színét. Az oszlopokat 0-tól indexeljük. Ha olyan oszlopba szeretnénk dobni, amely már tele van, akkor ne változzon meg a rács állapota! Ha nagyobb oszlopszámot adunk meg, mint amennyi oszlopunk van, akkor is a megadott rácsot adja vissza (tehát ekkor se változzon meg)!

putPiece :: Int{-oszlop-} -> Int{-korong-} -> [[Int]]{-induló rács-} -> [[Int]]

Test>
[[], [], [0], [], [], []] :: [[Int]]
Test>
[[1, 0, 1, 0], [1], [0, 0, 0, 1], [], [], [1, 1, 1, 0, 1, 0, 0]] :: [[Int]]
Test>
[[1, 0, 1, 0], [], [0, 0, 0, 1], [], [], [1, 1, 1, 0, 1, 0, 0]] :: [[Int]]
Test>
[[1, 0, 1, 0, 0], [], [0, 0, 0, 1], [], [], [1, 1, 1, 0, 1, 0, 0]] :: [[Int]]

Négy korong egy oszlopban (3 pont)

Adjuk meg, hogy a megadott állásban található-e n egyforma korong egy oszlopban egymás mellett az adott színből!

inAColumn :: Int{-egyformák-} -> Int{-szín-} -> [[Int]]{-rács-} -> Bool

Test>
False :: Bool
Test>
False :: Bool
Test>
True :: Bool
Test>
True :: Bool

Négy korong egy sorban (3 pont)

Ellenőrizzük le, hogy a megadott állásban, található-e n egyforma korong egy sorban egymás mellett az adott színből!

inARow :: Int{-egyformák-} -> Int{-szín-} -> [[Int]]{-rács-} -> Bool

Test>
True :: Bool
Test>
True :: Bool
Test>
True :: Bool
Test>
True :: Bool

Négy korong átlósan (4 pont)

Ellenőrizzük le, hogy a megadott állásban, található-e n egyforma korong átlósan egy adott színből egymás mellett!

inADiagonal :: Int{-egyformák-} -> Int{-szín-} -> [[Int]] -> Bool

Test>
False :: Bool
Test>
True :: Bool
Test>
False :: Bool
Test>
True :: Bool

Nyert-e valaki? (2 pont)

Az előbbi függvények felhasználásával adjuk meg, hogy egy adott rács szerint nyert-e valamelyik korong!

isThereAWinner :: [[Int]] -> [Int]

Test>
[] :: [Int]
Test>
[] :: [Int]
Test>
[1] :: [Int]
Test>
[0] :: [Int]

Pontozás

Ponthatárok: