Counter.c 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. // Created by Tinger-HM on 2023/7/13.
  2. #include <stdlib.h>
  3. #include "./Counter.h"
  4. // real definition
  5. static _ProducerId crate_producer() {
  6. _ProducerId producer = (_ProducerId) malloc(sizeof(_Producer));
  7. producer->stage = 0, producer->sid = 0, producer->paired = False;
  8. return producer;
  9. }
  10. static unsigned int is_producer_busy(_ProducerId producer) {
  11. return producer->stage == 1 || producer->stage == 2;
  12. }
  13. static unsigned char is_producer_alone(_ProducerId producer) {
  14. return producer->stage == 1 && !producer->paired;
  15. }
  16. static void change_producer_info(_ProducerId producer, unsigned char sta, unsigned int sid, unsigned char paired) {
  17. producer->stage = sta, producer->sid = sid, producer->paired = paired;
  18. }
  19. static unsigned char *get_neighbors(unsigned char index, unsigned char max, unsigned char *count) {
  20. unsigned char *res;
  21. if (index == 0) {
  22. *count = 1;
  23. res = (unsigned char *) malloc(_SoChar);
  24. res[0] = 1;
  25. } else if (index == max) {
  26. *count = 1;
  27. res = (unsigned char *) malloc(_SoChar);
  28. res[0] = max - 1;
  29. } else {
  30. *count = 2;
  31. res = (unsigned char *) malloc(_So2Char);
  32. res[0] = index - 1;
  33. res[1] = index + 1;
  34. }
  35. return res;
  36. }
  37. static unsigned char is_satisfied(CounterPtr world, double data) {
  38. return data < world->threshold;
  39. }
  40. extern CounterPtr CreateCounter(unsigned char producer_num, double threshold) {
  41. int i;
  42. CounterPtr counter = (CounterPtr) malloc(sizeof(Counter));
  43. counter->producers = (_ProducerId *) malloc(sizeof(_ProducerId) * producer_num);
  44. counter->total = 0, counter->producerCount = producer_num, counter->current = 0, counter->threshold = threshold;
  45. for (i = 0; i < producer_num; ++i) counter->producers[i] = crate_producer();
  46. return counter;
  47. }
  48. extern void CountByData(CounterPtr world, const double *data, unsigned int *total, unsigned char *current) {
  49. if (world == NULL) return;
  50. if (data == NULL) return;
  51. unsigned char i, j, *nears, nid, nearCount, judge;
  52. for (i = 0; i < world->producerCount; ++i) {
  53. judge = False, nears = get_neighbors(i, world->producerCount - 1, &nearCount);
  54. if (is_satisfied(world, data[i])) { // i提交的数据符合生产标准
  55. if (world->producers[i]->stage == 0) { // i之前没有在生产,看来是刚开始生产
  56. for (j = 0; j < nearCount; ++j) { // i开始从邻居中找伴侣
  57. nid = nears[j];
  58. if (is_producer_alone(world->producers[nid])) {
  59. // nid邻居在独自生产,看来i生产的孩子是帮nid在生产,让衪俩相爱,生同一个孩子
  60. world->producers[nid]->paired = True;
  61. change_producer_info(world->producers[i], 2, world->producers[nid]->sid, True);
  62. judge = True; // i只能帮一个人生产,不能同时爱上其他邻居
  63. break;
  64. }
  65. }
  66. if (!judge) { // i的所有邻居都已经与其衪人相爱或者目前没有生产欲望,那i只有自己生产了
  67. world->total++;
  68. world->current++;
  69. change_producer_info(world->producers[i], 1, world->total, False);
  70. }
  71. } else if (is_producer_busy(world->producers[i])) { // i之前已经处于生产状态,不予理会
  72. // pass, nothing to do
  73. } else { // i之前在等待自己的伴侣生产完成,此次衪有了新的身孕,原来衪是抛弃旧爱,独自开始生产,期望寻求新欢
  74. world->total++;
  75. world->current++;
  76. change_producer_info(world->producers[i], 1, world->total, False);
  77. }
  78. } else { // i提交的数据不符合生产标准
  79. if (world->producers[i]->stage == 0) { // i之前就没有在生产,不予理会
  80. // pass, nothing to do
  81. } else if (world->producers[i]->paired) { // i之前与邻居配对过
  82. for (j = 0; j < nearCount; ++j) {
  83. nid = nears[j];
  84. if (world->producers[i]->sid == world->producers[nid]->sid) { // 邻居nid和i生产的是同一个孩子,衪俩是爱人
  85. // nid还在生产,i已经不符合生产标准,则i开始等待
  86. if (is_producer_busy(world->producers[nid])) world->producers[i]->stage = 3;
  87. else if (world->producers[nid]->stage == 3) { // nid已经在等i结束了,衪结束生产与相爱关系,和平分开
  88. world->current--;
  89. change_producer_info(world->producers[i], 0, world->producers[i]->sid, False);
  90. change_producer_info(world->producers[nid], 0, world->producers[nid]->sid, False);
  91. }
  92. judge = True;
  93. break;
  94. }
  95. }
  96. if (!judge) { // 看起来i的伴侣已经提前离衪而去,渣造人人,i独自结束
  97. world->current--;
  98. change_producer_info(world->producers[i], 0, world->producers[i]->sid, False);
  99. }
  100. } else { // i从头到尾都是独自在生产,辛苦啊
  101. world->current--;
  102. change_producer_info(world->producers[i], 0, world->producers[i]->sid, False);
  103. }
  104. }
  105. free(nears); // 再见了我的邻居们,再见了我的爱恨情仇
  106. }
  107. *total = world->total, *current = world->current;
  108. }