想不到能这样摸鱼 | go 技术论坛-380玩彩网官网入口

介绍

想不到有一天我也能在写代码的同时还能斗一把小地主!

这种休闲 摸鱼 模式想法来自逛掘金时看到这篇文章 介绍的ratel。有兴趣的小伙伴可以直接搜索ratel具体了解。本着一个探索瞎折腾的心,决定仿照ratel实现自己的fish项目。

这款游戏基于golang实现,目前仅支持pvp模式,后续有时间再支持更多的模式。

项目地址

技术栈

  • golang
  • socketio

安装

首先下载编译,确保本地安装有golang环境

git clone git@github.com:yangchen5710/fish_client.git
cd fish_client
go build fish_client

接下来在终端下执行可执行文件

  • windows

    client.exe 47.101.212.202 8096
  • linux/macos

    ./client 47.101.212.202 8096

玩法

为啥论坛不能上传gif了?
想不到能这样摸鱼

出牌规则

所有牌型:

┌──┐──┐──┐──┐──┐──┐──┐──┐──┐──┐──┐──┐──┐──┐──┐
│3 |4 |5 |6 |7 |8 |9 |10|j |q |k |a |2 |s |x |
│♦ |||||||||||||  |  |
└──┘──┘──┘──┘──┘──┘──┘──┘──┘──┘──┘──┘──┘──┘──┘
  • 王炸: sx
  • 顺子: 34567
  • 三带一: 3334
  • 三带二: 33344
  • 飞机: 333444a2
  • 单张10: t
  • 单张a: a
  • 封顶顺子: 3456789tjqka
  • 不想出牌: pass

算法实现

首先我们先定义相关结构和接口以及相关常量

 const (
    rocket            = 12
    bomb              = 11
    pair              = 10
    three             = 9
    threewithone      = 8
    threewithtwo      = 7
    singlestraight    = 6
    doublestraight    = 5
    threestraight     = 4
    aircraftwithwings = 3
    fourwithtwo       = 2
    single            = 1
)
 type poker struct {
    level string //牌的数值
    type  string //牌的类型
}
type pokermath struct {
    pokertype   int
    minvalue    int
    pokerlength int
}
type pokeralgorithm interface {
    isrocket(poker, poker) (bool, pokermath)       //火箭 即大小王
    isbomb([]poker) (bool, pokermath)              //炸弹 四张同数值牌
    ispair([]poker) (bool, pokermath)              //对牌 数值相同的两张牌
    isthree([]poker) (bool, pokermath)             //三张牌 数值相同的三张牌
    isthreewithone([]poker) (bool, pokermath)      //三带一 数值相同的三张牌   一张单牌
    isthreewithtwo([]poker) (bool, pokermath)      //三带二 数值相同的三张牌   一张对牌
    issinglestraight([]poker) (bool, pokermath)    //单顺 五张或更多的连续单牌(如:45678 或 789tjqk)。不包括 2 点和双王
    isdoublestraight([]poker) (bool, pokermath)    //双顺 三对或更多的连续对牌(如:334455 、77 88 99 1010 jj)。不包括 2 点和双王
    isthreestraight([]poker) (bool, pokermath)     //三顺:二个或更多的连续三张牌(如:333444 、 555 666 777 888)。不包括 2 点和双王
    isaircraftwithwings([]poker) (bool, pokermath) //飞机带翅膀:三顺 同数量的单牌(或同数量的对牌)
    isfourwithtwo([]poker) (bool, pokermath)       //四带二:四张牌 两手牌(注意:四带二不是炸弹)。
    issingle(poker) (bool, pokermath)              //单牌
    comparepokers(pokermath, pokermath) bool       //比较牌型和大小
}

然后去实现相关的接口算法

