Commit af98897a authored by LAIRD Timothy's avatar LAIRD Timothy

Merge branch 'dev' into 'master'

dev to master

See merge request !9
parents bb881290 ebd3ad27
......@@ -10,3 +10,4 @@ doc/html
nw-*
config
*.o
risk
\ No newline at end of file
......@@ -4,7 +4,7 @@ cmake_minimum_required(VERSION 3.10)
# Activate C99 standard:
SET(CMAKE_C_COMPILER "gcc" )
SET(CMAKE_C_FLAGS "-std=c99" )
set(CMAKE_CXX_FLAGS_DEBUG_INIT "-Wall -Wextra")
set(CMAKE_CXX_FLAGS_DEBUG_INIT "-Wall -Wextra -g")
set(CMAKE_CXX_FLAGS_RELEASE_INIT "-Wall")
# project configuration :
......@@ -18,10 +18,11 @@ include_directories(${PROJECT_SOURCE_DIR} ${PROJECT_SOURCE_DIR}/src)
include_directories( ${PROJECT_SOURCE_DIR}/dpd/include )
link_directories( ${PROJECT_SOURCE_DIR}/dpd )
add_executable(nw-viewer src/main-viewer.c src/networld.c src/controlpanel.c src/entity.c)
target_link_libraries(nw-viewer raylib pthread dl rt X11 m)
add_executable(risk src/main-viewer.c src/networld.c src/controlpanel.c src/player.c src/random-map.c src/graphical-aspect.c src/window-manager.c src/menu-button.c src/main-menu.c src/int-input.c src/options-menu.c src/mission.c)
target_link_libraries(risk raylib pthread dl rt X11 m)
#without cmake package...
#include_directories(${PROJECT_SOURCE_DIR}/raylib/src)
#link_directories(${PROJECT_SOURCE_DIR}/raylib)
#target_link_libraries(nw-viewer raylib GL m pthread dl rt X11)
#target_link_libraries(risk raylib GL m pthread dl rt X11)
File added
......@@ -9,4 +9,4 @@ cmake ..
make
# Outputs
cp nw-viewer ..
cp risk ..
......@@ -27,14 +27,16 @@ void Panel_delete(Panel * self)
}
// Initialization
void Panel_initialize(Panel * self, NetWorld * world)
void Panel_initialize(Panel * self, NetWorld * world, const int screenWidth, const int screenHeight)
{
self->world= world;
self->camera.x= 0.f;
self->camera.y= 0.f;
self->screenCenter.x= 400.f;
self->screenCenter.y= 300.f;
self->screenCenter.x= screenWidth/2;
self->screenCenter.y= screenHeight/2;
self->scale= 10.f; //pixel per meters
self->screenWidth = screenWidth;
self->screenHeight = screenHeight;
}
// To String
......@@ -47,7 +49,69 @@ void Panel_print(Panel * self)
}
// Rendering
void Panel_draw(Panel * self)
void Panel_drawMainMenu(Panel * self, Main_Menu * menu){
Font font = GetFontDefault();
BeginDrawing();
DrawText("RISK", (self->screenWidth*35)/100 , (self->screenHeight*10)/100 , (self->screenWidth*10)/100,BLACK);
//Draw each button
for(int index = 0; index < menu->buttonCount; index++){
Menu_Button_draw(menu->buttons[index], &font, self->screenWidth, self->screenHeight, RED, (self->screenHeight*4)/100, (self->screenWidth/75), true);
}
ClearBackground(RAYWHITE);
UnloadFont(font);
EndDrawing();
}
void Panel_drawOptionsMenu(Panel * self, Options_Menu * menu){
Font font = GetFontDefault();
BeginDrawing();
DrawText("OPTIONS", (self->screenWidth*35)/100 , (self->screenHeight*15)/100 , (self->screenWidth*5)/100,BLACK);
//Draw each input field
for(int index = 0; index < menu->inputCount; index++){
Int_Input_draw(menu->inputs[index], &font, self->screenWidth, self->screenHeight);
}
DrawRectangleRec(menu->saveReturnBtn, GREEN);
DrawRectangleRec(menu->smallerSaveReturnBtn, WHITE);
DrawTextRec(font, "\tSave and Exit", menu->saveReturnBtn,(self->screenHeight*5)/100, (self->screenWidth/400), true, BLACK);
ClearBackground(RAYWHITE);
UnloadFont(font);
EndDrawing();
}
void Panel_drawRules(Panel * self, Main_Menu * rules){
Font font = GetFontDefault();
BeginDrawing();
DrawText("RULES", (self->screenWidth*40)/100 , (self->screenHeight*15)/100 , (self->screenWidth*5)/100,BLACK);
Menu_Button_draw(rules->buttons[0], &font, self->screenWidth, self->screenHeight, GREEN, (self->screenHeight*4)/100, (self->screenWidth/400), true);
Menu_Button_draw(rules->buttons[1], &font, self->screenWidth, self->screenHeight, BLACK, self->screenHeight/40, (self->screenWidth/400), true);
ClearBackground(RAYWHITE);
UnloadFont(font);
EndDrawing();
}
void Panel_drawWin(Panel * self, Player * player, Mission * mission){
BeginDrawing();
Font font = GetFontDefault();
DrawText("VICTORY", (self->screenWidth*35)/100 , (self->screenHeight*15)/100 , (self->screenWidth*5)/100,BLACK);
char * victoryText = malloc(sizeof(char)*100);
sprintf(victoryText, "%s has completed their mission and won the game\nTheir mission was : %s", player->name, mission->displayText);
DrawText(victoryText, (self->screenWidth*20)/100, (self->screenHeight*45)/100, (self->screenWidth*2)/100, BLACK);
free(victoryText);
UnloadFont(font);
ClearBackground(RAYWHITE);
EndDrawing();
}
void Panel_drawGame(Panel * self)
{
BeginDrawing();
ClearBackground(RAYWHITE);
......@@ -65,7 +129,7 @@ void Panel_draw(Panel * self)
{
Panel_drawNode( self, &(self->world->nodes[i]) );
}
Panel_drawBasis(self);
//Panel_drawBasis(self);
EndDrawing();
}
......@@ -87,10 +151,10 @@ void Panel_drawNode(Panel * self, Node * n)
Vector2 screenPosition= Panel_pixelFromPosition(self, &(n->position) );
DrawCircleV(screenPosition, 24, n->color);
DrawCircleV(screenPosition, 20, RAYWHITE);
char * soldierText;
soldierText= malloc(sizeof(int));
char * soldierText = malloc(20*sizeof(char));
sprintf(soldierText, "%d", n->soldiers);
DrawText(soldierText, (int)(screenPosition.x), (int)(screenPosition.y), 20, n->color);
DrawText(soldierText, (int)screenPosition.x - MeasureText(soldierText, 20)/2, (int)screenPosition.y, 20, n->color);
free(soldierText);
}
void Panel_drawEdge(Panel * self, Edge * e)
......
......@@ -2,8 +2,10 @@
#define CONTROLPANEL_H
#include "networld.h"
#include "main-menu.h"
#include "options-menu.h"
#include "player.h"
#include "mission.h"
// Tools
void printVector2( Vector2 v );
......@@ -14,6 +16,7 @@ void printVector2( Vector2 v );
struct Str_Panel {
Vector2 camera, screenCenter;
int screenWidth, screenHeight;
float scale; // meter per pixel
NetWorld * world;
};
......@@ -25,19 +28,31 @@ Panel * Panel_new();
void Panel_delete(Panel * self);
// Initialization
void Panel_initialize(Panel * self, NetWorld * world);
void Panel_initialize(Panel * self, NetWorld * world, const int screenWidth, const int screenHeight);
// To String
void Panel_print(Panel * self);
// Rendering
void Panel_draw(Panel * self);
// Rendering the game
void Panel_drawGame(Panel * self);
void Panel_drawBasis(Panel * self);
void Panel_drawNode(Panel * self, Node * n);
void Panel_drawEdge(Panel * self, Edge * e);
Vector2 Panel_pixelFromPosition(Panel * self, Vector2 * p);
Vector2 Panel_positionFromPixel(Panel * self, Vector2 * p);
//Rendering the main menu
void Panel_drawMainMenu(Panel * self, Main_Menu * menu);
//Rendering the options menu
void Panel_drawOptionsMenu(Panel * self, Options_Menu * menu);
//Rendering the rules menu
void Panel_drawRules(Panel * self, Main_Menu * rules);
//Rendering the victory screen
void Panel_drawWin(Panel * self, Player * player, Mission * mission);
// Control
void Panel_control(Panel * self);
void Panel_controlCamera(Panel * self);
......
#include "entity.h"
#ifndef ENTITY_H
#define ENTITY_H
#include "raylib.h"
//-----------------------------------//
//-- Entity Descriptor --//
//-----------------------------------//
struct Str_EntityDsc {
Color color;
};
typedef struct Str_EntityDsc EntityDsc;
struct Str_Entity {
//! Owner of the Entity (classically the player Id)
int owner;
EntityDsc descriptor;
};
typedef struct Str_Entity Entity;
#endif // ENTITY_H
\ No newline at end of file
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <math.h>
#include <string.h>
#include <time.h>
#include "graphical-aspect.h"
#include "networld.h"
#include "controlpanel.h"
#include "player.h"
#include "raylib.h"
void Graphic_ShowPlayerInfo(Player *player, int screenWidth, int screenHeight, Font *font)
{
Rectangle rec = {0, screenHeight - 250, 250, 250}; //Draw current player number on the bottom left
DrawRectangleLinesEx(rec, 10, player->color);
char *playerNumber = malloc(20 * sizeof(char));
sprintf(playerNumber, "%s", player->name);
DrawTextEx(*font, playerNumber, (Vector2){35, screenHeight - 240}, 30.0, 3.0, player->color);
char *soldierNumber = malloc(40 * sizeof(char)); //Draw current player number of soldiers
sprintf(soldierNumber, "Soldiers left %d", player->soldiers);
DrawTextEx(*font, soldierNumber, (Vector2){15, screenHeight - 180}, 24.0, 3.0, player->color);
int totalTroops = 0;
for (int i = 0; i < player->nodeCount; i++)
{
totalTroops += player->nodes[i]->soldiers;
}
char *str_totalTroops = malloc(40 * sizeof(char)); //Draw current player number of total troops owned
sprintf(str_totalTroops, "Total Troops %d", totalTroops);
DrawTextEx(*font, str_totalTroops, (Vector2){15, screenHeight - 150}, 24.0, 3.0, player->color);
char *str_nodeCount = malloc(40 * sizeof(char)); //Draw current player number of nodes owned
sprintf(str_nodeCount, "Nodes owned %d", player->nodeCount);
DrawTextEx(*font, str_nodeCount, (Vector2){15, screenHeight - 120}, 24.0, 3.0, player->color);
free(playerNumber);
free(soldierNumber);
free(str_totalTroops);
free(str_nodeCount);
}
void Graphic_RecrutementPhase(Player *player, int screenWidth, int screenHeight, Font *font)
{
Rectangle rec = {screenWidth - 300, 100, 300, 400}; //Display recruitment phase rules
DrawRectangleLinesEx(rec, 10, player->color);
DrawTextEx(*font, "Recrutement Phase", (Vector2){screenWidth - 275, 120}, 23.0, 3.0, player->color);
DrawTextRec(*font, " LEFT click on one of your node to recruit a soldier", (Rectangle){screenWidth - 285, 175, 270, 100}, 20.0, 3.0, true, player->color);
DrawTextRec(*font, " RIGHT click on the same node to remove the soldier", (Rectangle){screenWidth - 285, 295, 270, 100}, 20.0, 3.0, true, player->color);
DrawTextRec(*font, " click Confirm once finished", (Rectangle){screenWidth - 285, 415, 270, 100}, 20.0, 3.0, true, player->color);
}
void Graphic_AttackPhase(Player *player, int screenWidth, int screenHeight, Font *font)
{
Rectangle rec = {screenWidth - 300, 100, 300, 450}; //Display attack phase rules
DrawRectangleLinesEx(rec, 10, player->color);
DrawTextEx(*font, "Attack Phase", (Vector2){screenWidth - 265, 120}, 23.0, 3.0, player->color);
DrawTextRec(*font, " FIRST click on the node you want to attack from", (Rectangle){screenWidth - 285, 175, 270, 100}, 20.0, 3.0, true, player->color);
DrawTextRec(*font, " THEN click on one of neighbouring node you want to attack", (Rectangle){screenWidth - 285, 295, 270, 100}, 20.0, 3.0, true, player->color);
DrawTextRec(*font, " click Next Turn once finished all your attacks", (Rectangle){screenWidth - 285, 415, 270, 100}, 20.0, 3.0, true, player->color);
}
void Graphic_WhoseTurnIsIt(Player *player, int screenWidth, int screenHeight, Font *font)
{
char *whoseTurn = malloc(20 * sizeof(char)); //Display whose turn is it
sprintf(whoseTurn, "%ss Turn", player->name);
DrawTextEx(*font, whoseTurn, (Vector2){screenWidth / 2 - (MeasureTextEx(*font, whoseTurn, 50.0, 3.0).x) / 2, 30}, 50.0, 3.0, player->color);
free(whoseTurn);
}
Rectangle Graphic_ConfirmButton(Font *font)
{ //Confirm button for the recruitment phase
Rectangle nextPhase = {200, 200, 220, 55};
DrawRectangleRec(nextPhase, GREEN);
DrawTextEx(*font, "Confirm", (Vector2){220, 210}, 40.0, 3.0, BLACK);
return nextPhase;
}
void Graphic_MouseHoverNodeRecrutement(Player *player, Vector2 mousePosition, Panel *panel)
{
for (int nodeIndex = 0; nodeIndex < player->nodeCount; nodeIndex++)
{
Node *currentNode = player->nodes[nodeIndex]; //Draw a small ring when mouse hover one current player's node
if (CheckCollisionPointRec(mousePosition, currentNode->collisionHitbox))
{
Vector2 screenPosition = Panel_pixelFromPosition(panel, &(currentNode->position));
DrawRing(screenPosition, 24.0, 28.0, 0.0, 360.0, 0.1, MAGENTA);
if (player->soldiers > 0)
{
DrawText("+1", (int)screenPosition.x + 30, (int)screenPosition.y, 20, MAGENTA);
}
}
}
}
void Graphic_MouseHoverNodeChooseAttacker(Player *player, Vector2 mousePosition, Panel *panel)
{
for (int nodeIndex = 0; nodeIndex < player->nodeCount; nodeIndex++)
{
Node *currentNode = player->nodes[nodeIndex]; //Draw a small ring when mouse hover one current player's node
if (CheckCollisionPointRec(mousePosition, currentNode->collisionHitbox)) //and draw persistent ring when an attacker node is selected
{
Vector2 screenPosition = Panel_pixelFromPosition(panel, &(currentNode->position));
if (!player->hasSelectedNode && currentNode->soldiers > 1)
{
DrawRing(screenPosition, 24.0, 28.0, 0.0, 360.0, 0.1, GOLD);
DrawText("attacker", (int)screenPosition.x + 30, (int)screenPosition.y, 20, GOLD);
Graphic_MouseHoverNodeChooseTarget(currentNode, mousePosition, panel);
}
}
}
if (player->hasSelectedNode)
{
Vector2 screenPosition = Panel_pixelFromPosition(panel, &(player->selectedNode->position));
DrawRing(screenPosition, 24.0, 28.0, 0.0, 360.0, 0.1, GOLD);
DrawText("attacker", (int)screenPosition.x + 30, (int)screenPosition.y, 20, GOLD);
}
}
void Graphic_MouseHoverNodeChooseTarget(Node *originNode, Vector2 mousePosition, Panel *panel)
{
for (int neighbourIndex = 0; neighbourIndex < originNode->card; neighbourIndex++) //Draw a ring for all the enemy nodes which can be attacked from the current selected attacker
{
Vector2 screenPosition = Panel_pixelFromPosition(panel, &(originNode->edges[neighbourIndex]._target->position));
if (originNode->edges[neighbourIndex]._target->color.r != originNode->color.r || originNode->edges[neighbourIndex]._target->color.g != originNode->color.g || originNode->edges[neighbourIndex]._target->color.b != originNode->color.b || originNode->edges[neighbourIndex]._target->color.a != originNode->color.a)
{
DrawRing(screenPosition, 24.0, 30.0, 0.0, 360.0, 0.1, GREEN);
if (CheckCollisionPointRec(mousePosition, originNode->edges[neighbourIndex]._target->collisionHitbox) && &(originNode->edges[neighbourIndex]._target->color) != &(originNode->color))
{
DrawRing(screenPosition, 30.0, 33.0, 0.0, 360.0, 0.1, MAROON);
}
}
}
}
int Graphic_ChooseNumberOfAttackers(Player *attacker, Player *defender, Node *originNode, Node *targetNode, Font *font)
{
const int screenWidth = 1700;
const int screenHeight = 800;
bool endAnimation = false;
SetTargetFPS(60);
//Display rectangles to choose how many soldiers/dices you want to engage in the fight
Rectangle nbAttackerRectangle[10];
for (int i = 0; i < originNode->soldiers; i++)
{
nbAttackerRectangle[i] = (Rectangle){200 + (i - 1) * 250, screenHeight - 500, 150, 70};
}
char whoseTurnToAttack[20];
sprintf(whoseTurnToAttack, "%s attacks ", attacker->name);
char whoseTurnToDefend[20];
sprintf(whoseTurnToDefend, "%s", defender->name);
while (!endAnimation)
{
BeginDrawing();
ClearBackground(RAYWHITE);
Vector2 mousePosition = GetMousePosition();
DrawTextEx(*font, whoseTurnToAttack, (Vector2){screenWidth / 2 - (MeasureTextEx(*font, whoseTurnToAttack, 50.0, 3.0).x) + 100, 70}, 50.0, 3.0, attacker->color);
DrawTextEx(*font, whoseTurnToDefend, (Vector2){screenWidth / 2 + 100, 70}, 50.0, 3.0, defender->color);
DrawText("How many dices do you want to involve in the fight ?", screenWidth / 2 - (MeasureTextEx(*font, "How many dice do you want to involve in the fight ?", 30.0, 3.0).x) / 2 + 50, 150, 30, attacker->color);
for (int i = 1; i < originNode->soldiers; i++)
{
DrawRectangleRec(nbAttackerRectangle[i], BLACK);
char str_i[5];
sprintf(str_i, "%d", i);
DrawTextEx(*font, str_i, (Vector2){nbAttackerRectangle[i].x + 55, nbAttackerRectangle[i].y + 5}, 70.0, 3.0, WHITE);
if (CheckCollisionPointRec(mousePosition, nbAttackerRectangle[i]))
{
DrawRectangleLinesEx(nbAttackerRectangle[i], 5, GREEN);
}
if (IsMouseButtonPressed(MOUSE_LEFT_BUTTON))
{
if (CheckCollisionPointRec(mousePosition, nbAttackerRectangle[i]))
{
printf("colision dés choix %d \n", i);
return i;
}
}
}
EndDrawing();
}
}
void Graphic_diceRolling(Player *attacker, Player *defender, Node *originNode, Node *targetNode, int nbOfAttackers, int nbOfDefenders, int *listOfDices, Font *font)
{
const int screenWidth = 1700;
const int screenHeight = 800;
Image texture = LoadImage("resources/diceRolling.png");
ImageResize(&(texture), 100, 800);
Texture2D diceTexture = LoadTextureFromImage(texture);
int defendersCount = nbOfDefenders;
int attackersCount = nbOfAttackers;
char *whoseTurnToAttack = malloc(20 * sizeof(char));
sprintf(whoseTurnToAttack, "%s ", attacker->name);
char *whoseTurnToDefend = malloc(20 * sizeof(char));
sprintf(whoseTurnToDefend, "%s ", defender->name);
Rectangle skipAnimation = {screenWidth / 2 - 225, 200, 190, 50};
Rectangle skipResult = {screenWidth / 2 - 205, 200, 150, 50};
Vector2 *positionDiceAttacker = malloc(20 * sizeof(Vector2));
Vector2 *positionDiceDefender = malloc(20 * sizeof(Vector2));
for (int i = 0; i < nbOfAttackers; i++)
{
positionDiceAttacker[i] = (Vector2){200 + (i)*150, screenHeight - 500};
}
for (int i = 0; i < defendersCount; i++)
{
positionDiceDefender[i] = (Vector2){1000 + (i)*150, screenHeight - 500};
}
Rectangle frameRec = {0.0f, 0.0f, (float)diceTexture.width, (float)diceTexture.height / 9};
int currentFrame = 0;
int framesCounter = 0;
int framesSpeed = 7;
int frameExit = 0;
bool endAnimationDice = false;
SetTargetFPS(60);
while (!endAnimationDice) //Animation of dices
{
Vector2 mousePosition = GetMousePosition();
framesCounter++;
frameExit++;
if (frameExit == 200)
endAnimationDice = true;
if (IsMouseButtonPressed(MOUSE_LEFT_BUTTON))
{
if (CheckCollisionPointRec(mousePosition, skipAnimation))
{
endAnimationDice = true;
}
}
if (framesCounter >= (60 / framesSpeed))
{
framesCounter = 0;
currentFrame++;
if (currentFrame > 8)
currentFrame = 0;
frameRec.y = (float)currentFrame * (float)diceTexture.height / 9;
}
BeginDrawing();
ClearBackground(RAYWHITE);
DrawTextEx(*font, whoseTurnToAttack, (Vector2){250, 100}, 40.0, 3.0, attacker->color);
DrawTextEx(*font, whoseTurnToDefend, (Vector2){screenWidth - 700, 100}, 40.0, 3.0, defender->color);
DrawTextEx(*font, " attacker", (Vector2){225, 150}, 30.0, 3.0, attacker->color);
DrawTextEx(*font, " defender", (Vector2){screenWidth - 725, 150}, 30.0, 3.0, defender->color);
DrawRectangleRec(skipAnimation, BLUE);
DrawTextEx(*font, "Skip Animation", (Vector2){screenWidth / 2 - 215, 210}, 18.0, 3.0, BLACK);
for (int i = 0; i < nbOfAttackers; i++)
{
DrawTextureRec(diceTexture, frameRec, positionDiceAttacker[i], WHITE);
}
for (int i = 0; i < defendersCount; i++)
{
DrawTextureRec(diceTexture, frameRec, positionDiceDefender[i], WHITE);
}
EndDrawing();
}
currentFrame = 0;
framesCounter = 0;
bool endDisplayResult = false;
while (!endDisplayResult) //Display result of the dice rolling
{
Vector2 mousePosition = GetMousePosition();
framesCounter++;
frameExit++;
if (frameExit == 350)
endDisplayResult = true;
if (IsMouseButtonPressed(MOUSE_LEFT_BUTTON))
{
if (CheckCollisionPointRec(mousePosition, skipResult))
{
endDisplayResult = true;
}
}
if (framesCounter >= (60 / framesSpeed))
{
framesCounter = 0;
currentFrame++;
if (currentFrame > 8)
currentFrame = 0;
frameRec.y = (float)currentFrame * (float)diceTexture.height / 9;
}
BeginDrawing();
ClearBackground(RAYWHITE);
DrawTextEx(*font, whoseTurnToAttack, (Vector2){250, 100}, 40.0, 3.0, attacker->color);
DrawTextEx(*font, whoseTurnToDefend, (Vector2){screenWidth - 700, 100}, 40.0, 3.0, defender->color);
DrawTextEx(*font, " attacker", (Vector2){225, 150}, 30.0, 3.0, attacker->color);
DrawTextEx(*font, " defender", (Vector2){screenWidth - 725, 150}, 30.0, 3.0, defender->color);
DrawRectangleRec(skipResult, BLUE);
DrawTextEx(*font, "Skip Result", (Vector2){screenWidth / 2 - 200, 210}, 18.0, 3.0, BLACK);
for (int i = 0; i < nbOfAttackers; i++)
{
switch (listOfDices[i])
{
case 1:
frameRec.y = 9 * (float)diceTexture.height / 9;
DrawTextureRec(diceTexture, frameRec, positionDiceAttacker[i], WHITE);
DrawTextEx(*font, "1", (Vector2){positionDiceAttacker[i].x + 30, positionDiceAttacker[i].y + 100}, 50.0, 3.0, BLACK);
break;
case 2:
frameRec.y = 1 * (float)diceTexture.height / 9;
DrawTextureRec(diceTexture, frameRec, positionDiceAttacker[i], WHITE);
DrawTextEx(*font, "2", (Vector2){positionDiceAttacker[i].x + 30, positionDiceAttacker[i].y + 100}, 50.0, 3.0, BLACK);
break;
case 3:
frameRec.y = 2 * (float)diceTexture.height / 9;
DrawTextureRec(diceTexture, frameRec, positionDiceAttacker[i], WHITE);
DrawTextEx(*font, "3", (Vector2){positionDiceAttacker[i].x + 30, positionDiceAttacker[i].y + 100}, 50.0, 3.0, BLACK);
break;
case 4:
frameRec.y = 3 * (float)diceTexture.height / 9;
DrawTextureRec(diceTexture, frameRec, positionDiceAttacker[i], WHITE);
DrawTextEx(*font, "4", (Vector2){positionDiceAttacker[i].x + 30, positionDiceAttacker[i].y + 100}, 50.0, 3.0, BLACK);
break;
case 5:
frameRec.y = 4 * (float)diceTexture.height / 9;
DrawTextureRec(diceTexture, frameRec, positionDiceAttacker[i], WHITE);
DrawTextEx(*font, "5", (Vector2){positionDiceAttacker[i].x + 30, positionDiceAttacker[i].y + 100}, 50.0, 3.0, BLACK);
break;
case 6:
frameRec.y = 5 * (float)diceTexture.height / 9;
DrawTextureRec(diceTexture, frameRec, positionDiceAttacker[i], WHITE);
DrawTextEx(*font, "6", (Vector2){positionDiceAttacker[i].x + 30, positionDiceAttacker[i].y + 100}, 50.0, 3.0, BLACK);
break;
default:
break;
}
}
for (int i = nbOfAttackers; i < nbOfAttackers + defendersCount; i++)
{
switch (listOfDices[i])
{
case 1:
frameRec.y = 9 * (float)diceTexture.height / 9;
DrawTextureRec(diceTexture, frameRec, positionDiceDefender[i - nbOfAttackers], WHITE);
DrawTextEx(*font, "1", (Vector2){positionDiceDefender[i - nbOfAttackers].x + 30, positionDiceDefender[i - nbOfAttackers].y + 100}, 50.0, 3.0, BLACK);
break;
case 2:
frameRec.y = 1 * (float)diceTexture.height / 9;
DrawTextureRec(diceTexture, frameRec, positionDiceDefender[i - nbOfAttackers], WHITE);
DrawTextEx(*font, "2", (Vector2){positionDiceDefender[i - nbOfAttackers].x + 30, positionDiceDefender[i - nbOfAttackers].y + 100}, 50.0, 3.0, BLACK);
break;
case 3:
frameRec.y = 2 * (float)diceTexture.height / 9;
DrawTextureRec(diceTexture, frameRec, positionDiceDefender[i - nbOfAttackers], WHITE);
DrawTextEx(*font, "3", (Vector2){positionDiceDefender[i - nbOfAttackers].x + 30, positionDiceDefender[i - nbOfAttackers].y + 100}, 50.0, 3.0, BLACK);
break;
case 4:
frameRec.y = 3 * (float)diceTexture.height / 9;
DrawTextureRec(diceTexture, frameRec, positionDiceDefender[i - nbOfAttackers], WHITE);
DrawTextEx(*font, "4", (Vector2){positionDiceDefender[i - nbOfAttackers].x + 30, positionDiceDefender[i - nbOfAttackers].y + 100}, 50.0, 3.0, BLACK);
break;
case 5:
frameRec.y = 4 * (float)diceTexture.height / 9;
DrawTextureRec(diceTexture, frameRec, positionDiceDefender[i - nbOfAttackers], WHITE);
DrawTextEx(*font, "5", (Vector2){positionDiceDefender[i - nbOfAttackers].x + 30, positionDiceDefender[i - nbOfAttackers].y + 100}, 50.0, 3.0, BLACK);
break;
case 6:
frameRec.y = 5 * (float)diceTexture.height / 9;
DrawTextureRec(diceTexture, frameRec, positionDiceDefender[i - nbOfAttackers], WHITE);
DrawTextEx(*font, "6", (Vector2){positionDiceDefender[i - nbOfAttackers].x + 30, positionDiceDefender[i - nbOfAttackers].y + 100}, 50.0, 3.0, BLACK);
break;
default:
break;
}
}
int remainingAttackers = attackersCount;
for (int index = 0; index < fmin(defendersCount, attackersCount); index++)
{
if (listOfDices[index] > listOfDices[index + attackersCount])
{
DrawTextEx(*font, defender->name, (Vector2){screenWidth / 2 - 300, 600}, 50.0, 3.0, BLACK);
DrawTextEx(*font, " lose a soldier", (Vector2){screenWidth / 2 -300 + MeasureTextEx(*font, defender->name, 50.0, 3.0).x , 600}, 50.0, 3.0, defender->color);
}
else
{
DrawTextEx(*font, attacker->name, (Vector2){screenWidth / 2 - 300, 600}, 50.0, 3.0, BLACK);
DrawTextEx(*font, " lose a soldier", (Vector2){screenWidth / 2 - 300 + MeasureTextEx(*font, attacker->name, 50.0, 3.0).x , 600}, 50.0, 3.0, attacker->color);
}
}
if (targetNode->soldiers <= 0)
{
DrawTextEx(*font, "Node has been conquered", (Vector2){screenWidth / 2 - MeasureTextEx(*font, "Node has been conquered", 50.0, 3.0).x / 2 - 50, 700}, 50.0, 3.0, BLACK);
}
EndDrawing();
}
free(whoseTurnToAttack);
free(whoseTurnToDefend);
free(positionDiceAttacker);
free(positionDiceDefender);
UnloadImage(texture);
UnloadTexture(diceTexture);
}
#ifndef GRAPHICALASPECT_H
#define GRAPHICALASPECT_H
#include "raylib.h"
#include "networld.h"
#include "player.h"
#include "controlpanel.h"
//Graphical view
//Display players' number of nodes owned, number of total troops and number of soldier to place on the bottom left of the screen
void Graphic_ShowPlayerInfo(Player * player, const int screenWidth, const int screenHeight, Font * font);
//Display recrutement phase rules on the right of the screen
void Graphic_RecrutementPhase(Player * player, const int screenWidth, const int screenHeight, Font * font);
//Display attack phase rules on the right of the screen
void Graphic_AttackPhase(Player * player, const int screenWidth, const int screenHeight, Font * font);
//Display whose turn is it on the top of the screen
void Graphic_WhoseTurnIsIt(Player * player, const int screenWidth, const int screenHeight, Font * font);
//Confirm button for the recruitment phase
Rectangle Graphic_ConfirmButton(Font * font);
//Animation when mouse hover node during recruitment phase
void Graphic_MouseHoverNodeRecrutement(Player * self, Vector2 mousePosition, Panel * panel);
//Animation when mouse hover node when choosing attacker node during attack phase
void Graphic_MouseHoverNodeChooseAttacker(Player * player, Vector2 mousePosition, Panel * panel);
//Animation when mouse hover node when choosing target node during attack phase
void Graphic_MouseHoverNodeChooseTarget(Node * originNode, Vector2 mousePosition, Panel * panel);
//Display a window to choose number of dices to involve in a fight + return the number chosen
int Graphic_ChooseNumberOfAttackers(Player * attacker, Player * defender, Node * originNode, Node * targetNode, Font * font);
//Display animation of dice rolling + results of the dice rolling
void Graphic_diceRolling(Player * attacker, Player * defender, Node * originNode, Node * targetNode, int nbOfAttackers, int nbOfDefenders, int * listOfDices, Font * font);
#endif
\ No newline at end of file
#include "int-input.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
Int_Input * Int_Input_init(char* name, int * targetInt, Rectangle * inputBox){
Int_Input * self = malloc(sizeof(Int_Input));
self->name = name;
self->targetInt = targetInt;
self->value = malloc(sizeof(char)*50);
sprintf(self->value, "%d", *targetInt);
self->valueLength = strlen(self->value);
self->inputBox = *inputBox;
self->inputActive = false;
return self;
}
void Int_Input_delete(Int_Input * self){
free(self->value);
free(self);
}
void Int_Input_add_char(Int_Input * self, int * key){
self->value[self->valueLength] = (char) *key;
self->valueLength++;
self->value[self->valueLength] = '\0';
}
void Int_Input_remove_char(Int_Input * self){
self->valueLength--;
if (self->valueLength < 0) self->valueLength = 0;
self->value[self->valueLength] = '\0';
}
void Int_Input_save_value(Int_Input * self){
if(self->valueLength > 0){
*(self->targetInt) = atoi(self->value);
}
}
void Int_Input_draw(Int_Input * self, Font * font, const int screenWidth, const int screenHeight){
DrawRectangleRec(self->inputBox, LIGHTGRAY);
DrawText(self->name, self->inputBox.x/2, self->inputBox.y, (screenHeight*4)/100, BLACK);
DrawTextRec(*font, self->value, self->inputBox, (screenHeight*4)/100, (screenWidth/75), true, BLACK);
}
\ No newline at end of file
#ifndef INTINPUT_H
#define INTINPUT_H
#include "raylib.h"
struct Str_Int_Input{
//! Text to display
char* name;
//! Pointer to the value to change
int * targetInt;
//! Current stored value
char* value;
//! char count of value
int valueLength;
//! Panel input box
Rectangle inputBox;
bool inputActive;
};
typedef struct Str_Int_Input Int_Input;
/**
* @brief Initialise an input field.
* @param name the text to display
* @param targetInt pointer to the value to change
* @param inputBox panel input box
* @return The pointer to the new Int_Input.
*/
Int_Input * Int_Input_init(char* name, int * targetInt, Rectangle *inputBox);
/**
* @brief Free an Int_Input
* @param self the element to void
*/
void Int_Input_delete(Int_Input * self);
/**
* @brief Add a char to the current value
* @param self the Int_Input to add to
* @param key the character to add
*/
void Int_Input_add_char(Int_Input * self, int * key);
/**
* @brief Remove a char from the current value
* @param self the Int_Input to remove from
*/
void Int_Input_remove_char(Int_Input * self);
/**
* @brief Save the stored input value in the actual game parameter
* @param self the Int_Input to save in
*/
void Int_Input_save_value(Int_Input * self);
/**
* @brief Draw the Int_Input on the panel
* @param self the Int_Input to draw
* @param font the text font to use
* @param screenWidth the width of the screen
* @param screenHeight the height of the screen
*/
void Int_Input_draw(Int_Input * self, Font * font, const int screenWidth, const int screenHeight);
#endif
\ No newline at end of file
#include "main-menu.h"
#include <stdlib.h>
#include <stdio.h>
Main_Menu * Main_Menu_init(const int screenWidth, const int screenHeight){
Main_Menu * self = malloc(sizeof(Main_Menu));
//Init of the play game btn
Rectangle playGameBtn = {(screenWidth*32)/100, (screenHeight*35)/100, (screenWidth*30)/100, (screenHeight*5)/100};
Rectangle smallPlayGameBtn = {3 + (screenWidth*32/100), 3 + (screenHeight*35/100), (screenWidth*30/100) - 6, (screenHeight*5/100) - 6};
Rectangle playGameTextBox = {smallPlayGameBtn.x + smallPlayGameBtn.width/3, smallPlayGameBtn.y, smallPlayGameBtn.width, smallPlayGameBtn.height};
Menu_Button * playGame = Menu_Button_init(&playGameBtn, &playGameTextBox, "PLAY", game_ui);
//Init of the options btn
Rectangle optionsBtn = {(screenWidth*32)/100, (screenHeight*45)/100, (screenWidth*30)/100, (screenHeight*5)/100};
Rectangle smallOptionsBtn = {3 + (screenWidth*32/100), 3 + (screenHeight*45/100), (screenWidth*30/100) - 6, (screenHeight*5/100) - 6};
Rectangle optionsTextBox = {smallOptionsBtn.x + smallOptionsBtn.width/4, smallOptionsBtn.y, smallOptionsBtn.width, smallOptionsBtn.height};
Menu_Button * optionsMenu = Menu_Button_init(&optionsBtn, &optionsTextBox, "OPTIONS", options);
//Init of the rules btn
Rectangle rulesBtn = {(screenWidth*32)/100, (screenHeight*55)/100, (screenWidth*30)/100, (screenHeight*5)/100};
Rectangle smallRulesBtn = {3 + (screenWidth*32/100), 3 + (screenHeight*55/100), (screenWidth*30/100) - 6, (screenHeight*5/100) - 6};
Rectangle rulesTextBox = {smallRulesBtn.x + smallRulesBtn.width*4/13, smallRulesBtn.y, smallRulesBtn.width, smallRulesBtn.height};
Menu_Button * rulesMenu = Menu_Button_init(&rulesBtn, &rulesTextBox, "RULES", rules);
//Init of the exit btn
Rectangle exitBtn = {0, (screenHeight*95)/100, (screenWidth*10)/100, (screenHeight*10)/100};
Rectangle smallerExitBtn = {3, 3 +(screenHeight*95)/100, -6 + (screenWidth*10)/100, -6 + (screenHeight*10)/100};
Rectangle exitTextBox = {smallerExitBtn.x + smallerExitBtn.width/10, smallerExitBtn.y, smallerExitBtn.width, smallerExitBtn.height};
Menu_Button * terminateBtn = Menu_Button_init(&exitBtn, &exitTextBox, "EXIT", exitRoute);
self->buttonCount = 4;
self->buttons = malloc(sizeof(Menu_Button) * self->buttonCount);
self->buttons[game_ui] = playGame;
self->buttons[options] = optionsMenu;
self->buttons[rules] = rulesMenu;
self->buttons[exitRoute] = terminateBtn;
return self;
}
Main_Menu * Rules_Menu_init(const int screenWidth, const int screenHeight){
Main_Menu * self = malloc(sizeof(Main_Menu));
//Init of the return btn
Rectangle returnBtn = {0, (screenHeight*95)/100, (screenWidth*15)/100, (screenHeight*10)/100};
Rectangle smallerReturnBtn = {3, 3 +(screenHeight*95)/100, -6 + (screenWidth*15)/100, -6 + (screenHeight*10)/100};
Rectangle returnTextBox = {smallerReturnBtn.x + smallerReturnBtn.width/7, smallerReturnBtn.y, smallerReturnBtn.width, smallerReturnBtn.height};
Menu_Button * rulesMenu = Menu_Button_init(&returnBtn, &returnTextBox, "Main Menu", main_menu);
//Init of the rules text box
Rectangle rulesBox = {(screenWidth*25)/100, (screenHeight*30)/100, (screenWidth*50)/100, (screenHeight*60)/100};
Rectangle smallerRulesBox = {3 + (screenWidth*25)/100, 3 +(screenHeight*30)/100, -6 + (screenWidth*50)/100, -6 + (screenHeight*60)/100};
Rectangle rulesTextBox = {5 + (screenWidth*25)/100, 5 +(screenHeight*30)/100, -10 + (screenWidth*50)/100, -10 + (screenHeight*60)/100};
Menu_Button * rulesText = Menu_Button_init(&rulesBox, &rulesTextBox,
"This game is an adapted and computerized version of the board game Risk.\nEach player will be given a set of territories (nodes) and a mission to win the game.\nSuccessively, each player will play their turns which happens in 2 phases :\n-\tThe recruitment phase, in which a player is given reinforcements to place on his node, and move existing soldiers, although any given nodes needs at least 1 soldier at all times.\n-\tThe attack phase, in which a player may attack neighboring nodes that he doesnt own. He will have to engage up to 3 soldiers in a fight, which resolves in throwing one die per soldier engage. The outcome will be determined by the head to head comparison of the results from the attacker and the defender.\nA player wins by accomplishing their mission.",
rules);
self->buttonCount = 2;
self->buttons = malloc(sizeof(Menu_Button) * self->buttonCount);
self->buttons[0] = rulesMenu;
self->buttons[1] = rulesText;
return self;
}
Display Main_Menu_detect_click(Main_Menu * self, Vector2 * mousePos){
for(int index = 0; index < self->buttonCount; index++){
Menu_Button * currentBtn = self->buttons[index];
if(CheckCollisionPointRec(*mousePos, currentBtn->button)){
return currentBtn->displayOnClick;
}
}
return main_menu;
}
void Main_Menu_delete(Main_Menu * self){
for(int index = 0; index < self->buttonCount; index++){
Menu_Button_delete(self->buttons[index]);
}
free(self->buttons);
free(self);
}
#ifndef MAINMENU_H
#define MAINMENU_H
#include "menu-button.h"
struct Str_Main_Menu{
//! Button pointer list
Menu_Button ** buttons;
//! Nb of buttons
int buttonCount;
};
typedef struct Str_Main_Menu Main_Menu;
/**
* @brief Initialise a new Main_Menu object
* @param screenWidth the width of the screen
* @param screenHeight the height of the screen
* @return A pointer to the new Main_Menu
*/
Main_Menu * Main_Menu_init(const int screenWidth, const int screenHeight);
/**
* @brief Initialise a new Main_Menu object for the rules menu
* @param screenWidth the width of the screen
* @param screenHeight the height of the screen
* @return A pointer to the new Main_Menu
*/
Main_Menu * Rules_Menu_init(const int screenWidth, const int screenHeight);
/**
* @brief Detect if any buttons have been clicked
* @param self the Main_Menu context
* @param mousePos the position of the mouse on click
* @return An enum element indicating which screen to display in the next frame
*/
Display Main_Menu_detect_click(Main_Menu * self, Vector2 * mousePos);
/**
* @brief Delete a Main_Menu
* @param self the menu to void
*/
void Main_Menu_delete(Main_Menu * self);
#endif
\ No newline at end of file
......@@ -9,71 +9,280 @@
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include "networld.h"
#include "player.h"
#include "controlpanel.h"
#include "random-map.h"
#include "graphical-aspect.h"
#include "window-manager.h"
#include "main-menu.h"
#include "options-menu.h"
#include "mission.h"
// Program attributes
//-------------------
const int screenWidth = 800;
const int screenHeight = 600;
const int screenWidth = 1700;
const int screenHeight = 800;
const int targetFPS = 60;
void game_update(NetWorld * world);
int game_update(NetWorld * world, Player * players, Mission * missions, Font *font, Panel * panel);
// Game attributes
//-----------------
bool game_end;
bool game_end = false;
int main(int nbArg, char ** arg)
{
// Game Initialization
//--------------------
game_end= false;
NetWorld * world= NetWorld_new(3);
Node_set( &(world->nodes[0]), (Vector2){1.4f, 1.28f}, RED );
Node_set( &(world->nodes[1]), (Vector2){21.0f, 22.8f}, MAGENTA );
Node_set( &(world->nodes[2]), (Vector2){18.4f, -12.2f}, GRAY );
int nodeCount = 10;
int playerCount = 3;
NetWorld_connect(world, 0, 1);
NetWorld_connect(world, 1, 2);
NetWorld_biconnect(world, 2, 0);
Panel * panel= Panel_new();
Panel_initialize(panel, world);
NetWorld * world = malloc(sizeof(NetWorld));
Player * players = malloc(sizeof(Player));
Mission * missions = malloc(sizeof(Mission));
// Raylib Initialization
//----------------------
InitWindow(screenWidth, screenHeight, "NetWorld basic viewer");
SetTargetFPS(targetFPS);
Font gameFont = LoadFont("resources/GAMERIA.ttf");
// Main game loop
// Some verificcations
//--------------------
puts("world variable:");
NetWorld_print(world);
puts("world expected:\n[10.4, 12.8]\n[110.4, 52.8]\n[384.5, 422.2]");
Panel_print(panel);
Vector2 position= {1.f, 1.f};
position= Panel_pixelFromPosition( panel, &position );
printf("[%.2f,%.2f]\n", position.x, position.y);
//UI elements
Panel * panel = Panel_new();
Panel_initialize(panel, world, screenWidth, screenHeight);
Main_Menu * menu = Main_Menu_init(screenWidth, screenHeight);
Main_Menu * rulesMenu = Rules_Menu_init(screenWidth, screenHeight);
Options_Menu * optionsMenu = Options_Menu_init(&playerCount, &nodeCount, screenWidth, screenHeight);
Window_Manager * manager = Window_Manager_new(panel, menu, rulesMenu, optionsMenu);
Rectangle gameReturnBtn = {0,0, (screenWidth*13)/100, (screenHeight*5)/100};
Rectangle gameReturnTextBox = {3,3, -6 +(screenWidth*13)/100, -6 +(screenHeight*5)/100};
Menu_Button* gameReturn = Menu_Button_init(&gameReturnBtn, &gameReturnTextBox, "Main Menu", main_menu);
// Main game loop
while (!game_end && !WindowShouldClose()) // Detect window close button or ESC key
{
Panel_control(panel);
game_update(world);
Panel_draw(panel);
DrawFPS(screenWidth - 100,screenHeight - 50);
Window_Manager_display(manager, world, players, missions);
Vector2 mousePos;
int key;
switch (manager->display)
{
case main_menu:
if(IsMouseButtonPressed(MOUSE_LEFT_BUTTON)){
mousePos = GetMousePosition();
manager->display = Main_Menu_detect_click(menu, &mousePos);
if(manager->display == game_ui){
//Initialising a new game with inputted parameters
*world = *NetWorld_new(nodeCount, playerCount);
Random_map(world);
Color colors[] = {BLACK, RED, BLUE, BROWN, PURPLE, PINK, YELLOW};
char* names[] = {"Black", "Red", "Blue", "Brown", "Purple", "Pink", "Yellow"};
players = Player_newArray(playerCount, colors, names);
missions = Mission_newArray(playerCount, world, players);
//Distribute nodes to players evenly
for(int index = 0; index < world->size; index++){
Player_add_Node(&(players[index % playerCount]), &(world->nodes[index]));
}
world->currentPlayer = 0;
Player_start_turn(&(players[world->currentPlayer]));
}
}
break;
case game_ui:
Panel_control(panel);
Menu_Button_draw(gameReturn, &gameFont, screenWidth, screenHeight, RED, (screenHeight*4)/100, (screenWidth/400), true);
if(IsMouseButtonPressed(MOUSE_LEFT_BUTTON)){
mousePos = GetMousePosition();
if(CheckCollisionPointRec(mousePos, gameReturn->button)){
manager->display = gameReturn->displayOnClick;
}
}
//Draw the hitboxes for each node
for(int index = 0; index < world->size; index++){
Vector2 screenPosition= Panel_pixelFromPosition(panel, &(world->nodes[index]).position);
world->nodes[index].collisionHitbox.x = screenPosition.x - 24;
world->nodes[index].collisionHitbox.y = screenPosition.y - 24;
}
world->winner = game_update(world, players, missions, &gameFont, panel);
if(world->hasWinner){
manager->display = win;
}
break;
case options:
//Activate/Deactivate inputs on click and detect click on the save btn
if(IsMouseButtonPressed(MOUSE_LEFT_BUTTON)){
mousePos = GetMousePosition();
if(Options_Menu_check_save_click(optionsMenu, &mousePos)){
manager->display = main_menu;
for(int index = 0; index < optionsMenu->inputCount; index++){
Int_Input_save_value(optionsMenu->inputs[index]);
}
}
Options_Menu_check_input_click(optionsMenu, &mousePos);
}
key = GetKeyPressed();
//Check key inputs for active input fields (only accepts numerical characters)
for(int index = 0; index < optionsMenu->inputCount; index++){
if(optionsMenu->inputs[index]->inputActive){
DrawRectangleLinesEx((Rectangle){optionsMenu->inputBox[index].x-3,optionsMenu->inputBox[index].y-3,optionsMenu->inputBox[index].width+5,optionsMenu->inputBox[index].height+5}, 5, BLACK);
if ((key >= 48) && (key <= 57) && (optionsMenu->inputCount < 3)){
Int_Input_add_char(optionsMenu->inputs[index], &key);
}
if (IsKeyPressed(KEY_BACKSPACE)){
Int_Input_remove_char(optionsMenu->inputs[index]);
}
}
}
break;
case rules:
if(IsMouseButtonPressed(MOUSE_LEFT_BUTTON)){
mousePos = GetMousePosition();
manager->display = Main_Menu_detect_click(rulesMenu, &mousePos);
}
break;
case win:
Menu_Button_draw(gameReturn, &gameFont, screenWidth, screenHeight, RED, (screenHeight*4)/100, (screenWidth/400), true);
if(IsMouseButtonPressed(MOUSE_LEFT_BUTTON)){
mousePos = GetMousePosition();
if(CheckCollisionPointRec(mousePos, gameReturn->button)){
manager->display = gameReturn->displayOnClick;
}
}
break;
case exitRoute:
game_end = true;
break;
default:
break;
}
}
// proper closing
//---------------
Players_delete(players, playerCount);
Mission_deleteArray(missions,playerCount);
NetWorld_delete(world);
Main_Menu_delete(menu);
Main_Menu_delete(rulesMenu);
Menu_Button_delete(gameReturn);
Options_Menu_delete(optionsMenu);
Window_Manager_delete(manager);
Panel_delete(panel);
UnloadFont(gameFont);
CloseWindow(); // Close window and OpenGL context
return 0;
}
void game_update(NetWorld * world)
int game_update(NetWorld * world, Player * players, Mission * missions, Font* font, Panel * panel)
{
//Game frame init
int winner = 0;
Vector2 mousePosition = GetMousePosition();
Player * currentPlayer = &(players[world->currentPlayer]);
Graphic_ShowPlayerInfo(currentPlayer, screenWidth, screenHeight, font);
Graphic_WhoseTurnIsIt(currentPlayer, screenWidth, screenHeight, font);
int playerCount = world->playerCount;
Rectangle missionDisplay = {screenWidth*30/100, screenHeight*95/100, screenWidth*40/100, screenHeight*10/100};
Rectangle missionTextBox = {missionDisplay.x + missionDisplay.width/5, missionDisplay.y, missionDisplay.width, missionDisplay.height};
DrawTextRec(*font, missions[currentPlayer->ID].displayText, missionTextBox, (screenHeight*4)/100, (screenWidth/400), true, BLACK);
switch(currentPlayer->turnPhase){
case recruitment:
Graphic_RecrutementPhase(currentPlayer, screenWidth, screenHeight, font);
Graphic_MouseHoverNodeRecrutement(currentPlayer, mousePosition, panel);
if(currentPlayer->soldiers > 0){
if (IsMouseButtonPressed(MOUSE_LEFT_BUTTON)){
Player_add_soldier(currentPlayer, &mousePosition);
}
}else{
//Finish the recruitment phase
Rectangle nextPhaseButton = Graphic_ConfirmButton(font);
if (IsMouseButtonPressed(MOUSE_LEFT_BUTTON)){
if(CheckCollisionPointRec(mousePosition, nextPhaseButton)){
Player_confirm_recrutement(currentPlayer);
currentPlayer->turnPhase = attack;
}
}
}
if(IsMouseButtonPressed(MOUSE_RIGHT_BUTTON)){
Player_remove_soldier(currentPlayer, &mousePosition);
}
break;
case attack:
Graphic_AttackPhase(currentPlayer, screenWidth, screenHeight, font);
Graphic_MouseHoverNodeChooseAttacker(currentPlayer, mousePosition, panel);
if(currentPlayer->hasSelectedNode){
Graphic_MouseHoverNodeChooseTarget(currentPlayer->selectedNode, mousePosition, panel);
if(IsMouseButtonPressed(MOUSE_RIGHT_BUTTON)){
Player_unselect_Node(currentPlayer, &mousePosition);
}
if (IsMouseButtonPressed(MOUSE_LEFT_BUTTON)){
Node * originNode = currentPlayer->selectedNode;
//Detect if the player declared an attack
for(int nodeIndex = 0; nodeIndex < world->size; nodeIndex++){
Node* currentNode = &(world->nodes[nodeIndex]);
if(CheckCollisionPointRec(mousePosition, currentNode->collisionHitbox)){
int nodePlayerID = currentNode->playerID;
if(nodePlayerID == currentPlayer->ID){
currentPlayer->selectedNode = currentNode;
}
else if(Node_are_connected(originNode, currentNode) && (originNode->soldiers > 1) && originNode->canAttack){
printf("Engagine attack on target Node\n");
int nbOfAttackers = Graphic_ChooseNumberOfAttackers(currentPlayer, &(players[nodePlayerID]), originNode, currentNode, font);
int nbOfDefenders = currentNode->soldiers;
printf("nbOfAtackers %d \n", nbOfAttackers);
printf("nbOfdefenders %d \n", nbOfDefenders);
int * listOfDices = Player_attack_Node(currentPlayer, &(players[nodePlayerID]), originNode, currentNode, nbOfAttackers);
for(int i = 0; i< nbOfDefenders+nbOfAttackers; i++){
printf("listOfdices3 [%d] : %d \n",i,listOfDices[i]);
}
Graphic_diceRolling(currentPlayer, &(players[nodePlayerID]), originNode, currentNode, nbOfAttackers ,nbOfDefenders, listOfDices, font);
currentPlayer->hasSelectedNode = false;
free(listOfDices);
}
}
}
}
}else{
if (IsMouseButtonPressed(MOUSE_LEFT_BUTTON)){
Player_select_Node(currentPlayer, &mousePosition);
}
}
//End turn btn
Rectangle nextPhase = {200, 200, 270, 55};
DrawRectangleRec(nextPhase, GREEN);
DrawTextEx(*font, "Next Turn",(Vector2){220 , 210} , 40.0, 3.0, BLACK);
if (IsMouseButtonPressed(MOUSE_LEFT_BUTTON)){
if(CheckCollisionPointRec(mousePosition, nextPhase)){
currentPlayer->turnPhase = init;
}
}
break;
case init :
//Check on missions
if(Mission_check(&missions[currentPlayer->ID], world, players)){
world->hasWinner = true;
winner = currentPlayer->ID;
}
//Switch turns
Player_end_turn(currentPlayer);
world->currentPlayer = (world->currentPlayer + 1) % playerCount;
Player_start_turn(&(players[world->currentPlayer]));
break;
default:
break;
}
return winner;
}
#include "menu-button.h"
#include <stdlib.h>
#include <stdio.h>
Menu_Button * Menu_Button_init(Rectangle* button, Rectangle* textBox, char* displayText, Display display){
Menu_Button * self = malloc(sizeof(Menu_Button));
self->button = *button;
self->textBox = *textBox;
self->displayText = displayText;
self->displayOnClick = display;
return self;
}
void Menu_Button_draw(Menu_Button * self, Font * font, const int screenWidth, const int screenHeight, Color colour,int fontSize, int spacing, bool wordWrap){
DrawRectangleLinesEx(self->button, 3, colour);
DrawTextRec(*font, self->displayText, self->textBox, fontSize, spacing, wordWrap, BLACK);
}
void Menu_Button_delete(Menu_Button * self){
free(self);
}
#ifndef MENUBUTTON_H
#define MENUBUTTON_H
#include "raylib.h"
enum displays {game_ui, options, rules, exitRoute, main_menu, win};
typedef enum displays Display;
struct Str_Menu_Button{
//! Panel elements
Rectangle button;
Rectangle textBox;
//! Text to display in the button
char* displayText;
//! Menu to display if the button is clicked
Display displayOnClick;
};
typedef struct Str_Menu_Button Menu_Button;
/**
* @brief Init a Menu_Button
* @param button Button hitbox
* @param textBox Container for displayText
* @param displayText Text to display
* @param Display Enum element referencing to a screen display
* @return A pointer to the new button
*/
Menu_Button * Menu_Button_init(Rectangle* button, Rectangle* textBox, char* displayText, Display display);
/**
* @brief Draw the Menu_Button
* @param self The button to draw
* @param font The font to use
* @param screenWidth Width of the screen
* @param screenHeight Height of the screen
*/
void Menu_Button_draw(Menu_Button * self, Font * font, const int screenWidth, const int screenHeight, Color colour, int fontSize, int spacing, bool wordWrap);
/**
* @brief Void a Menu_button
* @param self The button to void
*/
void Menu_Button_delete(Menu_Button * self);
#endif
\ No newline at end of file
#include "mission.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
bool Player_conquer_threshold(NetWorld * world, Player * players, const int playerID, const int threshold){
return players[playerID].nodeCount >= threshold;
}
bool Player_eliminated(NetWorld * world, Player * players, const int playerID, const int targetPlayer){
return players[targetPlayer].nodeCount == 0;
}
void Mission_init(Mission * self, const int playerID, NetWorld * world, Player * players){
char* displayText = malloc(sizeof(char)*50);
self->playerID = playerID;
switch(rand()%2){
case 0:
self->mission = &Player_conquer_threshold;
self->target = world->size/2 + ((rand()%(world->size/5)) + (world->size/10));
sprintf(displayText, "Conquer %d nodes", self->target);
self->displayText = displayText;
break;
case 1:
self->mission = &Player_eliminated;
self->target = rand()%world->playerCount;
while(self->target == self->playerID){
self->target = rand()%world->playerCount;
}
sprintf(displayText, "Eliminate %s", players[self->target].name);
self->displayText = displayText;
break;
}
//return self;
}
Mission * Mission_newArray(const int playerCount, NetWorld * world, Player * players){
Mission * missionArray = malloc(sizeof(Mission) * playerCount);
for(int i = 0; i < playerCount; i++){
Mission_init((missionArray+i),i ,world, players);
}
return missionArray;
}
bool Mission_check(Mission * self, NetWorld * world, Player * players){
return self->mission(world, players, self->playerID, self->target);
}
void Mission_deleteArray(Mission * array, int playerCount){
free(array);
}
\ No newline at end of file
#ifndef MISSION_H
#define MISSION_H
#include "networld.h"
#include "player.h"
struct Str_Mission{
//! Boolean function to check if the mission is accomplished
bool (*mission)(NetWorld*, Player*, const int, const int);
//! Player needing to accomplish the mission
int playerID;
//! Relevant target int for mission (node count, player ID, ...)
int target;
//! Mission Description
char* displayText;
};
typedef struct Str_Mission Mission;
/**
* @brief Initialise a new Mission.
* @return The pointer to the new Mission.
*/
void Mission_init(Mission * self, const int playerID, NetWorld * world, Player * players);
/**
* @brief Check if the missions is completed.
* @return A boolean.
*/
bool Mission_check(Mission * self, NetWorld * world, Player * players);
/**
* @brief Void a mission array
*/
void Mission_deleteArray(Mission * array, int playerCount);
/**
* @brief Initialise a new Mission array
* @return The pointer to the new Mission array.
*/
Mission * Mission_newArray(const int playerCount, NetWorld * world, Player * players);
#endif
\ No newline at end of file
......@@ -12,14 +12,14 @@
// Constructor / Destructor
void Node_construct(Node * self)
{
Node_set( self, (Vector2){0.f, 0.f}, GRAY );
Node_set( self, (Vector2){0.f, 0.f}, GRAY);
self->card= 0;
self->edges= Edge_newArray( 0 );
self->name= malloc( sizeof(char)*32 );
self->continent= malloc( sizeof(char)*32 );
self->soldiers= 1;
strcpy(self->continent, "None");
strcpy( self->name, "Node" );
self->soldiers = 1;
self->playerID = -1;
Rectangle tmp = {0,0,48,48};
self->collisionHitbox = tmp;
self->canAttack = true;
}
Node * Node_new()
......@@ -43,7 +43,6 @@ Node * Node_newArray(int size)
void Node_delete( Node * node )
{
Edge_deleteArray( node->card, node->edges );
free( node );
}
/**
......@@ -51,8 +50,9 @@ void Node_delete( Node * node )
*/
void Node_deleteArray( int n, Node * array )
{
for(int i= 0 ; i < n ; ++i )
Edge_deleteArray( array[i].card, array[i].edges );
for(int i= 0 ; i < n ; ++i ){
Node_delete((array+i));
}
free( array );
}
......@@ -85,7 +85,7 @@ void Node_resize( Node * self, int card )
self->card= card;
}
void Node_set( Node * self, Vector2 position, Color color )
void Node_set( Node * self, Vector2 position, Color color)
{
self->position= position;
self->color= color;
......@@ -114,6 +114,16 @@ int Node_biconnect( Node * node1, Node * node2 )
return i1;
}
bool Node_are_connected(Node * self, Node * target){
for(int index = 0; index < self->card; index++){
Edge currentEdge = self->edges[index];
if(currentEdge._target == target){
return true;
}
}
return false;
}
//-----------------------------------//
//-- Edge --//
//-----------------------------------//
......@@ -182,11 +192,15 @@ void Edge_copy( Edge * copy, Edge * model )
// Constructor / Destructor
NetWorld * NetWorld_new(int size)
NetWorld * NetWorld_new(int size, int playerCount)
{
NetWorld * p = malloc( sizeof(NetWorld) );
p->size= size;
p->nodes= Node_newArray( p->size );
p->currentPlayer = -1;
p->playerCount = playerCount;
p->hasWinner = false;
p->winner = 0;
return p;
}
......
......@@ -2,13 +2,6 @@
#define NETWORLD_H
#include "raylib.h"
struct Str_Player{
int id;
};
typedef struct Str_Player Player;
//-----------------------------------//
//-- Node --//
//-----------------------------------//
......@@ -25,11 +18,14 @@ struct Str_Node {
//! cardinality of the node (i.e. number of edges)
int card;
// Content:
//! name of the node
char* name;
//! Number of soldiers at the node
int soldiers;
char* continent;
Player player;
//! Player the node belongs to
int playerID;
//! Click hitbox for the node
Rectangle collisionHitbox;
//! Boolean indicating if a node has attacked this turn
bool canAttack;
};
/**
......@@ -134,6 +130,15 @@ int Node_biconnect(
Node * node2
);
/**
* @brief Text if 2 nodes are connected
* @param self The origin node
* @param target The target node
* @return A boolean
*/
bool Node_are_connected(Node * self, Node * target);
//-----------------------------------//
//-- Edge --//
//-----------------------------------//
......@@ -219,6 +224,14 @@ struct Str_NetWorld {
int size;
//! Array of 'size' nodes
Node * nodes;
//! Current Player ID
int currentPlayer;
//! Total Player count;
int playerCount;
//! Does the game have a winner
bool hasWinner;
//! ID of the game's winner
int winner;
};
typedef struct Str_NetWorld NetWorld;
......@@ -230,7 +243,9 @@ typedef struct Str_NetWorld NetWorld;
*/
NetWorld * NetWorld_new(
//! the number of Nodes composing the new NetWorld
int aSize
int aSize,
//! the number of players in the game
int playerCount
);
/**
......
#include "options-menu.h"
#include <stdlib.h>
#include <stdio.h>
Options_Menu * Options_Menu_init(int * playerCount, int * nodeCount, const int screenWidth, const int screenHeight){
Options_Menu * self = malloc(sizeof(Options_Menu));
//Input for the player count
Rectangle playerCountInputBox = {(screenWidth*32)/100, (screenHeight*35)/100, (screenWidth*30)/100, (screenHeight*5)/100};
Int_Input * playerCountInput = Int_Input_init("Nb. of Players : ", playerCount, &playerCountInputBox);
//Input for the node count
Rectangle nodeCountInputBox = {(screenWidth*32)/100, (screenHeight*45)/100, (screenWidth*30)/100, (screenHeight*5)/100};
Int_Input * nodeCountInput = Int_Input_init("Nb. of Nodes : ", nodeCount, &nodeCountInputBox);
self->inputCount = 2;
self->inputs = malloc(sizeof(Int_Input) * self->inputCount);
self->inputs[0] = playerCountInput;
self->inputs[1] = nodeCountInput;
self->inputBox[0] = playerCountInputBox;
self->inputBox[1] = nodeCountInputBox;
//Save and exit btn
Rectangle saveBtn = {0, (screenHeight*95)/100, (screenWidth*20)/100, (screenHeight*10)/100};
Rectangle smallerSaveBtn = {3, 3 +(screenHeight*95)/100, -6 + (screenWidth*20)/100, -6 + (screenHeight*10)/100};
self->saveReturnBtn = saveBtn;
self->smallerSaveReturnBtn = smallerSaveBtn;
return self;
}
bool Options_Menu_check_save_click(Options_Menu * self, Vector2 * mousePos){
return CheckCollisionPointRec(*mousePos, self->saveReturnBtn);
}
void Options_Menu_check_input_click(Options_Menu * self, Vector2 * mousePos){
for(int index = 0; index < self->inputCount; index++){
self->inputs[index]->inputActive = CheckCollisionPointRec(*mousePos, self->inputs[index]->inputBox);
}
}
void Options_Menu_delete(Options_Menu * self){
for(int index = 0; index < self->inputCount; index++){
Int_Input_delete(self->inputs[index]);
}
free(self->inputs);
free(self);
}
\ No newline at end of file
#ifndef OPTIONSBUTTON_H
#define OPTIONSBUTTON_H
#include "raylib.h"
#include "int-input.h"
struct Str_Options_Menu{
//! List of input fields
Int_Input ** inputs;
//! Nb of input fields
int inputCount;
//Return btn
Rectangle saveReturnBtn;
Rectangle smallerSaveReturnBtn;
Rectangle inputBox[2];
};
typedef struct Str_Options_Menu Options_Menu;
/**
* @brief Initialise a new Options_Menu
* @param playerCount Reference to the playerCount game variable
* @param nodeCount Reference to the nodeCount game variable
* @param screenWidth Width of the screen
* @param screenHeight Height of the screen
* @return A pointer to the Options_Menu element
*/
Options_Menu * Options_Menu_init(int * playerCount, int * nodeCount, const int screenWidth, const int screenHeight);
/**
* @brief Check if the save btn has been clicked
* @param self The options menu context
* @param mousePos The position of the mouse on click
* @return A boolean
*/
bool Options_Menu_check_save_click(Options_Menu * self, Vector2 * mousePos);
/**
* @brief Activate/Deactivate inputs on click
* @param self The options menu context
* @param mousePos The position of the mouse on click
*/
void Options_Menu_check_input_click(Options_Menu * self, Vector2 * mousePos);
/**
* @brief Delete an Options_Menu
* @param self The object to void
*/
void Options_Menu_delete(Options_Menu * self);
#endif
\ No newline at end of file
#include "player.h"
#include <math.h>
#include <stdlib.h>
#include <stdio.h>
void Player_construct(Player * self, int i, Color color, char* name)
{
self->ID = i;
self->nodes = malloc(sizeof(Node*));
self->nodeCount = 0;
self->color = color;
self->turnPhase = init;
self->soldiers = 0;
self->selectedNode = malloc(sizeof(Node));
self->hasSelectedNode = false;
self->name = name;
}
Player * Player_new()
{
Player * player= malloc( sizeof(Player) );
Player_construct(player, 0, BLACK, "Black");
return player;
}
Player * Player_newArray(int size, Color color[], char* names[])
{
size= fmaxf(1, size);
Player * p= malloc( sizeof(Player)*size );
for(int i=0 ; i < size ; ++i )
{
Player_construct( &(p[i]), i, color[i], names[i]);
}
return p;
}
void Players_delete(Player * player, int size)
{
free(player);
}
void Player_add_Node( Player * self, Node * node )
{
Node ** newNodes = malloc(sizeof(Node*)*(self->nodeCount + 1));
for( int i = 0 ; i < self->nodeCount ; i++ )
{
newNodes[i] = self->nodes[i];
}
node->color = self->color;
for (int i = 0 ; i < node->card ; i++){
node->edges[i].color = self->color;
}
node->playerID = self->ID;
newNodes[self->nodeCount] = node;
free(self->nodes);
self->nodes = NULL;
self->nodes= newNodes;
self->nodeCount += 1;
}
void Player_remove_Node( Player * self, Node * node )
{
Node ** newNodes = malloc(sizeof(Node*)*(self->nodeCount - 1));
bool nodeFound = false;
for( int i = 0 ; i < self->nodeCount-1 ; i++ )
{
if(!nodeFound && self->nodes[i] == node){
nodeFound = true;
}
if(nodeFound){
newNodes[i] = self->nodes[i+1];
}else{
newNodes[i] = self->nodes[i];
}
}
free(self->nodes);
self->nodes = newNodes;
node->playerID = -1;
self->nodeCount -= 1;
}
void Player_start_turn(Player * self){
if(self->nodeCount == 0){
self->turnPhase = init;
}else{
int totalSoldierCount = 0;
for(int nodeIndex = 0; nodeIndex < self->nodeCount; nodeIndex++){
totalSoldierCount += self->nodes[nodeIndex]->soldiers;
}
self->soldiers = fmax(3, totalSoldierCount/3);
self->turnPhase = recruitment;
}
}
void Player_end_turn(Player * self){
self->turnPhase = init;
}
void Player_add_soldier(Player * self, Vector2 * mousePos){
for(int nodeIndex = 0; nodeIndex < self->nodeCount; nodeIndex++){
Node* currentNode = self->nodes[nodeIndex];
if(CheckCollisionPointRec(*mousePos, currentNode->collisionHitbox)){
currentNode->soldiers++;
self->soldiers--;
break;
}
}
}
void Player_remove_soldier(Player * self, Vector2 * mousePos){
for(int nodeIndex = 0; nodeIndex < self->nodeCount; nodeIndex++){
Node* currentNode = self->nodes[nodeIndex];
if(CheckCollisionPointRec(*mousePos, currentNode->collisionHitbox) && currentNode->soldiers > 0){
if(currentNode->soldiers > 1){
currentNode->soldiers--;
self->soldiers++;
}
break;
}
}
}
void Player_select_Node(Player * self, Vector2 * mousePos){
for(int nodeIndex = 0; nodeIndex < self->nodeCount; nodeIndex++){
Node* currentNode = self->nodes[nodeIndex];
if(CheckCollisionPointRec(*mousePos, currentNode->collisionHitbox)){
if(currentNode->soldiers > 1){
self->hasSelectedNode = true;
self->selectedNode = currentNode;
}
break;
}
}
}
void Player_unselect_Node(Player * self, Vector2 * mousePos){
for(int nodeIndex = 0; nodeIndex < self->nodeCount; nodeIndex++){
Node* currentNode = self->nodes[nodeIndex];
if(CheckCollisionPointRec(*mousePos, currentNode->collisionHitbox)){
self->hasSelectedNode = false;
}
}
}
void Player_confirm_recrutement(Player * self){
for(int nodeIndex = 0; nodeIndex < self->nodeCount; nodeIndex++){
self->nodes[nodeIndex]->canAttack = true;
}
};
int * Player_attack_Node(Player * self, Player * defender, Node * originNode, Node * targetNode, const int attackersCount){
int * listOfDices = malloc(20*sizeof(int));
int defendersCount = targetNode->soldiers;
int attDiceRolls[attackersCount];
int defDiceRolls[defendersCount];
for(int index = 0; index < attackersCount; index++){
attDiceRolls[index] = (rand() % 6) + 1;
}
for(int index = 0; index < defendersCount; index++){
defDiceRolls[index] = (rand() % 6) + 1;
}
for(int _ = 1; _ < attackersCount; _++){
for(int index = 0; index < attackersCount - 1; index++){
if(attDiceRolls[index] < attDiceRolls[index + 1]){
int tmp = attDiceRolls[index];
attDiceRolls[index] = attDiceRolls[index + 1];
attDiceRolls[index + 1] = tmp;
}
}
}
for(int _ = 1; _ < defendersCount; _++){
for(int index = 0; index < defendersCount - 1; index++){
if(defDiceRolls[index] < defDiceRolls[index + 1]){
int tmp = defDiceRolls[index];
defDiceRolls[index] = defDiceRolls[index + 1];
defDiceRolls[index + 1] = tmp;
}
}
}
for(int index = 0; index < attackersCount; index++){
listOfDices[index] = attDiceRolls[index];
}
for(int index = 0; index < defendersCount; index++){
listOfDices[index + attackersCount ] = defDiceRolls[index];
}
printf("Attackers dice rolls :\t");
for(int index = 0; index < attackersCount; index++){
printf("%i\t", attDiceRolls[index]);
}
printf("\n");
printf("Defenders dice rolls :\t");
for(int index = 0; index < defendersCount; index++){
printf("%i\t", defDiceRolls[index]);
}
printf("\n");
int remainingAttackers = attackersCount;
for(int index = 0; index < fmin(defendersCount, attackersCount); index++){
if(attDiceRolls[index] > defDiceRolls[index]){
targetNode->soldiers--;
printf("Defenders lose a soldier\n");
}else{
originNode->soldiers--;
remainingAttackers--;
printf("Attackers lose a soldier\n");
}
}
if(targetNode->soldiers <= 0){
printf("Node has been conquered\n");
Player_remove_Node(defender, targetNode);
Player_add_Node(self, targetNode);
targetNode->soldiers = attackersCount;
originNode->soldiers -= attackersCount;
}
originNode->canAttack = false;
return listOfDices;
}
void Delete_Player_attack_Node(int * listOfDices){
free(listOfDices);
}
#ifndef PLAYER_H
#define PLAYER_H
#include "networld.h"
enum turnPhases {init, recruitment, attack};
typedef enum turnPhases TurnPhases;
struct Str_Player{
//! Player ID
int ID;
//! List of node pointers belonging to the player
Node ** nodes;
//! Nb of owned nodes
int nodeCount;
//! Player Color
Color color;
//! Player's turn phase
TurnPhases turnPhase;
//! Player soldier count for the recruitement phase
int soldiers;
//! Player's selected node for the attack phase
Node * selectedNode;
bool hasSelectedNode;
char* name;
};
typedef struct Str_Player Player;
// Constructor / Destructor
/**
* @brief Construct all the elements of an empty Player.
* @param self an empty Player not yet constructed.
* @return The pointer to the new Player.
*/
void Player_construct(Player * self, int id, Color color, char* name);
/**
* @brief Allocate the memory to store a Player
* @return The pointer to the new Player.
*/
Player * Player_new();
/**
* @brief Allocate 'size' Players.
* @return The pointer to the new array of 'size' Player.
*/
Player * Player_newArray(int size, Color colors[], char* names[]);
/**
* @brief Destructor.
*/
void Players_delete(
//! the Player list to delete
Player * self,
//! the Player list size to delete
int size
);
/**
* @brief Add a node to the player's territory.
*/
void Player_add_Node(
//! The player;
Player * self,
//! The Node to add
Node * node
);
/**
* @brief Remove a node from the player's territory.
*/
void Player_remove_Node(
//! The player;
Player * self,
//! The Node to remove
Node * node
);
/**
* @brief Start a player's turn and take all actions before player's first input
*/
void Player_start_turn(Player * self);
/**
* @brief End a player's turn
*/
void Player_end_turn(Player * self);
/**
* @brief Add a soldier to a player's node
* @param self The player context
* @param mousePos the position of the mouse to detect which node has been clicked
*/
void Player_add_soldier(Player * self, Vector2 * mousePos);
/**
* @brief Remove a soldier from a player's node
* @param self The player context
* @param mousePos the position of the mouse to detect which node has been clicked
*/
void Player_remove_soldier(Player * self, Vector2 * mousePos);
/**
* @brief A player selects a node
* @param self The player context
* @param mousePos the position of the mouse to detect which node has been clicked
*/
void Player_select_Node(Player * self, Vector2 * mousePos);
/**
* @brief A player unselects a node
* @param self The player context
* @param mousePos the position of the mouse to detect which node has been clicked
*/
void Player_unselect_Node(Player * self, Vector2 * mousePos);
/**
* @brief Attack declaration
* @param self The attacking player
* @param defender The defending player
* @param originNode The attacker's node
* @param targetNode The defender's node
* @param numberOfAttackers Number of attacking soldiers
*/
int * Player_attack_Node(Player * self, Player * defender, Node * originNode, Node * targetNode, const int attackersCount);
/**
* @brief Confirm placement of soldiers
* @param self The player context
*/
void Player_confirm_recrutement(Player * self);
#endif
\ No newline at end of file
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <math.h>
#include <string.h>
#include <time.h>
#include "networld.h"
#include "controlpanel.h"
#include "random-map.h"
#include "raylib.h"
double randfrom(double min, double max)
{
double range = (max - min);
double div = RAND_MAX / range;
return min + (rand() / div);
}
double dist(Vector2 vector1, Vector2 vector2)
{
return (sqrt((vector2.x - vector1.x) * (vector2.x - vector1.x) + (vector2.y - vector1.y) * (vector2.y - vector1.y)));
}
double distNode(Node node1, Node node2)
{
return (dist(node1.position, node2.position));
}
const double rangeForXcoordinates = 30.0;
const double rangeForYcoordinates = 30.0;
const double minimumDistance = 8.0;
void Random_map(NetWorld *world)
{
int nbNode = world->size;
float randomX, randomY;
/* Intializes random number generator */
srand(time(NULL));
/* Generate nbNode*2 random numbers for y-coordinates and x-coordinates of the nodes*/
for (int i = 0; i < nbNode; i++)
{
if (i > 0)
{
bool continueLoop = true;
while (continueLoop) //loop until the minimum distance between the new node and the others is respected
{
continueLoop = false;
randomX = randfrom(-rangeForXcoordinates, rangeForXcoordinates);
randomY = randfrom(-rangeForYcoordinates, rangeForYcoordinates);
Vector2 newPosition = (Vector2){randomX, randomY};
for (int j = 0; j < i; j++)
{
if (dist(world->nodes[j].position, newPosition) < minimumDistance)
{
continueLoop = true;
}
}
}
//har *name; name = malloc(20*sizeof(char)); sprintf(name, "name : %d", i);
Node_set(&(world->nodes[i]), (Vector2){randomX, randomY}, RED);
//free(name);
}
else
{
randomX = randfrom(-15.0, 15.0);
randomY = randfrom(-15.0, 15.0);
//char name[20]; sprintf(name, "name : %d", i);
Node_set(&(world->nodes[i]), (Vector2){randomX, randomY}, RED);
}
}
//Gabriel graph sort
for (int i = 0; i < nbNode - 1; i++)
{
for (int j = i + 1; j < nbNode; j++)
{
int compteurPointDansLeCercle = 0;
float xm = 0.5 * (world->nodes[i].position.x + world->nodes[j].position.x);
float ym = 0.5 * (world->nodes[i].position.y + world->nodes[j].position.y);
Vector2 M = {xm, ym};
float distNodeCenterOfij = dist(world->nodes[i].position, M);
for (int k = 0; k < nbNode; k++)
{
if (dist(world->nodes[k].position, M) < distNodeCenterOfij - 0.05)
{
compteurPointDansLeCercle++;
}
}
if (compteurPointDansLeCercle == 0)
{
NetWorld_biconnect(world, i, j);
}
}
}
}
\ No newline at end of file
#ifndef RANDOMMAP_H
#define RANDOMMAP_H
#include "raylib.h"
#include "networld.h"
//random function
double randfrom(double min, double max);
//distance between 2 points(Vector2)
double dist(Vector2 vector1, Vector2 vector2);
//distance between 2 nodes
double distNode(Node node1, Node node2);
//generation of a random map following Gabriel Graph theory
void Random_map(NetWorld * world);
#endif
\ No newline at end of file
#include "window-manager.h"
#include "controlpanel.h"
#include <stdlib.h>
#include <stdio.h>
Window_Manager * Window_Manager_new(Panel * panel, Main_Menu * menu, Main_Menu * rules, Options_Menu * optionsMenu){
Window_Manager * self = malloc(sizeof(Window_Manager));
self->panel = panel;
self->display = (Display) main_menu;
self->menu = menu;
self->rules = rules;
self->options = optionsMenu;
return self;
}
void Window_Manager_delete(Window_Manager * manager){
free(manager);
}
void Window_Manager_display(Window_Manager * self, NetWorld * world, Player * players, Mission * missions){
switch(self->display){
case main_menu:
Panel_drawMainMenu(self->panel, self->menu);
break;
case options:
Panel_drawOptionsMenu(self->panel, self->options);
break;
case game_ui:
Panel_drawGame(self->panel);
break;
case rules:
Panel_drawRules(self->panel, self->rules);
break;
case win:
Panel_drawWin(self->panel, players+world->winner, missions+world->winner);
break;
default:
break;
}
}
\ No newline at end of file
#ifndef DISPLAYMANAGER_H
#define DISPLAYMANAGER_H
#include "networld.h"
#include "controlpanel.h"
#include "mission.h"
struct Str_Window_Manager{
//! frame to display
Display display;
//! Reference to the panel context
Panel * panel;
//! Reference to the main menu context
Main_Menu * menu;
//! Reference to the rules menu context
Main_Menu * rules;
//! Reference to the options context
Options_Menu * options;
};
typedef struct Str_Window_Manager Window_Manager;
/**
* @brief Initialise a Window_Manager
* @param panel Reference to the panel context
* @param menu Reference to the main menu context
* @param optionsMenu Reference to the options menu context
*/
Window_Manager * Window_Manager_new(Panel * panel, Main_Menu * menu, Main_Menu * rules, Options_Menu * optionsMenu);
/**
* @brief Void a Window Manager
* @param self The element to void
*/
void Window_Manager_delete(Window_Manager * manager);
/**
* @brief Displays the appropriate frame
* @param self The manager context
*/
void Window_Manager_display(Window_Manager * self, NetWorld * world, Player * players, Mission * missions);
#endif
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment