Untitled
unknown
c_cpp
2 years ago
7.8 kB
2
Indexable
#include <fcntl.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/stat.h> #include <sys/types.h> #include <unistd.h> #include "status.h" #define ERR_EXIT(m) \ do { \ perror(m); \ exit(EXIT_FAILURE); \ } while (0) char buffer[1024]; char msg[20]; char status_msg[5][20]; char PSSM_msg[100]; void parseStatus(Status *status) { int id = 0, ptr = 0; for (int i = 0; i < msg[i]; i++) { if (msg[i] == ' ') { strncpy(status_msg[id], &msg[ptr], i - ptr); status_msg[id++][i - ptr] = 0; ptr = i + 1; } } strncpy(status_msg[id], &msg[ptr], 1); status_msg[id++][1] = 0; // create status status->HP = atoi(status_msg[0]); status->ATK = atoi(status_msg[1]); if (!strcmp(status_msg[2], "FIRE")) { status->attr = FIRE; } else if (!strcmp(status_msg[2], "GRASS")) { status->attr = GRASS; } else { status->attr = WATER; } status->current_battle_id = status_msg[3][0]; status->battle_ended_flag = atoi(status_msg[4]); } void pickOutStatus(int ptr) { int msg_len = 0; for (int i = ptr; buffer[i] != '\n'; i++) { msg_len++; } strncpy(msg, &buffer[ptr], msg_len); } int readFile(Status *status, int id) { FILE *fp = fopen("player_status.txt", "r"); fread(buffer, sizeof(char), 1024, fp); int cnt = id, ptr = -1; for (int i = 0; buffer[i]; i++) { if (cnt == 0) { ptr = i; break; } if (buffer[i] == '\n') cnt--; } fclose(fp); return ptr; } void generatePSSM(Status *status, int player_id) { status->real_player_id = player_id; int ptr = readFile(status, player_id); pickOutStatus(ptr); parseStatus(status); } int decideTargetID(char ch) { int id = -1; switch (ch) { case 'G': id = 8; break; case 'I': id = 9; break; case 'D': id = 10; break; case 'H': id = 11; break; case 'J': id = 12; break; case 'E': id = 13; break; case 'B': id = 14; break; } return id; } int main(int argc, char **argv) { int player_id = atoi(argv[1]); int parent_pid = atoi(argv[2]); // create fifo char pathname[20]; for (int i = 8; i <= 14; i++) { snprintf(pathname, 20, "player%d.fifo", i); mkfifo(pathname, 0666); memset(pathname, 0, sizeof(pathname)); } Status status; // if is real player if (player_id <= 7 && player_id >= 0) { // create log file snprintf(pathname, 20, "log_player%d.txt", player_id); FILE *logfile_fp = fopen(pathname, "w+"); // GeneratePSSM generatePSSM(&status, player_id); int initial_hp = status.HP; // join battle, continuously receiving/sending data from/to parent char buf[100]; while (1) { // write to log file memset(buf, 0, sizeof(buf)); snprintf(buf, 100, "%d,%d pipe to %c,%d %d,%d,%c,%d\n", status.real_player_id, getpid(), status.current_battle_id, parent_pid, status.real_player_id, status.HP, status.current_battle_id, status.battle_ended_flag); fprintf(stderr, "real player pipe to buf: %s", buf); fprintf(logfile_fp, "%s", buf); // send PSSM to parent if (write(STDOUT_FILENO, &status, sizeof(Status)) < 0) perror("Error: "); // receive PSSM from parent if (read(STDIN_FILENO, &status, sizeof(Status)) < 0) perror("Error: "); // write to log file memset(buf, 0, sizeof(buf)); snprintf(buf, 100, "%d,%d pipe from %c,%d %d,%d,%c,%d\n", status.real_player_id, getpid(), status.current_battle_id, parent_pid, status.real_player_id, status.HP, status.current_battle_id, status.battle_ended_flag); fprintf(stderr, "real player pipe from buf: %s", buf); fprintf(logfile_fp, "%s", buf); // if battle is end (battle_ended_flag) if (status.battle_ended_flag == 1) { // turn off battle_ended_flag status.battle_ended_flag = 0; // if is last game if (status.current_battle_id == 'A') break; // if win if (status.HP > 0) { // recover half blood status.HP += (initial_hp - status.HP) / 2; } // else (lose) else { // recover full blood status.HP = initial_hp; // write to log file (fifo to) memset(buf, 0, sizeof(buf)); int target_id = decideTargetID(status.current_battle_id); snprintf(buf, 100, "%d,%d fifo to %d %d,%d\n", status.real_player_id, getpid(), target_id, status.real_player_id, status.HP); fprintf(logfile_fp, "%s", buf); fprintf(stderr, "fifo to buf: %s", buf); // write pssm to agent player (corresponds to current_battle_id by // fifo) memset(pathname, 0, sizeof(pathname)); snprintf(pathname, 20, "player%d.fifo", target_id); int fd; if(open(pathname, O_WRONLY)<0) perror("Error: "); if (write(fd, &status, sizeof(status)) < 0) perror("Error: "); // close logfile and fifo fclose(logfile_fp); close(fd); // exit exit(0); } } } exit(0); } // else (agent player) else { // wait until read something from fifo (inherit status) memset(pathname, 0, sizeof(pathname)); snprintf(pathname, 20, "player%d.fifo", player_id); int fd = open(pathname, O_WRONLY), n; while (n = read(fd, &status, sizeof(status)) < 0) ; // open real player's log file int rpi = status.real_player_id; // real player id int initial_hp = status.HP; memset(pathname, 0, sizeof(pathname)); snprintf(pathname, 20, "log_player%d.txt", rpi); FILE *logfile_fp = fopen(pathname, "w+"); // write to real player's log file (fifo from) char buf[100]; memset(buf, 0, sizeof(buf)); snprintf(buf, 100, "%d,%d fifo from %d %d,%d\n", player_id, getpid(), rpi, rpi, status.HP); fprintf(logfile_fp, "%s", buf); fprintf(stderr, "fifo from buf: %s", buf); // join battle, continuously receiving/sending data from/to parent while (1) { // write to log file memset(buf, 0, sizeof(buf)); snprintf(buf, 100, "%d,%d pipe to %c,%d %d,%d,%c,%d\n", player_id, getpid(), status.current_battle_id, parent_pid, rpi, status.HP, status.current_battle_id, status.battle_ended_flag); fprintf(logfile_fp, "%s", buf); fprintf(stderr, "agent player pipe to buf: %s", buf); // send PSSM to parent if (write(STDOUT_FILENO, &status, sizeof(Status)) < 0) perror("Error: "); // receive PSSM from parent if (read(STDIN_FILENO, &status, sizeof(Status)) < 0) perror("Error: "); // write to log file memset(buf, 0, sizeof(buf)); snprintf(buf, 100, "%d,%d pipe from %c,%d %d,%d,%c,%d\n", player_id, getpid(), status.current_battle_id, parent_pid, rpi, status.HP, status.current_battle_id, status.battle_ended_flag); fprintf(logfile_fp, "%s", buf); fprintf(stderr, "agent player pipe from buf: %s", buf); // if battle is end (battle_ended_flag) if (status.battle_ended_flag == 1) { status.battle_ended_flag = 0; // if is last game if (status.current_battle_id == 'A') break; // if win if (status.HP > 0) { // recover half blood status.HP += (initial_hp - status.HP) / 2; } // else (lose) else { // close logfile and fifo fclose(logfile_fp); close(fd); // exit exit(0); } } } exit(0); } exit(0); }
Editor is loading...