开发概述
前期开发已实现:
1、进行游戏:玩家输入名字(设有默认值)数字(数字隐藏显示为•,并强制要求输入),并通过计算得出黄金点和赢家,然后可进行下一局(可无限进行)
2、游戏存档:每一局完成后将每位玩家的数字和每局的黄金点和赢家存入数据库
3、查看游戏记录:可以分别查看每位玩家在每一局游戏输入的数字和每局的黄金点和赢家,并且可以按照制定的分类标准(场次或玩家)进行查看
4、继续游戏:在重新启动应用后,可以从数据库中获取以前游戏的信息,并自动给出相应数量的输入框
5、新游戏:提示用户输入玩家数量(必填,理论上可覆盖整个int范围),从数据库中删除原有信息,并在游戏界面显示相应数量的输入框
6、输入控制:对用户输入(或粘贴)的内容进行强制性限制,比如必须输入正整数或必须输入小数,对于输入非法的字符直接立刻使之消失
7、数字检查与提示:检查玩家输入的数字是否在0~100的范围内,如果有玩家输入的数字超出了范围,则停止后续操作,并显示所有输出超过范围的玩家的名字
8、数据可视化:用折线图展示黄金点的变化趋势,用条形统计图展示每一位玩家赢的次数
本阶段开发概述:
本阶段在之前开发的基础上实现了局域网内联机游戏
由主持人发起游戏,将链接发给各位玩家,玩家在客户端输入名字和数字,然后由主持人操作得到赢家,同时也有与单机版一样的查看每位玩家在每一局游戏输入的数字和每局的黄金点和赢家以及可视化功能
拓扑结构:
测试用例
主持人发起游戏
以主持人角色进入游戏后,点击联机游戏
输入玩家数量,输入框通过JavaScript语句进行了控制,只能输入正整数,具体实现见上一篇博客
点击完成之后进入游戏界面,主持人需要将输入链接发送给玩家,并且可以通过刷新按钮实时监控有多少玩家已经提交了数字,只有等达到了设定的玩家数量之后才会出现查看结果按钮
玩家输入
打开主持人提供的链接,输入名字和数字并点击提交,数字通过JavaScript语句控制了只能输入0~100的浮点数,详细实现情况见上一篇博客
主持人揭晓结果
当已经有预定数量的玩家提交了数字之后,会出现查看结果按钮
点击查看结果按钮,可以得到本局游戏的黄金点和赢家
主持人查看结果记录
与单机版一样的查看每位玩家在每一局游戏输入的数字和每局的黄金点和赢家,并且可以按照制定的分类标准(场次或玩家)进行查看,以及用折线图展示黄金点的变化趋势,用条形统计图展示每一位玩家赢的次数,详情见前两篇博客。
实现方法
一些功能的代码重用了单机版,这里不赘述,此处重点介绍新添加的代码。
user_add.jsp
玩家输入:
新增了一个数据表game_per,暂存每一局游戏中每位玩家的名字和数字(在揭晓结果之后所有记录被删除),获取一位玩家输入的名字和数字并存入该数据表中
<%@page pageEncoding="UTF-8" contentType="text/html; charset=UTF-8"%>
<%@page
import="java.sql.*,java.io.*,java.util.ArrayList,java.lang.Math,java.lang.Double"%>
<html>
<head>
<title>保存增加</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head>
<body>
<%
String user = request.getParameter("user2");
String strnum = (request.getParameter("num2"));
boolean illegalnum=false;
double num=Double.parseDouble(strnum);
if(num<0 || num>100){
out.print("输入数字超出范围!<br>");
illegalnum=true;}
if(illegalnum){
%>
<input type='button' value='重新输入'
onclick="javascript:history.back(-1);">
<%
}
else{
request.setCharacterEncoding("UTF-8");
//out.println("页面传递过来的数据获取完毕");
System.out.println("页面传递过来的数据获取完毕");
//System.out.println("id="+id+",deviceId="+deviceId+",deviceName="+deviceName);
//开始连接数据库,需要先把mysql-connector-java-5.0.4-bin.jar和json.jar拷贝到ROOT/WEB-INF/lib下
try {
Class.forName("com.mysql.jdbc.Driver");
} catch (ClassNotFoundException classnotfoundexception) {
classnotfoundexception.printStackTrace();
}
//out.println("加载了JDBC驱动");
System.out.println("加载了JDBC驱动");
//然后链接数据库,开始操作数据表
try {
Connection conn = DriverManager
.getConnection("jdbc:mysql://localhost:3306/mydb?user=DataUser&password=1q2w3e&useUnicode=true&characterEncoding=UTF-8");
System.out.println("准备statement。");
Statement statement = conn.createStatement();
System.out.println("已经链接上数据库!");
//out.println("Connect Database Ok!!!<br>");
String sql="insert into game_per(user,num) values('" + user+ "'," +num + ")";
//out.println("即将执行的SQL语句是:"+sql.get(i));
System.out.println("即将执行的SQL语句是:"+sql);
statement.executeUpdate(sql);
statement.close();
conn.close();
//out.println("Database Closed!!!<br>");
System.out.println("操作数据完毕,关闭了数据库!");
%>
<br>
请等待主持人操作...
<%
} catch (SQLException sqlexception) {
sqlexception.printStackTrace();
%>
<br>
操作失败!
<%}
}
%>
</body>
</html>
gaming_host.jsp
获取主机IP
由于联机游戏是将我的电脑作为服务器,所以在生成链接的时候需要获取主机IP地址,使用了Java的InetAddress类
import java.net.Inet4Address;
import java.net.InetAddress;
import java.net.UnknownHostException;
try {
InetAddress ip4 = Inet4Address.getLocalHost();
System.out.println(ip4.getHostAddress());
} catch (UnknownHostException e) {
e.printStackTrace();
}
实时获取玩家输入情况
每一次刷新都会统计game_per表中的记录数,然后在界面显示
gaming_host.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@page
import="java.sql.*,java.io.*,java.util.ArrayList,java.lang.Math,java.lang.Integer,java.net.Inet4Address,
java.net.InetAddress,
java.net.UnknownHostException"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort()
+ path + "/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">
<title>黄金点游戏</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<!--
<link rel="stylesheet" type="text/css" href="styles.css">
-->
</head>
<body>
<%
int user_num = 0;
int user_num_now=0;
try {
Class.forName("com.mysql.jdbc.Driver");
} catch (ClassNotFoundException classnotfoundexception) {
classnotfoundexception.printStackTrace();
}
//out.println("加载了JDBC驱动");
System.out.println("加载了JDBC驱动");
//然后链接数据库,开始操作数据表
try {
Connection conn = DriverManager.getConnection(
"jdbc:mysql://localhost:3306/mydb?user=DataUser&password=1q2w3e&useUnicode=true&characterEncoding=UTF-8");
System.out.println("准备statement。");
Statement statement = conn.createStatement();
System.out.println("已经链接上数据库!");
//out.println("Connect Database Ok!!!<br>");
String user1 = request.getParameter("user_num2");
System.out.println(user1+"++++++++++++++++++++++++++++");
Integer users = Integer.parseInt(user1);
user_num = users.intValue();
System.out.println(user1);
ResultSet rs = statement.executeQuery("select count(*) from game_per");
rs.next();
user_num_now = rs.getInt("count(*)");
statement.close();
conn.close();
//out.println("Database Closed!!!<br>");
System.out.println("操作数据完毕,关闭了数据库!user=" + user_num_now);
} catch (SQLException sqlexception) {
sqlexception.printStackTrace();
}
//out.println("页面执行完毕!");
System.out.println("页面执行完毕!");
%>
<h1 align="center">黄金点游戏</h1>
<br>
<div align="center" style="margin:50px;border:2px solid;">
<%
try {
InetAddress ip4 = Inet4Address.getLocalHost();
System.out.println(ip4.getHostAddress());
out.println("请将链接(http://"+ip4.getHostAddress()+":8080/GoldPointGame/user_input_2dfer387i6wcb4.jsp)发送给玩家(多余的数字将被舍弃)<br>");
} catch (UnknownHostException e) {
e.printStackTrace();
}
out.print("现在已有"+user_num_now+"位玩家提交了数字");
System.out.print(user_num);
%>
<input type="button" value="刷新" onclick="location.reload();">
</div>
<div align="right">
<% if(user_num_now>=user_num)
out.print("<form id='fin' name='fin' action='host_ok.jsp'><input type='text' id='user_num2' name='user_num2' value='"+user_num+"' style='visibility: hidden;'> <input type='submit' value='查看结果' /></form>");
%>
</div>
</body>
</html>
host_ok.jsp
揭晓结果
从game_per表中读取所有记录,然后计算黄金点和赢家,,将输入情况和结果情况分别写入数据库中的game和outcome表中,以供以表格形式展示和以折线图和条形统计图展示
<%@page pageEncoding="UTF-8" contentType="text/html; charset=UTF-8"%>
<%@page
import="java.sql.*,java.io.*,java.util.ArrayList,java.lang.Math,java.lang.Double"%>
<html>
<head>
<title>保存增加</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head>
<body>
<%
int user_num=0;
String user1 = request.getParameter("user_num2");
System.out.println(user1+"++++++++++++++++++++++++++++");
Integer users = Integer.parseInt(user1);
user_num = users.intValue();
request.setCharacterEncoding("UTF-8");
//out.println("页面传递过来的数据获取完毕");
System.out.println("页面传递过来的数据获取完毕");
//System.out.println("id="+id+",deviceId="+deviceId+",deviceName="+deviceName);
//开始连接数据库,需要先把mysql-connector-java-5.0.4-bin.jar和json.jar拷贝到ROOT/WEB-INF/lib下
try {
Class.forName("com.mysql.jdbc.Driver");
} catch (ClassNotFoundException classnotfoundexception) {
classnotfoundexception.printStackTrace();
}
//out.println("加载了JDBC驱动");
System.out.println("加载了JDBC驱动");
//然后链接数据库,开始操作数据表
try {
Connection conn = DriverManager
.getConnection("jdbc:mysql://localhost:3306/mydb?user=DataUser&password=1q2w3e&useUnicode=true&characterEncoding=UTF-8");
System.out.println("准备statement。");
Statement statement = conn.createStatement();
System.out.println("已经链接上数据库!");
//out.println("Connect Database Ok!!!<br>");
int term=0;
ResultSet rs = statement.executeQuery("select max(term) from game");
if(rs.next()){term=(rs.getInt("max(term)"));}
term+=1;
ResultSet table=statement.executeQuery("select * from game_per limit "+user_num);
ArrayList<String> user=new ArrayList<String>();
ArrayList<Double> num=new ArrayList<Double>();
while(table.next()){
user.add(table.getString("user"));
num.add(table.getDouble("num"));
}
ArrayList<String> sql =new ArrayList<>();
double sum=0;
for(int i=0;i<user_num;i++){
sum+=num.get(i).doubleValue();
sql.add("insert into game(term,user,num) values("+ term + ",'" + user.get(i)+ "'," +num.get(i).doubleValue() + ")");
//out.println("即将执行的SQL语句是:"+sql.get(i));
System.out.println("即将执行的SQL语句是:"+sql.get(i));
statement.executeUpdate(sql.get(i));
}
double goldpoint;
goldpoint=0.618*sum/user_num;
ArrayList<Double> d=new ArrayList<>();
for(int i=0;i<user_num;i++){
d.add((Math.abs(num.get(i).doubleValue()-goldpoint)));}
double m=num.get(0).doubleValue();
int k=0;
for(int i=0;i<user_num;i++){if (num.get(i).doubleValue()<m) {m=num.get(i).doubleValue();k=i;}}
out.println("goldpoint:"+goldpoint+"\nwinner:"+user.get(k));
String sql2=new String("insert into outcome(term,goldpoint,winner) values("+ term +","+goldpoint+ ",'" + user.get(k)+ "')");
//out.println("即将执行的SQL语句是:"+sql.get(i));
System.out.println("即将执行的SQL语句是:"+sql2);
statement.executeUpdate(sql2);
statement.executeUpdate("delete from game_per");
statement.close();
conn.close();
//out.println("Database Closed!!!<br>");
System.out.println("操作数据完毕,关闭了数据库!");
%>
<br>
<input type="button" name="listBtn" value="下一回合"
onclick="javascript:history.back(-1);">
<%
} catch (SQLException sqlexception) {
%>
<br>
<input type="button" name="listBtn" value="游戏失败"
onclick="javascript:history.back(-1);">
<%
sqlexception.printStackTrace();}
//out.println("页面执行完毕!");
System.out.println("页面执行完毕!");
%>
</body>
</html>
后期完善
1、界面美化和逻辑重构
2、供外网访问