# Tako Judo
* Bárbara Filipa da Silva Carvalho (50%) - up202004695
* Luís Tiago Trindade Cabral (50%) - up202006464
# Instalação e execução
To play this game, you first need to have SICStus Prolog 4.7 or a newer version currently installed on your machine plus the folder with the source code.
Next, on the SICStus interpreter, consult the file loads.pl located in the source root directory.
```
?- consult('./loads.pl').
```
Now you just need to run the predicate play/0 to enter the game main menu:
```
?- play.
```
# Game Description
Tako Judo is an abstract strategy game for 2 players in which the objective is to prevent your opponent from being able to move. It is played on a NxN board, where N is an even number between 8 and 26. Each player controls the head and eight tentacles of an octopus. The head takes up a 2x2 square area, and each tentacle takes up one square area. Any piece can move like a Chess queen (any distance along an open orthogonal or diagonal line, but without jumping) provided that there is also a clear line of sight between that piece's original location and the head piece for the octopus to which it belongs. A player whose octopus is no longer able to effectively move its head or any tentacles looses the game.
# Game Logic
**Game state and internal representation**
To identify the game state, we need the current board and the current player.
The board is represented by a list of lists, where each list is a line and each element in the list is a board cell. A cell can be empty (represented by ' . ') or contain a piece.
There are different pieces for each player:
- Player 1 is represented by lowercase letters, 't' for tentacles and 'h' for head.
- Player 2 is represented by uppercase letters, 'T' for tentacles and 'H' for head.
Initial state

Intermediate state

Final State


(Player 2 lost)
**Game state visualization**
The predicates for the game visualization are separated into two different modules:`displays` and`board`, representing the menu and game state's interaction and display.
- The main menu is created by the predicate `mainMenu`. It allows to navigate to other menus, like start the game, rules and about us.

- The predicate that deals with inputs is `askForMove`. Since there are many interactions with the user, there's a bigger chance to get invalid inputs. With that in mind, we created predicates to validate each input, for example `checkInputForBoard` and `invalidInput`, that inform the players of possible errors before asking for another input. To give more freedom to the user, with the predicate `checkQuitting` we allowed him to quit at any time he wants.
- The game has a flexible NxN board and the initial game state can be obtained with the predicate initial_state/2:
```
initialState(+Size, -GameState)
```
- The game board is displayed to the user by the predicate display_game/1:
```
display_game(+GameState)
```
It uses other support predicates like `drawAuxiliaryPosition/1` which displays the columns header,
and `writelist` which prints a line of the board.

**Move execution**
After start playing the game, the predicate `move/3` is responsible for validating and moving the chosen piece.
If the user chooses a move that is not possible, either because the piece has no clear line of sight to the head piece, or the final position chosen is already occupied by another piece, it will be printed a message accordingly to the type of error.

Since the game has two types of pieces, tentacles and head of octopus, we created two specific predicates, `movePiece` and `moveHead` that move each type respectively. The head is composed of 4 pieces, which creates the necessity of validating the final position of each piece. This is accomplished with the predicate `checkObstacles`.
For changing the piece position on the board, it is used the predicate `moveTentacle`, which finds the element in the given position, replaces its original position by an empty cell and places the piece on the its destinated place.
**List of valid moves**
To calculate the list of valid moves we used the predicate `valid_moves/3`, that gets all the player's visible tentacles and all the empty spaces, and for each one of the tentacles, checks if the move to each one of the empty spaces is possible. If it is, it appends it to a list, returning it in the end of the iteration.
**Game over**
The strategy for checking if the game was over was to create the predicate `game_over` that with the help of `checkLossP1` and `checkLossP2` verifies if any of the players had lost.
The concept behind this predicates is the following:
- First, we look for all tentacles of a certain player. (`getAllPlayerTentacles`)
- Then we check which of those have a clear line of sight to the head piece. (`findAllVisible`)
- If there's no visible tentacle, the player has lost.
**Game state evaluation**
Since there really isn't much information about the game Tako Judo for us to explore, we deemed that the current score of the player would be determined by the following formula:
`Score = Visible_Player_Tentacles + Invisible_Opponent_Tentacles`
For that, we created the predicate `value/3` that takes as arguments the current Board, the player we wish to know the Score of and the Value, which is the actual score. To calculate the previously mentioned formula, we used the predicate `getAllPlayerTentacles` as well as the `length/2` predicate to calculate the first parcel of the sum, and the predicate `getAllVisibleTentacles` to calculate the second one.
**Computer move**
For the computer moves we created the predicate `choose_move/3` that took as argument the Board, the PlayerNumber and the Level itself. We separated the predicate in two, given the level. For the first level, we chose to pick a random visible Tentacle (or the head), a random empty Space and checked if there was a possible move from the tentacle (or the head) to the space. If the move was possible, it was made, if it wasn't, we would recall the predicate, getting another space, for the same tentacle. For the second level we only allowed the computer to pick a move that would not make the tentacle invisible, therefore giving it an advanced level of difficulty for the player.
# Conclusion
The board game Tako Judo was successfully implemented in the SicStus Prolog 4.7 language. The game can be played Player vs Player, Player vs Computer or Computer vs Computer with different levels.
One of the difficulties on the project was creating an intuitive board in the SicStus terminal.
Another limitation, was the inability of using certain predicates in SicStus Prolog 4.7, like `atom_number`, which would be really helpful in converting the position in coordinates.
We would have liked to be able to output the text in different colors, to make it more aesthetically pleasing, but we couldn't find any information on that matter.
We also would have wanted to be able to make better menus, but, given Prolog's capacity of output, we decided with simple text ones.
# Sources
https://boardgamegeek.com/boardgame/29291/tako-judo