Linux程序开发(十一):进程与进程间通信设计之趣味猫咪抓老鼠游戏

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 运行结果图

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/636681.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Java堆栈分区

Java在内存分配区域&#xff1a;栈区&#xff08;stack&#xff09;、堆区&#xff08;heap&#xff09;、方法区&#xff08;Method Area&#xff09;、常量池。 一、栈区 每个方法&#xff08;Method&#xff09;执行时&#xff0c;都会创建一个方法栈区。用于存储局部变量表…

【FreeRTOS移植到STM32F103C8T6超详细教程-->>>基于标准库】

移植教程 FreeRTOS简介FreeRTOS 介绍FreeRTOS优点 FreeRTOS移植FreeRTOS 下载FreeRTOS目录结构移植开始Keil5打开工程修改FreeRTOSConfig.h文件修改stm32f10x_it.c 测试FreeRTOS闪烁第一颗小灯 FreeRTOS简介 FreeRTOS 介绍 FreeRTOS 是市场领先的面向微控制器和小型微处理器的…

linux 安装chrome浏览器

一、下载安装包 下载地址&#xff1a;https://download.csdn.net/download/k0307x1990y/89349171 二、安装流程 [rootlocalhost ~]# rpm -ivh *.rpm [rootlocalhost ~]# yum -y localinstall google-chrome-stable_current_x86_64.rpm [rootlocalhost ~]# 三、修改配置文件…

Web(数字媒体)期末作业

一.前言 1.本资源为类似于打飞机的网页游戏 2.链接如下&#xff1a;【免费】前端web或者数字媒体的期末作业&#xff08;类似于打飞机的2D网页小游戏&#xff09;资源-CSDN文库 二.介绍文档

不靠后端,前端也能搞定接口!

嘿&#xff0c;前端开发达人们&#xff01;有个超酷的消息要告诉你们&#xff1a;MemFire Cloud来袭啦&#xff01;这个神奇的东东让你们不用依赖后端小伙伴们&#xff0c;也能妥妥地搞定 API 接口。是不是觉得有点不可思议&#xff1f;但是事实就是这样&#xff0c;让我们一起…

跨境电商赛道,云手机到底能不能化繁为简?

当下国内电商背景&#xff1a; 从零售额的数据来看&#xff1a;随着互联网的普及和消费者购物习惯的改变&#xff0c;国内电商市场规模持续扩大。据相关数据显示&#xff0c;网络消费亮点纷呈&#xff0c;一季度全国网上零售额达到了3.3万亿元&#xff0c;同比增长12.4%。这表…

聊一聊抖音小店

大家好&#xff0c;我是喷火龙。 一招鲜&#xff0c;吃遍天&#xff0c;以不变&#xff0c;应万变; 这是上次直播分享结束的时候我做的一个小总结&#xff0c;其实这几个字&#xff0c;也可以作为我们这几年电商经历的一个缩影与概括&#xff0c;也是对我们这群人最真切的一种…

谷粒商城环境准备~下 docker版

10. 配置中心 1&#xff09;修改“gulimall-coupon”模块 添加pom依赖&#xff1a; <dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId> </dependency>创建bootstr…

学习Uni-app开发小程序Day24

这一章节是要将从首页的点击进入子组件&#xff0c;然后展示对应的数据。这里涉及到页面传递参数、将获取的数据渲染到页面上 给组件通过defineProps声明变量传值渲染 因为使用的是子组件&#xff0c;那就需要再父组件中点击后&#xff0c;给子组件传递参数&#xff0c;根据参…

2021年上半年软件设计师上午真题及答案解析

1.在CPU中&#xff0c;用&#xff08; &#xff09;给出将要执行的下一条指令在内存中的地址。 A.程序计数器 B.指令寄存器 C.主存地址寄存器 D.状态条件寄存器 2.以下关于RISC和CISC计算机的叙述中&#xff0c;正确的是&#xff08; &#xff09;。…

iptables防火墙【其二 实验篇】

