Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
Next revision
Previous revision
pp:2023:scala:l06 [2023/04/07 16:16]
alexandra.udrescu01
pp:2023:scala:l06 [2023/04/08 07:49] (current)
pdmatei
Line 3: Line 3:
 ==== 5-Tic-Tac-Toe ==== ==== 5-Tic-Tac-Toe ====
  
-**Tic Tac Toe** is usually played on a 3x3 board, marking positions by each player in rounds. Our game is slightly different:+**Tic Tac Toe** is usually played on a 3x3 board, marking positions by each player in rounds. Our game is slightly different ​(usually called 5-in-a-row):
   * it can be played on a square board of any size **larger or equal to 5**.   * it can 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.    * A player wins if it has marked a line, column or diagonal of **5 consecutive positions** in a row. 
Line 31: Line 31:
   * In your project template, ''​X''​ is encoded as the **first** player (''​One''​),​ and ''​0'',​ as ''​Two''​.   * In your project template, ''​X''​ is encoded as the **first** player (''​One''​),​ and ''​0'',​ as ''​Two''​.
 <code scala> <code scala>
-trait Player {} 
 trait Player {} trait Player {}
 case object One extends Player { case object One extends Player {
Line 45: Line 44:
   * 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, although ''​Empty''​ cannot be seen as a valid player. This makes the code slightly easier to write.   * 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, although ''​Empty''​ cannot be seen as a valid player. This makes the code slightly easier to write.
 <code scala> <code scala>
-type BoardList ​List[List[Player]]+type Line = List[Player] 
 +type BoardList = List[Line]
  
-class Board(b: BoardList) {+case class Board(b: BoardList) {
   override def toString: String = ???   override def toString: String = ???
- 
-  def getList(): BoardList = b 
 } }
 </​code>​ </​code>​
  
 ==== Tasks ==== ==== Tasks ====
 +The following functions have a given signature. However, it is up to the student to decide whether these will be methods of a class or just simple functions.
  
 **6.1.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: **6.1.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:
Line 74: Line 73:
 **6.1.2.** Write a function which checks if a position on the board is free. Recall that list indexing can be done using ''​l(_)''​. Positions are numbered from 0. **6.1.2.** Write a function which checks if a position on the board is free. Recall that list indexing can be done using ''​l(_)''​. Positions are numbered from 0.
 <code scala> <code scala>
-def isFree(x:​Int,​ y:Int, b:Board):Boolean = ???+def isFree(x:​Int,​ y:​Int):​Boolean = ???
 </​code>​ </​code>​
  
Line 83: Line 82:
  
 **6.1.4.** We want to write a function which converts a board to a string, following the same strategy. Complete the ''​toString''​ in the Board class. Hint: instead of ''​foldRight'',​ you can use ''​reduce''​ which works quite similarly, but without requiring an accumulator. **6.1.4.** We want to write a function which converts a board to a string, following the same strategy. Complete the ''​toString''​ in the Board class. Hint: instead of ''​foldRight'',​ you can use ''​reduce''​ which works quite similarly, but without requiring an accumulator.
- 
-<code scala> 
-def show(b: Board): String = b.toString 
-</​code>​ 
  
 **6.1.5.** Write a function which returns the //columns// of a board: **6.1.5.** Write a function which returns the //columns// of a board:
 <code scala> <code scala>
-def getColumns(b:Board): Board = ???+def getColumns: Board = ???
 </​code>​ </​code>​
  
 **6.1.6.** Implement the following two functions for extracting the first and second diagonal, as lines, from a board. Hint: use for comprehensions. **6.1.6.** Implement the following two functions for extracting the first and second diagonal, as lines, from a board. Hint: use for comprehensions.
 <code scala> <code scala>
-def getFstDiag(b:Board): Line = ??? +def getFstDiag():​ Line = ??? 
-def getSndDiag(b:Board): Line = ???+def getSndDiag():​ Line = ???
 </​code>​ </​code>​
  
 **6.1.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. **6.1.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.
 <code scala> <code scala>
-def getAboveFstDiag(b: Board): List[Line] = ??? +def getAboveFstDiag:​ List[Line] = ??? 
-def getBelowFstDiag(b: Board): List[Line] = ??? +def getBelowFstDiag:​ List[Line] = ??? 
-def getAboveSndDiag(b: Board): List[Line] = ??? +def getAboveSndDiag:​ List[Line] = ??? 
-def getBelowSndDiag(b: Board): List[Line] = ???+def getBelowSndDiag:​ List[Line] = ???
 </​code>​ </​code>​
  
 **6.1.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. **6.1.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.
 <code scala> <code scala>
-def winner(p: Player)(b: Board): Boolean = +def winner(p: Player): Boolean = ???
 </​code>​ </​code>​
  
 **6.1.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''​. **6.1.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''​.
 <code scala> <code scala>
-def update(p: Player)(ln: Int, col: Int, b: Board) : Board = ??? +def update(p: Player)(ln: Int, col: Int) : Board = ??? 
 </​code>​ </​code>​
  
-**6.1.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.+**6.1.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.
 <code scala> <code scala>
-def next(p: Player)(b: Board): List[Board] = ???+def next(p: Player): List[Board] = ???
 </​code>​ </​code>​
  
Line 126: Line 121:
 Use the following board configurations to test your solutions: Use the following board configurations to test your solutions:
 <code scala> <code scala>
-    todo+val t1 = 
 +  """​X0X0X0 
 +    |0X0X0X 
 +    |X0X0X0 
 +    |.XX0.. 
 +    |X00... 
 +    |X0X0X0"""​.stripMargin 
 + 
 +val t2 = 
 +  """​...... 
 +    |...... 
 +    |...... 
 +    |.XX... 
 +    |.0000. 
 +    |......"""​.stripMargin 
 + 
 +val t3 = 
 +  """​0X0X0. 
 +    |000.X0 
 +    |0.0X.. 
 +    |0..0.. 
 +    |0X..0X 
 +    |...X.."""​.stripMargin
 </​code>​ </​code>​