MyToy No.2: Odd Person Wins

该博客用Java实现三人猜硬币游戏。定义Person类继承Thread,每个线程有PipedWriter和PipedReader用于通信。各线程用随机数模拟抛硬币,比较结果判断输赢,记录获胜次数。所有回合结束后,线程将结果发给主线程,主线程统计获胜和平局数目。

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

/*
 * Created on 2004-11-22
 */

/**
 * @author TinyPandaBear
 *
 * Suppose you have three people and need a fair way to pick one of the three to
 * win some prize or do some task. A common method is for each of them to flip a
 * coin. If one coin comes up differently than the other two, that person wins.
 * We can make a game out of this by repeating the contest a number of times and
 * seeing who wins the most times.
 */

import java.util.*;
import java.io.*;

class Person extends Thread {
    private static Random rand = new Random();
   
    private PipedWriter[] out;
    private PipedReader[] in;

    // give every thread a unique ID, for toString()
    private static int counter = 0;
    private int number = counter++;

    private int NumOfGames;
    private int mywin = 0;

    public Person() {/*default constructor*/}

    public Person(int nog) {
        NumOfGames = nog;
       
        // two for other players, one for main() thread
        out = new PipedWriter[3];
        for (int i = 0; i < 3; i++)
            out[i] = new PipedWriter();
    }

    public void setPipedReaderArray(Person[] p) throws IOException {
        in = new PipedReader[2];
        in[0] = new PipedReader(p[(number + 1) % 3].getPipedWriter(0));
        in[1] = new PipedReader(p[(number + 2) % 3].getPipedWriter(1));
    }

    public PipedWriter getPipedWriter(int index) {
        return out[index];
    }

    public void run() {
        for (int i = 0; i < NumOfGames; i++) {
            try {
                int coin = rand.nextInt(2);
                out[0].write(coin);
                out[1].write(coin);
                int diff = 0;
                for (int j = 0; j < 2; j++) {
                    int other = (int) in[j].read();
                    if (coin != other)
                        diff++;
                }
                if (diff == 2) {
                    mywin++;
                    System.out.println("round " + i + " finished, " + this
                            + "won.");
                }
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }

        try {
            // report the results to main()
            out[2].write(mywin);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    public String toString() {
        return "Person " + number + " ";
    }
}

public class OddPersonWins {
    static PipedReader[] readchannel = new PipedReader[3];

    static Person[] p = new Person[3];

    public static void main(String[] args) throws IOException {
        // if use args[0] here, OutOfBoundException should be handled.
        int rounds = 100;//Integer.parseInt(args[0]);
        for (int i = 0; i < 3; i++) {
            p[i] = new Person(rounds);
            readchannel[i] = new PipedReader(p[i].getPipedWriter(2));
        }
        // set PipedReader should be after array has been initialized.
        for (int i = 0; i < 3; i++)
            p[i].setPipedReaderArray(p);
        // threads should start after initialization finished.
        for (int i = 0; i < 3; i++)
            p[i].start();
        // wait until all threads finished running.
        for (int i = 0; i < 3; i++)
            try {
                p[i].join();
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        System.out.println("Total Games: " + rounds);
        for (int i = 0; i < 3; i++) {
            int won = (int) readchannel[i].read();
            System.out.println("Player " + i + " won: " + won);
            rounds -= won;
        }
        System.out.println("Total ties: " + rounds);
    }
}

问题描述见源代码。

每个线程有5个pipe,两个read,三个writer,reader和writer相对应,多出来的writer用于和main()互交,在游戏完成时把自己的状态发给主线程用于统计信息。

每个回合各线程用rand.nextInt(2)生成一个或0或1的随机数,然后发给另外两个线程,然后从pipe里读另外两个线程发过来的结果,一一和自己的结果比较,如果都不同,那么就是自己赢,在mywin上加一,反之则什么都不作。当所有的回合都结束时,把mywin发给主线程,主线程收到三个线程分别发过来的mywin后,和总回合数相减,得到平局的数目。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值