===== Homework 3: 5-in-a-row =====
In this homework, you will implement some functionality which will allow you to design a completely functional 5-in-a-row AI. The latter will be part of homework 4.
==== About 5-in-a-row ====
The game:
* an be played on a square board of any size larger or equal to 5.
* A player wins if it has marked a line, column or diagonal of 5 consecutive positions in a row.
Example of a winning position for ''X'' on a 5x5 board:
X...0
0X.0.
..X0.
...X.
.0..X
Example of a winning position for ''0'' on a 7x7 board:
.X...X.
...0...
...0...
.X.0..X
0..0..0
...0...
...X...
==== Coding conventions ====
* In your project template, ''X'' is encoded as the **first** player (''One''), and ''0'', as ''Two''.
* A ''Board'' is encoded as a List of Lists of **positions** (i.e. a matrix), where a position can be ''One'', ''Two'' or ''Empty''. We make no distinction in the code between a position and a player. This makes the code slightly easier to write, however ''Empty'' cannot be seen as a valid player.
==== Coding tasks ====
**1.** Write a function which converts a string into a ''Board''. As a helper, you can use ''_.split(c)'' where c is a separator string, and ''_.toList''. The best solution is to use a combination of ''map'' calls with the above mentioned functions. A string is encoded exactly as in the examples shown above:
* there are no whitespaces - empty positions are marked by the character '.'
* lines are delimited by '\n' (the last line does not have a trailing '\n').
def makeBoard(s: String): Board = {
def toPos(c: Char): Player =
c match {
case 'X' => One
case '0' => Two
case _ => Empty
}
???
**2.** Write a function which checks if a position ''(x,y)'' on the board is free. Recall that list indexing can be done using ''l(_)''. Positions are numbered from 0.
def isFree(x:Int, y:Int, b:Board):Boolean = ???
**3.** Write a function which returns the //opponent// of a player:
def complement(p: Player): Player =
**4.** Write a function which converts a board to a string, following the same strategy. **Important:** this function will be used throughout the tests. Make sure the string doesn't end with '\n'. Hint: instead of ''foldRight'', you can use ''reduce'' which works quite similarly, but without requiring an accumulator.
def show(b: Board): String = ???
**5.** Write a function which returns the //columns// of a board:
def getColumns(b:Board): Board = ???
**6.** Implement the following two functions for extracting the first and second diagonal, as lines, from a board. Hint: use for comprehensions.
def getFstDiag(b:Board): Line = ???
def getSndDiag(b:Board): Line = ???
**7.** Implement the following functions for extracting diagonals above/below the first/second diagonal, as lines. It's not really necessary to make sure that at least 5 positions are available, for now. Hint: if one function must be implemented with element-by-element iteration, the three other can be implemented using each-other, as single-line calls.
def getAboveFstDiag(b: Board): List[Line] = ???
def getBelowFstDiag(b: Board): List[Line] = ???
def getAboveSndDiag(b: Board): List[Line] = ???
def getBelowSndDiag(b: Board): List[Line] = ???
**8.** Write a function which checks if a player is the winner. Hint: functions ''l.forall(_)'' and ''l.exists(_)'' may be very helpful, together with patterns.
def winner(p: Player)(b: Board): Boolean =
**9.** Write a function which updates a position from the board, with a given player. The position need not be empty and you are not required to check this. Hint: re-use an inner aux-function together with ''take'' and ''drop''.
def update(p: Player)(ln: Int, col: Int, b: Board) : Board = ???
**10.** Write a function which generates all possible next-moves for any of the two players. A next-move consists in a new board, where the player-at-hand played his move. The order in which you generate next-moves is not important.
def next(p: Player)(b: Board): List[Board] = ???
===== Submission rules =====
* Please follow the [[fp2023:submission-guidelines| Submission guidelines]] which are the same for all homework.
* To solve your homework, download the {{:fp2023:h3-5-in-a-row.zip|Project template}}, import it in IntellIJ, and you are all set. Do not rename the project manually, as this may cause problems with IntellIJ.