Untitled
unknown
c_cpp
3 years ago
7.8 kB
3
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...