写C程序,使用Linux中的IPC机制,与人机完成 “石头、剪子、布”的游戏。完整代码
时间: 2024-11-22 15:41:21 浏览: 24
Linux下的石头剪刀布游戏
3星 · 编辑精心推荐
在Linux下编写一个C程序,结合IPC(Inter-Process Communication,进程间通信)机制,比如使用共享内存和消息队列,实现一个简单的“石头、剪子、布”游戏的人机对战。以下是一个基本的框架,包括必要的头文件、主函数以及关键的部分——创建共享内存区域和消息队列,以及用户输入和游戏逻辑:
```c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/msg.h>
#include <semaphore.h>
#define SHM_KEY 12345
#define MSG_KEY 67890
typedef enum { ROCK, PAPER, SCISSORS } Move;
// 定义共享内存结构体
typedef struct {
Move player_choice; // 玩家选择
Move ai_choice; // AI选择
} SharedMemoryData;
// 创建共享内存
SharedMemoryData* shared_memory = NULL;
sem_t init_sem; // 初始化信号量
void create_shared_memory() {
int shm_key = ftok("/tmp", 'S');
shared_memory = shmat(shm_key, NULL, 0);
if (shared_memory == (char*)-1) {
perror("shmat");
exit(1);
}
sem_init(&init_sem, 0, 1);
}
// 发送消息到消息队列
void send_message(Move move) {
struct msgbuf msg;
msg.buf = (char*)&move;
msg.len = sizeof(move);
msg.type = 0;
if (msgsnd(MSG_KEY, &msg, msg.len, 0) == -1) {
perror("msgsnd");
}
}
// 从消息队列接收AI的选择
Move receive_ai_choice() {
struct msgbuf msg;
ssize_t len = msgrcv(MSG_KEY, &msg, sizeof(Move), 0, 0);
if (len == sizeof(Move)) {
return (Move)msg.buf;
} else {
perror("msgrcv");
return ROCK; // 返回默认AI动作
}
}
int compare_moves(Move player, Move ai) {
switch (player) {
case ROCK:
return ai == PAPER ? 1 : (ai == SCISSORS ? -1 : 0);
case PAPER:
return ai == SCISSORS ? 1 : (ai == ROCK ? -1 : 0);
case SCISSORS:
return ai == ROCK ? 1 : (ai == PAPER ? -1 : 0);
default:
return 0;
}
}
int main(int argc, char *argv[]) {
atexit(shmdt(&shared_memory)); // 销毁共享内存
create_shared_memory();
sem_wait(&init_sem); // 等待其他进程初始化
int user_choice;
while (true) {
printf("Your choice (rock/paper/scissors): ");
scanf("%d", &user_choice);
user_choice = (user_choice - 1) % 3; // 转换为枚举值
// AI做出选择
Move ai_choice = receive_ai_choice();
// 判断胜负
int result = compare_moves(user_choice, ai_choice);
if (result > 0) {
printf("You lose! AI chose %s.\n", move_name[ai_choice]);
} else if (result < 0) {
printf("You win! You chose %s.\n", move_name[user_choice]);
} else {
printf("Tie! Both chose %s.\n", move_name[user_choice]);
}
// 更新共享内存
shared_memory->player_choice = user_choice;
shared_memory->ai_choice = ai_choice;
}
return 0;
}
```
注意:这里假设了`move_name[]`是一个字符串数组,用于表示每个移动的名称。此外,为了保证游戏顺序,你需要确保只有当两个进程都准备好后才能开始游戏,这需要额外的同步机制,例如使用互斥锁或信号量。
阅读全文