谁是卧底的游戏相信大家都玩儿过或者见过,写成游戏呢无非就是socket发消息,发来发去,主要是发消息的时间也就是发送逻辑要把握好就能成为好玩的小游戏:
登录界面(数据库存放卧底号,积分)
开始游戏:
服务器生成当前发言人序号(随机数)
Message{
int type;
String name;//发消息人的卧底号
//Map<int,String> map;//准备人序号和卧底号
int id;//当前发言人序号(准备人员)
int maxNum;//最大准备人数
String message;//普通聊天消息
List total;//房间总人数
List prepare;//当前准备人id列表(平民冤死更新)
int undercover;//卧底数
List id_list;//已发言人
List vote;//最大票数发言人id列表
int id_vote;//被投人
String word;//卧底词
Map said_map;//发言词和id
}
type:
0:—请求进入房间,maxNum
1:服务器发送进房消息,total,message
2:—发送聊天消息和接收发言词消息,id,name,message(服务器接收到自动转发
给客户端)
3:—请求准备游戏,name
4:服务器发送已准备好的消息,prepare,maxNum
5:服务器发送当前随机取得的发言人的个人信息给客户端,map
6:服务器发送请求投票消息,
//7:—发送投票消息,id_
7:服务器发送发言完毕的消息,法官,message
服务器发送找到/未找到卧底(冤死)消息
8:—发送投票结果消息给服务器判断,id_vote
9:服务器发送投票判断结果消息(包括惩罚),
找到卧底(客户端收到后将准备人数清零,重新开始准备游戏)
未找到卧底(发送消息4,将得到的vote赋给prepare)
10:客户端接收发言词消息(操作在客户端完成)
11:服务器发送初始id给客户端,以及prepare_list
12:服务器发送游戏结束消息,准备人数清零
13:服务器发送卧底词,客户端弹出显示词语窗口
14:—-客户端所有人发言完毕的消息
15:发送积分增加成功消息
16:发送是否旁观消息
注:其中没有写Message的type各种类型的使用,请大家写代码时注意使用
Server端:
sql类:存储用户基本信息(卧底名,积分),成对词语
ResultSet sqlQuery(String sql);//查询卧底词和卧底名
void sqlUpdate(String sql);//注册用户
Server类: 服务端线程管理客户端;
void startServer();//线程管理,提供socket给每个客户端线程
void sendMsgToAll(Message msg);
//统计投票结果
Map<int,int> map;//id和票数
ServerThread类: 接收消息
void sendMsg(Message msg);//提供给Server类使用
//提供各种IO流对象给消息处理类Judge,
Judge类: (判断用户冤死,判断平民和卧底输赢)
//voteRule调用
Judge(Message msg);
//返回0(平民赢),返回-1(票数相同再轮),返回卧底编号(卧底赢),返回平民编
号(平民冤死)
//返回-2(无人投票,游戏结束)
int getResult(List vote,List prepare,int undercover);
StartGameRule类: 怎样开始游戏
//接收到消息3时ServerThread调用
StartGameRule(Socket socket,ServerThread里的各种需要用到的流);
NormalOperationRule类: 怎样正常游戏
//接收到消息2时ServerThread调用
NormalOperationRule(Socket socket,ServerThread里的各种需要用到的流);
PunishRule 类: 怎样惩罚失败方
//Judge类调用
PunishRule(Socket socket,Judge里提供的各种流);
voteRule类: 投票后处理规则
//接收到消息9时ServerThread调用
voteRule(Socket socket,ServerThread里的各种需要用到的流);
message类:(用户进入房间消息,进入游戏消息;提示某用户发送描述语句消息,用户用户发送描述语句过时消息,用户投票消息,投票过时消息,投票结果类,用户冤死消息,游戏结束消息,惩罚消息)
client端:
clientLoginFrame类: (登入,注册)
//调用clientMianFrame类
SetRoom类: 房间设置界面
//调用MainFrame
MainFrame类: 游戏主界面
MainFrame(Socket socket,ClientThread ct);
ClientThread类: 客户端线程
//收发消息
vote类: 投票界面,用户怎样投票,得出投票结果
int vote();
数据库设计
create database undercover character set utf8;
create table user(
id int(5),
name varchar(10),
score int(6)
);
insert into user values(1,'杨碧佳',200);
update user set name='杨碧佳' where id=1;
delete from user where id=7;
select * from user;
create table words(
id int(5),
name1 varchar(10),
name2 varchar(10)
);
select * from words;
insert into words values(5,'眉毛','睫毛'),(2,'调情','调戏'),(3,'浴缸','鱼
缸'),(4,'电动车','摩拖车');
insert into words values(1,'冬瓜皮','西瓜皮'),(6,'笤帚','拖把'),(7,'可口
可乐','百事'),(8,'电话','手机');
insert into words values(9,'电影','电视剧'),(10,'玫瑰','月季'),(11,'保
安','保镖'),(12,'董永','许仙'); insert into words values(13,'橙子','橘
子'),(14,'警察','捕快'),(15,'作家','编剧'),(16,'枕头','抱枕');
insert into words values(17,'同学','同桌'),(18,'班主任','辅导员'),(19,'小
笼包','灌汤包');
insert into words values(20,'包青天','狄仁杰'),(21,'神雕侠侣','天龙八
部'),(22,'十面埋伏','四面楚歌');
insert into words values(23,'大白兔','金丝猴'),(24,'甄子丹','李连杰');
服务器处理消息
public class ServerThread extends Thread {
Socket socket;
Server ser;
InputStream is;
OutputStream os;
ObjectInputStream ois;
ObjectOutputStream oos;
String s;
int id;
public ServerThread(Socket socket, Server server) {
this.socket = socket;
this.ser = server;
try {
os = socket.getOutputStream();
is = socket.getInputStream();
System.out.println("建好输入输出流。。。");
oos = new ObjectOutputStream(os);
ois = new ObjectInputStream(is);
System.out.println("建好对象流。。。");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
this.start();
}
@Override
public void run() {
try {
while (true) {
Message message = (Message) ois.readObject();
System.out.println("已接收消息" + message.getType()
+ ",message.getName()=" + message.getName());
// 登录消息
if (message.getType() == 7) {
String name = message.getName();
SQLConnection conn = new SQLConnection();
String sql = "select * from user ";
try {
ResultSet rs1 = conn.sqlQuery(sql);
boolean flag = false;
while (rs1.next()) {
int id = rs1.getInt("id");
String names = rs1.getString("name");
int score = rs1.getInt("score");
if (names.equals(message.getName())) {
s = name;
System.out.println("卧底号:" + name + "登录成功!积分:"
+ score);
//
ser.sendMsgToAll(new Message(7, null, 1, score,
null, null, null, ser.maxNum, null,
null, 0, null, null));
System.out.println("已给客户端发送7消息");
flag = true;
break;
}
}
if (!flag) {
System.out.println("卧底号:" + name + "登录失败!");
ser.sendMsgToAll(new Message(7, null, 2, 0, null,
null, null, 0, null, null, 0, null, null));
System.out.println("已给客户端发送7消息");
}
conn.closeConn();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
// 注册消息
if (message.getType() == 12) {
String name = message.getName();
SQLConnection conn = new SQLConnection();
try {
String sql1 = "select id from user";
ResultSet rs = conn.sqlQuery(sql1);
int len = 1;
while (rs.next()) {
len++;
}
int score = 200;
String sql = "insert into user values('" + len + "','"
+ name + "','" + score + "')";
int i = conn.sqlUpdate(sql);
if (i == 1) {
System.out.println("卧底号:" + name + "注册成功!");
ser.sendMsgToAll(new Message(12, null, 1, 0, null,
null, null, 0, null, null, 0, null, null));
} else {
System.out.println("卧底号:" + name + "注册失败!");
ser.sendMsgToAll(new Message(12, null, 2, 0, null,
null, null, 0, null, null, 0, null, null));
}
conn.closeConn();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
// 请求进入房间
if (message.getType() == 0) {
// 旁观消息
System.out.println("进房时ser.flag=" + ser.flag);
ser.sendMsgToAll(new Message(15, null, ser.flag, 0, null,
null, null, 0, null, null, 0, null, null));
System.out.println(message.getName() + "请求进入房间");
List total_copylist = new ArrayList<String>();
total_copylist.addAll(ser.total);
total_copylist.add(message.getName());
ser.total = total_copylist;
// 发送积分
ScoreOperation so = new ScoreOperation(ser);
// for (int i = 0; i < ser.total.size(); i++) {
int score = so.queryScore(s);
ser.sendMsgToAll(new Message(16, message.getName(), score,
0, null, null, null, 0, null, null, 0, null, null));
// }
if (ser.total.size() == 1) {
ser.maxNum = message.getMaxNum();
ser.sendMsgToAll(new Message(1, "法官", 0, message
.getMaxNum(),
message.getName() + "进入房间,你是第一个人", ser.total,
ser.prepare, 0, null, null, ser.play, null,
null));
} else {
System.out.println("请求进入房间,ser.maxNum=" + ser.maxNum);
ser.sendMsgToAll(new Message(1, "法官", 0, ser.maxNum,
message.getName() + "进入房间", ser.total,
ser.prepare, 0, null, null, ser.play, null,
null));
}
}
// 聊天消息
if (message.getType() == 2) {
if (message.getId() == 0)
ser.sendMsgToAll(new Message(2, message.getName(), 0,
0, message.getMessage(), null, null, 0, null,
null, 0, null, null));
else
ser.sendMsgToAll(new Message(2, message.getName(),
message.getId(), 0, message.getMessage(), null,
null, 0, null, null, 0, null, null));
}
// 请求准备游戏
if (message.getType() == 3) {
System.out
.println("==================准备====================");
ser.temp++;
List prepare_copylist = new ArrayList<String>();
prepare_copylist.addAll(ser.prepare);
prepare_copylist.add(ser.temp);
ser.prepare = prepare_copylist;
ser.play = ser.prepare.size();
for (int i = 0; i < ser.prepare.size(); i++)
System.out.println("ser.prepare=" + ser.prepare.get(i));
ser.map.put(ser.temp, message.getName());
// 给客户端发送id以及准备人
ser.sendMsgToAll(new Message(11, null, 0, 0, null, null,
ser.prepare, 0, null, null, ser.play, null, null));
ser.sendMsgToAll(new Message(2, message.getName(), 0, 0,
"我准备好啦", null, null, 0, null, null, 0, null, null));
System.out.println("发送准备消息,ser.temp=" + ser.temp
+ ",ser.maxNum=" + ser.maxNum);
if (ser.temp == ser.maxNum) {
ser.flag = 2;// 旁观标志
ser.sendMsgToAll(new Message(15, null, ser.flag, 0,
null, null, null, 0, null, null, 0, null, null));
// 游戏开始
System.out.println("准备完成,游戏开始");
ser.temp = 0;
ser.max = ser.maxNum;
Random ran = new Random();
// 第一个发言人
int x = ran.nextInt(ser.maxNum) + 1;
// 初始化玩家id列表
ser.id_list.add(x);
for (int i = 1; i < ser.prepare.size(); i++) {
if ((x + i) % ser.max != 0)
ser.id_list.add((x + i) % ser.max);
else
ser.id_list.add(ser.max);
}
for (int i = 0; i < ser.id_list.size(); i++)
System.out.println("::" + ser.id_list.get(i));
// 设置id和卧底词的map
InitialMap im = new InitialMap(ser);
im.setId_Word();
System.out.println("发送卧底词");
ser.sendMsgToAll(new Message(4, null, 0, 0, null, null,
null, 0, null, null, 0, null, null));
for (int i = 0; i < ser.maxNum; i++) {
System.out.println("id=" + (i + 1) + ",word="
+ ser.id_word.get(i + 1));
ser.sendMsgToAll(new Message(13, null, i + 1, 0,
null, null, null, 0, null, null, 0,
ser.id_word.get(i + 1), null));
}
ser.sendMsgToAll(new Message(2, "法官", 0, 0, message
.getName() + "游戏开始,请从" + x + "号开始描述。", null,
null, 0, null, null, 0, null, null));
// 卧底游戏开始
// StartGameRule sgr = new StartGameRule(ser, ois, oos);
// sgr.startGame();
ser.sendMsgToAll(new Message(5, "法官", ser.id_list
.get(0), 0, "正在冥思苦想中。。。", null, null, 0, null,
null, 0, null, null));
ser.id_list.remove(0);
// ser.word_count++;
}
}
// 接收发言词
if (message.getType() == 10) {
InitialMap im = new InitialMap(ser);
if (ser.word_count == 0) {
im.clearId_Speak();
}
im.setId_Speak(message.getId(), message.getWord());
System.out.println("ser.id_speak.size()="
+ ser.id_speak.size());
// 已发言人数
ser.word_count++;
System.out.println();
System.out.println("收到发言词:" + message.getWord() + ",id="
+ message.getId());
// 设置发言词map
// 将发言词转发给客户端,1代表本消息为发言词消息
ser.sendMsgToAll(new Message(2, message.getName(), message
.getId(), 0, message.getWord() + "(发言词)", null,
null, 0, null, null, 0, null, null));
System.out.println("已向客户端发送发言词:" + message.getWord()
+ ",id=" + message.getId());
if (ser.id_list.size() > 0) {
System.out.println(" ser.id_list.get(0)="
+ ser.id_list.get(0) + ",ser.id_list="
+ ser.id_list.size() + ",ser.word_count="
+ ser.word_count);
ser.sendMsgToAll(new Message(5, "法官", ser.id_list
.get(0), 0, "正在冥思苦想中。。。", null, null, 0, null,
null, 0, null, null));
ser.id_list.remove(0);
}
System.out.println();
System.out.println();
if (ser.word_count == ser.max) {
// TODO 应该在所有人发言完毕后再发送当前消息
ser.sendMsgToAll(new Message(2, "法官", 0, 0,
"发言完毕,开始投票!", null, null, 0, null, null, 0,
null, null));
// 初始化投票信息的map
for (int i = 0; i < ser.max; i++) {
ser.vote.put(i + 1, 0);
// System.out.println("ser.id_speak" + (i + 1) + "="
// + ser.id_speak.get(i + 1));
}
Iterator it = ser.id_speak.keySet().iterator();
while (it.hasNext()) {
int key = (int) it.next();
String value = ser.id_speak.get(key);
System.out.println("id=" + key + ",speak=" + value);
}
Map<Integer, String> idSpeak = new HashMap<Integer, String>();
idSpeak.putAll(ser.id_speak);
// 请求投票
if (!ser.equal)
ser.sendMsgToAll(new Message(6, null, 0, 0, null,
null, null, 0, null, null, 1, null, idSpeak));
else {
List<Integer> pp = new ArrayList<Integer>();
Iterator itr = ser.id_word.keySet().iterator();
while (itr.hasNext()) {
int key = (int) itr.next();
if (!ser.die.contains(key)) {
pp.add(key);
}
}
ser.sendMsgToAll(new Message(6, null, 0, 0, null,
null, pp, 0, null, null, 2, null, idSpeak));
}
System.out.println("服务端发送请求投票消息");
}
}
// 投票消息
if (message.getType() == 8) {
ser.temp++;
// System.out.println("ser.play.size()=" + ser.play.size());
System.out.println("现在被投票人有" + ser.temp + "个,ser.play="
+ ser.play);
VoteRule vr = new VoteRule(ser);
System.out.println("投票id=" + message.getId_vote());
vr.setVote(message.getId_vote());
if (ser.temp <= ser.play) {
if (message.getId_vote() != 0)
ser.sendMsgToAll(new Message(2, message.getName(),
message.getId(), 0, "投"
+ message.getId_vote(), null, null,
0, null, null, 0, null, null));
else
ser.sendMsgToAll(new Message(2, message.getName(),
message.getId(), 0, message.getWord(),
null, null, 0, null, null, 0, null, null));
}
if (ser.temp == ser.play) {
// 投票结束
System.out.println("投票结束");
ser.temp = 0;
ser.equal = false;
ser.word_count = 0;
// 最大票数人id列表
ArrayList<Integer> list = vr.getVoteList();
System.out.println("list的内容为:");
for (int i = 0; i < list.size(); i++) {
System.out
.println("list(" + i + ")=" + list.get(i));
}
Judge judge = new Judge(list, ser);
int result = judge.getResult();
System.out.println("result为:" + result);
// 无人投票,游戏结束
if (result == -2) {
ser.flag = 1;// 解除旁观
ser.sendMsgToAll(new Message(15, null, ser.flag, 0,
null, null, null, 0, null, null, 0, null,
null));
// 发送积分
ScoreOperation so = new ScoreOperation(ser);
int score = so.queryScore(s);
ser.sendMsgToAll(new Message(16, message.getName(),
score, 0, null, null, null, 0, null, null,
0, null, null));
System.out.println("无人投票,游戏结束");
HandleWord hw = new HandleWord(ser);
hw.handle();
String common = hw.getCommon();
String undercover = hw.getUndercover();
ser.sendMsgToAll(new Message(9, "法官", 0, 0,
"这一轮没人投票,法官很伤心,感觉不会再爱了。。。\r\n游戏自动结束。"
+ ser.undercoverId + "号是卧底,平民词是"
+ common + ",卧底词是" + undercover,
null, null, 0, null, null, 0, null, null));
ser.prepare.clear();
ser.play = 0;
ser.die.clear();
ser.id_list.clear();
ser.id_word.clear();
ser.undercoverId = 0;
}
// 平票
else if (result == -1) {
System.out.println("平票");
ser.equal = true;
String str = "";
for (int i = 0; i < list.size(); i++) {
str += list.get(i) + "号,";
}
ser.sendMsgToAll(new Message(2, "法官", 0, 0, str
+ "你们平票,请再来一轮。\r\n从" + list.get(0)
+ "号开始发言", null, null, 0, null, null, 0,
null, null));
ser.prepare = list;
ser.id_list.clear();
// 初始化玩家id列表
for (int i = 0; i < ser.prepare.size(); i++) {
ser.id_list.add(ser.prepare.get(i));
}
ser.id_speak.clear();
ser.vote.clear();
ser.max = list.size();
ser.word_count = 0;
// 发出请求弹出描述界面的消息
ser.sendMsgToAll(new Message(5, "法官", ser.id_list
.get(0), 0, "正在冥思苦想中。。。", null, null, 0,
null, null, 0, null, null));
ser.id_list.remove(0);
}
// 卧底输
else if (result == 0) {
ser.flag = 1;// 解除旁观
ser.sendMsgToAll(new Message(15, null, ser.flag, 0,
null, null, null, 0, null, null, 0, null,
null));
// 发送积分
ScoreOperation so = new ScoreOperation(ser);
int score = so.queryScore(s);
ser.sendMsgToAll(new Message(16, message.getName(),
score, 0, null, null, null, 0, null, null,
0, null, null));
System.out.println("卧底输");
HandleWord hw = new HandleWord(ser);
hw.handle();
String common = hw.getCommon();
String undercover = hw.getUndercover();
// 加积分
ScoreOperation as = new ScoreOperation(ser);
as.addCommonScore(ser.map.get(ser.undercoverId));
ser.sendMsgToAll(new Message(
9,
"法官",
0,
0,
ser.undercoverId
+ "号票数最多,他是卧底,出来混迟早要还的!\r\n卧底都被找出来了,平民胜利!\r\n"
+ ser.undercoverId + "号是卧底,平民词是"
+ common + ",卧底词是" + undercover,
null, null, 0, null, null, 0, null, null));
ser.sendMsgToAll(new Message(
2,
"法官",
0,
0,
"必须惩罚!请输的人摇色子接收惩罚!\r\n(1)自拍:拍一个穷凶极恶的表情\r\n(2)给大家说个重口味段子,不重口不给过\r\n(3)自拍:拍一张翻鼻孔的照片(4)把自己的昵称改成”我是傻逼“\r\n(5)模仿古代特殊职业女子拉客\r\n(6)唱一首周杰伦的歌,不得少于一分钟",
null, null, 0, null, null, 0, null, null));
System.out.println("发送消息9给客户端");
ser.play = 0;
ser.prepare.clear();
ser.die.clear();
ser.id_list.clear();
ser.id_word.clear();
ser.undercoverId = 0;
ser.max = 0;
}
// 返回-3(平民冤死,卧底赢)
else if (result == -3) {
// 发送积分
ser.flag = 1;// 解除旁观
ser.sendMsgToAll(new Message(15, null, ser.flag, 0,
null, null, null, 0, null, null, 0, null,
null));
ScoreOperation so = new ScoreOperation(ser);
int score = so.queryScore(s);
ser.sendMsgToAll(new Message(16, message.getName(),
score, 0, null, null, null, 0, null, null,
0, null, null));
System.out.println("返回-3(平民冤死,卧底赢)");
HandleWord hw = new HandleWord(ser);
hw.handle();
String common = hw.getCommon();
String undercover = hw.getUndercover();
// 加积分
ScoreOperation as = new ScoreOperation(ser);
as.addUndercoverScore(ser.map.get(ser.undercoverId));
// 游戏结束为2
ser.sendMsgToAll(new Message(
9,
"法官",
list.get(0),
2,
list.get(0)
+ "号得票最多,他是平民。平民冤死!卧底胜利!\r\n你这么机智你家里人知道吗?\r\n"
+ ser.undercoverId + "号是卧底,平民词是"
+ common + ",卧底词是" + undercover,
null, null, 0, null, null, 0, null, null));
ser.sendMsgToAll(new Message(
2,
"法官",
0,
0,
"必须惩罚!请输的人摇色子接收惩罚!\r\n(1)自拍:拍一个穷凶极恶的表情\r\n(2)给大家说个重口味段子,不重口不给过\r\n(3)自拍:拍一张翻鼻孔的照片(4)把自己的昵称改成”我是傻逼“\r\n(5)模仿古代特殊职业女子拉客\r\n(6)唱一首周杰伦的歌,不得少于一分钟",
null, null, 0, null, null, 0, null, null));
ser.prepare.clear();
ser.play = 0;
ser.die.clear();
ser.id_list.clear();
ser.id_word.clear();
ser.undercoverId = 0;
ser.max = 0;
}
// 平民冤死,游戏继续(平民编号)
else {
System.out.println("平民冤死,游戏继续");
ser.die.add(list.get(0));
ser.prepare.clear();
ser.play--;
Iterator it = ser.id_word.keySet().iterator();
while (it.hasNext()) {
int key = (int) it.next();
if (!ser.die.contains(key)) {
ser.prepare.add(key);
}
}
System.out.println("冤死后ser.prepare.size()="
+ ser.prepare.size());
// 游戏继续为1
ser.sendMsgToAll(new Message(2, "法官", list.get(0),
list.get(0), list.get(0)
+ "号得票最多,他是平民。\r\n平民冤死!游戏继续!\r\n从"
+ ser.prepare.get(0) + "号开始发言",
null, ser.prepare, 0, null, null, 0, null,
null));
ser.id_speak.clear();
ser.vote.clear();
ser.word_count = 0;
ser.id_list = ser.prepare;
System.out.println();
ser.max = ser.prepare.size();
System.out.println("ser.prepare.size()="
+ ser.prepare.size());
// 请求客户端弹出描述界面
ser.sendMsgToAll(new Message(5, "法官", ser.id_list
.get(0), 0, "正在冥思苦想中。。。", null, null, 0,
null, null, 0, null, null));
ser.id_list.remove(0);
}
}
}
}
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
System.out.println("---------ClassNotFoundException");
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
System.out.println("---------IOException");
// e.printStackTrace();
// ser.id_list.clear();
// ser.id_word.clear();
for (int i = 0; i < ser.allThread.size(); i++) {
if (ser.allThread.get(i).s.equals(s)) {
ser.allThread.remove(i);
ser.total.remove(i);
System.out.println("ser.total=" + ser.total.size());
List total_copylist = new ArrayList<String>();
total_copylist.addAll(ser.total);
ser.total = total_copylist;
List prepare_copylist = new ArrayList<String>();
prepare_copylist.addAll(ser.prepare);
ser.prepare = prepare_copylist;
ser.sendMsgToAll(new Message(1, "法官", 0, 0, s + "退出房间",
ser.total, ser.prepare, 0, null, null, 0, null,
null));
break;
}
}
System.out.println("用户:" + s + "下线啦");
}
}
public void sendMsg(Message msg) {
try {
oos.writeObject(msg);
oos.flush();
System.out.println("已发送message对象流");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}