/* * stv: run a stv vote. */ #include #include #include #include #include #include #include /* * each candidate */ struct vt { char *who; /* the candidate */ int votes; /* how many votes they got this round */ int eliminated; /* have they been eliminated from the race */ } *candidates; int nr_candidates = 0; #define RANKINGS 10 /* 10 candidates max */ /* * each voter */ struct vote { char *who; /* voters From: address */ int choice[RANKINGS]; /* their preferences */ } *votes; int nr_votes = 0; char bfr[2000]; char key[1000]; /* * more_candidates() -- adds another candidate to the list */ more_candidates(char *who) { fflush(stdout); candidates = realloc(candidates, (1+nr_candidates)*sizeof candidates[0]); candidates[nr_candidates].who = strdup(who); candidates[nr_candidates].votes = 0; candidates[nr_candidates].eliminated = 0; nr_candidates++; } /* * do a round of voting. */ pick_votes(int round) { int i, j, cand, total, least, deleted; printf("%*svoting, round %d", round, "", round); fflush(stdout); /* initialize votes */ for (i=0; i= 0 && cand < RANKINGS) { candidates[cand].votes++; total++; } } printf("..."); fflush(stdout); if (total == 0) { printf("ran out of ballots without a winner ?\n"); return 0; } /* check if somebody won */ for (i=0; i total) { printf("[%s] wins with %d (of %d) votes\n", candidates[i].who, candidates[i].votes, nr_votes); return 1; } /* delete worst candidate, percolate choices */ least = total; for (i=0; i= 0 && cand < RANKINGS && candidates[cand].eliminated) { deleted = 1; for (j=1; j 0); vote = nextkey(vote)) { int pick; ballot = fetch(vote); if (ballot.dsize == 0) continue; votes = realloc(votes, (1+nr_votes) * sizeof *votes); strncpy(bfr, vote.dptr, vote.dsize); bfr[vote.dsize] = 0; votes[nr_votes].who = strdup(bfr); for (pick=0; pick