package tian;
import java.net.*;
import java.io.*;
import java.util.*;
public class OmokServer {
private ServerSocket server;
private BManager bMan = new BManager();//消息广播者
private Random rnd = new Random();//随机确定黑棋或者白棋
public OmokServer() {
}
void startServer() {//启动服务器
try {
server = new ServerSocket(7777);
while (true) {
//获取与客户端的连接
Socket socket = server.accept();
//创建并启动总线程
Omok_Thread ot = new Omok_Thread(socket);
ot.start();
//向bMan添加线程
bMan.add(ot);
System.out.println("连接数: " + bMan.size());
}
} catch (Exception e) {
System.out.println(e);
}
}
//负责与客户机通信的线程类
class Omok_Thread extends Thread {
private int roomNumber = -1;
private String userName = null;//用户类
private Socket socket;
//游戏是否准备就绪
private boolean ready = false;
private BufferedReader reader;
private PrintWriter writer;
Omok_Thread(Socket socket) {
this.socket = socket;
}
Socket getSocket() {
return socket;
}
int getRoomNumber() {
return roomNumber;
}
String getUserName() {
return userName;
}
boolean isReady() {
return ready;
}
public void run() {
try {
reader = new BufferedReader(new InputStreamReader(socket
.getInputStream()));
writer = new PrintWriter(socket.getOutputStream(), true);
String msg;
while ((msg = reader.readLine()) != null) {
if (msg.startsWith("[NAME]")) {
userName = msg.substring(6);
} else if (msg.startsWith("[ROOM]")) {
int roomNum = Integer.parseInt(msg.substring(6));
if (!bMan.isFull(roomNum)) {
if (roomNumber != -1)
bMan.sendToOthers(this, "[EXIT]" + userName);
roomNumber = roomNum;
writer.println(msg);
writer.println(bMan.getNamesInRoom(roomNumber));
bMan.sendToOthers(this, "[ENTER]" + userName);
} else
writer.println("[FULL]");
} else if (roomNumber >= 1 && msg.startsWith("[STONE]"))
bMan.sendToOthers(this, msg);
else if (msg.startsWith("[MSG]"))
bMan.sendToRoom(roomNumber, "[" + userName + "]: "
+ msg.substring(5));
else if (msg.startsWith("[START]")) {
ready = true;
if (bMan.isReady(roomNumber)) {
int a = rnd.nextInt(2);
if (a == 0) {
writer.println("[COLOR]BLACK");
bMan.sendToOthers(this, "[COLOR]WHITE");
} else {
writer.println("[COLOR]WHITE");
bMan.sendToOthers(this, "[COLOR]BLACK");
}
}
} else if (msg.startsWith("[STOPGAME]"))
ready = false;
else if (msg.startsWith("[DROPGAME]")) {
ready = false;
bMan.sendToOthers(this, "[DROPGAME]");
} else if (msg.startsWith("[WIN]")) {
ready = false;
writer.println("[WIN]");
bMan.sendToOthers(this, "[LOSE]");
}
}
} catch (Exception e) {
} finally {//用户断线
try {
bMan.remove(this);
if (reader != null)
reader.close();
if (writer != null)
writer.close();
if (socket != null)
socket.close();
reader = null;
writer = null;
socket = null;
System.out.println(userName + "已断线.");
System.out.println("连接人数: " + bMan.size());
bMan.sendToRoom(roomNumber, "[DISCONNECT]" + userName);
} catch (Exception e) {
}
}
}
}
class BManager extends Vector {
BManager() {}
void add(Omok_Thread ot) {
super.add(ot);
}
void remove(Omok_Thread ot) {
super.remove(ot);
}
Omok_Thread getOT(int i) {
return (Omok_Thread) elementAt(i);
}
Socket getSocket(int i) {
return getOT(i).getSocket();
}
void sendTo(int i, String msg) {
try {
PrintWriter pw = new PrintWriter(
getSocket(i).getOutputStream(), true);
pw.println(msg);
} catch (Exception e) {
}
}
int getRoomNumber(int i) {
return getOT(i).getRoomNumber();
}
synchronized boolean isFull(int roomNum) {
if (roomNum == 0)
return false;
int count = 0;
for (int i = 0; i < size(); i++)
if (roomNum == getRoomNumber(i))
count++;
if (count >= 2)
return true;
return false;
}
void sendToRoom(int roomNum, String msg) {
for (int i = 0; i < size(); i++)
if (roomNum == getRoomNumber(i))
sendTo(i, msg);
}
void sendToOthers(Omok_Thread ot, String msg) {
for (int i = 0; i < size(); i++)
if (getRoomNumber(i) == ot.getRoomNumber() && getOT(i) != ot)
sendTo(i, msg);
}
synchronized boolean isReady(int roomNum) {
int count = 0;
for (int i = 0; i < size(); i++)
if (roomNum == getRoomNumber(i) && getOT(i).isReady())
count++;
if (count == 2)
return true;
return false;
}
String getNamesInRoom(int roomNum) {
StringBuffer sb = new StringBuffer("[PLAYERS]");
for (int i = 0; i < size(); i++)
if (roomNum == getRoomNumber(i))
sb.append(getOT(i).getUserName() + ""t");
return sb.toString();
}
}
//调用
public static void main(String[] args) {
OmokServer server = new OmokServer();
server.startServer();
}
}
package tian;
import java.awt.*;
import java.net.*;
import java.io.*;
import java.util.*;
import java.awt.event.*;
import java.awt.geom.*;
class OmokBoard extends Canvas {
public static final int BLACK = 1, WHITE = -1;
private int[][] map;
private int size, cell;
private String info = "游戏终止";
private int color = BLACK;
private boolean enable = false;
private boolean running = false;
private PrintWriter writer;
private Graphics gboard, gbuff;
private Image buff;
OmokBoard(int s, int c) {
this.size = s;
this.cell = c;
map = new int[size + 2][];
for (int i = 0; i < map.length; i++)
map[i] = new int[size + 2];
setBackground(new Color(200, 200, 100));
setSize(size * (cell + 1) + size, size * (cell + 1) + size);
addMouseListener(new MouseAdapter() {
public void mousePressed(MouseEvent me) {
if (!enable)
return;
int x = (int) Math.round(me.getX() / (double) cell);
int y = (int) Math.round(me.getY() / (double) cell);
if (x == 0 || y == 0 || x == size + 1 || y == size + 1)
return;
if (map[x][y] == BLACK || map[x][y] == WHITE)
return;
writer.println("[STONE]" + x + " " + y);
map[x][y] = color;
if (check(new Point(x, y), color)) {
info = "获胜.";
writer.println("[WIN]");
} else
info = "等待对方落子.";
repaint();
enable = false;
}
});
}
public boolean isRunning() {
return running;
}
public void startGame(String col) {
running = true;
if (col.equals("BLACK")) {
enable = true;
color = BLACK;
info = "开始游戏... 请落子";
} else {
enable = false;
color = WHITE;
info = "开始游戏... 请等待.";
}
}
public void stopGame() {
reset();
writer.println("[STOPGAME]");
enable = false;
running = false;
}
public void putOpponent(int x, int y) {
map[x][y] = -color;
info = "对方已落子 请落子.";
repaint();
}
public void setEnable(boolean enable) {
this.enable = enable;
}
public void setWriter(PrintWriter writer) {
this.writer = writer;
}
public void update(Graphics g) {
paint(g);
}
public void paint(Graphics g) {
if (gbuff == null) {
buff = createImage(getWidth(), getHeight());
gbuff = buff.getGraphics();
}
drawBoard(g);
}
public void reset() {
for (int i = 0; i < map.length; i++)
for (int j = 0; j < map[i].length; j++)
map[i][j] = 0;
info = "游戏终止";
repaint();
}
private void drawLine() {
gbuff.setColor(Color.black);
for (int i = 1; i <= size; i++) {
gbuff.drawLine(cell, i * cell, cell * size, i * cell);
gbuff.drawLine(i * cell, cell, i * cell, cell * size);
}
}
private void drawBlack(int x, int y) {
Graphics2D gbuff = (Graphics2D) this.gbuff;
gbuff.setColor(Color.black);
gbuff.fillOval(x * cell - cell / 2, y * cell - cell / 2, cell, cell);
gbuff.setColor(Color.white);
gbuff.drawOval(x * cell - cell / 2, y * cell - cell / 2, cell, cell);
}
private void drawWhite(int x, int y) {
gbuff.setColor(Color.white);
gbuff.fillOval(x * cell - cell / 2, y * cell - cell / 2, cell, cell);
gbuff.setColor(Color.black);
gbuff.drawOval(x * cell - cell / 2, y * cell - cell / 2, cell, cell);
}
private void drawStones() {
for (int x = 1; x <= size; x++)
for (int y = 1; y <= size; y++) {
if (map[x][y] == BLACK)
drawBlack(x, y);
else if (map[x][y] == WHITE)
drawWhite(x, y);
}
}
synchronized private void drawBoard(Graphics g) {
gbuff.clearRect(0, 0, getWidth(), getHeight());
drawLine();
drawStones();
gbuff.setColor(Color.red);
gbuff.drawString(info, 20, 15);
g.drawImage(buff, 0, 0, this);
}
private boolean check(Point p, int col) {
if (count(p, 1, 0, col) + count(p, -1, 0, col) == 4)
return true;
if (count(p, 0, 1, col) + count(p, 0, -1, col) == 4)
return true;
if (count(p, -1, -1, col) + count(p, 1, 1, col) == 4)
return true;
if (count(p, 1, -1, col) + count(p, -1, 1, col) == 4)
return true;
return false;
}
private int count(Point p, int dx, int dy, int col) {
int i = 0;
for (; map[p.x + (i + 1) * dx][p.y + (i + 1) * dy] == col; i++)
;
return i;
}
}
public class OmokClient extends Frame implements Runnable, ActionListener {
private TextArea msgView = new TextArea("", 1, 1, 1);
private TextField sendBox = new TextField("");
private TextField nameBox = new TextField();
private TextField roomBox = new TextField("0");
private Label pInfo = new Label("待机室:名");
private java.awt.List pList = new java.awt.List();
private Button startButton = new Button("开始对决");
private Button stopButton = new Button("弃权");
private Button enterButton = new Button("入场");
private Button exitButton = new Button("去待机室");
private Label infoView = new Label("< Thinking in java >", 1);
private OmokBoard board = new OmokBoard(15, 30);
private BufferedReader reader;
private PrintWriter writer;
private Socket socket;
private int roomNumber = -1;
private String userName = null;
public OmokClient(String title) {
super(title);
setLayout(null);
msgView.setEditable(false);
infoView.setBounds(10, 30, 480, 30);
infoView.setBackground(new Color(200, 200, 255));
board.setLocation(10, 70);
add(infoView);
add(board);
Panel p = new Panel();
p.setBackground(new Color(200, 255, 255));
p.setLayout(new GridLayout(3, 3));
p.add(new Label("名 字:", 2));
p.add(nameBox);
p.add(new Label("房间号:", 2));
p.add(roomBox);
p.add(enterButton);
p.add(exitButton);
enterButton.setEnabled(false);
p.setBounds(500, 30, 250, 70);
Panel p2 = new Panel();
p2.setBackground(new Color(255, 255, 100));
p2.setLayout(new BorderLayout());
Panel p2_1 = new Panel();
p2_1.add(startButton);
p2_1.add(stopButton);
p2.add(pInfo, "North");
p2.add(pList, "Center");
p2.add(p2_1, "South");
startButton.setEnabled(false);
stopButton.setEnabled(false);
p2.setBounds(500, 110, 250, 180);
Panel p3 = new Panel();
p3.setLayout(new BorderLayout());
p3.add(msgView, "Center");
p3.add(sendBox, "South");
p3.setBounds(500, 300, 250, 250);
add(p);
add(p2);
add(p3);
sendBox.addActionListener(this);
enterButton.addActionListener(this);
exitButton.addActionListener(this);
startButton.addActionListener(this);
stopButton.addActionListener(this);
addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent we) {
System.exit(0);
}
});
}
public void actionPerformed(ActionEvent ae) {
if (ae.getSource() == sendBox) {
String msg = sendBox.getText();
if (msg.length() == 0)
return;
if (msg.length() >= 30)
msg = msg.substring(0, 30);
try {
writer.println("[MSG]" + msg);
sendBox.setText("");
} catch (Exception ie) {
}
} else if (ae.getSource() == enterButton) {
try {
if (Integer.parseInt(roomBox.getText()) < 1) {
infoView.setText("房间号 错误. 大于1");
return;
}
writer.println("[ROOM]" + Integer.parseInt(roomBox.getText()));
msgView.setText("");
} catch (Exception ie) {
infoView.setText("输入的事件项错误 .");
}
} else if (ae.getSource() == exitButton) {
try {
goToWaitRoom();
startButton.setEnabled(false);
stopButton.setEnabled(false);
} catch (Exception e) {
}
} else if (ae.getSource() == startButton) {
try {
writer.println("[START]");
infoView.setText("等待对方决定.");
startButton.setEnabled(false);
} catch (Exception e) {
}
} else if (ae.getSource() == stopButton) {
try {
writer.println("[DROPGAME]");
endGame("已弃权.");
} catch (Exception e) {
}
}
}
void goToWaitRoom() {
if (userName == null) {
String name = nameBox.getText().trim();
if (name.length() <= 2 || name.length() > 10) {
infoView.setText("名字错误. 3~10个字");
nameBox.requestFocus();
return;
}
userName = name;
writer.println("[NAME]" + userName);
nameBox.setText(userName);
nameBox.setEditable(false);
}
msgView.setText("");
writer.println("[ROOM]0");
infoView.setText("已进入待机室.");
roomBox.setText("0");
enterButton.setEnabled(true);
exitButton.setEnabled(false);
}
public void run() {
String msg;
try {
while ((msg = reader.readLine()) != null) {
if (msg.startsWith("[STONE]")) {
String temp = msg.substring(7);
int x = Integer.parseInt(temp.substring(0, temp
.indexOf(" ")));
int y = Integer.parseInt(temp
.substring(temp.indexOf(" ") + 1));
board.putOpponent(x, y);
board.setEnable(true);
} else if (msg.startsWith("[ROOM]")) {
if (!msg.equals("[ROOM]0")) {
enterButton.setEnabled(false);
exitButton.setEnabled(true);
infoView.setText(msg.substring(6) + "号 房间已被进入.");
} else
infoView.setText("已进入待机室.");
roomNumber = Integer.parseInt(msg.substring(6));
if (board.isRunning()) {
board.stopGame();
}
} else if (msg.startsWith("[FULL]")) {
infoView.setText("房间满员 禁止入内.");
} else if (msg.startsWith("[PLAYERS]")) {
nameList(msg.substring(9));
} else if (msg.startsWith("[ENTER]")) {
pList.add(msg.substring(7));
playersInfo();
msgView.append("[" + msg.substring(7) + "]入场."n");
} else if (msg.startsWith("[EXIT]")) {
pList.remove(msg.substring(6));
playersInfo();
msgView.append("[" + msg.substring(6)
+ "]进入其他房间."n");
if (roomNumber != 0)
endGame("对方离开.");
} else if (msg.startsWith("[DISCONNECT]")) {
pList.remove(msg.substring(12));
playersInfo();
msgView
.append("[" + msg.substring(12)
+ "]中断连接."n");
if (roomNumber != 0)
endGame("对方离开.");
} else if (msg.startsWith("[COLOR]")) {
String color = msg.substring(7);
board.startGame(color);
if (color.equals("BLACK"))
infoView.setText("得到黑子.");
else
infoView.setText("得到白子.");
stopButton.setEnabled(true);
} else if (msg.startsWith("[DROPGAME]"))
endGame("对方弃权.");
else if (msg.startsWith("[WIN]"))
endGame("获胜.");
else if (msg.startsWith("[LOSE]"))
endGame("失败.");
else
msgView.append(msg + ""n");
}
} catch (IOException ie) {
msgView.append(ie + ""n");
}
msgView.append("连接中断.");
}
private void endGame(String msg) {
infoView.setText(msg);
startButton.setEnabled(false);
stopButton.setEnabled(false);
try {
Thread.sleep(2000);
} catch (Exception e) {
}
if (board.isRunning())
board.stopGame();
if (pList.getItemCount() == 2)
startButton.setEnabled(true);
}
private void playersInfo() {
int count = pList.getItemCount();
if (roomNumber == 0)
pInfo.setText("待机室: " + count + "名");
else
pInfo.setText(roomNumber + " 号房: " + count + "名");
if (count == 2 && roomNumber != 0)
startButton.setEnabled(true);
else
startButton.setEnabled(false);
}
private void nameList(String msg) {
pList.removeAll();
StringTokenizer st = new StringTokenizer(msg, ""t");
while (st.hasMoreElements())
pList.add(st.nextToken());
playersInfo();
}
private void connect(String ip , int port) {
try {
msgView.append("请求连接服务器."n");
socket = new Socket(ip, port);
msgView.append("---连接成功--."n");
msgView.append("请输入大名 然后进入待机室."n");
reader = new BufferedReader(new InputStreamReader(socket
.getInputStream()));
writer = new PrintWriter(socket.getOutputStream(), true);
new Thread(this).start();
board.setWriter(writer);
} catch (Exception e) {
msgView.append(e + ""n"n连接失败.."n");
}
}
public static void main(String[] args) {
String ip = "127.0.0.1";
int port = 7777;
OmokClient client = new OmokClient("");
client.setSize(760, 560);
client.setVisible(true);
client.connect(ip,port);
}
}
作者:[韩]徐明浩