一、项目成员
141461085
龚泽楠
141461012
蔡铧荣
二、项目名称
黄金点小游戏
三、项目简介
游戏规则: N个同学( N通常大于 10 ),每人写一个 0~100 之间的有理数 (不包括 0或100) ,交给裁判算出所有数字的平均值然后乘以 0.618 (所谓黄金分割常数),得到 G值。提交的数字最靠近 G(取绝对值)的同 学得到 N分,离 G最远的同学得到- 2分,其他同学得 0分。
黄金点游戏其实是一个博弈论G值(博弈值,在黄金点游戏中为黄金点;在市场竞标中为标线;在拍卖中为成交额)的数据收集实验,因此该项目为社会公益项目,普遍情况黄金点游戏项目都会将最后数据或实时数据上传至网络公开使用。
这个游戏规定第一名得到全部的分数, 第二名(不管多接近)到倒数第二名都是 0 分,最后一名还要倒扣分。
四、UI设计
为了实现局域网联机功能,项目重新设计了新的UI界面,设计如下:
五、概要设计(局域网通讯部分)
目前设计思路为分为服务器和客户端两个程序,服务器主要负责接收以及整合所有客户端发来的数据,并将这些数据传回客户端。
黄金点的计算以及得分排名的计算等都在客户端本地完成。
服务器只起到分发数据,判断玩家状态的作用。
六、实现代码
目前只实现了部分项目功能。数据传输使用Socket。数据传送形式使用Json传输。
客户端登录连接服务器:
packagegp.Client;importjava.awt.FlowLayout;importjava.awt.event.ActionEvent;importjava.awt.event.ActionListener;importjava.io.IOException;.InetAddress;.UnknownHostException;importjavax.swing.Box;importjavax.swing.JButton;importjavax.swing.JDialog;importjavax.swing.JFrame;importjavax.swing.JLabel;importjavax.swing.JTextField;public classMain {public static void main(String[] args) throwsUnknownHostException {//登录界面设计
Box baseBox, box1 = null, box2 = null;
JFrame LoginUI= newJFrame();
LoginUI.setLayout(newFlowLayout());
LoginUI.setBounds(0, 0, 300, 110);
LoginUI.setLocationRelativeTo(LoginUI.getOwner());
LoginUI.setTitle("黄金点小游戏登录");
LoginUI.setResizable(false);
box1=Box.createVerticalBox();
box1.add(new JLabel("服务器地址"));
box1.add(Box.createVerticalStrut(10));
box1.add(new JLabel("用户姓名"));
box1.add(Box.createVerticalStrut(10));
box2=Box.createVerticalBox();final JTextField textField1 = new JTextField(10);
box2.add(textField1);
box2.add(Box.createVerticalStrut(10));final JTextField textField2 = new JTextField(10);
box2.add(textField2);
box2.add(Box.createVerticalStrut(10));
baseBox=Box.createHorizontalBox();
baseBox.add(box1);
baseBox.add(Box.createHorizontalStrut(10));
baseBox.add(box2);
LoginUI.add(baseBox);
JButton button= new JButton("登陆");
button.setLocation(50, 50);
LoginUI.add(button);
LoginUI.setLocationRelativeTo(LoginUI.getOwner());
LoginUI.setVisible(true);
LoginUI.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//获取本地IP
InetAddress ip =InetAddress.getLocalHost();
String IPs=ip.toString();
String []IP= IPs.split("\\/");//登录按钮点击事件
button.addActionListener(newActionListener() {
@Overridepublic voidactionPerformed(ActionEvent e) {if (isIP(IP[1].trim())) {try{
GoldenPointUI ui= newGoldenPointUI(textField1.getText(), textField2.getText());newThread(ui).start();
LoginUI.setVisible(false);
}catch(IOException e1) {
e1.printStackTrace();
}
}else{
Error.show("IP格式不正确");
}
}
});
}//判断函数,检测IP地址是否出错
public static booleanisIP(String str) {
String[] ss= str.split("\\.");for(String string : ss) {try{int a =Integer.parseInt(string);if (a <= 0 || a > 255)return false;
}catch(Exception e) {return false;
}
}return true;
}
}classError {public static voidshow(String text) {
JDialog dialog= newJDialog();
JLabel label= newJLabel(text);
dialog.add(label);
dialog.setSize(100, 100);
dialog.setLocationRelativeTo(null);
dialog.setModal(true);
dialog.setVisible(true);
dialog.setResizable(true);
}
}
客户机接受服务器信息代码:
@Overridepublic voidrun() {try{
DataInputStream dis= newDataInputStream(socket.getInputStream());
DataOutputStream dos= newDataOutputStream(socket.getOutputStream());
dos.write(player_name.getBytes());while (true) {//repaint();
byte[] b = new byte[3000];
dis.read(b);
String msg= newString(b).trim();
System.out.println("服务端发来:" +msg);
JSONObject json= newJSONObject(msg);int commandType = json.getInt("type");switch(commandType){case 1: //收到确认玩家提交数据 (提示玩家等待其他人提交)
break;case 2: //收到确认所有玩家已经提交数据 (返回黄金点,游戏结果等数据)
break;case 3: //收到玩家姓名,等信息 (设置相关文本)
break;case 4: //收到提交玩家数字的命令 (设置轮数文本,显示提交按钮,提示玩家输入数据)
break;default:
System.out.println("json数据不合法");break;
}
}
}catch(IOException e) {
e.printStackTrace();
}catch(JSONException e) {
e.printStackTrace();
}
}booleanisString(String string) {try{int num =Integer.valueOf(string);return true;
}catch(Exception e){return false;
}
}
客户端发送数据代码:
packagegp.Client;importjava.io.DataOutputStream;importjava.io.IOException;public classToServer {//给服务器端发送消息
public static void sendMsg(String str, DataOutputStream dos) throwsIOException {
System.out.println("发送给服务器:" +str);
dos.write(str.getBytes());
}
}
服务器接受程序代码:
packagegp.Server;import javax.swing.*;importjava.io.DataInputStream;importjava.io.DataOutputStream;.ServerSocket;.Socket;public classMain {public static Player[] players = new Player[4];public static voidmain(String[] args) {try{
Socket[] socket= new Socket[5];
DataOutputStream[] dos= new DataOutputStream[5];
DataInputStream[] dis= new DataInputStream[5];
Thread[] thread= new Thread[5];int x = 1;//等待连接
ServerSocket ss = new ServerSocket(8888);
String[] playernames= new String[5];//接收所有玩家登录信息
while (true) {
socket[x]=ss.accept();
dos[x]= newDataOutputStream(socket[x].getOutputStream());
dis[x]= newDataInputStream(socket[x].getInputStream());
System.out.println(socket[x].getInetAddress().getHostAddress()+ "连接");byte[] b = new byte[1024];
dis[x].read(b);
playernames[x]= newString(b).trim();/*players[x].setName(playernames[x]);
players[x].setPlayNumber(x);
System.out.println(playernames[x]);*/x+= 1;if (x == 5) {
System.out.println(x+ "wwww");break;
}
}
ServerCtrl sc= newServerCtrl(socket, dos, dis);for (int i = 1; i <= 4; i++) {
thread[i]= new Thread(newSocketThread(sc, dis[i]));
}//玩家姓名列表,并发送到各个
String playername= playernames[1] + " " + playernames[2] + " " + playernames[3] + " " + playernames[4];
sc.setPlayer(playername);//发送完毕后开启四个线程接收各个客户端的消息
thread[1].start();
thread[2].start();
thread[3].start();
thread[4].start();
}catch(Exception e) {//TODO: handle exception
}
}
}
服务器接收线程:
packagegp.Server;importjava.io.DataInputStream;importjava.io.IOException;importorg.json.JSONException;importorg.json.JSONObject;public class SocketThread implementsRunnable{privateDataInputStream dis;privateServerCtrl sc;private intbossflag ;publicSocketThread(ServerCtrl sc, DataInputStream dis) {super();this.sc =sc;this.dis =dis;this.bossflag=0;
}
@Overridepublic voidrun() {try{while (true) {byte [] b = new byte[10240];this.dis.read(b);
String clientMsg= new String(b).trim();//来自客户端的命令
JSONObject json = new JSONObject(clientMsg);//转化为json数据格式
System.out.println("服务器收到:"+clientMsg);switch (json.getInt("type")) {case 1://接收提交黄金点信息
receivePoint(json);break;case 2://接收下一局请求信息
break;case 3:break;default:
System.out.println("json数据不合法");break;
}
}
}catch(Exception e) {//TODO: handle exception
}
}//接收提交黄金点信息处理程序
private void receivePoint(JSONObject json) throwsJSONException, IOException {int num = json.getInt("mark");
String point= json.getString("point");
Main.players[num].setPoint(point);for(int i = 1; i < Main.players.length; i++){if(Main.players[i].isSubmitted() && i < 4){continue;
}else if(Main.players[i].isSubmitted() && i == 4){
String result= Main.players[1].getPoint() + " " + Main.players[2].getPoint() + " " + Main.players[3].getPoint() + " " + Main.players[4].getPoint();
sc.sendResult(result);
}else{break;
}
}
}
}
服务器发送程序代码:
packagegp.Server;importjava.io.DataInputStream;importjava.io.DataOutputStream;importjava.io.IOException;.Socket;importjava.util.ArrayList;importjava.util.Collections;importjava.util.List;importorg.json.JSONException;importorg.json.JSONObject;public classServerCtrl {
Socket[] socket= new Socket[5];
DataOutputStream[] dos= new DataOutputStream[5];
DataInputStream[] dis= new DataInputStream[5];publicServerCtrl(Socket[] socket, DataOutputStream[] dos, DataInputStream[] dis) {super();this.socket =socket;this.dos =dos;this.dis =dis;
}public void setPlayer(String playername) throwsJSONException, IOException {
JSONObject json= newJSONObject();
json.put("type", 3);
json.put("msg", playername);
System.out.println(json.toString());
sendMsg(json);
}public void sendResult(String result) throwsJSONException, IOException {
JSONObject json= newJSONObject();
json.put("type", 2);
json.put("msg", result);
System.out.println(json.toString());
sendMsg(json);
}private void sendMsg(JSONObject json) throwsIOException {for (int i = 1; i <= 4; i++) {
dos[i].write(json.toString().getBytes());
}
System.out.println("服务器发送"+json.toString());
}
}
七、运行结果截图
八、 后期计划
1、继续实现局域网相关功能。
2、将产品进行优化,将主要计算移植到服务器程序中,实现客户端轻量化。
3、增加其他功能