diff options
author | LAN-TW <lantw44@gmail.com> | 2013-11-16 02:33:03 +0800 |
---|---|---|
committer | LAN-TW <lantw44@gmail.com> | 2013-11-16 02:33:03 +0800 |
commit | e6d786a403a36b98e4f6082ee9848473825db8e8 (patch) | |
tree | 9dbff1670f9a30e64c6b0fe6a3f2fcd36da67173 /hw2/big_judge.c | |
parent | fd5eea92e3f2337e5fd5f336863e5356eda4226f (diff) | |
download | sp2013-e6d786a403a36b98e4f6082ee9848473825db8e8.tar sp2013-e6d786a403a36b98e4f6082ee9848473825db8e8.tar.gz sp2013-e6d786a403a36b98e4f6082ee9848473825db8e8.tar.bz2 sp2013-e6d786a403a36b98e4f6082ee9848473825db8e8.tar.lz sp2013-e6d786a403a36b98e4f6082ee9848473825db8e8.tar.xz sp2013-e6d786a403a36b98e4f6082ee9848473825db8e8.tar.zst sp2013-e6d786a403a36b98e4f6082ee9848473825db8e8.zip |
HW2: big_judge 大致可以運作了
Diffstat (limited to 'hw2/big_judge.c')
-rw-r--r-- | hw2/big_judge.c | 107 |
1 files changed, 105 insertions, 2 deletions
diff --git a/hw2/big_judge.c b/hw2/big_judge.c index 92ca701..05077a7 100644 --- a/hw2/big_judge.c +++ b/hw2/big_judge.c @@ -7,6 +7,8 @@ #include "xwrap.h" #include <errno.h> +#include <poll.h> +#include <signal.h> #include <stdbool.h> #include <stdio.h> #include <stdlib.h> @@ -18,13 +20,15 @@ typedef struct { pid_t pid; int read; int write; + bool working; + XBuf buf; } JudgeData; typedef struct { long score; } PlayerData; -bool comb4 (Comp135* comp, int players[], long player_num) { +static bool comb4 (int players[], long player_num) { for (int i = 3; i >= 0; i--) { if (players[i] + 1 <= player_num && players[i] + 1 + (3 - i) <= player_num) { @@ -38,6 +42,69 @@ bool comb4 (Comp135* comp, int players[], long player_num) { return false; } +static int nextjudge (JudgeData* jd, long judge_num) { + for (int i = 0; i < judge_num; i++) { + if (!(jd[i].working)) { + return i; + } + } + return -1; +} + +static int nextscore (Comp135* comp, JudgeData* jd, long judge_num, + PlayerData* pd, long player_num, struct pollfd* jpoll) { + +repoll: + if (poll (jpoll, judge_num, -1) <= 0) { + fprintf (stderr, "Poll fail: %s\n", strerror (errno)); + return -1; + } + + for (int i = 0; i < judge_num; i++) { + if (jpoll[i].revents & POLLIN || jpoll[i].revents & POLLPRI) { + comp135_log (comp, "Waiting for judge %d input", i + 1); + for (int j = 0; j < 4; j++) { + char* r; + while ( + (r = xgetline (jpoll[i].fd, &jd[i].buf, '\n')) == NULL && + !(jd[i].buf.buf_error) && !(jd[i].buf.buf_eof)); + if (r == NULL) { + goto repoll; + } + + long id, rank, scr; + if (sscanf (r, "%ld %ld", &id, &rank) < 2) { + comp135_log (comp, "Judge %d send bad input %s", i + 1, r); + j--; + continue; + } + free (r); + + if (id > player_num || id <= 0) { + comp135_log (comp, "Bad player ID: %ld", player_num); + j--; + continue; + } + if (rank > 4 || rank < 1) { + comp135_log (comp, "Bad rank: %ld", rank); + j--; + continue; + } + + scr = 4 - rank; + comp135_log (comp, "Player %ld gets %ld points", id, scr); + pd[id - 1].score += scr; + comp135_log (comp, "Player %ld has %ld points now", id, pd[id - 1].score); + } + comp135_log (comp, "Judge %d is available now", i + 1); + jd[i].working = false; + break; + } + } + + return 0; +} + int main (int argc, char* argv[]) { if (argc < 3) { fprintf (stderr, "Usage: %s judge_num player_num\n", argv[0]); @@ -64,6 +131,13 @@ int main (int argc, char* argv[]) { return 3; } + struct sigaction sa = { + .sa_handler = SIG_IGN, + .sa_flags = 0 + }; + sigemptyset (&sa.sa_mask); + sigaction (SIGPIPE, &sa, NULL); + Comp135 comp_struct, *comp; comp = &comp_struct; @@ -71,6 +145,7 @@ int main (int argc, char* argv[]) { JudgeData* jd = xmalloc (sizeof (JudgeData) * judge_num); PlayerData* pd = xmalloc (sizeof (PlayerData) * player_num); + struct pollfd* jpoll = xmalloc (sizeof (struct pollfd) * judge_num); for (int i = 0; i < player_num; i++) { pd[i].score = 0; @@ -96,22 +171,50 @@ int main (int argc, char* argv[]) { } else { close (fdr[0]); close (fdw[1]); + dup2 (fdw[0], STDIN_FILENO); + close (fdw[0]); + dup2 (fdr[1], STDOUT_FILENO); + close (fdr[1]); char* myjudge = xgetres ("judge"); execl (myjudge, "judge", xsprintf ("%d", i + 1), (char*)NULL); fprintf (stderr, "%s: execl: %s: %s\n", argv[0], myjudge, strerror (errno)); _exit (1); } + jpoll[i].fd = fdr[0]; + jpoll[i].events = POLLIN | POLLPRI; + jpoll[i].revents = 0; jd[i].read = fdr[0]; jd[i].write = fdw[1]; + jd[i].working = false; + xbufinit (&jd[i].buf); comp135_log (comp, "Judge %d created: PID = %u, read = %d, write = %d", i + 1, jd[i].pid, jd[i].read, jd[i].write); } int players[4] = {1, 2, 3, 4}; + long completed_jobs = 0; do { + char msg[20]; + int msglen; + int jnext; + msglen = snprintf (msg, 20, "%d %d %d %d\n", + players[0], players[1], players[2], players[3]); + + while ((jnext = nextjudge (jd, judge_num)) < 0) { + if (nextscore (comp, jd, judge_num, pd, player_num, jpoll) < 0) { + continue; + } + completed_jobs++; + } + + comp135_log (comp, "Send %d %d %d %d to judge %d", + players[0], players[1], players[2], players[3], jnext + 1); + write (jd[jnext].write, msg, msglen); + comp135_log (comp, "Judge %d is working now", jnext + 1); + jd[jnext].working = true; - } while (comb4 (comp, players, player_num)); + } while (comb4 (players, player_num)); comp135_destroy (comp); |