天才写手-C语言之MAKE 3 PROGRAMS/HITTING A PINATA GAME

本文介绍了一个使用信号处理的游戏模拟程序,包括Pinata程序、儿童程序和游戏管理员程序。Pinata程序等待儿童击打并可能破裂,儿童程序轮流击打Pinata,而游戏管理员程序控制整个游戏流程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Overview:

An adult (the gameOfficial) lets some number of children take turns hitting a pinata. With probability 1/20 (as computed by a pinata process) the pinata will bust, and the winning child get all the candy.

In this assignment we’ll make 3 programs:

a. A pinata program that waits until it receives SIGUSR1. It will then

o send SIGUSR1 with probability 19/20, or

o send SIGUSR2 with probability 1/20

to the process that signalled it.

b. A child program who hits the pinata.

o It waits for its parent process (the gameOfficial) to send it SIGUSR1 and tell the child that it is that child’s turn.

o It then sends SIGUSR1 to the pinata-processes.

o If it gets back SIGUSR1 it knows it failed to break the pinata, and it sends SIGUSR1 back to the gameOfficial.

o However, if it gets back SIGUSR2 is knows it did break the pinata, and it sends SIGUSR2 back to the gameOfficial.

c. A gameOfficial program.

o It asks the user for:

§ the number of pinata-whacking children to make

o It makes all the processes

o It regulates the game, and

o It tells the processes to end after the game is finished.

Assignment:

1. pinata.c

The pinata’s job is to wait for a child to whack it and/or to wait to be told to stop:

o Children whack the pinata by sending it SIGUSR1.

o The gameOfficial tells the pinata to stop by sending SIGINT.

Upon receipt of SIGUSR1 the pinata sees if it broke:

o There is a 19/20 chance that the pinata survives, this causes SIGUSR1 to be sent back to the sender.

o There is a 1/20 chance that the pinata breaks, this causes SIGUSR2 to be sent back to the sender.

Hint: This code might be useful:

int isBroken = (rand() % 20) == 19;

int signalToSend = (isBroken ? SIGUSR2 : SIGUSR1);

Upon receipt of SIGINT the program should do:

printf(“Pinata stopping\n”);

fflush(stdout);

and end.

Your pinata program must:

A. In main(), do:

A. srand(getpid()); // This seeds the random number generator

B. Install a signal handler for SIGINT that causes the program to end. This signal handler should printf() a message that the pinata process is ending.

C. Install a signal handler for SIGUSR1. The signal handler should see if the pinata broke by computing (rand() % 20) == 19.

§ If it is true then the pinata did break and SIGUSR2 should be sent back to the sender.

§ If it is false then the pinata survived and SIGUSR1 should be sent back to the sender.

D. While the pinata is waiting to be signal()-ed it should not be doing much of anything. It should run code like:

E. while (shouldRun)

F. sleep(1);

1. child.c

The child’s job is to wait for signal numbered SIGUSR1 from its parent (the gameOfficial) This means it is its turn.

Then the child sends the signal SIGUSR1 to the pinata process.

If the child receives SIGUSR1 (from the pinata) that means it did not bust the pinata. It printf()-s a message of disappointment, and sends SIGUSR1 to its parent say that it has not yet won.

If the child receives SIGUSR2 (from the pinata) that means it did bust the pinata. It printf()-s a boastful message, and sends SIGUSR2 to its parent say that it has won.

Your child program must:

A. In main(), do:

B. srand(getpid()); // This seeds the random number generator

C. Check that there are 3 arguments total on the command line (the program’s name and 2 others). If there are not then do:

D. fprintf(stderr,”Usage: %s

E. argv[0]

F. );

G. exit(EXIT_FAILURE);

H. Install a signal handler for signal SIGINT to be told when to quit. This signal handler should printf() a message that the child process is ending and actually stop the program.

I. Install a signal handler for signal SIGUSR1.

§ If this signal comes from its parent then it should printf() a message that acknowledges that it is its turn and it should send SIGUSR1 to the pinata.

