更多的多任务 java 问题

发布于 2024-08-28 07:27:52 字数 2515 浏览 6 评论 0原文

我的任务是编写一个简单的游戏,模拟两个玩家接连拿起 1-3 场比赛,直到一堆比赛消失。我设法让计算机选择匹配的随机值,但现在我想更进一步,允许人类玩游戏。这是我已经拥有的: http://paste.pocoo.org/show/200660/

Class Player 是计算机玩家,PlayerMan 应该是人类。问题是,PlayerMan 的线程应该等待,直到给出正确的匹配值,但我不能让它以这种方式工作。当我输入值时,它有时会捕获它们并减少匹配数量,但这并不完全是我要做的:)逻辑是:我检查当前玩家的值。如果它对应于当前活动的线程,我使用扫描仪来捕获匹配的数量。否则我等一秒钟(我知道这有点苛刻的解决方案,但我不知道该怎么做)。
共享类保留当前玩家的价值以及比赛数量。

顺便问一下,有什么方法可以使 Player 和 Shared 属性私有而不是公开,并且仍然使代码正常工作?

CONSOLE和INPUT-DIALOG仅用于选择插入值的方式。

class PlayerMan extends Player{

    static final int CONSOLE=0;
    static final int INPUT_DIALOG=1;
    private int input;

    public PlayerMan(String name, Shared data, int c){
    super(name, data);
    input = c;
    }

@Override
    public void run(){
        Scanner scanner = new Scanner(System.in);
        int n = 0;

        System.out.println("Matches on table: "+data.matchesAmount);
        System.out.println("which: "+data.which);
        System.out.println("number: "+number);

        while(data.matchesAmount != 0){
            if(number == data.which){

                System.out.println("Choose amount of matches (from 1 to 3): ");
                n = scanner.nextInt();

                if(data.matchesAmount == 1){
                    System.out.println("There's only 1 match left !");
                    while(n != 1){
                        n = scanner.nextInt();
                    }
                }
                else{
                    do{
                        n = scanner.nextInt();
                    }
                    while(n <= 1 && n >= 3);
                }

                data.matchesAmount = data.matchesAmount - n;
                System.out.println("                          "+
                        name+" takes "+n+" matches.");
                if(number != 0){
                    data.which = 0;
                }
                else{
                    data.which = 1;
                }
            }
            else{
                try {
                    Thread.sleep(1000);
                } catch(InterruptedException exc) {
                    System.out.println("End of thread.");
                    return;
                }
            }
            System.out.println("Matches on table: "+data.matchesAmount);
        }
        if(data.matchesAmount == 0){
            System.out.println("Winner is player: "+name);
            stop();
        }
    }
}

I had a task to write simple game simulating two players picking up 1-3 matches one after another until the pile is gone. I managed to do it for computer choosing random value of matches but now I'd like to go further and allow humans to play the game. Here's what I already have : http://paste.pocoo.org/show/200660/

Class Player is a computer player, and PlayerMan should be human being. Problem is, that thread of PlayerMan should wait until proper value of matches is given but I cannot make it work this way. When I type the values it sometimes catches them and decrease amount of matches but that's not exactly what I was up to :) Logics is : I check the value of current player. If it corresponds to this of the thread currently active I use scanner to catch the amount of matches. Else I wait one second (I know it's kinda harsh solution, but I have no other idea how to do it).
Class Shared keeps the value of current player, and also amount of matches.

By the way, is there any way I can make Player and Shared attributes private instead of public and still make the code work ?

CONSOLE and INPUT-DIALOG is just for choosing way of inserting values.

class PlayerMan extends Player{

    static final int CONSOLE=0;
    static final int INPUT_DIALOG=1;
    private int input;

    public PlayerMan(String name, Shared data, int c){
    super(name, data);
    input = c;
    }

@Override
    public void run(){
        Scanner scanner = new Scanner(System.in);
        int n = 0;

        System.out.println("Matches on table: "+data.matchesAmount);
        System.out.println("which: "+data.which);
        System.out.println("number: "+number);

        while(data.matchesAmount != 0){
            if(number == data.which){

                System.out.println("Choose amount of matches (from 1 to 3): ");
                n = scanner.nextInt();

                if(data.matchesAmount == 1){
                    System.out.println("There's only 1 match left !");
                    while(n != 1){
                        n = scanner.nextInt();
                    }
                }
                else{
                    do{
                        n = scanner.nextInt();
                    }
                    while(n <= 1 && n >= 3);
                }

                data.matchesAmount = data.matchesAmount - n;
                System.out.println("                          "+
                        name+" takes "+n+" matches.");
                if(number != 0){
                    data.which = 0;
                }
                else{
                    data.which = 1;
                }
            }
            else{
                try {
                    Thread.sleep(1000);
                } catch(InterruptedException exc) {
                    System.out.println("End of thread.");
                    return;
                }
            }
            System.out.println("Matches on table: "+data.matchesAmount);
        }
        if(data.matchesAmount == 0){
            System.out.println("Winner is player: "+name);
            stop();
        }
    }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

还在原地等你 2024-09-04 07:27:52

您应该与读取器/写入器锁同步。 编辑:再想一想,也许一个简单的条件就足够了。你可以使用这样的东西:

private Lock playerLock = new ReentrantLock();
private Condition[] playerConditions = { playerLock.newCondition(), playerLock.newCondition() };

// Later on:
while (data.matchesAmount != 0) {
  while (number != data.which) {
    playerConditions[number].await();
  }
  // do work here

  // now release the other player -- this assumes there are only 2
  data.which = 1 - number;
  playerConditions[1 - number].signalAll();
}

这里唯一的问题是,如果 data.which 到达这里时没有正确初始化,你可能会阻塞两个线程等待它们的条件。您应该确保它在启动线程之前已初始化。

You should synchronize with reader/writer locks. EDIT: On a second thought, perhaps a simple condition should be enough. You could use something like this:

private Lock playerLock = new ReentrantLock();
private Condition[] playerConditions = { playerLock.newCondition(), playerLock.newCondition() };

// Later on:
while (data.matchesAmount != 0) {
  while (number != data.which) {
    playerConditions[number].await();
  }
  // do work here

  // now release the other player -- this assumes there are only 2
  data.which = 1 - number;
  playerConditions[1 - number].signalAll();
}

The only problem here is that you may block both threads waiting for their conditions if data.which is not properly initialized when they get here. You should make sure it is initialized before starting their threads.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文