在基于 Linux 的系统中使用 C 创建具有 2 名球员和裁判(进程)的 "game"

Creating a "game" with 2 players and referee (processes) using C in Linux based system

我现在正在尝试为基于 Linux 的系统创建一个游戏,其中包含三个进程:

  1. 裁判-主流程
  2. Blue Player - 第一个子进程
  3. 红色玩家 - 第二个子进程

当然这两个子进程是使用fork()函数创建的

现在一切都已创建,我正在使用共享内存来存储板和三个进程共有的更多变量。

我的问题是,当我试图考虑如何实现回合制游戏时 - 我创建了一个通用布尔变量,用于指示游戏是仍在进行还是已完成,并决定轮到谁是吗

现在我们进入共享部分,我暂停了两个子进程并向第一个子进程发送了一个信号到 "wake him up",但是从现在开始我如何将所有三个进程保持在一起并且同步(裁判唤醒第一个进程,它完成转弯并暂停,比裁判唤醒第二个,依此类推...)

我想我必须将那部分保留在某种 while(game_finished == FALSE) 循环中,但从那里我被卡住了。

我如何按照我刚才解释的方式实现该游戏?谢谢

由于您想使用单独的进程,实现您想要的目标的一种方法是使用障碍。您已经有一个 "controller" 过程,并且玩家有一个简单的状态行为(等待一回合,玩一回合)。控制器进程(你称之为裁判)可以向子进程发送游戏状态信号,并在障碍处同步所有内容。

下面是一个简化版本的伪代码:

// Controller
while (game_running) {
    barrier 1
    // wait for player1
    barrier 2
    // wait for player2
}

// Player 1
while (game_running) {
    barrier 1 // Sinchronize with controller
    // do stuff
    barrier 2
}

// Player2
while (game_running) {
    barrier 1 // Wait for player1
    barrier 2
    // do stuff  
}

可能需要一些额外的障碍来允许控制器处理来自玩家的数据然后同步玩家,但这是控制多个玩家的基本机制。

有关 linux API 提供的屏障功能的更多详细信息,请查看此 link:http://pubs.opengroup.org/onlinepubs/009695399/functions/pthread_barrier_wait.html

有多种选择,但忙等待是最糟糕的选择之一。您可以考虑基于共享信号量构建的解决方案,但我会选择基于管道的解决方案。一个进程将阻止对当前没有可用数据的打开文件描述符执行读取,因此这是一种使各个进程相互等待以轮流进行的简单方法。

只需在裁判进程和每个玩家进程之间的各个方向创建管道即可。在每一轮,每个玩家进程都会尝试从裁判读取一个字节。直到裁判在管道的末端写了一些东西,它才会继续。作为奖励,写入的字节可以传送额外的数据/指令,例如,区分 "make a play" 和 "game over"。当然,同样的同步也适用于另一个方向。

我有 2 人游戏代码。这是使用管道实现的。希望这对你有用。

int main(int argc, char *argv[]){
int fd1[2], fd2[2], fd3[2], fd4[2];
char turn='T';
printf("This is a 2-player game with a referee\n");
pipe(fd1);
pipe(fd2);
if(!fork())
player("TOTO", fd1, fd2);
close(fd1[0]); // parent only write to pipe 1
close(fd2[1]); // parent only reads from pipe 2
pipe(fd3);
pipe(fd4);
if(!fork())
player("TITI", fd3, fd4);
close(fd3[0]); // parent only write to pipe 3
close(fd4[1]); // parent only reads from pipe 4
while(1){
printf("\nReferee: TOTO plays\n\n");
write(fd1[1], &turn, 1);
read(fd2[0], &turn, 1);
printf("\nReferee: TITI plays\n\n");
write(fd3[1], &turn, 1);
read(fd4[0], &turn, 1);
}
}

void player(char *s, int *fd1, int *fd2){
int points=0;
int dice;
long int ss=0;
char turn;
while(1){
read(fd1[0], &turn, 1);
printf("%s: playing my dice\n", s);
dice =(int) time(&ss)%10 + 1;
printf("%s: got %d points\n", s, dice);
points+=dice;
printf("%s: Total so far %d\n\n", s, points);
if(points >= 50){
printf("%s: game over I won\n", s);
kill(0, SIGTERM);
}
sleep(5); // to slow down the execution
write(fd2[1], &turn, 1);
}
}