// Created by Tinger-HM on 2023/7/13. #include #include "./Counter.h" // real definition static _ProducerId crate_producer() { _ProducerId producer = (_ProducerId) malloc(sizeof(_Producer)); producer->stage = 0, producer->sid = 0, producer->paired = False; return producer; } static unsigned int is_producer_busy(_ProducerId producer) { return producer->stage == 1 || producer->stage == 2; } static unsigned char is_producer_alone(_ProducerId producer) { return producer->stage == 1 && !producer->paired; } static void change_producer_info(_ProducerId producer, unsigned char sta, unsigned int sid, unsigned char paired) { producer->stage = sta, producer->sid = sid, producer->paired = paired; } static unsigned char *get_neighbors(unsigned char index, unsigned char max, unsigned char *count) { unsigned char *res; if (index == 0) { *count = 1; res = (unsigned char *) malloc(_SoChar); res[0] = 1; } else if (index == max) { *count = 1; res = (unsigned char *) malloc(_SoChar); res[0] = max - 1; } else { *count = 2; res = (unsigned char *) malloc(_So2Char); res[0] = index - 1; res[1] = index + 1; } return res; } static unsigned char is_satisfied(CounterPtr world, double data) { return data < world->threshold; } extern CounterPtr CreateCounter(unsigned char producer_num, double threshold) { int i; CounterPtr counter = (CounterPtr) malloc(sizeof(Counter)); counter->producers = (_ProducerId *) malloc(sizeof(_ProducerId) * producer_num); counter->total = 0, counter->producerCount = producer_num, counter->current = 0, counter->threshold = threshold; for (i = 0; i < producer_num; ++i) counter->producers[i] = crate_producer(); return counter; } extern void CountByData(CounterPtr world, const double *data, unsigned int *total, unsigned char *current) { if (world == NULL) return; if (data == NULL) return; unsigned char i, j, *nears, nid, nearCount, judge; for (i = 0; i < world->producerCount; ++i) { judge = False, nears = get_neighbors(i, world->producerCount - 1, &nearCount); if (is_satisfied(world, data[i])) { // i提交的数据符合生产标准 if (world->producers[i]->stage == 0) { // i之前没有在生产,看来是刚开始生产 for (j = 0; j < nearCount; ++j) { // i开始从邻居中找伴侣 nid = nears[j]; if (is_producer_alone(world->producers[nid])) { // nid邻居在独自生产,看来i生产的孩子是帮nid在生产,让衪俩相爱,生同一个孩子 world->producers[nid]->paired = True; change_producer_info(world->producers[i], 2, world->producers[nid]->sid, True); judge = True; // i只能帮一个人生产,不能同时爱上其他邻居 break; } } if (!judge) { // i的所有邻居都已经与其衪人相爱或者目前没有生产欲望,那i只有自己生产了 world->total++; world->current++; change_producer_info(world->producers[i], 1, world->total, False); } } else if (is_producer_busy(world->producers[i])) { // i之前已经处于生产状态,不予理会 // pass, nothing to do } else { // i之前在等待自己的伴侣生产完成,此次衪有了新的身孕,原来衪是抛弃旧爱,独自开始生产,期望寻求新欢 world->total++; world->current++; change_producer_info(world->producers[i], 1, world->total, False); } } else { // i提交的数据不符合生产标准 if (world->producers[i]->stage == 0) { // i之前就没有在生产,不予理会 // pass, nothing to do } else if (world->producers[i]->paired) { // i之前与邻居配对过 for (j = 0; j < nearCount; ++j) { nid = nears[j]; if (world->producers[i]->sid == world->producers[nid]->sid) { // 邻居nid和i生产的是同一个孩子,衪俩是爱人 // nid还在生产,i已经不符合生产标准,则i开始等待 if (is_producer_busy(world->producers[nid])) world->producers[i]->stage = 3; else if (world->producers[nid]->stage == 3) { // nid已经在等i结束了,衪结束生产与相爱关系,和平分开 world->current--; change_producer_info(world->producers[i], 0, world->producers[i]->sid, False); change_producer_info(world->producers[nid], 0, world->producers[nid]->sid, False); } judge = True; break; } } if (!judge) { // 看起来i的伴侣已经提前离衪而去,渣造人人,i独自结束 world->current--; change_producer_info(world->producers[i], 0, world->producers[i]->sid, False); } } else { // i从头到尾都是独自在生产,辛苦啊 world->current--; change_producer_info(world->producers[i], 0, world->producers[i]->sid, False); } } free(nears); // 再见了我的邻居们,再见了我的爱恨情仇 } *total = world->total, *current = world->current; }