src/hash_map.c

Functions

Name
uint32_t pow_u32(uint32_t x, int n)Calculate power for uint32_t type.
hash_t ** create_hash_map()Generate an empty hash_map.
uint32_t hash_board(board_t * board)Return the unmoduled hash of a board.
hash_t * create_linked_hash(uint32_t hashed_board, linked_plays_t * plays, hash_t * next)Initialize and fills the hash_t structure.
void merge_plays(play_t * play, play_t * new_play)Merge two plays scores in place.
void hash_map_add(hash_t ** hash_map, board_t * board, linked_plays_t * plays)Adds a board to the hash_map.
void free_plays(play_t * plays)Free play_t list.
void free_linked_plays(linked_plays_t * linked_plays)Free linked_play_t list.
void free_hash_list(hash_t * hash)Free all the hash in a hash_map entry.
void free_hash_map(hash_t ** hash_map)Free the hash_map.

Functions Documentation

function pow_u32

uint32_t pow_u32(
    uint32_t x,
    int n
)

Calculate power for uint32_t type.

function create_hash_map

hash_t ** create_hash_map()

Generate an empty hash_map.

function hash_board

uint32_t hash_board(
    board_t * board
)

Return the unmoduled hash of a board.

function create_linked_hash

hash_t * create_linked_hash(
    uint32_t hashed_board,
    linked_plays_t * plays,
    hash_t * next
)

Initialize and fills the hash_t structure.

function merge_plays

void merge_plays(
    play_t * play,
    play_t * new_play
)

Merge two plays scores in place.

function hash_map_add

void hash_map_add(
    hash_t ** hash_map,
    board_t * board,
    linked_plays_t * plays
)

Adds a board to the hash_map.

function free_plays

void free_plays(
    play_t * plays
)

Free play_t list.

function free_linked_plays

void free_linked_plays(
    linked_plays_t * linked_plays
)

Free linked_play_t list.

function free_hash_list

void free_hash_list(
    hash_t * hash
)

Free all the hash in a hash_map entry.

function free_hash_map

void free_hash_map(
    hash_t ** hash_map
)

Free the hash_map.

Source code

/* name : tests_matheo.c
 * authors : eloi petit, matheo thomas, domitille vale
 * date : 23-06-24
 */

#include <stdio.h>
#include <stdlib.h>
#include "hash_map.h"



// Pow with exponentation by squaring
uint32_t pow_u32(uint32_t x, int n) {
    uint32_t res = 1;
    while (1) {
        if (n & 1) {
            res *= x;
        }
        // equivalent to (n - 1) / 2
        n >>= 1;
        // if n is zero
        if (!n) {
            break;
        }
        x *= x;
    }

    return res;
}

hash_t ** create_hash_map() {

    hash_t ** hash_map = malloc(sizeof(hash_t *) * HASHMAP_SIZE);
    for (int i = 0; i < HASHMAP_SIZE; i++) {
        hash_map[i] = NULL;
    }

    return hash_map;
}

uint32_t hash_board(board_t * board) {

    uint32_t nb_tiles = 0;
    uint32_t nb_cells = 0;
    uint32_t sum_cells_ids = 0;
    uint32_t sum_cells_values = 0;
    uint32_t sum_orientation_id_tiles = 0;

    cell_t ** cell_tab = board -> cell_tab;

    for (int i = 0; i < CELL_NUMBER; i++) {
        if (cell_tab[i] -> level -> cell_type != EMPTY) {
            nb_cells++;
            nb_tiles++;
            sum_cells_ids += cell_tab[i] -> id;
            sum_cells_values += cell_tab[i] -> level -> cell_type;
            sum_orientation_id_tiles += cell_tab[i] -> level -> tile -> orientation * cell_tab[i] -> level -> tile -> id;
        }
    }

    uint32_t hash = 31 * board -> score + pow_u32(31, 2) * nb_tiles + pow_u32(31, 3) * nb_cells + pow_u32(31, 4) * sum_orientation_id_tiles + pow_u32(31, 5) * sum_cells_values + pow_u32(31, 6) * sum_cells_ids;

    return hash;
}

hash_t * create_linked_hash(uint32_t hashed_board, linked_plays_t * plays, hash_t * next) {
    hash_t * new_hash = malloc(sizeof(hash_t));
    new_hash -> hashed_board = hashed_board;
    new_hash -> plays = plays;
    new_hash -> next = next;

    return new_hash;
}

void merge_plays(play_t * play, play_t * new_play) {

    while (play != NULL && new_play != NULL) {
        play -> n_coup += new_play -> n_coup;
        play -> gain_coup += new_play -> gain_coup;
        play = play -> next;
        new_play = new_play -> next;
    }
    if ((play != NULL) ^ (new_play != NULL)) {
        fprintf(stderr, "play or new_play may be of different size play : %p new_play %p\n", play, new_play);
    }
}

void hash_map_add(hash_t ** hash_map, board_t * board, linked_plays_t * plays) {
    uint32_t hashed_board = hash_board(board);
    int hash_index = hashed_board % HASHMAP_SIZE;

    hash_t * hash = hash_map[hash_index];

    if (hash == NULL) {
        hash_map[hash_index] = create_linked_hash(hashed_board, plays, NULL);
        return;
    }

    while (hash -> next != NULL) {
        if (hash -> hashed_board == hashed_board) {
            merge_plays(hash -> plays -> play, plays -> play);
            return;
        }
        else {
            hash = hash -> next;
        }
    }
    if (hash -> hashed_board == hashed_board) {
            merge_plays(hash -> plays -> play, plays -> play);
    }
    else {
        hash -> next = create_linked_hash(hashed_board, plays, NULL);
    }
}

void free_plays(play_t * plays) {

    play_t * previous = plays;

    while (plays != NULL) {
        previous = plays;
        plays = plays -> next;
        free(previous);
    }
}

void free_linked_plays(linked_plays_t * linked_plays) {
    free_plays(linked_plays -> play);
    free(linked_plays);
}

void free_hash_list(hash_t * hash) {

    hash_t * previous = hash;

    while (hash != NULL) {
        previous = hash;
        hash = hash -> next;
        free_linked_plays(previous -> plays);
        free(previous);
    }
}

void free_hash_map(hash_t ** hash_map) {

    for (int i = 0; i < HASHMAP_SIZE; i++) {
        free_hash_list(hash_map[i]);
    }
    free(hash_map);
}

Updated on 2024-06-28 at 08:11:55 +0200