multiple_participants/
multiple_participants.rs1use par::{
2 exchange::{Recv, Send},
3 runtimes::tokio::fork,
4 Dual,
5};
6use std::time::Duration;
7
8#[derive(Debug)]
9enum Move {
10 Up,
11 Down,
12}
13
14enum Outcome {
15 Win,
16 Loss,
17 Draw(Round),
18}
19
20type Round = Send<Move, Recv<Outcome>>;
21type Player = Dual<Round>; #[derive(Debug)]
24enum Winner {
25 First,
26 Second,
27 Third,
28}
29
30type Game = Send<(Player, Player, Player), Recv<Winner>>;
31
32fn start_playing() -> Game {
33 use {Move::*, Outcome::*, Winner::*};
34
35 fork(|game: Dual<Game>| async {
36 let ((mut player1, mut player2, mut player3), winner) = game.recv().await;
37
38 loop {
39 let (move1, outcome1) = player1.recv().await;
40 let (move2, outcome2) = player2.recv().await;
41 let (move3, outcome3) = player3.recv().await;
42
43 tokio::time::sleep(Duration::from_secs(1)).await;
44 println!("{:?} {:?} {:?}", move1, move2, move3);
45 tokio::time::sleep(Duration::from_secs(1)).await;
46
47 match (move1, move2, move3) {
48 (Up, Down, Down) | (Down, Up, Up) => {
49 outcome1.send1(Win);
50 outcome2.send1(Loss);
51 outcome3.send1(Loss);
52 break winner.send1(First);
53 }
54 (Down, Up, Down) | (Up, Down, Up) => {
55 outcome1.send1(Loss);
56 outcome2.send1(Win);
57 outcome3.send1(Loss);
58 break winner.send1(Second);
59 }
60 (Down, Down, Up) | (Up, Up, Down) => {
61 outcome1.send1(Loss);
62 outcome2.send1(Loss);
63 outcome3.send1(Win);
64 break winner.send1(Third);
65 }
66 (Up, Up, Up) | (Down, Down, Down) => {
67 player1 = outcome1.choose(Draw);
68 player2 = outcome2.choose(Draw);
69 player3 = outcome3.choose(Draw);
70 println!("Draw...");
71 }
72 }
73 }
74 })
75}
76
77fn random_player() -> Player {
78 fork(|mut round: Round| async move {
79 while let Outcome::Draw(next_round) = round.send(random_move()).recv1().await {
80 round = next_round;
81 }
82 })
83}
84
85fn random_move() -> Move {
86 if fastrand::bool() {
87 Move::Up
88 } else {
89 Move::Down
90 }
91}
92
93#[tokio::main]
94async fn main() {
95 for _ in 0..10 {
96 let winner = start_playing()
97 .send((random_player(), random_player(), random_player()))
98 .recv1()
99 .await;
100 println!("{:?}!\n", winner);
101 }
102}