aboutsummaryrefslogtreecommitdiffstats
path: root/src/board.c
blob: c22aa0d77f90a39fc0be2a28c0a342c5ce969ba0 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
#include <stdlib.h>
#include <assert.h>
#include <stdio.h>
#include <string.h>

#include "board.h"

struct BOARD {
	unsigned int* arr;
	unsigned int arr_size;
	unsigned int w;
	unsigned int h;
};

BOARD newboard(unsigned int w, unsigned int h) {
	BOARD ret = (BOARD) malloc(sizeof(struct BOARD));
	ret->w = w;
	ret->h = h;
	// (a / b) + ((a % b) != 0)
	unsigned int bits = sizeof(unsigned int) * 8;
	ret->arr_size = w * h / bits + ((w * h) % bits != 0);
	ret->arr = ( unsigned int*) calloc(ret->arr_size, sizeof(unsigned int));
	return ret;
}

BOARD dupboard (BOARD old) {
	BOARD ret = (BOARD) malloc(sizeof(struct BOARD));
	ret->w = old->w;
	ret->h = old->h;
	ret->arr_size = old->arr_size;
	ret->arr = ( unsigned int*) calloc(old->arr_size, sizeof(unsigned int));
	memcpy(ret->arr, old->arr, old->arr_size * sizeof(*old->arr));
	return ret;
}

// Copy boards of the same size
// For boards of differing sizes, just use dupboard
BOARD cpyboard (BOARD dest, BOARD src) {
	assert(dest != NULL && dest->arr != NULL);
	assert(src != NULL && src->arr != NULL);
	memcpy(dest->arr, src->arr, src->arr_size * sizeof(*src->arr));
	return dest;
}

void delboard(BOARD b) {
	free(b->arr);
	free(b);
}

unsigned int board_getval(BOARD b, unsigned int x, unsigned int y) {
	assert(("board_getval out of bounds", x < b->w && y < b->h));
	unsigned int n = b->w * y + x;
	return (b->arr[n / sizeof(unsigned int) / 8] >> (n % (sizeof(unsigned int) * 8))) & 1;
}

unsigned int board_setval(BOARD b, unsigned int x, unsigned int y, unsigned int val) {
	assert(("board_setval out of bounds", x < b->w && y < b->h));
	unsigned int n = b->w * y + x;
	unsigned int retval = (b->arr[n / sizeof(unsigned int) / 8] >> (n % (sizeof(unsigned int) * 8))) & 1;
	unsigned int pos = n % (sizeof(unsigned int) * 8);
	switch (val) {
	case 0:
		b->arr[n / sizeof(unsigned int) / 8] &= ~(( unsigned int) (1 << pos));
		break;
	case 1:
	default:
		b->arr[n / sizeof(unsigned int) / 8] |= 1 << pos;
		break;
	}
	return retval;
}
unsigned int board_flip(BOARD b, unsigned int x, unsigned int y) {
	assert(("board_flip out of bounds", x < b->w && y < b->h));
	unsigned int n = b->w * y + x;
	unsigned int retval = (b->arr[n / sizeof(unsigned int) / 8] >> (n % (sizeof(unsigned int) * 8))) & 1;
	unsigned int pos = n % (sizeof(unsigned int) * 8);
	b->arr[n / sizeof(unsigned int) / 8] ^= 1 << pos;
	return retval;
}

unsigned int board_getval_i(BOARD b, unsigned int i) {
	assert(("board_getval_i out of bounds", i < b->w * b->h));
	return (b->arr[i / sizeof(unsigned int) / 8] >> (i % (sizeof(unsigned int) * 8))) & 1;
}

unsigned int board_setval_i(BOARD b, unsigned int i, unsigned int val) {
	assert(("board_setval_i out of bounds", i < b->w * b->h));
	unsigned int retval = (b->arr[i / sizeof(unsigned int) / 8] >> (i % (sizeof(unsigned int) * 8))) & 1;
	unsigned int pos = i % (sizeof(unsigned int) * 8);
	switch (val) {
	case 0:
		b->arr[i / sizeof(unsigned int) / 8] &= ~(( unsigned int) (1 << pos));
		break;
	case 1:
	default:
		b->arr[i / sizeof(unsigned int) / 8] |= 1 << pos;
		break;
	}
	return retval;
}

unsigned int board_flip_i(BOARD b, unsigned int i) {
	assert(("board_flip_i out of bounds", i < b->w * b->h));
	unsigned int retval = (b->arr[i / sizeof(unsigned int) / 8] >> (i % (sizeof(unsigned int) * 8))) & 1;
	unsigned int pos = i % (sizeof(unsigned int) * 8);
	b->arr[i / sizeof(unsigned int) / 8] ^= 1 << pos;
	return retval;
}

void board_setall(BOARD b, unsigned int val) {
	assert(b != NULL);
	memset(b->arr, val == 0 ? 0 : 1, b->arr_size * sizeof(*b->arr));
}