Tips:"分享是快樂的源泉💧,在我的博客里,不僅有知識的海洋🌊,還有滿滿的正能量加持💪,快來和我一起分享這份快樂吧😊!
喜歡我的博客的話,記得點個紅心??和小關小注哦!您的支持是我創作的動力!數據源
存放在我的資源下載區啦!
Linux程序開發(十一):進程與進程間通信設計之趣味貓咪抓老鼠游戲
目錄
- Linux程序開發(十一):進程與進程間通信設計之趣味貓咪抓老鼠游戲
- 題目:貓咪抓老鼠游戲
- 題目描述:
- 示例輸入:
- 示例輸出:
- 提示:
- 解答:
- 截圖:
題目:貓咪抓老鼠游戲
題目描述:
小明有一只貓咪和幾只老鼠,他想編寫一個Linux下的C程序來實現貓咪捉老鼠的游戲。具體來說,程序中需要啟動兩個進程,一個進程代表貓咪,另一個進程代表老鼠。貓咪和老鼠在一個二維平面上移動,貓咪的初始位置隨機生成,老鼠的初始位置也隨機生成。貓咪和老鼠每次移動時,會隨機選擇上下左右四個方向之一,然后向該方向移動一個單位距離。如果貓咪和老鼠的位置重合,則貓咪抓住老鼠,游戲結束。
請你編寫一個C程序,實現貓咪抓老鼠的游戲。程序需要滿足以下要求:
1、貓咪和老鼠的初始位置、移動速度等參數需要在程序運行時由用戶輸入。
2、程序需要啟動兩個進程,分別代表貓咪和老鼠。
3、進程間需要通過消息隊列進行通信,貓咪和老鼠每次移動后需要將自己的位置信息發送給對方進程。
4、程序需要使用信號量和互斥鎖等機制來實現進程間同步和互斥訪問共享資源(如二維平面上的位置信息)。
5、程序需在貓咪抓住老鼠或一定時間內未能抓住老鼠時結束,并輸出游戲結果。
示例輸入:
請輸入貓咪和老鼠的移動速度:10
請輸入游戲時間(秒):30
示例輸出:
貓咪和老鼠的初始位置為:(3, 5) 和 (7, 9)
游戲結束,貓咪抓住了老鼠!
提示:
可使用Linux系統函數fork()來創建進程。
可使用Linux系統函數msgget()、msgsnd()和msgrcv()來創建和使用消息隊列。
可使用Linux系統函數sem_init()、sem_wait()、sem_post()和sem_destroy()來創建和使用信號量。
可使用Linux系統函數pthread_mutex_init()、pthread_mutex_lock()、pthread_mutex_unlock()和pthread_mutex_destroy()來創建和使用互斥鎖。
解答:
# pthread.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <time.h>
#include <sys/msg.h>
#include <pthread.h>
#include <semaphore.h> // 添加頭文件#define MSG_TYPE_CAT 1
#define MSG_TYPE_MOUSE 2// 定義消息結構體
struct Message {long type;int x;int y;
};// 定義互斥鎖和信號量
pthread_mutex_t mutex;
sem_t sem;// 定義全局變量
int catX, catY, mouseX, mouseY;
int gameResult = 0;void* catThread(void* arg) {key_t* pMsgId = (key_t*)arg; // 修改參數類型為 key_t*struct Message msg;while (!gameResult) {// 貓咪向隨機方向移動pthread_mutex_lock(&mutex);int dx = rand() % 3 - 1;int dy = rand() % 3 - 1;catX += dx;catY += dy;if (catX < 0) catX = 0;if (catX > 20) catX = 20;if (catY < 0) catY = 0;if (catY > 20) catY = 20;pthread_mutex_unlock(&mutex);// 發送貓咪的位置消息給老鼠msg.type = MSG_TYPE_CAT;msg.x = catX;msg.y = catY;msgsnd(*pMsgId, &msg, sizeof(msg), 0); // 使用間接尋址操作獲取 msgId// 等待老鼠的位置消息msgrcv(*pMsgId, &msg, sizeof(msg), MSG_TYPE_MOUSE, 0);// 判斷是否抓住老鼠if (msg.x == catX && msg.y == catY) {gameResult = 1;printf("游戲結束,貓咪抓住了老鼠!\n");}// 等待一段時間usleep(1000000 / *(int*)arg);}return NULL;
}void* mouseThread(void* arg) {key_t* pMsgId = (key_t*)arg; // 修改參數類型為 key_t*struct Message msg;while (!gameResult) {// 老鼠向隨機方向移動pthread_mutex_lock(&mutex);int dx = rand() % 3 - 1;int dy = rand() % 3 - 1;mouseX += dx;mouseY += dy;if (mouseX < 0) mouseX = 0;if (mouseX > 20) mouseX = 20;if (mouseY < 0) mouseY = 0;if (mouseY > 20) mouseY = 20;pthread_mutex_unlock(&mutex);// 發送老鼠的位置消息給貓咪msg.type = MSG_TYPE_MOUSE;msg.x = mouseX;msg.y = mouseY;msgsnd(*pMsgId, &msg, sizeof(msg), 0); // 使用間接尋址操作獲取 msgId// 等待貓咪的位置消息msgrcv(*pMsgId, &msg, sizeof(msg), MSG_TYPE_CAT, 0);// 判斷是否被貓咪抓住if (msg.x == mouseX && msg.y == mouseY) {gameResult = 2;printf("游戲結束,老鼠被貓咪抓住了!\n");}// 等待一段時間usleep(1000000 / *(int*)arg);}return NULL;
}int main() {int speed, gameTime;pid_t pid;key_t msgId;pthread_t catTid, mouseTid;srand(time(NULL));// 獲取輸入參數printf("請輸入貓咪和老鼠的移動速度:");scanf("%d", &speed);printf("請輸入游戲時間(秒):");scanf("%d", &gameTime);// 初始化互斥鎖和信號量pthread_mutex_init(&mutex, NULL);sem_init(&sem, 0, 1);// 隨機生成貓咪和老鼠的初始位置catX = rand() % 21;catY = rand() % 21;mouseX = rand() % 21;mouseY = rand() % 21;// 輸出初始位置printf("貓咪和老鼠的初始位置為:(%d, %d) 和 (%d, %d)\n", catX, catY, mouseX, mouseY);// 創建消息隊列msgId = msgget(IPC_PRIVATE, IPC_CREAT | 0666);if (msgId < 0) {printf("Failed to create message queue!\n");return 1;}// 創建貓咪進程pid = fork();if (pid == 0) {catThread(&msgId); // 修改函數調用,傳遞 msgId 變量的指針return 0;} else if (pid < 0) {printf("Failed to create cat process!\n");return 1;}// 創建老鼠進程pid = fork();if (pid == 0) {mouseThread(&msgId); // 修改函數調用,傳遞 msgId 變量的指針return 0;} else if (pid < 0) {printf("Failed to create mouse process!\n");return 1;}// 等待一段時間sleep(gameTime);// 結束游戲gameResult = 3;// 銷毀互斥鎖和信號量pthread_mutex_destroy(&mutex);sem_destroy(&sem);return 0;
}
截圖:
圖 2.1 運行結果圖