我将之命名为 ratel,对,没错,平头哥,就是这么霸气(怂
在发这篇主题的时候,ratel 还在开发的最后阶段,已经完成了基本的交互和游戏环节,有待优化,这里放出技术栈:
项目地址:https://github.com/ainilili/ratel
整个流程不难,首先,我需要将客户端和服务端搭起来,netty 提供着简洁的 api,可以快速的部署服务端和客户端,所以这个环节没有任何难度!一个简单的结构图如下:
通讯这一块搞定,接下来要思考的问题就是如何进行互动,这个问题将会引发出更深层的问题?
作为一个正在开发的项目,更多的难以解决的疑难杂症还等待着我去发现,本帖也将持续更新至 ratel 完结。
针对于以上问题的思考之后,我决定将数据持久化在内存中(要考虑 jvm 会不会 gc 掉,所以这里使用 final 修饰 static ),服务端抽象出Room - 游戏房间
,ClientSide - 客户端信息
和Poker - 结构
这三个最主要的数据结构,网路逐渐变得复杂起来
详细结构如下
Room{ Client{ Poker{
int 唯一标识 int 唯一标识 int 大小
int 状态 int 房间标识 int 花色
map 客户端字典 str 昵称 }
list 客户端列表 list 手持牌
int 地主标识 int 状态
int 地主牌 int 类型(农民|地主)
struct 上次出手的信息 client 下手
int 上次出手人 client 上手
} }
每当一个客户端连接时,将会构造一个 Client 对象,分配一个唯一的标识供服务端识别,Room 由客户端建立,并且在此基础之上,其他客户端可以加入已创建且状态未满的房间,当游戏开始后,将会为房间中的所有客户端派发 Poker。
这种流程看似可行,按照这种模式,ratel 由 0 走到了 1
但 ratel 的重点并不止于此,各种问题(网络,安全,用户体验等)还有待解决。
ratel 开发完毕之后,大家工作之余偷偷开心一下,命令行下划划水。
根据大家的建议,对ratel的出牌方式做了一些修改,以及新增客户端退出或者异常断开的应对方案。
新的出牌规则: 3 -> 3 4 -> 4 5 -> 5 6 -> 6 7 -> 7 8 -> 8 9 -> 9 10 -> T/t/0 J -> J/j Q -> Q/q K -> K/k A -> A/a/1 2 -> 2 S(小王)-> S/s X(大王)-> X/x
例如如下牌:
Poker: ┌──┐──┐──┐──┐──┐──┐──┐──┐──┐──┐──┐──┐──┐──┐──┐──┐──┐──┐──┐──┐
│3 |5 |6 |6 |7 |8 |8 |9 |9 |9 |10|J |Q |Q |K |K |2 |2 |2 |X |
│♥ |♥ |♠ |♣ |♣ |♣ |♠ |♦ |♣ |♥ |♥ |♠ |♣ |♥ |♦ |♥ |♠ |♣ |♦ | |
└──┘──┘──┘──┘──┘──┘──┘──┘──┘──┘──┘──┘──┘──┘──┘──┘──┘──┘──┘──┘
出牌的输入是:
56789 t jqk
则输出是:
Poker: ┌──┐──┐──┐──┐──┐──┐──┐──┐──┐
│5 |6 |7 |8 |9 |10|J |Q |K |
│♥ |♠ |♣ |♣ |♦ |♥ |♠ |♣ |♦ |
└──┘──┘──┘──┘──┘──┘──┘──┘──┘
56789 t jqk
将会被解析成{'5','6','7','8','9','t','j','q','k'}并发往服务端进行命中判断及出牌
最后上图
1
cnit 2018-11-06 22:24:00 +08:00
牛皮,我就会 9*9 乘法表
|
2
liaojl 2018-11-06 22:55:23 +08:00 via iPhone
叫地主
|
3
iamniconico OP @liaojl 我抢
|
4
iamniconico OP 大佬低调了,斗地主都是 javase 的知识
|
5
Bigglesworth 2018-11-06 23:33:46 +08:00
要不起
|
6
hourann 2018-11-06 23:36:27 +08:00 via iPhone
牛啊😂
|
7
johnniang 2018-11-06 23:36:55 +08:00 via Android
厉害厉害
|
8
richangfan 2018-11-06 23:38:37 +08:00 via Android
pass
|
9
zaneenaz 2018-11-06 23:40:52 +08:00 via Android
快点啊等到花儿都谢了,😄,厉害。
|
10
iamniconico OP 四个二带俩王,我摊牌了😎
|
11
lovefantasy 2018-11-07 00:08:34 +08:00 via iPhone
大佬啊
|
12
whwq2012 2018-11-07 00:11:28 +08:00 via Android
声音有不
|
13
alakey1989 2018-11-07 00:30:43 +08:00
膜拜老哥
|
14
catinsides 2018-11-07 00:39:33 +08:00
自带 bgm 的主题
|
15
sinv 2018-11-07 01:07:06 +08:00 via iPhone 1
上次有一把,上家在要地主的过程超时了,应该是掉线了,根据规则他就托管了,我一看直接要了 3 分牌还不错,惊喜来了,下家一看直接放弃抵抗也托管了,然后就变成我斗俩机器人农民。
…… …… 干,我特么输了。 被轰了三个炸弹,然后我自己还放了 4 个 A,3 个 2 加一个小鬼憋手里了…… 干 |
16
May725 2018-11-07 02:14:44 +08:00 via iPhone
哈哈,前两年也有在终端斗地主的想法,用 c 写了一半,就没继续下去了。加油,以后 v2 滑水又多了一种方式
|
17
Cbdy 2018-11-07 07:10:55 +08:00 via Android
o 家不是要把 jvm 序列化砍了吗?
|
18
easylee 2018-11-07 07:44:40 +08:00 via Android
有才!看到标题我还在想怎么显示牌呢。戳 star 去咯。
|
19
iamniconico OP @Cbdy java10 不清楚,java8 还在
|
20
iamniconico OP @whwq2012 想法不错,准备试试
|
21
Cbdy 2018-11-07 09:02:02 +08:00
|
23
artandlol 2018-11-07 09:07:53 +08:00
什么时候出 releases
|
24
hfc 2018-11-07 09:09:49 +08:00
请问,你是在考虑涉及完大部分数据结构、逻辑等之后才开始开发的嘛?
|
25
iamniconico OP @artandlol 预计近两周内
|
26
simonguo 2018-11-07 09:12:26 +08:00 via iPhone
👍
|
27
iamniconico OP @hfc 不全是,有些逻辑和数据结构的缺陷是在开发过程中发现的!
|
28
baicheng10 2018-11-07 09:13:57 +08:00
插眼
|
29
loongwang 2018-11-07 09:15:38 +08:00
牛皮牛皮
|
30
KgM4gLtF0shViDH3 2018-11-07 09:16:29 +08:00 via iPhone
花色怎么看啊
|
31
iamniconico OP @Cbdy 看样子是准备要砍了,同时也准备给出弥补?
> To replace the current serialization technology, a small serialization framework would be placed in the platform once records, the Java version of data classes, are supported. The framework could support a graph of records, and developers could plug in a serialization engine of their choice, supporting formats such as JSON or XML, enabling serialization of records in a safe way. But Reinhold cannot yet say which release of Java will have the records capability. |
32
iamniconico OP @bestkayle 看下最后一张图
|
33
reticentfat 2018-11-07 09:18:33 +08:00
出了请通知我
|
34
CodingDoge 2018-11-07 09:19:10 +08:00
划水新境界
|
35
zhang1215 2018-11-07 09:26:08 +08:00 via iPhone
花式划水
|
36
realkenshinji 2018-11-07 09:28:25 +08:00
没有 test ?我们除了 watch 和 star 你的项目,难道不能 contribute ??
|
37
Cbdy 2018-11-07 09:36:09 +08:00
@iamniconico
估计是 JDK 官方出一个 JSON 库吧,类似 GSON 或者 FastXML 转正的感觉 参考一下这个:JSR 374 Specification,https://javaee.github.io/jsonp/ |
38
Daveedo 2018-11-07 09:38:38 +08:00
加油鸭!
|
39
iamniconico OP @realkenshinji 等 Beta 版本完毕
|
40
iamniconico OP @Daveedo 感谢支持
|
41
iamniconico OP @Cbdy json 固然好,我之前也考虑用之,不足的一点是 json 无法传递对象类型,接收方在不知道什么类型的情况下,只能转为 map 结构,数据处理起来不太方便,但是我之后还是会换一种编解码方式的,jvm serialization 局限性太高,影响 ratel client 向 python,shell 发展
|
42
qwe61655 2018-11-07 10:30:42 +08:00 via iPhone
收藏了,
|
43
bullettrain1433 2018-11-07 10:45:15 +08:00
等消息
|
44
loveCoding 2018-11-07 10:47:54 +08:00
@iamniconico #41 pb 序列化吧
|
45
iamniconico OP ratel 不会让大家久等的
|
46
iamniconico OP @loveCoding pb 好麻烦的,回头试试,不知道适不适合当前模型
|
47
lrh3321 2018-11-07 10:59:03 +08:00
star 了
|
48
zclHIT 2018-11-07 11:09:18 +08:00
star 了,坐等 beta test 和 release:)
|
49
iamniconico OP @zclHIT 感谢支持
|
50
tianlang1989 2018-11-07 11:44:58 +08:00
能不能不要有牌的样式 就纯数字就行了
划水利器 先 star 为敬 |
51
iamniconico OP @tianlang1989 好主意,我会提供主题的修改入口的
|
52
tigerZhang 2018-11-07 11:58:54 +08:00
输入 index ,有点蛋疼,能不能通过光标左右选牌
|
53
mason961125 2018-11-07 12:00:32 +08:00
工作量严重不饱和!(滑稽
|
54
leavan 2018-11-07 12:48:28 +08:00
我觉得可以增加选牌的动态效果。比如输入 2,第二张牌就弹出来...比较直观。
|
55
iamniconico OP @tigerZhang 命令行版的应该做不了,我会思考一下的
|
56
iamniconico OP @leavan 优化时会改进一下选牌方案,不过弹出来有点不现实,可能需要 gui 的支持
|
57
natforum 2018-11-07 13:30:26 +08:00 6
|
58
cstj0505 2018-11-07 13:32:11 +08:00
@iamniconico 对象类型作为属性放进去,反序列化先去拿到对象类型
|
59
iamniconico OP @cstj0505 我也这样想过,准备换一种跨平台的方式,优化一下数据传输结构
|
60
leavan 2018-11-07 13:45:54 +08:00
@iamniconico 没有不现实吧,你就在字符界面里牌的顶端留一个空白行,弹出来的就把这张牌空白行放到底端就行了
|
61
kulove 2018-11-07 13:48:47 +08:00
直接输牌数字也行吧?比如对 2,是 2 2,三带一是,9 9 9 6.。
|
62
iamniconico OP @leavan 命令行打印只能 append,不能 modify 之前已经输出的,所以做不到的
|
63
crab 2018-11-07 13:51:28 +08:00
给阿姨倒杯卡布奇诺
|
64
leavan 2018-11-07 13:52:05 +08:00
最好能做一个光标,不需要鼠标,用类似 Vim 的操作模式,然后空格弹出或弹回某张牌,回车出牌,操作模式会简单很多。对这种精致的小项目很喜欢,已 star,不过不太喜欢这种交互性比较少的出牌方式,期待改进哈~
|
65
iamniconico OP @kulove 主意不错,这样方便选取,感谢
|
67
leavan 2018-11-07 13:54:33 +08:00
@iamniconico 我记得是有方法的,你去搜一下某些进度条的实现方式...
|
68
iamniconico OP @leavan 感谢,之后会扩展客户端至其他平台,可能 linux 的 shell 下就可以实现你说的
|
69
iamniconico OP @crab 作者是男的,只是爱好动漫
|
70
ID2333 2018-11-07 14:08:49 +08:00
脑洞真 6,想玩~
|
71
NotNil1 2018-11-07 14:11:12 +08:00
感觉做个下五子棋的会简单一点哈
|
72
1847bell 2018-11-07 14:14:58 +08:00
我的🐴🦆,看得出来你确实很闲……
|
73
NotNil1 2018-11-07 14:20:07 +08:00
客户端代码怎么分发呢
|
74
MicroPan 2018-11-07 14:35:32 +08:00
666,前排关注~
|
75
MrUser 2018-11-07 14:37:40 +08:00
出牌时直接输入要出的牌呗,程序给转成索引,输入 index 太难受了:1=3,3=5,5=6 ……快绕晕了都还怎么记牌
|
76
realpg 2018-11-07 14:47:28 +08:00
@iamniconico #65
其实直接输入牌字母也可以 定义一下两个王是什么符号,比如 A 和 B 然后 1(A)23456789XJQK 问你出啥牌 直接输 111JJ 有效避免图形界面摸鱼困难 另外 提供老板键 一键终端变为编译界面 |
77
iamniconico OP @MrUser 没问题,我也发现这个挺蛋疼的
|
78
iamniconico OP @realpg 我再考虑 10 用什么字母代替,还是说用 0 ?
|
79
realpg 2018-11-07 15:24:57 +08:00
|
80
iamniconico OP 3 4 5 6 7 8 9 T J Q K A 2 S X
3 4 5 6 7 8 9 10 J Q K A 2 小王 大王 单字母取消空格 |
81
iamniconico OP @realpg 可以的,不过 X 我准备用来表示大王
|
82
MrUser 2018-11-07 15:43:46 +08:00
大王大写 W,小王小写 w
|
83
abmin521 2018-11-07 16:02:01 +08:00
前排预定
|
84
Kirscheis 2018-11-07 16:10:24 +08:00 via Android
nb,插个眼
|
85
wsstest 2018-11-07 16:44:49 +08:00
坐等,更新求艾特
|
86
q397064399 2018-11-07 17:07:36 +08:00
现在搞个 Java 依赖是真的多,一下子 springboot 全家桶 全来了
|
87
ginux 2018-11-07 17:15:30 +08:00
服务端的高并发考虑是怎么处理的
|
88
iamniconico OP @ginux
高并发危险点主要在于加入房间这一块,不过也简单,对 status 加 volatile 修饰,处理事件时判断一下,创建房间的 id 分配采用 AtomicInteger 生成 id,客户端的 id 则直接采用 channel 的 socketAddress 在服务端的应用端口。 当然还有一些未知的并发问题和安全问题,之后会加强优化 |
89
iamniconico OP |
90
q397064399 2018-11-07 17:30:27 +08:00
@iamniconico #89 还有目前我都没跑起来你那个程序. 把打包上传到 maven 的跟使用的 隔离开来吧 或者写个打包运行的描述也好.
|
91
susucoolsama 2018-11-07 18:07:34 +08:00
lei 了,想法不错啊,有木有智障对手的设定。
|
92
iamniconico OP |
93
iamniconico OP @wsstest 已更新,看附言<(_ _)>
|
94
dinjufen 2018-11-07 19:02:40 +08:00
看完了我想写一个 GUI 的斗地主,但感觉好难
|
95
iamniconico OP @susucoolsama 说出你的想法
|
96
waruqi 2018-11-07 19:36:59 +08:00 via Android
纯字符?还是用 tui?
|
97
iamniconico OP @waruqi 纯文字
|
98
mseasons 2018-11-07 19:49:28 +08:00
有意思,我去用 Python3 弄一个
|
99
lexuskingxx 2018-11-07 20:16:26 +08:00
牛 13 了
|
100
iamniconico OP @mseasons 我准备将服务端做成通用的,以后你可以考虑用 py 写客户端<(_ _)>
|