连接四个多线程设计——作业

Connect four multithread design - Homework

我正在尝试制作一个连接四场比赛的总结。

该程序应该有三个线程 - 玩家 1、玩家 2 和游戏 controller.The 游戏控制器线程负责将控制权从一个玩家转移到另一个玩家,必须监控线程是否超过 5第二个执行,检查是否有赢家等等。

播放器 classes 必须实现的接口是:

public interface Player extends Runnable { 
   public int nextMove(int otherPlayerLastMove); 
   public void gameOver();
}

方法nextMove return 玩家将他的下一个标记放在列的编号,并将对手玩家放置他最后一个标记的列的编号作为参数。

必须从 game controller 线程调用方法 gameOver 以指示游戏结束并释放玩家的所有资源。

我自己实现游戏逻辑没有问题,但我在设计方面遇到了问题。我只是想不出我需要什么 classes 以及它们应该如何交互。明显的 classes 是 PlayerImplGameController - 我认为应该为游戏保留 table (二维字符数组)并实现检查逻辑。或者我是否需要第三个 class 只包含 table 而其他两个可以访问?

基本代码在这里:

public class GameController implements Runnable{

private static char [][] table;

private void initTable(){
    table = new char[6][7];
    for (int i = 0; i < table.length; i++) {
        for (int j = 0; j < table[i].length; j++) {
            table[i][j] = '*';
        }
    }
}

public void printTable(){
    for (int i = 0; i < table.length; i++) {
        for (int j = 0; j < table[i].length; j++) {
            System.out.print(table[i][j] + " ");
        }
        System.out.println();
    }
}

private char checkWinner(){
    //check for horizontal line
    for (int i = 0; i < table.length; i++) {            
        for (int j = 0; j < 4; j++) {
            if ( table[i][j] != '*' && table[i][j+1] != '*' && table[i][j+2] != '*' && table[i][j+3] != '*' && 
                    table[i][j] == table [i][j+1] && table[i][j+1] == table[i][j+2] && table[i][j+2] == table[i][j+3])
                return table[i][j];
        }           
    }
    //check for vertical line
    for (int i = 0; i < 3; i++) {
        for (int j = 0; j < 7; j++) {
            if ( table[i][j] != '*' && table[i+1][j] != '*' && table[i+2][j] != '*' && table[i+3][j] != '*' && 
                    table[i][j] == table [i+1][j] && table[i+1][j] == table[i+2][j] && table[i+2][j] == table[i+3][j])
                return table[i][j];
        }
    }
    // left to right diagonals

    for (int i = 0; i < 3; i++) {
        for (int j = 3; j < 7; j++) {
            if ( table[i][j] != '*' && table[i+1][j-1] != '*' && table[i+2][j-2] != '*' && table[i+3][j-3] != '*' && 
                    table[i][j] == table [i+1][j-1] && table[i+1][j-1] == table[i+2][j-2] && table[i+2][j-2] == table[i+3][j-3])
                return table[i][j];
        }
    }

    // right to left diagonals

    for (int i = 0; i < 2; i++) {
        for (int j = 3; j >=0; j--) {
            if ( table[i][j] != '*' && table[i+1][j+1] != '*' && table[i+2][j+2] != '*' && table[i+3][j+3] != '*' && 
                    table[i][j] == table [i+1][j+1] && table[i+1][j+1] == table[i+2][j+2] && table[i+2][j+2] == table[i+3][j+3])
                return table[i][j];
        }
    }

    return 0;

}

public void addToken(int column, char token){
    for (int i = table.length ; i >= 0 ; i--) {
        if(table[i][column] == '*'){
            table[i][column] = token;
            break;
        }
    }
}

@Override
public void run() {
    // TODO Auto-generated method stub

  }

}

那么你会如何设计这样的问题呢?解释或只是一个 UML 图会很棒。提前致谢:)

你的 Runnable 上有方法这一事实告诉我你有点想要演员模型。

这只是概念上的意思,你有玩家和控制器,都有自己的线程(它们都是 "actors"),并通过发送消息进行通信。在您的例子中,您是通过接受方法调用(nextMovegameOver)来做到这一点的。

这里有一些东西可以让你的代码更接近于 actor 模式。

class User extends Runnable {
    int userId;
    Controller controller;
    Queue<Message> msgQueue;

    void nextMove(int whoMoved, int whatMove){
        msgQueue.offer(new NextMove(whoMoved, whatMove));
    }

    void gameOver(){
        msgQueue.offer(new GameOver());
    }

    run(){
        while(true){
            Message msg = msgQueue.poll();
            if(msg != null){
                // deal with it
                // Maybe send message to controller
                controller.nextMove(new NextMove(userId, 4));
            } else {
                // Do something else, like talking to user
                // sleep to avoid hogging CPU
                Thread.sleep(10);
            }
        }
    }
}

该代码有很多问题(比如它的扩展性非常差,抽象不是很好等等),但我希望它能说明该方法。典型的真实参与者模型实现使用绿色线程来解决可伸缩性问题,并提供标准化的方式来发送和接收消息(例如,参见 Akka、Erlang)。