046 195
1.接口设计
客户端 用户登录后,启动一个线程来进行游戏,等待服务器信息及发送新数据
服务器 开始时,主程序一直等待用户登录,有新用户登录就开一个线程去为其服务
等到用户都登录完成,服务器开启一个游戏控制线程每隔1秒给全部用户发送一个“START” 信息,通知用户开始新的一轮开始,然后在0.5秒以后计算数据和分数,然后给全部用户发送这一轮结果。
服务器为每个用户都提供了一个服务线程,用于接收用户提交的数据
2.运行截图
3个用户 运行10轮
3.实现代码
只在这里提供重要代码
import java.net.ServerSocket;
import java.net.Socket;
import java.io.File;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.BufferedReader;
import java.io.PrintWriter;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask; import javax.swing.JFrame; public class ServerDemo extends JFrame{
public static ArrayList<UserMessage> list=new ArrayList();
public static int newGame = 0;
public static boolean gameStart = true;
public static double Gpoint = 0;
public static double Sum = 0;
public static int turns = 0;
public static List <Double>G_List = new ArrayList<Double>();
public static ViewFrame vf;
public static String getAllUsersList(){
StringBuffer buffer=new StringBuffer("USER");
for (int i = 0; i<list.size(); i++){
UserMessage user=(UserMessage)list.get(i);
buffer.append(":").append(user.getName());
}
return buffer.toString();
}
public static void sendAllUsersList(){
PrintWriter pw=null;
String listUsers=getAllUsersList();
// System.out.println (listUsers);
for (int i = 0; i<list.size(); i++){
UserMessage user=(UserMessage)list.get(i);
if(user.getName().equals("admin"))
continue;
try {
pw=new PrintWriter(user.getSocket().getOutputStream());
pw.println(listUsers);
pw.flush(); }
catch (Exception ex) {
} }
}
public static boolean addNewClient(UserMessage userNew){
String name=userNew.getName();
boolean flag=false;
for (int i = 0; i<list.size(); i++){
UserMessage user=(UserMessage)list.get(i);
if((user.getName()).equals(name)){
flag=true;
break;
}
}
if(!flag){
list.add(userNew);
//System.out.println (userNew.getName()+" 进入聊天室");
return true;
}
else
return false; } public static void sayToAllUsers(String msg){
//System.out.println ("群聊");
for (int i = 0; i<list.size(); i++){
UserMessage user=(UserMessage)list.get(i);
//System.out.println(user.getName());
if(user.getName().equals("admin"))
continue;
Socket sok=user.getSocket();
sentMessageToClient(sok,msg);
} } public static void sentMessageToClient(Socket sok,String msg){
try {
PrintWriter pw=new PrintWriter(sok.getOutputStream());
pw.println(msg);
pw.flush();
}
catch (Exception ex) {
}
}
public static void addsubmit( double d){
Sum += d;
System.out.println("Sum "+ Sum + " "+ turns);
} public static void startGame(){
turns = 0;
Timer timer = new Timer();
TimerTask task = new TimerTask() {
public void run() {
if(newGame == 0){
if(turns >= 10){
this.cancel();
System.out.println("end?!");
}
for (int i = 0; i<list.size(); i++){
UserMessage user=(UserMessage)list.get(i);
Socket sok=user.getSocket();
sentMessageToClient(sok,"START");
}
newGame = 1;
} else {
turns++;
System.out.println("turns = "+turns);
newGame = 0; //计算G点
Gpoint = Sum/list.size()*0.618;
System.out.println("Now Gpoint = "+Gpoint); //计算每个玩家分数 第一名加分 最后一面的减分
double xxx = 10000,max = 0,min = 100000;
int best=0,sb=0;
for (int i = 0; i<list.size(); i++){
UserMessage user=(UserMessage)list.get(i);
xxx = Math.abs(user.submit - Gpoint);
System.out.println(user.getName()+" "+user.submit+"-"+Gpoint);
if(xxx > max){
sb =i;
max = xxx;
}
if(xxx < min){
best =i;
min = xxx;
}
}
UserMessage sbuser=(UserMessage)list.get(sb);
UserMessage bestuser=(UserMessage)list.get(best);
sbuser.score -= 1;
bestuser.score += 10; StringBuffer buffer=new StringBuffer("");
StringBuffer Ubuffer=new StringBuffer("用户 分数");
for (int j = 0; j<list.size(); j++){
UserMessage userx=(UserMessage)list.get(j);
buffer.append(":"+userx.getName()+" "+userx.score);
Ubuffer.append("\n"+userx.getName()+" "+userx.score);
} for (int i = 0; i<list.size(); i++){
UserMessage user=(UserMessage)list.get(i);
Socket sok=user.getSocket();
sentMessageToClient(sok,"GPOINT"+":"+turns+":"+Gpoint+buffer.toString());
}
String src=vf.JTextArea_mess.getText();
if(src.equals("")){
vf.JTextArea_mess.setText("第"+turns+"轮Gpoint是"+Gpoint);
}else{
vf.JTextArea_mess.setText(src+"\n"+"第"+turns+"轮Gpoint是"+Gpoint);
}
vf.JTextArea_user.setText(Ubuffer.toString());
Gpoint = 0;
Sum = 0;
System.out.println("end turns = "+turns);
}
}
};
timer.schedule(task, 0, 500);
} public static void main (String[] args) {
ServerSocket server = null;
Socket socket = null; vf = new ViewFrame();
vf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
vf.setSize(400,400);
vf.setVisible(true); try {
server=new ServerSocket(6000);
socket=new Socket();
System.out.println ("Server is beginning......");
while(gameStart){
socket = server.accept();
BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
String userMess = br.readLine();
System.out.println(userMess);
String[] mess = userMess.split(":");
System.out.println(userMess);
if(mess[0].equals("LOGIN")){
File fl = new File("test.xls");
Excel excel = new Excel(fl);
System.out.println("some one enter");
Date currentTime = new Date();
SimpleDateFormat formatter = new SimpleDateFormat("HH:mm:ss");
String dateString = formatter.format(currentTime); //登录
if(mess[3].equals(excel.getUserPassword(mess[1]))){
UserMessage userNew=new UserMessage(mess[1],mess[2],socket);
if(addNewClient(userNew)){
PrintWriter pw=new PrintWriter(socket.getOutputStream());
pw.println("NORMAL");
pw.flush(); ServerThread thread=new ServerThread(userNew);
thread.start();
System.out.println("电脑|" + dateString + "|登录成功|" + mess[1]);
}
else{
PrintWriter pw=new PrintWriter(socket.getOutputStream());
pw.println("ON");
pw.flush();
System.out.println("电脑|" + dateString + "|登录失败|" + mess[1]);
}
}
else{
PrintWriter pw=new PrintWriter(socket.getOutputStream());
pw.println("NO");
pw.flush();
System.out.println("电脑|" + dateString + "|登录失败|" + mess[1]);
}
}
}
}
catch (Exception ex) {
}
}
}
服务器主要部分
import java.awt.Point;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.Socket; class ClientThread extends Thread{
private Socket socket;
private ClientDemo client;
public boolean flag = true; public ClientThread(Socket socket,ClientDemo client){
this.socket=socket;
this.client=client;
}
public void run(){
while(flag){
try {
BufferedReader br=new BufferedReader(new InputStreamReader(socket.getInputStream()));
String msg=br.readLine();
String mess[]=msg.split(":");
if(mess[0].equals("START")){
client.sendGpoint();
} if(mess[0].equals("GPOINT")){
client.gpoint = Double.parseDouble(mess[1]);
StringBuffer buffer=new StringBuffer("第"); buffer.append(mess[1]).append("轮").append("Gpoint是").append(mess[2]); String src=client.JTextArea_mess.getText();
if(src.equals("")){
client.JTextArea_mess.setText(buffer.toString());
}else{
client.JTextArea_mess.setText(src+"\n"+buffer.toString());
}
StringBuffer ubuffer=new StringBuffer("用户 分数 \n");
for(int i=3; i<mess.length; i++)
ubuffer.append(mess[i]+"\n");
client.JTextArea_user.setText(ubuffer.toString());
} if(mess[0].equals("STATE")){
StringBuffer buffer2 = new StringBuffer(mess[2]);
if(mess[1].equals("UP")){
buffer2.append(" 上线了 @" + mess[3] + ":" + mess[4] + ":" + mess[5]);
if(mess[6].equals("M"))
buffer2.append(" [手机]");
}
else{
buffer2.append(" 下线了 @" + mess[3] + ":" + mess[4] + ":" + mess[5]);
if(mess[6].equals("M"))
buffer2.append(" [手机]");
} String src=client.JTextArea_mess.getText();
if(src.equals("")){
client.JTextArea_mess.setText(buffer2.toString());
}
else{
client.JTextArea_mess.append("\n"+buffer2.toString());
Point p= new Point(0,client.JTextArea_mess.getLineCount()*20);
client.JScrollPane_mess.getViewport().setViewPosition(p);
}
}
}
catch (Exception ex) {
} }
}
}
用户线程(主要)
4.感想
这一个终于有了小伙伴,有小伙伴一起编程效率高了许多~
Personal Software Process Stages |
原来估计的时间 (分钟) |
实际花费的时间 (分钟) |
||
Planning |
计划 |
20 | 30 | |
· Estimate |
· 估计这个任务需要多少时间,把工作细化并大致排序 |
20 | 30 | |
Development |
开发 |
60 | 90 | |
· Analysis |
· 需求分析 (包括学习新技术) |
10 | 15 | |
· Design Spec |
· 生成设计文档 |
0 | 0 | |
· Design Review |
· 设计复审 (和同事审核设计文档) |
0 | 0 | |
· Coding Standard |
· 代码规范 (制定合适的规范) |
0 | 0 | |
· Design |
· 具体设计 |
5 | 7.5 | |
· Coding |
· 具体编码 |
20 | 30 | |
· Code Review |
· 代码复审 |
5 | 7.5 | |
· Test |
· 测试(自我测试,修改代码,提交修改) |
20 | 30 | |
Reporting |
总结报告 |
20 | 30 | |
· Test Report |
· 测试报告 |
10 | 15 | |
· Size Measurement |
· 计算工作量 |
5 | 7.5 | |
· Postmortem & Improvement Plan |
· 事后总结, 并提出改进 |
5 | 7.5 | |
Total |
总计 |
总估计的用时 |
总用时 |