Commit 46774d6e authored by LAIRD Timothy's avatar LAIRD Timothy

Merge branch 'dev' into 'generation'

# Conflicts:
#   src/main-viewer.c
#   src/networld.c
parents d606d893 d83cb1ce
......@@ -18,7 +18,7 @@ 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)
add_executable(nw-viewer src/main-viewer.c src/networld.c src/controlpanel.c src/entity.c src/player.c)
target_link_libraries(nw-viewer raylib pthread dl rt X11 m)
#without cmake package...
......
......@@ -87,10 +87,9 @@ 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));
sprintf(soldierText, "%d", n->soldiers);
DrawText(soldierText, (int)(screenPosition.x), (int)(screenPosition.y), 20, n->color);
char * soldierText = malloc(sizeof(int));
sprintf(soldierText, "%d", n->soldiers + n->soldiersToAdd);
DrawText(soldierText, (int)screenPosition.x - MeasureText(soldierText, 20)/2, (int)screenPosition.y, 20, n->color);
}
void Panel_drawEdge(Panel * self, Edge * e)
......
......@@ -9,8 +9,10 @@
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include "networld.h"
#include "player.h"
#include "controlpanel.h"
#include "randomMap.h"
......@@ -20,7 +22,7 @@ const int screenWidth = 800;
const int screenHeight = 600;
const int targetFPS = 60;
void game_update(NetWorld * world);
void game_update(NetWorld * world, Player * players);
// Game attributes
//-----------------
......@@ -53,6 +55,13 @@ int main(int nbArg, char ** arg)
Panel * panel= Panel_new();
Panel_initialize(panel, world);
Color colors[] = {BLACK, RED, BLUE};
Player * players = Player_newArray(playerCount, colors);
for(int index = 0; index < world->size; index++){
Player_add_Node(&(players[index % playerCount]), &(world->nodes[index]));
}
Player_remove_Node(&(players[0]), &(world->nodes[3]));
Player_add_Node(&(players[1]), &(world->nodes[3]));
// Raylib Initialization
//----------------------
InitWindow(screenWidth, screenHeight, "NetWorld basic viewer");
......@@ -72,22 +81,113 @@ int main(int nbArg, char ** arg)
*/
// Main game loop
world->currentPlayer = 0;
Player_start_turn(&(players[world->currentPlayer]));
while (!game_end && !WindowShouldClose()) // Detect window close button or ESC key
{
DrawFPS(10, 10);
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;
}
Panel_control(panel);
game_update(world);
game_update(world, players);
Panel_draw(panel);
}
// proper closing
//---------------
NetWorld_delete(world);
Player_delete(players);
CloseWindow(); // Close window and OpenGL context
return 0;
}
void game_update(NetWorld * world)
void game_update(NetWorld * world, Player * players)
{
Player * currentPlayer = &(players[world->currentPlayer]);
int playerCount = world->playerCount;
switch(currentPlayer->turnPhase){
case 1:
if(currentPlayer->soldiers > 0){
if (IsMouseButtonPressed(MOUSE_LEFT_BUTTON)){
Vector2 mousePosition = GetMousePosition();
Player_add_soldier(currentPlayer, mousePosition);
}
}else{
Rectangle nextPhase = {screenWidth-48,screenHeight-48,48,48};
DrawRectangleRec(nextPhase, GREEN);
if (IsMouseButtonPressed(MOUSE_LEFT_BUTTON)){
Vector2 mousePosition = GetMousePosition();
if(CheckCollisionPointRec(mousePosition, nextPhase)){
Player_confirm_recrutement(currentPlayer);
printf("Recrutement confirmed\n");
currentPlayer->turnPhase = 2;
printf("Attack phase\n");
}
}
}
if(IsMouseButtonPressed(MOUSE_RIGHT_BUTTON)){
Vector2 mousePosition = GetMousePosition();
Player_remove_soldier(currentPlayer, mousePosition);
}
break;
case 2:
if(currentPlayer->hasSelectedNode){
if(IsMouseButtonPressed(MOUSE_RIGHT_BUTTON)){
Vector2 mousePosition = GetMousePosition();
Player_unselect_Node(currentPlayer, mousePosition);
}
if (IsMouseButtonPressed(MOUSE_LEFT_BUTTON)){
Vector2 mousePosition = GetMousePosition();
Node * originNode = currentPlayer->selectedNode;
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){
printf("Selected target Node\n");
currentPlayer->selectedNode = currentNode;
}
else if(Node_are_connected(originNode, currentNode) && (originNode->soldiers > 1) && originNode->canAttack){
printf("Engagine attack on target Node\n");
Player_attack_Node(currentPlayer, &(players[nodePlayerID]), originNode, currentNode);
}else{
printf("Failed to attack target : Origin has already attacked, nodes aren't connected or origin node has too few soldiers\n");
}
}
}
}
}else{
if (IsMouseButtonPressed(MOUSE_LEFT_BUTTON)){
Vector2 mousePosition = GetMousePosition();
Player_select_Node(currentPlayer, mousePosition);
}
}
Rectangle nextPhase = {screenWidth-48,screenHeight-48,48,48};
DrawRectangleRec(nextPhase, GREEN);
if (IsMouseButtonPressed(MOUSE_LEFT_BUTTON)){
Vector2 mousePosition = GetMousePosition();
if(CheckCollisionPointRec(mousePosition, nextPhase)){
printf("Attack phase ended\n");
currentPlayer->turnPhase = -1;
}
}
break;
default:;
}
if(currentPlayer->turnPhase == -1){
Player_end_turn(currentPlayer);
printf("Turn ended\n");
world->currentPlayer = (world->currentPlayer + 1) % playerCount;
printf("Player changed\n");
Player_start_turn(&(players[world->currentPlayer]));
printf("Turn started\n");
printf("Recrutement phase\n");
}
}
......@@ -17,9 +17,14 @@ void Node_construct(Node * self)
self->edges= Edge_newArray( 0 );
self->name= malloc( sizeof(char)*32 );
self->continent= malloc( sizeof(char)*32 );
self->soldiers= 5;
self->soldiers = 1;
self->soldiersToAdd = 0;
self->playerID = -1;
Rectangle tmp = {0,0,48,48};
self->collisionHitbox = tmp;
strcpy(self->continent, "None");
strcpy( self->name, "Node" );
self->canAttack = true;
}
Node * Node_new()
......@@ -115,6 +120,21 @@ int Node_biconnect( Node * node1, Node * node2 )
return i1;
}
void Node_confirm_placement(Node * self){
self->soldiers+= self->soldiersToAdd;
self->soldiersToAdd = 0;
}
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 --//
//-----------------------------------//
......@@ -183,11 +203,13 @@ 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;
return p;
}
......
......@@ -2,13 +2,6 @@
#define NETWORLD_H
#include "raylib.h"
struct Str_Player{
int id;
};
typedef struct Str_Player Player;
//-----------------------------------//
//-- Node --//
//-----------------------------------//
......@@ -27,9 +20,16 @@ struct Str_Node {
// Content:
//! name of the node
char* name;
//! Number of soldiers at the node
int soldiers;
int soldiersToAdd;
//! Continent the node belongs to
char* continent;
Player player;
//! Player the node belongs to
int playerID;
//! Click hitbox for the node
Rectangle collisionHitbox;
bool canAttack;
};
/**
......@@ -137,6 +137,11 @@ int Node_biconnect(
Node * node2
);
void Node_confirm_placement(Node * self);
bool Node_are_connected(Node * self, Node * target);
//-----------------------------------//
//-- Edge --//
//-----------------------------------//
......@@ -222,6 +227,10 @@ struct Str_NetWorld {
int size;
//! Array of 'size' nodes
Node * nodes;
//! Current Player ID
int currentPlayer;
//! Total Player count;
int playerCount;
};
typedef struct Str_NetWorld NetWorld;
......@@ -233,7 +242,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 "player.h"
#include <math.h>
#include <stdlib.h>
#include <stdio.h>
void Player_construct(Player * self, int i, Color color)
{
self->ID = i;
self->nodes = malloc(sizeof(Node*));
self->nodeCount = 0;
self->color = color;
self->turnPhase = 0;
self->soldiers = 0;
self->selectedNode = malloc(sizeof(Node));
self->hasSelectedNode = false;
}
Player * Player_new()
{
Player * player= malloc( sizeof(Player) );
Player_construct(player, 0, BLACK);
return player;
}
Player * Player_newArray(int size, Color color[])
{
size= fmaxf(1, size);
Player * p= malloc( sizeof(Player)*size );
for(int i=0 ; i < size ; ++i )
{
Player_construct( &(p[i]), i, color[i]);
}
return p;
}
void Player_delete( Player * player )
{
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;
node->playerID = self->ID;
newNodes[self->nodeCount] = node;
free(self->nodes);
self->nodes= newNodes;
self->nodeCount += 1;
}
void Player_remove_Node( Player * self, Node * node )
{
bool nodeFound = false;
for( int i = 0 ; i < self->nodeCount-1 ; i++ )
{
if(nodeFound || self->nodes[i] == node){
self->nodes[i] = self->nodes[i+1];
}
}
Node ** newNodes = malloc(sizeof(Node*)*(self->nodeCount - 1));
for( int i = 0 ; i < self->nodeCount-1 ; i++ )
{
newNodes[i] = self->nodes[i];
}
free(self->nodes);
self->nodes = newNodes;
node->playerID = -1;
self->nodeCount -= 1;
}
void Player_start_turn(Player * self){
int totalSoldierCount = 0;
for(int nodeIndex = 0; nodeIndex < self->nodeCount; nodeIndex++){
totalSoldierCount += self->nodes[nodeIndex]->soldiers;
}
self->soldiers = fmax(1, totalSoldierCount/3);
self->turnPhase = 1;
printf("Current player : %i\n", self->ID);
printf("Current player soldiers : %i\n", self->soldiers);
}
void Player_end_turn(Player * self){
self->turnPhase = 0;
}
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->soldiersToAdd++;
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->soldiersToAdd > 0){
currentNode->soldiersToAdd--;
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;
printf("Selected target Node\n");
}
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;
printf("Unselected target node\n");
}
}
}
void Player_confirm_recrutement(Player * self){
for(int nodeIndex = 0; nodeIndex < self->nodeCount; nodeIndex++){
Node_confirm_placement(self->nodes[nodeIndex]);
self->nodes[nodeIndex]->canAttack = true;
}
};
void Player_attack_Node(Player * self, Player * defender, Node * originNode, Node * targetNode){
int attackersCount = fmin(3, (originNode->soldiers-1));
int defendersCount = targetNode->soldiers >= 3? 2:1;
int attDiceRolls[attackersCount];
int defDiceRolls[defendersCount];
printf("%i attackers\n", attackersCount);
printf("%i defenders\n", 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;
}
}
}
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;
}
#ifndef PLAYER_H
#define PLAYER_H
#include "networld.h"
struct Str_Player{
int ID;
Node ** nodes;
int nodeCount;
Color color;
int turnPhase;
int soldiers;
Node * selectedNode;
bool hasSelectedNode;
};
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);
/**
* @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[]);
/**
* @brief Destructor.
*/
void Player_delete(
//! the Player to delete
Player * self
);
/**
* @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 to 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);
void Player_add_soldier(Player * self, Vector2 mousePos);
void Player_remove_soldier(Player * self, Vector2 mousePos);
void Player_select_Node(Player * self, Vector2 mousePos);
void Player_unselect_Node(Player * self, Vector2 mousePos);
void Player_attack_Node(Player * self, Player * defender, Node * originNode, Node * targetNode);
void Player_confirm_recrutement(Player * self);
#endif
\ No newline at end of file
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