保存&#xff0c;还原规则 防火墙规则的备份和还原 导出&#xff08;备份&#xff09;所有表的规则 iptables-save > /opt/ipt.txt 导入&#xff08;还原&#xff09;规则 iptables-restore < /opt/ipt.txt 将iptables规则文件保存在 /etc/sysconfig/iptables 中&#xf…

Rust学习心得

我分享一下一年的Rust学习经历&#xff0c;从书到代码都一网打尽。 关于新手如何学习Rust&#xff0c;我之前在Hacker News上看到了这么一篇教程&#xff1a; 这篇教程与其他教程不同的时&#xff0c;他不是一个速成教程&#xff0c;而是通过自己的学习经历&#xff0c;向需要…

常用的框架——— Android UtilCode

AndroidUtilCode是一个功能强大且易于使用的Android库。该库封装了Android开发中经常使用的具备完整演示和单元测试的功能。经过使用其封装的API&#xff0c;能够大大提升开发效率。该程序主要由两个模块组成&#xff0c;utilcode&#xff08;一般在开发中使用&#xff09;和su…

【C语言】实现贪吃蛇--项目实践(超详细)

前言&#xff1a; 贪吃蛇游戏大家都玩过吧&#xff1f;这次我们要用C语言来亲手制作一个&#xff01;这个项目不仅能让我们复习C语言的知识&#xff0c;还能了解游戏是怎么一步步做出来的。我们会一起完成蛇的移动、食物的生成&#xff0c;还有碰撞检测等有趣的部分。准备好了…

LeetCode 79.单词搜索

原题链接&#xff1a;. - 力扣&#xff08;LeetCode&#xff09; 给定一个 m x n 二维字符网格 board 和一个字符串单词 word 。如果 word 存在于网格中&#xff0c;返回 true &#xff1b;否则&#xff0c;返回 false 。 单词必须按照字母顺序&#xff0c;通过相邻的单元格内…

基于51单片机的音乐喷泉

基于51单片机的音乐喷泉 &#xff08;程序&#xff0b;原理图&#xff0b;PCB&#xff0b;设计报告&#xff09; 功能介绍 具体功能&#xff1a; 1.检测音乐信号的声音强度&#xff0c;使喷头的水柱能够根据音乐的节奏和音量起伏&#xff1b; 2.系统将声音强度转化为模拟信…

【云原生】Kubeadm部署k8s

目录 一、部署步骤 二、部署kubernetes 2.1、所有节点关闭防火墙 核心防护 iptables规则 swap交换 2.2、修改主机名并添加主机映射 2.3、调整内核参数 三、安装Docker 3.1、所有节点安装docker 3.2、所有接点添加镜像加速器 3.3、开启docker、并设置开机自启、查看状态…

Visual Studio中MP编译参数

MP通常与OpenMP&#xff08;Open Multi-Processing&#xff09;关联&#xff0c;它是用于多平台共享内存并行编程的一个API。 在编译C或C代码时使用OpenMP&#xff0c;通常需要特定的编译参数来启用这一功能。对于GCC和G编译器&#xff0c;这些参数包括&#xff1a; -fopenmp…

【全开源】Java情侣飞行棋系统微信小程序+H5+微信公众号+APP 源码

情侣飞行棋系统源码&#xff1a;共享欢乐时光的数字新选择 引言 在这个数字化时代&#xff0c;人们越来越追求独特的娱乐方式&#xff0c;与伴侣共度美好时光。情侣飞行棋系统源码应运而生&#xff0c;它不仅仅是一款游戏&#xff0c;更是情侣间增进感情、共享欢乐时光的桥梁…

C++的线程安全队列模板类封装

目录 1 线程安全队列封装一 2 线程安全队列封装二 3 线程安全队列封装三 1 线程安全队列封装一 /*** ** Copyright (c) Huawei Technologies Co., Ltd. 2020-2022. All rights reserved.** Redistribution and use in source and binary forms, with or without* modif…