func (pm pokermath) isrocket(poker1, poker2 poker) (boolean bool, pokermath pokermath) {
    boolean = (poker1.level == "level_small_king" && poker2.level == "level_big_king") ||
        (poker1.level == "level_big_king" && poker2.level == "level_small_king")
    if boolean {
        pokermath = pokermath{pokertype: rocket, minvalue: 0, pokerlength: 2}
    }
    return
}
func (pm pokermath) isbomb(pokers []poker) (boolean bool, pokermath pokermath) {
    boolean = false
    if len(pokers) != 4 {
        return
    }
    valuemap := make(map[string]int)
    for _, poker := range pokers {
        valuemap[poker.level]
    }
    for pokerlevel, count := range valuemap {
        if count == 4 {
            boolean = true
            pokermath = pokermath{pokertype: bomb, minvalue: converttovalueinit(pokerlevel), pokerlength: 4}
            return
        }
    }
    return
}
func (pm pokermath) ispair(pokers []poker) (boolean bool, pokermath pokermath) {
    boolean = false
    if len(pokers) != 2 {
        return
    }
    valuemap := make(map[string]int)
    for _, poker := range pokers {
        valuemap[poker.level]
    }
    for pokerlevel, count := range valuemap {
        if count == 2 {
            boolean = true
            pokermath = pokermath{pokertype: pair, minvalue: converttovalueinit(pokerlevel), pokerlength: 2}
            return
        }
    }
    return
}
func (pm pokermath) isthree(pokers []poker) (boolean bool, pokermath pokermath) {
    boolean = false
    if len(pokers) != 3 {
        return
    }
    valuemap := make(map[string]int)
    for _, poker := range pokers {
        valuemap[poker.level]
    }
    for pokerlevel, count := range valuemap {
        if count == 3 {
            boolean = true
            pokermath = pokermath{pokertype: three, minvalue: converttovalueinit(pokerlevel), pokerlength: 3}
            return
        }
    }
    return
}
func (pm pokermath) isthreewithone(pokers []poker) (boolean bool, pokermath pokermath) {
    boolean = false
    if len(pokers) != 4 {
        return
    }
    sort.slice(pokers, func(i, j int) bool {
        return pokers[i].level < pokers[j].level
    })
    // 判断是否是三带一,即第一个三张牌点数相同,且第四张牌与其中一张牌的点数不同
    if pokers[0].level == pokers[1].level && pokers[1].level == pokers[2].level &&
        pokers[2].level != pokers[3].level {
        boolean = true
        pokermath = pokermath{pokertype: threewithone, minvalue: converttovalueinit(pokers[0].level), pokerlength: 4}
        return
    }
    // 也可以判断最后三张牌是否相同点数
    if pokers[1].level == pokers[2].level && pokers[2].level == pokers[3].level &&
        pokers[0].level != pokers[1].level {
        boolean = true
        pokermath = pokermath{pokertype: threewithone, minvalue: converttovalueinit(pokers[1].level), pokerlength: 4}
        return
    }
    return
}
func (pm pokermath) isthreewithtwo(pokers []poker) (boolean bool, pokermath pokermath) {
    boolean = false
    if len(pokers) != 5 {
        return
    }
    sort.slice(pokers, func(i, j int) bool {
        return pokers[i].level < pokers[j].level
    })
    // 判断是否是三带二
    if pokers[0].level == pokers[1].level && pokers[1].level == pokers[2].level &&
        pokers[3].level == pokers[4].level && pokers[2].level != pokers[3].level {
        boolean = true
        pokermath = pokermath{pokertype: threewithtwo, minvalue: converttovalueinit(pokers[0].level), pokerlength: 5}
        return
    }
    // 也可以判断三张和两张的位置对调
    if pokers[0].level == pokers[1].level && pokers[2].level == pokers[3].level &&
        pokers[3].level == pokers[4].level && pokers[1].level != pokers[2].level {
        boolean = true
        pokermath = pokermath{pokertype: threewithtwo, minvalue: converttovalueinit(pokers[2].level), pokerlength: 5}
        return
    }
    return
}
func (pm pokermath) issinglestraight(pokers []poker) (boolean bool, pokermath pokermath) {
    boolean = false
    if len(pokers) < 5 {
        return
    }
    sort.slice(pokers, func(i, j int) bool {
        // 将牌的值转换为对应的数值进行比较
        val1 := converttovalue(pokers[i].level)
        val2 := converttovalue(pokers[j].level)
        return val1 < val2
    })
    // 检查牌是否连续
    for i := 0; i < len(pokers)-1; i {
        if converttovalue(pokers[i1].level)-converttovalue(pokers[i].level) != 1 {
            return // 如果有间断,不是单顺
        }
    }
    boolean = true
    pokermath = pokermath{pokertype: singlestraight, minvalue: converttovalueinit(pokers[0].level), pokerlength: len(pokers)}
    return
}
func (pm pokermath) isdoublestraight(pokers []poker) (boolean bool, pokermath pokermath) {
    boolean = false
    if len(pokers)%2 != 0 || len(pokers) < 6 {
        return // 牌数必须是偶数且至少6张才可能是双顺
    }
    // 对牌进行排序
    sort.slice(pokers, func(i, j int) bool {
        // 将牌的值转换为对应的数值进行比较
        val1 := converttovalue(pokers[i].level)
        val2 := converttovalue(pokers[j].level)
        return val1 < val2
    })
    fmt.println(pokers)
    // 检查牌是否连续成对
    for i := 0; i < len(pokers)-1; i  = 2 {
        if converttovalue(pokers[i].level) != converttovalue(pokers[i1].level) ||
            (i > 0 && converttovalue(pokers[i].level)-converttovalue(pokers[i-1].level) != 1) {
            return // 如果不是成对连续,不是双顺
        }
    }
    boolean = true
    pokermath = pokermath{pokertype: doublestraight, minvalue: converttovalueinit(pokers[0].level), pokerlength: len(pokers)}
    return
}
func (pm pokermath) isthreestraight(pokers []poker) (boolean bool, pokermath pokermath) {
    boolean = false
    if len(pokers)%3 != 0 || len(pokers) < 6 {
        return // 牌数必须是3的倍数且至少6张才可能是三顺
    }
    // 对牌进行排序
    sort.slice(pokers, func(i, j int) bool {
        // 将牌的值转换为对应的数值进行比较
        val1 := converttovalue(pokers[i].level)
        val2 := converttovalue(pokers[j].level)
        return val1 < val2
    })
    // 检查牌是否连续三张
    for i := 0; i < len(pokers)-2; i  = 3 {
        if converttovalue(pokers[i].level) != converttovalue(pokers[i1].level) ||
            converttovalue(pokers[i].level) != converttovalue(pokers[i2].level) ||
            (i > 0 && converttovalue(pokers[i].level)-converttovalue(pokers[i-1].level) != 1) {
            return
        }
    }
    boolean = true
    pokermath = pokermath{pokertype: threestraight, minvalue: converttovalueinit(pokers[0].level), pokerlength: len(pokers)}
    return
}
func (pm pokermath) isaircraftwithwings(pokers []poker) (boolean bool, pokermath pokermath) {
    boolean = false
    if len(pokers)%4 != 0 || len(pokers) < 8 {
        return // 牌数必须是4的倍数且至少8张才可能是飞机带翅膀
    }
    // 对牌进行排序
    sort.slice(pokers, func(i, j int) bool {
        // 将牌的值转换为对应的数值进行比较
        val1 := converttovalue(pokers[i].level)
        val2 := converttovalue(pokers[j].level)
        return val1 < val2
    })
    // 计算连续三张的数量
    triplecount := 0
    minvalue := ""
    for i := 0; i < len(pokers)-2; i {
        if converttovalue(pokers[i].level) == converttovalue(pokers[i1].level) &&
            converttovalue(pokers[i].level) == converttovalue(pokers[i2].level) {
            triplecount
            if minvalue == "" {
                minvalue = pokers[i].level
            }
        }
    }
    // 检查是否有连续三张的数量大于等于2
    if triplecount < 2 {
        return // 如果连续三张的数量不足2组,不是飞机带翅膀
    }
    boolean = true
    pokermath = pokermath{pokertype: aircraftwithwings, minvalue: converttovalueinit(minvalue), pokerlength: len(pokers)}
    return
}
func (pm pokermath) isfourwithtwo(pokers []poker) (boolean bool, pokermath pokermath) {
    boolean = false
    if len(pokers) != 6 {
        return // 必须是六张牌才可能是四带二
    }
    // 对牌进行排序
    sort.slice(pokers, func(i, j int) bool {
        // 将牌的值转换为对应的数值进行比较
        val1 := converttovalue(pokers[i].level)
        val2 := converttovalue(pokers[j].level)
        return val1 < val2
    })
    // 计算四张牌的数量
    fourcount := 0
    minvalue := ""
    for i := 0; i < len(pokers)-3; i {
        if converttovalue(pokers[i].level) == converttovalue(pokers[i1].level) &&
            converttovalue(pokers[i].level) == converttovalue(pokers[i2].level) &&
            converttovalue(pokers[i].level) == converttovalue(pokers[i3].level) {
            fourcount
            if minvalue == "" {
                minvalue = pokers[i].level
            }
        }
    }
    // 检查是否有四张牌
    if fourcount != 1 {
        return // 如果不是四张牌,不是四带二
    }
    // 计算两张其他牌的数量
    othercount := 0
    for i := 0; i < len(pokers)-1; i {
        if converttovalue(pokers[i].level) != converttovalue(pokers[i1].level) {
            othercount
        }
    }
    if othercount != 1 {
        return // 如果不是两张其他牌,不是四带二
    }
    boolean = true
    pokermath = pokermath{pokertype: fourwithtwo, minvalue: converttovalueinit(minvalue), pokerlength: len(pokers)}
    return
}
func (pm pokermath) issingle(poker poker) (boolean bool, pokermath pokermath) {
    boolean = true
    pokermath = pokermath{pokertype: single, minvalue: converttovalueinit(poker.level), pokerlength: 1}
    return
}
func (pm pokermath) comparepokers(roompokermath, playerpokermath pokermath) bool {
    roompokertype := roompokermath.pokertype
    roompokerlength := roompokermath.pokerlength
    roomminvalue := roompokermath.minvalue
    if roompokertype == playerpokermath.pokertype &&
        roompokerlength == playerpokermath.pokerlength &&
        roomminvalue < playerpokermath.minvalue {
        return true
    }
    if roompokertype != playerpokermath.pokertype {
        switch roompokertype {
        case bomb:
            if playerpokermath.pokertype == rocket {
                return true
            }
        case pair, three, threewithone, threewithtwo, singlestraight, doublestraight, threestraight, aircraftwithwings, fourwithtwo, single:
            if playerpokermath.pokertype == rocket || playerpokermath.pokertype == bomb {
                return true
            }
        }
    }
    return false
}
func (pm pokermath) converttovaluestring(cardvalue string) string {
    valuemap := map[string]string{
        "3": "level_3", "4": "level_4", "5": "level_5", "6": "level_6",
        "7": "level_7", "8": "level_8", "9": "level_9",
        "0": "level_10", "t": "level_10", "t": "level_10",
        "j": "level_j", "j": "level_j",
        "q": "level_q", "q": "level_q",
        "k": "level_k", "k": "level_k",
        "a": "level_a", "a": "level_a", "1": "level_a",
        "2": "level_2",
        "s": "level_small_king", "s": "level_small_king",
        "x": "level_big_king", "x": "level_big_king",
    }
    return valuemap[cardvalue]
}
// 辅助函数:将牌的值转换为数值
func converttovalueinit(cardvalue string) int {
    valuemap := map[string]int{
        "level_3": 3, "level_4": 4, "level_5": 5, "level_6": 6, "level_7": 7,
        "level_8": 8, "level_9": 9, "level_10": 10, "level_j": 11, "level_q": 12,
        "level_k": 13, "level_a": 14, "level_2": 15, "level_small_king": 16, "level_big_king": 17,
    }
    return valuemap[cardvalue]
}
func converttovalue(cardvalue string) int {
    value := converttovalueinit(cardvalue)
    if value == 15 || value == 16 || value == 17 {
        value = -1
    }
    return value
}

计划

  • 支持pve
  • 支持个人得分
本作品采用《cc 协议》,转载必须注明作者和本文链接
to live is to change the world
讨论数量: 0
(= ̄ω ̄=)··· 暂无内容!

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!
网站地图