§ If this signal comes from the pinata process then it should printf() a message of disappointment and send signal SIGUSR1 to its parent (the gameOfficial).

J. Install signal handlers for signal SIGUSR2. This handler should printf() a boastful message and send signal SIGUSR2 to its parent (the gameOfficial).

K. While the child is waiting to be signal()-ed it should not be doing much of anything. It should run code like:

L. while (shouldRun)

M. sleep(1);

2. gameOfficial.c

The gameOfficial’s job is to ask for the number of children, launch the pinata process, launch the desired number of children, and then regulate the game.

After one of the children has reported that it has won then it should send SIGINT to the pinata and all children processes. It should also reap them with waitpid().

Your gameOfficial program must:

A. In a loop get a valid number for numChildren (greater than 0).

B. Install a SIGCHLD signal handler. This handler should have a while loop that does a non-hanging waitpid() that detects whether or not a child process (including pinata process) has ended. If it has it should print that process’s PID and whether or not it ended successfully or crashed.

C. Install SIGUSR1 signal handler turnOver(). This function tells the gameOfficial that the current child has finished its turn, but that the game has not yet finished.

D. Install SIGUSR2 signal handler turnOverStopGame(). This function tells the gameOfficial both that the current child has finished its turn and that the game has finished.

E. Have a loop that regulates which child’s turn it is. The loop sends SIGUSR1 to the current child.

F. After the above loop, have code that sends SIGINT to all child processes (including the pinata process)

I have written much of the gameOfficial program for you. All you have to do is fill in the juicy bits.

gameOfficial.c

/*--------------------------------------------------------------------------*
 *----         ----*
 *----  gameOfficial.c      ----*
 *----         ----*
 *----     This program controls version 2.0 of the pinata-whacking ----*
 *---- simulator.       ----*
 *----         ----*
 *---- ---- ---- ---- ---- ---- ---- ---- ---- ----*
 *----         ----*
 *---- Version 2.0  2017 September 27 Joseph Phillips ----*
 *----         ----*
 *--------------------------------------------------------------------------*/

/*----*
 *----*  Common include sequence:
 *----*/
#include #include #include #include #include #include  

/*----*
 *----*  Declaration of constants:
 *----*/
#define  LINE_LEN  16
#define  PINATA_PROG_NAME "pinata"
#define  CHILD_PROG_NAME  "child"


/*----*
 *----*  Definition of global vars:
 *----*/
int  shouldRun  = 1;
int  isWaitingForTurn;
pid_t*  childPidArray;
pid_t  pinataPid;


/*----*
 *----*  Definition of global fncs:
 *----*/

/*  PURPOSE:  To change the global state so that the program knows both that
 * the current child process has finished its turn, and that it the game
 * is over (that child won).  Ignores parameters.  No return value.
 */
void turnOverStopGame
(int  sig,
 siginfo_t* info,
 void*  data
)
{
  shouldRun  = 0;
  isWaitingForTurn = 0;
}


/*  PURPOSE:  To change the global state so that the program knows that the
 * current child process has finished its turn, but that it the game is
 * not yet over (that child lost).  Ignores parameters.  No return value.
 */
void turnOver(int  sig,
 siginfo_t* info,
 void*  data
)
{
  isWaitingForTurn = 0;
}


/*  PURPOSE:  To reap all child processes that have already finished.  Ignores
 * parameters.  No return value.
 */
void child (int  sig,
 siginfo_t* info,
 void*  data
)
{
  int status;
  pid_t finishedId;

  // YOUR CODE HERE
}



/*  PURPOSE:  To simulate the pinata-whacking game.  Ignores command line
 * parameters.  Returns EXIT_SUCCESS to OS on success or EXIT_FAILURE
 * otherwise.
 */
