连接四个多线程设计——作业
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 是 PlayerImpl
和 GameController
- 我认为应该为游戏保留 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"),并通过发送消息进行通信。在您的例子中,您是通过接受方法调用(nextMove
、gameOver
)来做到这一点的。
这里有一些东西可以让你的代码更接近于 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)。
我正在尝试制作一个连接四场比赛的总结。
该程序应该有三个线程 - 玩家 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 是 PlayerImpl
和 GameController
- 我认为应该为游戏保留 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"),并通过发送消息进行通信。在您的例子中,您是通过接受方法调用(nextMove
、gameOver
)来做到这一点的。
这里有一些东西可以让你的代码更接近于 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)。