首页   注册   登录
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
拉勾
V2EX  ›  程序员

闲来无事,写一个命令行版的斗地主

  •  2
     
  •   iamniconico · 132 天前 · 7606 次点击
    这是一个创建于 132 天前的主题,其中的信息可能已经有所发展或是发生改变。

    我将之命名为 ratel,对,没错,平头哥,就是这么霸气(怂

    在发这篇主题的时候,ratel 还在开发的最后阶段,已经完成了基本的交互和游戏环节,有待优化,这里放出技术栈:

    • 平台:Java
    • 网络包:netty 4.x
    • 通讯协议:TCP/IP
    • 编解码:粗暴的 jvm 字节码

    项目地址:https://github.com/ainilili/ratel

    整个流程不难,首先,我需要将客户端和服务端搭起来,netty 提供着简洁的 api,可以快速的部署服务端和客户端,所以这个环节没有任何难度!一个简单的结构图如下:

    通讯这一块搞定,接下来要思考的问题就是如何进行互动,这个问题将会引发出更深层的问题?

    • 1、服务端如何存储客户端信息
    • 2、服务端如何识别客户端
    • 3、Poker 出牌的操作怎么通过命令行完成
    • 4、Poker 的类型鉴定与比较
    • 5、命令行如何显示客户端的回合计时
    • 6、客户端掉线
    • 7、其余未知问题

    作为一个正在开发的项目,更多的难以解决的疑难杂症还等待着我去发现,本帖也将持续更新至 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 开发完毕之后,大家工作之余偷偷开心一下,命令行下划划水。

    第 1 条附言  ·  131 天前

    根据大家的建议,对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'}并发往服务端进行命中判断及出牌

    最后上图

    第 2 条附言  ·  126 天前
    107 回复  |  直到 2019-01-14 15:39:11 +08:00
    1  2  
        101
    XiLemon   131 天前 via iPhone
    👍🏻
        102
    khxu   130 天前
    666 楼主的想法真的很活跃
        103
    iamniconico   130 天前
    @khxu 想着划水玩
        104
    q397064399   130 天前
    @iamniconico #92 是不是发错了..
        105
    wsstest   126 天前
    装好了,但是貌似没人
        106
    iamniconico   126 天前
    @wsstest 加群一起玩 948365095
        107
    sybrave   63 天前
    插眼
    1  2  
    关于   ·   FAQ   ·   API   ·   我们的愿景   ·   广告投放   ·   感谢   ·   实用小工具   ·   4019 人在线   最高记录 4385   ·  
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.3 · 19ms · UTC 02:43 · PVG 10:43 · LAX 19:43 · JFK 22:43
    ♥ Do have faith in what you're doing.
    沪ICP备16043287号-1