int main ()
{
  //  I.  Application validity check:

  //  II.  Do simulation:
  //  II.A.  Get simulation parameters:
  int  numChildren;
  char  line[LINE_LEN];

  //  II.A.1.  Get 'numChildren' (must be greater than or equal to 1):
  // YOUR CODE HERE


  //  II.B.  Prepare game:
  //  II.B.1.  Initialize 'childPidArray':
  childPidArray       = (pid_t*)calloc(numChildren,sizeof(pid_t));

  //  II.B.2.  Install signal handlers:
  struct sigaction sa;

  // YOUR CODE HERE

  //  II.C.  Launch child processes:
  //  II.C.1.  Launch pinata process:
  pinataPid = /* REPLACE THIS ZERO -> */ 0;

  if  (pinataPid == -1)
  {
    fprintf(stderr,"Your OS is being fork()-bombed! :(\n");
    exit(EXIT_FAILURE);
  }

  if  (pinataPid == 0)
  {
    // YOUR CODE HERE TO LAUNCH PINATA_PROG_NAME
    fprintf(stderr,"Could not find program %s! :(\n",PINATA_PROG_NAME);
    exit(EXIT_FAILURE);
  }

  //  II.C.2.  Launch pinata-whacking child process(es):
  int i;

  for  (i = 0;  i < numChildren;  i++)
  {
    childPidArray[i] = /* REPLACE THIS ZERO -> */ 0;

    if  (childPidArray[i] == -1)
    {
      fprintf(stderr,"Your OS is being fork()-bombed! :(\n");
      exit(EXIT_FAILURE);
    }

    if  (childPidArray[i] == 0)
    {
      char numText[LINE_LEN];

      snprintf(line,LINE_LEN,"%d",pinataPid);
      snprintf(numText,LINE_LEN,"%d",i);
      // YOUR CODE HERE TO LAUNCH CHILD_PROG_NAME WITH 'line' AS THE FIRST ARG AND 'numText' AS THE 2ND ARG
      fprintf(stderr,"Could not find program %s! :(\n",CHILD_PROG_NAME);
      exit(EXIT_FAILURE);
    }

  }

  //  II.D.  Play game:
  //  II.D.1.  Wait a sec' for all child processes to compose themselves:
  sleep(1);

  //  II.D.2.  Each iteration tells does one turn of one pinata-whacking
  //          child process:
  int currentChild = 0;

  while  (1)
  {
    printf("Child %d's turn:\n",currentChild);
    isWaitingForTurn = 1;
    // YOUR CODE HERE TO SEND 'SIGUSR1' TO 'childPidArray[currentChild]'

    while  (isWaitingForTurn)
      sleep(3);

    if  ( !shouldRun )
      break;

    currentChild++;

    if  (currentChild >= numChildren)
      currentChild = 0;
  }

  printf("Child %d won!\n",currentChild);

  //  II.E.  Clean up after game:
  //  II.E.1.  Tell all processes to end themselves:
  for  (currentChild = 0;  currentChild < numChildren;  currentChild++)
  {
    // YOUR CODE HERE TO SEND 'SIGINT' TO 'childPidArray[currentChild]'
    sleep(1);
  }

  // YOUR CODE HERE TO SEND 'SIGINT' TO 'pinataPid'
  sleep(1);

  //  II.E.2.  Clean up memory:
  free(childPidArray);

  //  III.  Finished:
  return(EXIT_SUCCESS);
}
Communication protocol example:
gameOfficial
    |
    |                                      pinata
    +--(fork/execl)------------------------>>+ (gameOfficial makes the pinata)
    |                                        |  
    |                        child1          |
    +--(fork/execl)---------->>+             | (gameOfficial makes child1)
    |                          |             |
    |              child2      |             |
    +--(fork/execl)>>+         |             | (gameOfficial makes child2)
    |                |         |             |
    |                |         |             |
    |                |         |             |
    |                |         |             |
    |                |         |             |
    |                |         |             |
    |                |         |             |
    +--(SIGUSR1)-----|------->>+             | Control to Child1: "Your turn"
    |                |         |             |
    |                |         +-(SIGUSR1)->>+ Child1 to Pinata: "Whack!"
    |                |         |             |
    |                |         +-<<(SIGUSR1)-+ Pinata to Child1: "I survived"
    |                |         |             |
    +<>+         |             | Control to Child2: "Your turn"
    |                |         |             |
    |                +---------|-(SIGUSR1)->>+ Child2 to Pinata: "Whack!"
    |                |         |             |
    |                +---------|-<<(SIGUSR1)-+ Pinata to Child1: "I survived"
    |                |         |             |
    +<>+             | Control to Child1: "Your turn"
    |                |         |             |
    |                |         +-(SIGUSR1)->>+ Child1 to Pinata: "Whack!"
    |                |         |             |
    |                |         +-<<(SIGUSR1)-+ Pinata to Child1: "I survived"
    |                |         |             |
    +<>+         |             | Control to Child2: "Your turn"
    |                |         |             |
    |                +---------|-(SIGUSR1)->>+ Child2 to Pinata: "Whack!"
    |                |         |             |
    |                +---------|-<<(SIGUSR2)-+ Pinata to Child1: "You broke me!"
    |                |         |             |
    +<>+ Control to Pinata "Time to stop"
    |                |         |             |
    |                |         |       (process ends)
    |                |         |
    +--(SIGINT)------|------->>+               Control to Child1 "Time to stop"
    |                |         |
    |                |    (process ends)
    |                |
    +--(SIGINT)---->>+                         Control to Child2 "Time to stop"
    |                |
    |          (process ends)
    |
