int chain_rand(REMAILER *remailer, int badchains[MAXREM][MAXREM], int maxrem, int thischain[], int chainlen, int t, int ignore_constraints_if_necessary) /* set random chain. returns 0 if not random, 1 if random, -1 on error */ /* t... 0 for mixmaster Type II * 1 for cypherpunk Type I */ { int hop; int err = 0; int constraints_ignored = 0; assert(t == 0 || t == 1); start: for (hop = 0; hop < chainlen; hop++) if (thischain[hop] == 0) { int select[MAXREM]; int randavail = 0; int i; err = 1; if (hop > 0) assert(thischain[hop-1]); /* we already should have chosen a remailer after this one */ for (i = 1; i < maxrem; i++) { select[i] = ((remailer[i].flags.mix && t == 0) || /* remailer supports type */ (remailer[i].flags.pgp && remailer[i].flags.ek && t == 1)) && (remailer[i].info[t].reliability >= 100 * MINREL || constraints_ignored ) && /* remailer has sufficient reliability */ (remailer[i].info[t].latency <= MAXLAT || constraints_ignored ) && /* remailer has low enough latency */ (remailer[i].info[t].latency >= MINLAT || constraints_ignored ) && /* remailer has high enough latency */ !remailer[i].flags.star_ex && /* remailer is not excluded from random selection */ !badchains[i][0] && !badchains[i][thischain[hop-1]] && /* remailer can send to the next one */ (hop == chainlen-1 || !badchains[thischain[hop+1]][i]); /* we are at the first hop or the previous one can send to this (may be random) */ randavail += select[i]; } for (i = hop - DISTANCE; i <= hop + DISTANCE; i++) if (i >= 0 && i < chainlen && select[thischain[i]] && thischain[i]) { select[thischain[i]] = 0; randavail--; } assert(randavail >= 0); if (randavail < 1) { if (ignore_constraints_if_necessary && !constraints_ignored) { errlog(WARNING, "No reliable remailers. Ignoring for randhop\n"); constraints_ignored = 1; goto start; }; err = -1; goto end; } do thischain[hop] = rnd_number(maxrem - 1) + 1; while (!select[thischain[hop]]); } end: return (err); }
int chain_randfinal(int type, REMAILER *remailer, int badchains[MAXREM][MAXREM], int maxrem, int rtype, int chain[], int chainlen, int ignore_constraints_if_necessary) { int randavail; int i; int t; int select[MAXREM]; int secondtolasthop = (chainlen <= 1 ? -1 : chain[1]); int constraints_ignored = 0; t = rtype; if (rtype == 2) t = 1; start: randavail = 0; /* select a random final hop */ for (i = 1; i < maxrem; i++) { select[i] = ((remailer[i].flags.mix && rtype == 0) || /* remailer supports type */ (remailer[i].flags.pgp && remailer[i].flags.ek && rtype == 1) || (remailer[i].flags.newnym && rtype == 2)) && (remailer[i].info[t].reliability >= 100 * RELFINAL || constraints_ignored ) && /* remailer has sufficient reliability */ (remailer[i].info[t].latency <= MAXLAT || constraints_ignored ) && /* remailer has low enough latency */ (remailer[i].info[t].latency >= MINLAT || constraints_ignored ) && /* remailer has high enough latency */ (type == MSG_NULL || !remailer[i].flags.middle) && /* remailer is not middleman */ !remailer[i].flags.star_ex && /* remailer is not excluded from random selection */ (remailer[i].flags.post || type != MSG_POST) && /* remailer supports post when this is a post */ ((secondtolasthop == -1) || !badchains[secondtolasthop][i]); /* we only have hop or the previous one can send to this (may be random) */ randavail += select[i]; } for (i = 1; i <= DISTANCE; i++) if (i < chainlen && select[chain[i]] && chain[i]) { select[chain[i]] = 0; randavail--; } assert(randavail >= 0); if (randavail == 0) { if (ignore_constraints_if_necessary && !constraints_ignored) { errlog(WARNING, "No reliable remailers. Ignoring for randhop\n"); constraints_ignored = 1; goto start; }; i = -1; } else { do i = rnd_number(maxrem - 1) + 1; while (!select[i]); } return (i); }
system::Guess Randy::guess(const Game &game) const { auto &opp_hand = game.board.hands[system::Playsidetoi(system::invert(playside))]; // 入力 size_t place; int number; std::random_device rnd; std::mt19937 mt(rnd()); std::uniform_int_distribution <> rnd_place(0, opp_hand.size() - 1); while (true) { place = rnd_place(mt); if (!opp_hand[place].is_front) { break; } } std::uniform_int_distribution <> rnd_number(0, 11); number = rnd_number(mt); return system::Guess(place, number); }