# Manc-OS
## Autores
| Nombre | Numero de alumno |
| ------ | ---------------- |
| Sebastián Álvarez | 1362007J |
| Jorge Becerra | 14619725 |
| Rodrigo Cortés | 14620081 |
| Cindy Tarud | 13619888 |
## Instrucciones para ejecutar el programa
1. Compilar usando el comando `make`
2. Ejecutar servidor con `./server -i <ip_address> -p <tcp_port>`
3. Ejecutar cliente 1 con `./client -i <ip_address> -p <tcp_port>`
4. Ejecutar cliente 2 con `./client -i <ip_address> -p <tcp_port>`
## Iniciar el juego
1. Enviar nombre de cada jugador
2. Jugador 1 indica ruta a tablero
3. A jugar 😃 🎉 !
## Supuestos del juego
* El archivo .txt del tablero es relativa al cliente ubicado en `./src/client`, es decir si se indica la ruta tablero.txt, este archivo debe estar en `src/client/tablero.txt`
* Sólo se obtienen méritos al pasar la celda de salida (E), al caer en ella no pasa nada.
* Al caer en una tienda, si está el otro jugador en la misma celda, se le permitirá al jugador comprar antes de que se realice el duelo.
* En caso de que ambos jugadores caigan en la celda 'Y' de forma consecutiva (Fonda Don Yadran), el flujo del juego continuará de forma normal.
* Al comprar un poder en la tienda, este será al azar.
* Si se utiliza el poder "Dado Doble", ambos dados serán al azar.
## Códigos de mensajes
La siguiente tabla muestra los códigos utilizados para enviar mensajes entre el servidor y clientes
| Código | Servidor | Cliente |
| ------ | ------------------------- | ----------------------------------- |
| 1 | recibir nombre | recibir bienvenida |
| 2 | recibir contenido tablero | enviar contenido del tablero |
| 3 | recibir opción escogida (avanzar, poder, rendirse) | recibir información general para imprimir |
| 4 | recibir modalidad elegida para avanzar (manual o aleatoria) | recibir tablero y posiciones |
| 5 | recibir el valor del dado | enviar opción escogida (avanzar, poder, rendirse) |
| 6 | recibir opción elegida del jugador retador para el duelo (piedra, papel o tijera) | enviar modalidad elegida para avanzar (manual o aleatoria) |
| 7 | recibir opción elegida del jugador desafiado para el duelo (piedra, papel o tijera) | recibir valor del dado |
| 8 | recibir poder escogido a utilizar | enviar casillas a avanzar (manual) |
| 9 | enviar poder adquirido en tienda | enviar opción elegida del jugador retador para el duelo (piedra, papel o tijera) |
| 10 | enviar estadísticas de jugador en caso de no querer comprar en tienda | enviar opción elegida del jugador desafiado para el duelo (piedra, papel o tijera) |
| 11 | enviar poder adquirido en tienda e inicio de duelo (caso tienda + duelo) | enviar opción escogida en caso de no tener poder (avanzar, poder, rendirse) |
| 12 | enviar inicio de duelo | enviar poder a utilizar |
| 13 | | enviar decisión de comprar o no en la tienda si no hay duelo |
| 14 | | enviar decisión de comprar o no en la tienda si hay duelo |
| 20 | | imprimir ganador y término de juego |
## Principales decisiones de diseño
Nos basamos en el código de ejemplo de la ayudantía para la conexión cliente-servidor, lo que implica mantener una carpeta comunication y conection tanto para el cliente como para el servidor. Decidimos usar un único Makefile, que está encargado de compilar tanto la carpeta client como server. Se creó una struct Player para facilitar el manejo de los atributos para cada jugador inicializado.
En general, se mantuvo lo de tener clientes dumbs, salvo por la validación de inputs. Cualquier cómputo en el juego fue realizado en el server y la interacción principal era de los jugadores, utilizando al cliente como intermediario entre ellos y el server.
## Funciones principales
- `void client_send_message(int server_socket, int pkg_id, char *message)`: función para enviar mensaje desde un cliente al servidor. Para ello se debe especificar el socket del servidor, el tipo de paquete y el mensaje en sí.
- `int client_receive_id(int client_socket)`: cliente lee el tipo (id) del paquete recibido.
- `char *client_receive_payload(int client_socket)`: cliente lee el mensaje del paquete recibido.
- `int server_receive_id(int client_socket)`: función para enviar mensaje desde el servidor a un cliente. Para ello se debe especificar el socket del cliente, el tipo de paquete y el mensaje en sí.
- `char *server_receive_payload(int client_socket)`: servidor lee el tipo (id) del paquete recibido.
- `void server_send_message(int client_socket, int pkg_id, char *message)`: servidor lee el mensaje del paquete recibido.
- `int move(Player** players, int current_player, int dice_value, char* table)`: función que cambia la posición del jugador y decide qué hacer en base a la casilla en la que quedó.