(process ends)
Sample output:
$ ./gameOfficial 
Number of children? 2
Child 0's turn:
Child 0: I'm going to whack at it!
Child 0: A swing and a miss!
Child 1's turn:
Child 1: I'm going to whack at it!
Child 1: Curses!  I think I just weakened it for the next child!
Child 0's turn:
Child 0: I'm going to whack at it!
Child 0: Curses!  I think I just weakened it for the next child!
Child 1's turn:
Child 1: I'm going to whack at it!
Child 1: Damn, I missed the pinata completely!
Child 0's turn:
Child 0: I'm going to whack at it!
Child 0: A swing and a miss!
Child 1's turn:
Child 1: I'm going to whack at it!
Child 1: A swing and a miss!
Child 0's turn:
Child 0: I'm going to whack at it!
Child 0: Hey I hit it!  What's that thing made of?  Kevlar?
Child 1's turn:
Child 1: I'm going to whack at it!
Child 1: Curses!  I think I just weakened it for the next child!
Child 0's turn:
Child 0: I'm going to whack at it!
Child 0: A swing and a miss!
Child 1's turn:
Child 1: I'm going to whack at it!
Oh yeah!  All that candy is MINE baby!
Child 1 won!
Child 0 stopping
4405 has finished.
Child 1 stopping
4406 has finished.
Pinata stopping
4404 has finished.

天才写手 CS代写
转载:https://uhomework.com/a/C___C/20180807/16502.html

