123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120 |
- // Created by Tinger-HM on 2023/7/13.
- #include <stdlib.h>
- #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;
- }
|