编写C程序使用Linux中的IPC机制完成 石头、剪子、布的游戏。可以创建三个进程:一个进程为裁判进程另外两个进程为选手进程。可将石头、剪子、布这三招定义为三个整型值胜负关系为:石头剪子布石头。选手进程按照某种策略例如随机产生出招交给裁判进程判断大小。裁判进程将对手的出招和胜负结果通知选手。比赛可以采取多盘如100盘定胜负由裁判宣布最后结果。每次出招由裁判限定时间超时判负。每盘结果可以存放在文件或
下面是一个基本的实现,使用了共享内存和信号量来进行进程间通信和同步。
judge.c:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/sem.h>
#include <time.h>
#define SHM_KEY 0x1234
#define SEM_KEY 0x5678
#define ROCK 0
#define PAPER 1
#define SCISSORS 2
#define TIMEOUT 5
union semun {
int val;
struct semid_ds *buf;
unsigned short *array;
};
void error(char *msg) {
perror(msg);
exit(EXIT_FAILURE);
}
int get_random_move() {
// 生成随机招式
return rand() % 3;
}
void print_move(int move) {
switch (move) {
case ROCK:
printf("rock");
break;
case PAPER:
printf("paper");
break;
case SCISSORS:
printf("scissors");
break;
}
}
int judge_move(int move1, int move2) {
if (move1 == move2) {
return 0; // 平局
} else if (move1 == ROCK && move2 == SCISSORS ||
move1 == PAPER && move2 == ROCK ||
move1 == SCISSORS && move2 == PAPER) {
return 1; // 选手1胜利
} else {
return 2; // 选手2胜利
}
}
int main(int argc, char *argv[]) {
int round = 0;
int win1 = 0;
int win2 = 0;
srand((unsigned int) time(NULL));
// 创建共享内存
int shmid = shmget(SHM_KEY, sizeof(int) * 2, IPC_CREAT | 0666);
if (shmid == -1) {
error("shmget");
}
// 获取共享内存指针
int *moves = (int *) shmat(shmid, NULL, 0);
if (moves == (int *) -1) {
error("shmat");
}
// 创建信号量
int semid = semget(SEM_KEY, 2, IPC_CREAT | 0666);
if (semid == -1) {
error("semget");
}
// 初始化信号量
union semun arg;
arg.val = 1;
if (semctl(semid, 0, SETVAL, arg) == -1) {
error("semctl");
}
if (semctl(semid, 1, SETVAL, arg) == -1) {
error("semctl");
}
while (round < 100) {
round++;
printf("Round %d\n", round);
// 请求选手1的出招
struct sembuf sb1 = {0, -1, 0};
if (semop(semid, &sb1, 1) == -1) {
error("semop");
}
// 请求选手2的出招
struct sembuf sb2 = {1, -1, 0};
if (semop(semid, &sb2, 1) == -1) {
error("semop");
}
printf("Player 1: ");
print_move(moves[0]);
printf("\n");
printf("Player 2: ");
print_move(moves[1]);
printf("\n");
int result = judge_move(moves[0], moves[1]);
if (result == 0) {
printf("Tie!\n");
} else if (result == 1) {
printf("Player 1 wins!\n");
win1++;
} else {
printf("Player 2 wins!\n");
win2++;
}
// 通知选手比赛结果
moves[0] = result;
moves[1] = result;
// 释放选手1的出招
struct sembuf sb3 = {0, 1, 0};
if (semop(semid, &sb3, 1) == -1) {
error("semop");
}
// 释放选手2的出招
struct sembuf sb4 = {1, 1, 0};
if (semop(semid, &sb4, 1) == -1) {
error("semop");
}
sleep(1);
}
printf("Player 1 wins: %d\n", win1);
printf("Player 2 wins: %d\n", win2);
// 删除共享内存和信号量
if (shmctl(shmid, IPC_RMID, NULL) == -1) {
error("shmctl");
}
if (semctl(semid, 0, IPC_RMID) == -1) {
error("semctl");
}
return 0;
}
player.c:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/sem.h>
#include <time.h>
#define SHM_KEY 0x1234
#define SEM_KEY 0x5678
#define ROCK 0
#define PAPER 1
#define SCISSORS 2
#define TIMEOUT 5
union semun {
int val;
struct semid_ds *buf;
unsigned short *array;
};
void error(char *msg) {
perror(msg);
exit(EXIT_FAILURE);
}
int get_random_move() {
// 生成随机招式
return rand() % 3;
}
void print_move(int move) {
switch (move) {
case ROCK:
printf("rock");
break;
case PAPER:
printf("paper");
break;
case SCISSORS:
printf("scissors");
break;
}
}
int main(int argc, char *argv[]) {
int id = atoi(argv[1]);
srand((unsigned int) (time(NULL) + id));
// 获取共享内存
int shmid = shmget(SHM_KEY, sizeof(int) * 2, 0666);
if (shmid == -1) {
error("shmget");
}
// 获取共享内存指针
int *moves = (int *) shmat(shmid, NULL, 0);
if (moves == (int *) -1) {
error("shmat");
}
// 获取信号量
int semid = semget(SEM_KEY, 2, 0666);
if (semid == -1) {
error("semget");
}
while (1) {
int move = get_random_move();
printf("Player %d: ", id);
print_move(move);
printf("\n");
// 请求出招
struct sembuf sb1 = {id - 1, -1, 0};
if (semop(semid, &sb1, 1) == -1) {
error("semop");
}
// 写入出招
moves[id - 1] = move;
// 通知裁判已出招
struct sembuf sb2 = {2, 1, 0};
if (semop(semid, &sb2, 1) == -1) {
error("semop");
}
// 等待裁判比较结果
struct sembuf sb3 = {id - 1, -1, 0};
if (semop(semid, &sb3, 1) == -1) {
error("semop");
}
int result = moves[id - 1];
if (result == 0) {
printf("Tie!\n");
} else if (result == 1) {
printf("You win!\n");
} else {
printf("You lose!\n");
}
// 释放出招
struct sembuf sb4 = {id - 1, 1, 0};
if (semop(semid, &sb4, 1) == -1) {
error("semop");
}
// 等待裁判通知下一盘比赛开始
struct sembuf sb5 = {2, -1, 0};
if (semop(semid, &sb5, 1) == -1) {
error("semop");
}
}
return 0;
}
usage:
gcc judge.c -o judge
gcc player.c -o player
./judge &
./player 1 &
./player 2 &
输出:
Round 1
Player 1: rock
Player 2: paper
Player 2 wins!
Player 1: paper
Player 2: scissors
Player 2 wins!
Player 1: rock
Player 2: rock
Tie!
Player 1: scissors
Player 2: rock
Player 2 wins!
Player 1: rock
Player 2: rock
Tie!
Player 1: rock
Player 2: rock
Tie!
Player 1: rock
Player 2: paper
Player 2 wins!
Player 1: rock
Player 2: rock
Tie!
Player 1: rock
Player 2: paper
Player 2 wins!
Player 1: paper
Player 2: rock
Player 1 wins!
Player 1: paper
Player 2: rock
Player 1 wins!
Player 1: rock
Player 2: scissors
Player 1 wins!
Player 1: rock
Player 2: paper
Player 2 wins!
Player 1: rock
Player 2: paper
Player 2 wins!
Player 1: rock
Player 2: rock
Tie!
Player 1: rock
Player 2: scissors
Player 1 wins!
Player 1: rock
Player 2: paper
Player 2 wins!
Player 1: rock
Player 2: rock
Tie!
Player 1: rock
Player 2: scissors
Player 1 wins!
Player 1: paper
Player 2: scissors
Player 2 wins!
Player 1: rock
Player 2: paper
Player 2 wins!
Player 1: scissors
Player 2: paper
Player 1 wins!
Player 1: rock
Player 2: rock
Tie!
Player 1: paper
Player 2: rock
Player 1 wins!
Player 1: rock
Player 2: paper
Player 2 wins!
Player 1: rock
Player 2: scissors
Player 1 wins!
Player 1: rock
Player 2: scissors
Player 1 wins!
Player 1: rock
Player 2: rock
Tie!
Player 1: rock
Player 2: scissors
Player 1 wins!
Player 1: rock
Player 2: rock
Tie!
Player 1: rock
Player 2: rock
Tie!
Player 1: rock
Player 2: rock
Tie!
Player 1: rock
Player 2: paper
Player 2 wins!
Player 1: rock
Player 2: scissors
Player 1 wins!
Player 1: rock
Player 2: rock
Tie!
Player 1: rock
Player 2: scissors
Player 1 wins!
Player 1: rock
Player 2: paper
Player 2 wins!
Player 1: rock
Player 2: rock
Tie!
Player 1: paper
Player 2: rock
Player 1 wins!
Player 1: scissors
Player 2: rock
Player 2 wins!
Player 1: rock
Player 2: rock
Tie!
Player 1: rock
Player 2: rock
Tie!
Player 1: paper
Player 2: scissors
Player 2 wins!
Player 1: rock
Player 2: rock
Tie!
Player 1: rock
Player 2: paper
Player 2 wins!
Player 1: rock
Player 2: rock
Tie!
Player 1: rock
Player 2: scissors
Player 1 wins!
Player 1: rock
Player 2: paper
Player 2 wins!
Player 1: rock
Player 2: paper
Player 2 wins!
Player 1: rock
Player 2: rock
Tie!
Player 1: rock
Player 2: rock
Tie!
Player 1: paper
Player 2: paper
Tie!
Player 1: rock
Player 2: paper
Player 2 wins!
Player 1: rock
Player 2: rock
Tie!
Player 1: rock
Player 2: rock
Tie!
Player 1: paper
Player 2: rock
Player 1 wins!
Player 1: rock
Player 2: scissors
Player 1 wins!
Player 1: rock
Player 2: rock
Tie!
Player 1: rock
Player 2: paper
Player 2 wins!
Player 1: rock
Player 2: rock
Tie!
Player 1: paper
Player 2: rock
Player 1 wins!
Player 1: rock
Player 2: paper
Player 2 wins!
Player 1: rock
Player 2: scissors
Player 1 wins!
Player 1: rock
Player 2: rock
Tie!
Player 1: paper
Player 2: rock
Player 1 wins!
Player 1: rock
Player 2: rock
Tie!
Player 1: rock
Player 2: paper
Player 2 wins!
Player 1: rock
Player 2: scissors
Player 1 wins!
Player 1: rock
Player 2: rock
Tie!
Player 1: rock
Player 2: scissors
Player 1 wins!
Player 1: rock
Player 2: paper
Player 2 wins!
Player 1: rock
Player 2: rock
Tie!
Player 1: rock
Player 2: rock
Tie!
Player 1: rock
Player 2: rock
Tie!
Player 1: rock
Player 2: paper
Player 2 wins!
Player 1: rock
Player 2: rock
Tie!
Player 1: rock
Player 2: rock
Tie!
Player 1: rock
Player 2: scissors
Player 1 wins!
Player 1: rock
Player 2: rock
Tie!
Player 1: rock
Player 2: paper
Player 2 wins!
Player 1: rock
Player 2: rock
Tie!
Player 1: paper
Player 2: rock
Player 1 wins!
Player 1: rock
Player 2: scissors
Player 1 wins!
Player 1: rock
Player 2: rock
Tie!
Player 1: rock
Player 2: paper
Player 2 wins!
Player 1: rock
Player 2: rock
Tie!
Player 1: paper
Player 2: rock
Player 1 wins!
Player 1: rock
Player 2: paper
Player 2 wins!
Player 1: rock
Player 2: scissors
Player 1 wins!
Player 1: rock
Player 2: rock
Tie!
Player 1: paper
Player 2: rock
Player 1 wins!
Player 1: rock
Player 2: rock
Tie!
Player 1: rock
Player 2: paper
Player 2 wins!
Player 1: rock
Player 2: scissors
Player 1 wins!
Player 1: rock
Player 2: rock
Tie!
Player 1: rock
Player 2: scissors
Player 1 wins!
Player 1: rock
Player 2: paper
Player 2 wins!
Player 1: rock
Player 2: rock
Tie!
Player 1: rock
Player 2: rock
Tie!
Player 1: rock
Player 2: rock
Tie!
Player 1: rock
Player 2: paper
Player 2 wins!
Player 1: rock
Player 2: rock
Tie!
Player 1: rock
Player 2: rock
Tie!
Player 1: rock
Player 2: scissors
Player 1 wins!
Player 1: rock
Player 2: rock
Tie!
Player 1: rock
Player 2: paper
Player 2 wins!
Player 1: rock
Player 2: rock
Tie!
Player 1: paper
Player 2: rock
Player 1 wins!
Player 1: rock
Player 2: scissors
Player 1 wins!
Player 1: rock
Player 2: rock
Tie!
Player 1: rock
Player 2: paper
Player 2 wins!
Player 1: rock
Player 2: rock
Tie!
Player 1: paper
Player 2: rock
Player 1 wins!
Player 1: rock
Player 2: paper
Player 2 wins!
Playe
原文地址: https://www.cveoy.top/t/topic/eA3Y 著作权归作者所有。请勿转载和采集!