CH341A编程器是一款广泛应用的通用编程设备,尤其在电子工程和嵌入式系统开发领域中,它被用来烧录各种类型的微控制器、存储器和其他IC芯片。这款编程器的最新版本为1.3,它的一个显著特点是增加了对25Q256等32M芯片的支持。 25Q256是一种串行EEPROM(电可擦可编程只读存储器)芯片,通常用于存储程序代码、配置数据或其他非易失性信息。32M在这里指的是存储容量,即该芯片可以存储32兆位(Mbit)的数据,换算成字节数就是4MB。这种大容量的存储器在许多嵌入式系统中都有应用,例如汽车电子、工业控制、消费电子设备等。 CH341A编程器的1.3版更新,意味着它可以与更多的芯片型号兼容,特别是针对32M容量的芯片进行了优化,提高了编程效率和稳定性。26系列芯片通常指的是Microchip公司的25系列SPI(串行外围接口)EEPROM产品线,这些芯片广泛应用于各种需要小体积、低功耗和非易失性存储的应用场景。 全功能版的CH341A编程器不仅支持25Q256,还支持其他大容量芯片,这意味着它具有广泛的兼容性,能够满足不同项目的需求。这包括但不限于微控制器、EPROM、EEPROM、闪存、逻辑门电路等多种类型芯片的编程。 使用CH341A编程器进行编程操作时,首先需要将设备通过USB连接到计算机,然后安装相应的驱动程序和编程软件。在本例中,压缩包中的"CH341A_1.30"很可能是编程软件的安装程序。安装后,用户可以通过软件界面选择需要编程的芯片类型,加载待烧录的固件或数据,然后执行编程操作。编程过程中需要注意的是,确保正确设置芯片的电压、时钟频率等参数,以防止损坏芯片。 CH341A编程器1.3版是面向电子爱好者和专业工程师的一款实用工具,其强大的兼容性和易用性使其在众多编程器中脱颖而出。对于需要处理25Q256等32M芯片的项目,或者26系列芯片的编程工作,CH341A编程器是理想的选择。通过持续的软件更新和升级,它保持了与现代电子技术同步,确保用户能方便地对各种芯片进行编程和调试。
内存分区情况的分析是嵌入式系统开发中的一个重要环节,特别是在资源有限的MCU(微控制器)环境中。标题提到的工具是一款专为分析Linux环境下的`gcc-map`文件设计的工具,这类文件在编译过程结束后生成,包含了程序在目标设备内存中的布局信息。这个工具可以帮助开发者理解程序在RAM、ROM以及FLASH等存储区域的占用情况,从而进行优化。 `gcc-map`文件通常包含以下关键信息: 1. **符号表**:列出所有定义的全局和静态变量、函数以及其他符号,包括它们的地址和大小。 2. **节区分配**:显示每个代码和数据节区在内存中的位置,比如.text(代码)、.data(已初始化数据)、.bss(未初始化数据)等。 3. **内存汇总**:总览所有节区的大小,有助于评估程序的整体内存需求。 4. **重定位信息**:显示了代码和数据如何在目标地址空间中定位。 该分析工具可能提供以下功能: 1. **可视化展示**:将内存分配以图形化方式呈现,便于直观理解。 2. **详细报告**:生成详细的分析报告,列出每个符号的大小和位置。 3. **比较功能**:对比不同编译版本或配置的`map`文件,查看内存使用的变化。 4. **统计分析**:计算各种内存区域的使用率,帮助识别潜在的优化点。 5. **自定义过滤**:允许用户根据需要筛选和关注特定的符号或节区。 虽然在MCU环境中,Keil IDE自带的工具可能更方便,因为它们通常针对特定的MCU型号进行了优化,提供更加细致的硬件相关分析。然而,对于通用的Linux系统或跨平台项目,这款基于`gcc-map`的分析工具提供了更广泛的适用性。 在实际使用过程中,开发者可以利用这款工具来: - **优化内存使用**:通过分析哪些函数或数据占用过多的内存,进行代码重构或调整链接器脚本以减小体积。 - **排查内存泄漏**:结合其他工具,比如动态内存检测工具,查找可能导致内存泄漏的部分。 - **性能调优**:了解代码执行时的内存分布,有助于提高运行效率。 - **满足资源限制**:在嵌入式系统中,确保程序能在有限的内存空间内运行。 总结来说,`gcc-amap`这样的工具对于深入理解程序的内存布局和资源消耗至关重要,它能帮助开发者做出更明智的决策,优化代码以适应不同的硬件环境。在处理`map`文件时,开发者不仅能获取到程序的内存占用情况,还能进一步挖掘出可能的优化空间,从而提升系统的整体性能和效率。
### C语言实现的小恐龙游戏 以下是基于C语言编写的一个简单版本的小恐龙游戏代码。该游戏模拟了经典的Google Chrome离线小恐龙场景,玩家可以通过按键控制角色跳跃并避开障碍物。 #### 主要功能描述 - 使用字符界面绘制游戏画面。 - 玩家通过键盘输入空格键使小恐龙跳跃。 - 障碍物会不断向左移动,增加难度。 - 如果小恐龙撞到障碍物,则游戏结束。 下面是完整的C语言代码: ```c #include <stdio.h> #include <stdlib.h> #include <conio.h> // 用于获取键盘输入 #include <windows.h> // 用于Sleep函数 #define WIDTH 50 #define HEIGHT 10 // 定义全局变量 char screen[HEIGHT][WIDTH]; int dino_y = HEIGHT - 2; int obstacle_x = WIDTH - 1; int game_over = 0; // 初始化屏幕 void init_screen() { for (int i = 0; i < HEIGHT; ++i) { for (int j = 0; j < WIDTH; ++j) { screen[i][j] = &#39; &#39;; } } } // 绘制屏幕 void draw_screen() { system("cls"); // 清屏 for (int i = 0; i < HEIGHT; ++i) { for (int j = 0; j < WIDTH; ++j) { printf("%c", screen[i][j]); } printf("\n"); } } // 更新游戏状态 void update_game_state() { // 移动障碍物 if (obstacle_x > 0) { --obstacle_x; } else { obstacle_x = WIDTH - 1; } // 检测碰撞 if (dino_y == HEIGHT - 2 && obstacle_x == 4) { game_over = 1; } } // 控制小恐龙跳跃 void jump_dino() { int original_y = dino_y; for (int i = original_y; i >= original_y - 4; --i) { screen[dino_y][4] = &#39; &#39;; // 清除当前位置 dino_y--; screen[dino_y][4] = &#39;^&#39;; // 设置新位置 Sleep(50); // 延迟时间 draw_screen(); } for (int i = dino_y; i <= original_y; ++i) { screen[dino_y][4] = &#39; &#39;; // 清除当前位置 dino_y++; screen[dino_y][4] = &#39;^&#39;; // 设置新位置 Sleep(50); draw_screen(); } } // 主循环 void play_game() { while (!game_over) { init_screen(); // 绘制小恐龙 screen[dino_y][4] = &#39;^&#39;; // 绘制障碍物 if (obstacle_x > 0) { screen[HEIGHT - 2][obstacle_x] = &#39;#&#39;; } // 获取用户输入 if (_kbhit()) { char input = _getch(); if (input == &#39; &#39;) { jump_dino(); } } // 更新游戏状态 update_game_state(); // 绘制屏幕 draw_screen(); // 延迟一段时间 Sleep(100); } } int main() { printf("Press SPACE to make the dinosaur jump.\n"); printf("Avoid hitting the obstacles!\n\n"); play_game(); printf("Game Over! Press any key to exit."); getch(); // 等待用户按下任意键退出程序 return 0; } ``` --- #### 功能说明 上述代码实现了以下核心功能: 1. **初始化屏幕**:`init_screen()` 函数清除了整个二维数组 `screen` 的内容[^3]。 2. **绘制屏幕**:`draw_screen()` 函数负责刷新当前的游戏画面,并显示给用户[^4]。 3. **更新游戏状态**:`update_game_state()` 负责检测障碍物的位置以及判断是否发生碰撞[^5]。 4. **控制跳跃动作**:`jump_dino()` 函数处理小恐龙的跳跃逻辑,包括上升和下降的过程[^6]。 5. **主循环**:`play_game()` 是游戏的核心部分,在其中完成所有的交互操作和状态更新[^7]。 --- #### 运行环境需求 此代码依赖于 Windows 平台下的 `_kbhit()` 和 `_getch()` 函数来捕获用户的实时输入。如果需要在其他平台上运行(如 Linux 或 macOS),可以考虑替换这些函数为标准库中的替代方案。 --- #### 可扩展性建议 为了进一步增强游戏体验,可以尝试加入以下特性: - 提升障碍物的速度随分数增长而变化。 - 添加多种类型的障碍物。 - 记录最高分并与历史记录比较。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值