Skip to content

Instantly share code, notes, and snippets.

@woodrowbarlow
Last active October 13, 2018 20:52
Show Gist options
  • Save woodrowbarlow/5d9fa6f43f2ad6bdabb43dbb9a63dfeb to your computer and use it in GitHub Desktop.
Save woodrowbarlow/5d9fa6f43f2ad6bdabb43dbb9a63dfeb to your computer and use it in GitHub Desktop.
gcc hex.c -o hex; ./hex
#include <stdio.h>
#include <stdlib.h>
#define BOARD_WIDTH 11
#define BOARD_HEIGHT 11
#define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0]))
#define TRAVERSE_DIRECTION(iterator, source, direction) \
for (iterator = source; iterator != NULL; \
iterator = iterator->edges[direction])
typedef enum edge_e
{
EDGE_RIGHT,
EDGE_BOT_RIGHT,
EDGE_BOT_LEFT,
EDGE_LEFT,
EDGE_TOP_LEFT,
EDGE_TOP_RIGHT,
EDGES_MAX
} edge;
typedef enum team_e
{
TEAM_UNASSIGNED,
TEAM_RED,
TEAM_BLUE,
TEAMS_MAX
} team;
typedef struct node_s
{
struct node_s *edges[6];
team alignment;
} node;
/* top left */
node *source = NULL;
node *create_node(team alignment)
{
int i;
node *ret = calloc(sizeof(node), 1);
if (ret == NULL)
{
return NULL;
}
ret->alignment = alignment;
return ret;
}
void link_edges(edge direction, node *src, node *dst)
{
src->edges[direction] = dst;
/* use the opposite edge on dst */
dst->edges[(direction + (EDGES_MAX / 2)) % EDGES_MAX] = src;
}
void init(void)
{
int i, j;
/* first create 11 nodes along the top edge */
source = create_node(TEAM_UNASSIGNED);
node *iterator = source;
for (i = 0; i < BOARD_WIDTH - 1; i++)
{
node *new = create_node(TEAM_UNASSIGNED);
link_edges(EDGE_RIGHT, iterator, new);
iterator = iterator->edges[EDGE_RIGHT];
}
/* start with that first row we just created and stack ten more rows
* below that.
*/
node *local_source = source;
for (i = 0; i < BOARD_HEIGHT - 1; i++)
{
node *prev_new = NULL;
/* work our way from left to right across this row. for each
* node in the row, create a new node on its bottom right edge,
* being careful to link all the edges that touch other nodes.
*/
TRAVERSE_DIRECTION(iterator, local_source, EDGE_RIGHT)
{
node *iterator_next = iterator->edges[EDGE_RIGHT];
node *new = create_node(TEAM_UNASSIGNED);
/* add the new node bottom-right of the current node */
link_edges(EDGE_BOT_RIGHT, iterator, new);
/* this is true except the first time through this loop */
if (prev_new != NULL)
{
link_edges(EDGE_RIGHT, prev_new, new);
}
/* this is true except the last time through this loop */
if (iterator_next != NULL)
{
link_edges(EDGE_BOT_LEFT, iterator_next, new);
}
prev_new = new;
}
/* repeat the process for the new row */
local_source = local_source->edges[EDGE_BOT_RIGHT];
}
}
void print(void)
{
int i = 0;
node *iterator;
TRAVERSE_DIRECTION(iterator, source, EDGE_BOT_RIGHT)
{
int j = 0;
node *iterator_inner;
for (j = 0; j < i; j++)
{
printf(" ");
}
printf("|");
TRAVERSE_DIRECTION(iterator_inner, iterator, EDGE_RIGHT)
{
switch (iterator_inner->alignment)
{
case TEAM_UNASSIGNED:
printf(" |");
break;
case TEAM_RED:
printf(" R |");
break;
case TEAM_BLUE:
printf(" B |");
break;
default:
printf(" ? |");
break;
}
}
printf("\n");
i++;
}
}
void _deinit(node *n)
{
int i;
for (i = 0; i < EDGES_MAX; i++)
{
if (n->edges[i] != NULL)
{
node *tmp = n->edges[i];
n->edges[i] = NULL;
_deinit(tmp);
}
}
free(n);
}
void deinit()
{
/* recursive */
_deinit(source);
source = NULL;
}
int main(void)
{
init();
print();
deinit();
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment