-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathchunk.c
143 lines (115 loc) · 3.66 KB
/
chunk.c
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
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
//
// Created by 15533 on 2021/11/2.
//
#include <memory.h>
#include <stdio.h>
#include <stdlib.h>
#include "chunk.h"
#include "board.h"
struct CHUNK* init_chunk(struct BOARD *board, int x, int y) {
struct CHUNK *last_chunk = board->init_chunk; // 找到最后一个区块
while(last_chunk->next != NULL) {
if (last_chunk->x == x && last_chunk->y == y) { // 区块已经存在, 不创建
return NULL;
}
last_chunk = last_chunk->next;
}
if (last_chunk->x == x && last_chunk->y == y) { // 区块已经存在, 不创建
return NULL;
}
struct CHUNK *chunk;
chunk = (struct CHUNK*) malloc(sizeof(struct CHUNK));
board->chunk_num++;
// 初始化区块
printf("[CHUNK] new chunk at: (%d, %d)\n", x, y);
memset(chunk, 0, sizeof(struct CHUNK));
chunk->x = x;
chunk->y = y;
chunk->cell_num = 1; // 第一次无论如何还是检查一次
chunk->recycle_counter = MAX_EMPTY_ROUND;
chunk->prev = last_chunk;
last_chunk->next = chunk;
chunk->next = NULL;
return chunk;
}
// 查找目标区块
struct CHUNK* find_chunk(struct BOARD *board, int x, int y) {
struct CHUNK *chunk = board->init_chunk;
while (chunk != NULL) {
if (chunk->x == x && chunk->y == y) {
return chunk;
}
chunk = chunk->next;
}
return NULL;
}
int get_cell(const unsigned int *data, int x, int y) {
return (data[x] & (1 << y)) > 0;
}
// 自动获取相邻区块的细胞状态
int get_cell_in_chunk(struct CHUNK *chunk, int x, int y, struct BOARD *board) {
if (x >= 0 && x <= CHUNK_SIZE - 1 && y >= 0 && y <= CHUNK_SIZE - 1) {
return get_cell(chunk->data, x, y);
} else {
int chunk_x = chunk->x;
int chunk_y = chunk->y;
// 跨区块处理
if (x < 0) {
x += CHUNK_SIZE;
chunk_x -= 1;
}
if (x > CHUNK_SIZE - 1) {
x -= CHUNK_SIZE;
chunk_x += 1;
}
if (y < 0) {
y += CHUNK_SIZE;
chunk_y -= 1;
}
if (y > CHUNK_SIZE - 1) {
y -= CHUNK_SIZE;
chunk_y += 1;
}
struct CHUNK *target_chunk = find_chunk(board, chunk_x, chunk_y);
if (target_chunk == NULL) { // 如果目标区块还未被初始化 代表其不会被用到 全部为空
return 0;
} else {
// target_chunk->recycle_counter = MAX_EMPTY_ROUND;
return get_cell(target_chunk->data, x, y);
}
}
}
void set_cell(unsigned int *data, int x, int y) {
data[x] |= (1 << y);
}
// 仅限初始化时可用的设置细胞方法
void init_cell_in_board(struct BOARD *board, long long x, long long y) {
int chunk_x = (int) (x / CHUNK_SIZE);
int x_in_chunk = (int) (x % CHUNK_SIZE);
int chunk_y = (int) (y / CHUNK_SIZE);
int y_in_chunk = (int) (y % CHUNK_SIZE);
struct CHUNK *chunk = find_chunk(board, chunk_x, chunk_y);
if (chunk == NULL) { // 如果目标区块不存在创建
chunk = init_chunk(board, chunk_x, chunk_y);
}
// 设置目标细胞
set_cell(chunk->data, x_in_chunk, y_in_chunk);
chunk->cell_num++;
}
void free_chunk(struct CHUNK *chunk, struct BOARD *board) {
printf("[CHUNK] delete chunk at: (%d, %d)\n", chunk->x, chunk->y);
if (board->chunk_num == 1) { // 只有一个区块时不能回收
return;
}
if (chunk->prev == NULL) {
board->init_chunk = chunk->next;
chunk->next->prev = NULL;
} else {
chunk->prev->next = chunk->next;
}
if (chunk->next != NULL) {
chunk->next->prev = chunk->prev;
}
free(chunk);
board->chunk_num--;
}