LollipopGo开源游戏服务器框架--子游戏服务器源码

栏目: 后端 · 发布时间: 5年前

内容简介:大家好,我是彬哥,本节给大家讲下LollipopGov1.0.20190102版本游戏服务器子游戏服务器,抛砖引玉了,主要是针对Go语言游戏服务器子游戏斗兽棋服务器处理。每天坚持学习1小时Go语言,大家加油,我是彬哥,下期见!如果文章中不同观点、意见请文章下留言或者关注下方订阅号反馈!

大家好,我是彬哥,本节给大家讲下LollipopGov1.0.20190102版本游戏服务器子游戏服务器,抛砖引玉了,主要是针对 Go 语言游戏服务器子游戏斗兽棋服务器处理。

package main

import (
    "LollipopGo/LollipopGo/log"
    "Proto"
    "Proto/Proto2"
    "cache2go"
    "flag"
    "fmt"
    "net/rpc"
    "net/rpc/jsonrpc"
    "strings"
    "time"

    "LollipopGo/LollipopGo/util"
    _ "LollipopGo/ReadCSV"

    _ "LollipopGo/LollipopGo/player"

    "code.google.com/p/go.net/websocket"
)

var addrDSQ = flag.String("addrDSQ", "127.0.0.1:8888", "http service address") // 链接gateway
var ConnDSQ *websocket.Conn                                                    // 保存用户的链接信息,数据会在主动匹配成功后进行链接
var ConnDSQRPC *rpc.Client                                                     // 链接DB server
var DSQAllMap map[string]*RoomPlayerDSQ                                        // 游戏逻辑存储
var DSQ_qi = []int{                                                            // 1-8 A ;9-16 B ; 17 未翻牌; 18 已翻牌
    Proto2.Elephant, Proto2.Lion, Proto2.Tiger, Proto2.Leopard, Proto2.Wolf, Proto2.Dog, Proto2.Cat, Proto2.Mouse,
    Proto2.Mouse + Proto2.Elephant, Proto2.Mouse + Proto2.Lion, Proto2.Mouse + Proto2.Tiger, Proto2.Mouse + Proto2.Leopard,
    Proto2.Mouse + Proto2.Wolf, Proto2.Mouse + Proto2.Dog, Proto2.Mouse + Proto2.Cat, 2 * Proto2.Mouse}
var cacheDSQ *cache2go.CacheTable
var DSQLeftTime int = 30
var DSQTimeSpeed = time.Millisecond * 2000

type RoomPlayerDSQ struct {
    RoomID       int
    IsRoomID     bool
    OpenIDA      string
    OpenIDB      string
    OpenIDA_Seat int       // 默认是0; 1 表示坐下
    OpenIDB_Seat int       // 默认是0; 1 表示坐下
    Default      [4][4]int // 未翻牌的
    ChessData    [4][4]int // 棋盘数据
    ReChessData  [4][4]int // 重连棋盘数据
    AChessNum    int       // A的剩余的棋子的数量
    BChessNum    int       // B的剩余的棋子的数量
    GoAround     int       // 回合,如果每人出10次都没有吃子,系统推送平局;第七个回合提示数据 第10局平局
    LeftTime     int       // 剩余的时间
}

/*

    -----------------------------------------
    |                                       |
    |   [0,0]01 [1,0]02 [2,0]03 [3,0]04     |
    |                                       |
    |                                       |
    |   [0,1]05 [1,1]06 [2,1]07 [3,1]08     |
    |                                       |
    |                                       |
    |   [0,2]09 [1,2]10 [2,2]11 [3,2]12     |
    |                                       |
    |                                       |
    |   [0,3]13 [1,3]14 [2,3]15 [3,3]16     |
    |                                       |
    -----------------------------------------

*/

// 初始化操作
func init() {
    //if strServerType == "DSQ" {
    if !initDSQGateWayNet() {
        fmt.Println("链接 gateway server 失败!")
        return
    }
    fmt.Println("链接 gateway server 成功!")
    // 初始化数据
    initDSQNetRPC()
    //}
    return
}

// 初始化RPC
func initDSQNetRPC() {
    client, err := jsonrpc.Dial("tcp", service)
    if err != nil {
        log.Debug("dial error:", err)
    }
    ConnDSQRPC = client
    cacheDSQ = cache2go.Cache("LollipopGo_DSQ")
}

// 初始化网关
func initDSQGateWayNet() bool {

    fmt.Println("用户客户端客户端模拟!")
    log.Debug("用户客户端客户端模拟!")
    url := "ws://" + *addrDSQ + "/GolangLtd"
    conn, err := websocket.Dial(url, "", "test://golang/")
    if err != nil {
        fmt.Println("err:", err.Error())
        return false
    }
    ConnDSQ = conn
    // 协程支持  --接受线程操作 全球协议操作
    go GameServerReceiveDSQ(ConnDSQ)
    // 发送链接的协议 ---》
    initConnDSQ(ConnDSQ)
    return true
}

// 链接到网关
func initConnDSQ(conn *websocket.Conn) {
    fmt.Println("---------------------------------")
    // 协议修改
    data := &Proto2.DSQ2GW_ConnServer{
        Protocol:  Proto.G_GameDSQ_Proto, // 游戏主要协议
        Protocol2: Proto2.DSQ2GW_ConnServerProto2,
        ServerID:  util.MD5_LollipopGO("8895" + "DSQ server"),
    }
    fmt.Println(data)
    // 2 发送数据到服务器
    PlayerSendToServer(conn, data)
    return
}

// 处理数据
func GameServerReceiveDSQ(ws *websocket.Conn) {
    for {
        var content string
        err := websocket.Message.Receive(ws, &content)
        if err != nil {
            fmt.Println(err.Error())
            continue
        }
        // decode
        fmt.Println(strings.Trim("", "\""))
        fmt.Println(content)
        content = strings.Replace(content, "\"", "", -1)
        contentstr, errr := base64Decode([]byte(content))
        if errr != nil {
            fmt.Println(errr)
            continue
        }
        // 解析数据 --
        fmt.Println("返回数据:", string(contentstr))
        go SyncMeassgeFunDSQ(string(contentstr))
    }
}

// 链接分发 处理
func SyncMeassgeFunDSQ(content string) {
    var r Requestbody
    r.req = content

    if ProtocolData, err := r.Json2map(); err == nil {
        // 处理我们的函数
        HandleCltProtocolDSQ(ProtocolData["Protocol"], ProtocolData["Protocol2"], ProtocolData)
    } else {
        log.Debug("解析失败:", err.Error())
    }
}

//  主协议处理
func HandleCltProtocolDSQ(protocol interface{}, protocol2 interface{}, ProtocolData map[string]interface{}) {
    defer func() { // 必须要先声明defer,否则不能捕获到panic异常
        if err := recover(); err != nil {
            strerr := fmt.Sprintf("%s", err)
            //发消息给客户端
            ErrorST := Proto2.G_Error_All{
                Protocol:  Proto.G_Error_Proto,      // 主协议
                Protocol2: Proto2.G_Error_All_Proto, // 子协议
                ErrCode:   "80006",
                ErrMsg:    "亲,您发的数据的格式不对!" + strerr,
            }
            // 发送给玩家数据
            fmt.Println("Global server的主协议!!!", ErrorST)
        }
    }()

    // 协议处理
    switch protocol {
    case float64(Proto.G_GameDSQ_Proto):
        { // DSQ Server 主要协议处理
            fmt.Println("DSQ server 主协议!!!")
            HandleCltProtocol2DSQ(protocol2, ProtocolData)
        }
    default:
        panic("主协议:不存在!!!")
    }
    return
}

// 子协议的处理
func HandleCltProtocol2DSQ(protocol2 interface{}, ProtocolData map[string]interface{}) {

    switch protocol2 {
    case float64(Proto2.GW2G_ConnServerProto2):
        {
            fmt.Println("gateway server DSQ server 数据信息!!!")
        }
    case float64(Proto2.GW2DSQ_InitGameProto2):
        {
            fmt.Println("网关请求获取棋盘初始化数据等")
            DSQ2GW_PlayerGameInitProto2Fucn(ConnDSQ, ProtocolData)
        }
    case float64(Proto2.GW2DSQ_PlayerStirChessProto2):
        {
            fmt.Println("玩家翻棋子的协议")
            GW2DSQ_PlayerStirChessProto2Fucn(ConnDSQ, ProtocolData)
        }
    case float64(Proto2.GW2DSQ_PlayerMoveChessProto2):
        {
            fmt.Println("玩家移动棋子的协议")
            GW2DSQ_PlayerMoveChessProto2Fucn(ConnDSQ, ProtocolData)
        }
    case float64(Proto2.GW2DSQ_PlayerGiveUpProto2):
        {
            fmt.Println("玩家放弃游戏的协议")
            GW2DSQ_PlayerGiveUpProto2Fucn(ConnDSQ, ProtocolData)
        }
    case float64(Proto2.GW2DSQ_PlayerRelinkGameProto2):
        {
            fmt.Println("玩家重新链接游戏的协议")
            GW2DSQ_PlayerRelinkGameProto2Fucn(ConnDSQ, ProtocolData)
        }
    default:
        panic("子协议:不存在!!!")
    }
    return
}

func GW2DSQ_PlayerRelinkGameProto2Fucn(conn *websocket.Conn, ProtocolData map[string]interface{}) {
    if ProtocolData["OpenID"] == nil ||
        ProtocolData["RoomUID"] == nil {
        panic(ProtocolData)
        return
    }
    StrOpenID := ProtocolData["OpenID"].(string)
    iRoomID := int(ProtocolData["RoomUID"].(float64))
    redata, lefttime := CacheGetReChessData(iRoomID)
    // 发送数据
    data := &Proto2.DSQ2GW_PlayerRelinkGame{
        Protocol:  Proto.G_GameDSQ_Proto,
        Protocol2: Proto2.DSQ2GW_PlayerRelinkGameProto2,
        OpenIDA:   StrOpenID,
        // OpenIDB   string
        LeftTime:  lefttime,
        ChessData: redata,
    }
    PlayerSendToServer(conn, data)
    return
}

func GW2DSQ_PlayerGiveUpProto2Fucn(conn *websocket.Conn, ProtocolData map[string]interface{}) {

    fmt.Println("玩家数据为空--GW2DSQ_PlayerGiveUpProto2Fucn")

    if ProtocolData["OpenID"] == nil ||
        ProtocolData["RoomUID"] == nil {
        panic(ProtocolData)
        return
    }
    StrOpenID := ProtocolData["OpenID"].(string)
    iRoomID := int(ProtocolData["RoomUID"].(float64))
    // 发送数据
    data := &Proto2.DSQ2GW_BroadCast_GameOver{
        Protocol:  Proto.G_GameDSQ_Proto,
        Protocol2: Proto2.DSQ2GW_BroadCast_GameOverProto2,
        IsDraw:    false,
        OpenIDA:   StrOpenID,                                          // 默认失败
        OpenIDB:   CacheGetOtherPlayerByPlayerUID(iRoomID, StrOpenID), // 胜利者的
        //      FailGameLev_Exp: "" + ",0",                                                                   // 格式: 1,10
        //      SuccGameLev_Exp: "" + ",10",                                                                  // 格式: 1,10
        //      FailPlayer:      nil,                                                                         // 失败者
        //      SuccPlayer:      nil,                                                                         // 胜利者
    }
    PlayerSendToServer(conn, data)
    // 删除房间数据
    cacheDSQ.Delete(iRoomID)

    return
    //--------------------------------------------------------------------------
    // 失败者*数据保存到db
    dbdata := &Proto2.DB_GameOver{
        OpenID:    data.OpenIDA,
        GameID:    Proto2.DSQ_GameID,
        GameLev:   0,
        GameExp:   0,
        GameScore: 0,
        GameItem:  "",
    }
    ModefyGamePlayerDataGameInfo(dbdata)
    // 胜利者*数据保存到db
    if true {
        dbdata := &Proto2.DB_GameOver{
            OpenID:    data.OpenIDB,
            GameID:    Proto2.DSQ_GameID,
            GameLev:   0,                  // 查询
            GameExp:   Proto2.DSQ_GameExp, // 增加的经验,等级DB/GW自己计算
            GameScore: 0,
            GameItem:  "",
        }
        ModefyGamePlayerDataGameInfo(dbdata)
    }
    //--------------------------------------------------------------------------
    return
    // gamelev := util.Sort_LollipopGo(conf.DSQGameExp, expdata+data.GameExp)
}

// 修改数据
func ModefyGamePlayerDataGameInfo(data *Proto2.DB_GameOver) interface{} {

    args := data
    // 返回的数据
    var reply bool
    //--------------------------------------------------------------------------
    // 同步调用
    // err = ConnRPC_GM.Call("Arith.SavePlayerDataST2DB", args, &reply)
    // if err != nil {
    //  fmt.Println("Arith.SavePlayerDataST2DB call error:", err)
    // }
    // 异步调用
    divCall := ConnRPC_GM.Go("Arith.SavePlayerDataST2DB", args, &reply, nil)
    replyCall := <-divCall.Done // will be equal to divCall
    fmt.Println(replyCall.Reply)
    //--------------------------------------------------------------------------
    // 返回的数据
    fmt.Println("ModefyGamePlayerDataGameInfo :", reply)
    return reply
}

func GW2DSQ_PlayerMoveChessProto2Fucn(conn *websocket.Conn, ProtocolData map[string]interface{}) {
    if ProtocolData["OpenID"] == nil ||
        ProtocolData["RoomUID"] == nil {
        panic(ProtocolData)
        return
    }

    StrOpenID := ProtocolData["OpenID"].(string)
    iRoomID := int(ProtocolData["RoomUID"].(float64))
    StrOldPos := ProtocolData["OldPos"].(string)
    iMoveDir := int(ProtocolData["MoveDir"].(float64))
    // if GetPlayerChupai(StrOpenID) {
    //  data := &Proto2.DSQ2GW_PlayerMoveChess{
    //      Protocol:  Proto.G_GameDSQ_Proto,
    //      Protocol2: Proto2.DSQ2GW_PlayerMoveChessProto2,
    //  }
    //  data.ResultID = 60003
    //  PlayerSendToServer(conn, data)
    //  return
    // } else {
    //  SetPlayerChupai(StrOpenID)
    // }

    // 1,是否可以移动(一定位置是都已经翻,移动的位置是否是自己人)
    // 2,移动成功,更新棋盘位置
    stropenida, stropenidb, strnewpos := CacheMoveChessIsUpdateData(iRoomID, StrOldPos, iMoveDir, StrOpenID)
    data := &Proto2.DSQ2GW_PlayerMoveChess{
        Protocol:  Proto.G_GameDSQ_Proto,
        Protocol2: Proto2.DSQ2GW_PlayerMoveChessProto2,
        OpenIDA:   StrOpenID,
        OpenIDB:   stropenidb,
        RoomUID:   iRoomID,
        OldPos:    StrOldPos,
        NewPos:    strnewpos,
    }
    // fmt.Println("++++++++++++++++++++", stropenidb)
    // fmt.Println("++++++++++++++++++++", stropenida)
    // fmt.Println("++++++++++++++++++++", data)
    if StrOpenID != stropenida {
        data.OpenIDB = stropenida
    }
    // 检测棋子
    CheckGameIsOver(iRoomID, StrOpenID)
    // fmt.Println("++++++++++++++++++++", data)
    PlayerSendToServer(conn, data)
    return
}

func GW2DSQ_PlayerStirChessProto2Fucn(conn *websocket.Conn, ProtocolData map[string]interface{}) {

    if ProtocolData["OpenID"] == nil ||
        ProtocolData["RoomUID"] == nil {
        panic(ProtocolData)
        return
    }

    StrOpenID := ProtocolData["OpenID"].(string)
    iRoomID := int(ProtocolData["RoomUID"].(float64))
    StrStirPos := ProtocolData["StirPos"].(string)

    data := &Proto2.DSQ2GW_PlayerStirChess{
        Protocol:  Proto.G_GameDSQ_Proto,
        Protocol2: Proto2.DSQ2GW_PlayerStirChessProto2,
        OpenID:    StrOpenID,
        OpenID_b:  "",
        StirPos:   StrStirPos,
        ResultID:  0,
    }
    // if GetPlayerChupai(StrOpenID) {
    //  data.ResultID = 60003
    //  PlayerSendToServer(conn, data)
    //  return
    // } else {
    //  SetPlayerChupai(StrOpenID)
    // }

    // 通过位置获取对应的数据
    _, idata := CacheGetChessDefaultData(iRoomID, StrStirPos, 2, 18)
    data.ChessNum = idata
    stropenid := CacheGetPlayerUID(iRoomID, StrOpenID)
    data.OpenID_b = stropenid
    // fmt.Println("++++++++++++++++++++", stropenid)
    // 发送数据
    PlayerSendToServer(conn, data)

    return
}

func DSQ2GW_PlayerGameInitProto2Fucn(conn *websocket.Conn, ProtocolData map[string]interface{}) {

    if ProtocolData["OpenID"] == nil ||
        ProtocolData["RoomID"] == nil {
        panic("玩家数据错误!!!")
        return
    }
    StrOpenID := ProtocolData["OpenID"].(string)
    StrRoomID := ProtocolData["RoomID"].(string)
    iRoomID := util.Str2int_LollipopGo(StrRoomID)
    retdata, bret, iret := CacheGetRoomDataByRoomID(iRoomID, StrOpenID)
    // iret := CacheGetRoomDataByPlayer(iRoomID, StrOpenID)
    if bret {
        data := &Proto2.DSQ2GW_InitGame{
            Protocol:  Proto.G_GameDSQ_Proto,
            Protocol2: Proto2.DSQ2GW_InitGameProto2,
            OpenID:    StrOpenID,
            RoomID:    StrRoomID,
            SeatNum:   iret,
            InitData:  retdata,
        }
        fmt.Println(data)
        PlayerSendToServer(conn, data)
        //
        //CacheSavePlayerUID(iRoomID, StrOpenID)
        return
    }
    data1 := [4][4]int{{2*Proto2.Mouse + 1, 2*Proto2.Mouse + 1, 2*Proto2.Mouse + 1, 2*Proto2.Mouse + 1},
        {2*Proto2.Mouse + 1, 2*Proto2.Mouse + 1, 2*Proto2.Mouse + 1, 2*Proto2.Mouse + 1},
        {2*Proto2.Mouse + 1, 2*Proto2.Mouse + 1, 2*Proto2.Mouse + 1, 2*Proto2.Mouse + 1},
        {2*Proto2.Mouse + 1, 2*Proto2.Mouse + 1, 2*Proto2.Mouse + 1, 2*Proto2.Mouse + 1}}
    var DSQ_qinei = []int{ // 1-8 A ;9-16 B ; 17 未翻牌; 18 已翻牌
        Proto2.Elephant, Proto2.Lion, Proto2.Tiger, Proto2.Leopard, Proto2.Wolf, Proto2.Dog, Proto2.Cat, Proto2.Mouse,
        Proto2.Mouse + Proto2.Elephant, Proto2.Mouse + Proto2.Lion, Proto2.Mouse + Proto2.Tiger, Proto2.Mouse + Proto2.Leopard,
        Proto2.Mouse + Proto2.Wolf, Proto2.Mouse + Proto2.Dog, Proto2.Mouse + Proto2.Cat, 2 * Proto2.Mouse}
    DSQ_Pai := InitDSQ(DSQ_qinei)
    savedata := &RoomPlayerDSQ{
        RoomID:      iRoomID,
        IsRoomID:    true,
        Default:     data1,
        ChessData:   DSQ_Pai,
        ReChessData: data1,
    }
    CacheSaveRoomData(iRoomID, savedata, StrOpenID)
    data := &Proto2.DSQ2GW_InitGame{
        Protocol:  Proto.G_GameDSQ_Proto,
        Protocol2: Proto2.DSQ2GW_InitGameProto2,
        OpenID:    StrOpenID,
        RoomID:    StrRoomID,
        SeatNum:   1,
        InitData:  DSQ_Pai,
    }
    PlayerSendToServer(conn, data)
    // cserli go CheckGameOfPlayerLeftTime(iRoomID, conn)
    return
}

//------------------------------------------------------------------------------
func CheckGameOfPlayerLeftTime(iRoomID int, conn *websocket.Conn) {

    for {
        select {
        case <-time.After(DSQTimeSpeed):
            {
                res, err1 := cacheDSQ.Value(iRoomID)
                if err1 != nil {
                    continue
                }
                ilefttime := res.Data().(*RoomPlayerDSQ).LeftTime
                inowtime := int(util.GetNowUnix_LollipopGo())
                if inowtime-ilefttime > DSQLeftTime {
                    data := &Proto2.DSQ2GW_BroadCast_GameOver{
                        Protocol:  Proto.G_GameDSQ_Proto,
                        Protocol2: Proto2.DSQ2GW_BroadCast_GameOverProto2,
                        IsDraw:    false,
                    }
                    data.OpenIDA = res.Data().(*RoomPlayerDSQ).OpenIDA
                    data.OpenIDB = res.Data().(*RoomPlayerDSQ).OpenIDB
                    PlayerSendToServer(conn, data)
                    return
                }
            }
        }
    }
    return
}

//------------------------------------------------------------------------------
// 吃掉棋子去检测
func CheckGameIsOver(iRoomID int, strpopenid string) bool {

    fmt.Println("吃掉棋子去检测")
    res, err1 := cacheDSQ.Value(iRoomID)
    if err1 != nil {
        // panic("没有对应数据")
        return false
    }

    // 结束
    data := &Proto2.DSQ2GW_BroadCast_GameOver{
        Protocol:  Proto.G_GameDSQ_Proto,
        Protocol2: Proto2.DSQ2GW_BroadCast_GameOverProto2,
        IsDraw:    false,
    }

    if res.Data().(*RoomPlayerDSQ).OpenIDA == strpopenid {
        idataB := res.Data().(*RoomPlayerDSQ).BChessNum
        fmt.Println("已经吃掉几个B", idataB)
        if idataB == 8 {
            data.OpenIDA = strpopenid
            data.OpenIDB = res.Data().(*RoomPlayerDSQ).OpenIDB
            PlayerSendToServer(ConnDSQ, data)
            return true
        }
        idataA := res.Data().(*RoomPlayerDSQ).AChessNum
        fmt.Println("已经吃掉几个A", idataA)
        if idataA == 8 {
            data.OpenIDA = res.Data().(*RoomPlayerDSQ).OpenIDB
            data.OpenIDB = strpopenid
            PlayerSendToServer(ConnDSQ, data)
            return true
        }
    }

    if res.Data().(*RoomPlayerDSQ).OpenIDB == strpopenid {
        idataA := res.Data().(*RoomPlayerDSQ).AChessNum
        fmt.Println("已经吃掉几个A", idataA)
        if idataA == 8 {
            data.OpenIDA = strpopenid
            data.OpenIDB = res.Data().(*RoomPlayerDSQ).OpenIDA
            PlayerSendToServer(ConnDSQ, data)
            return true
        }

        idataB := res.Data().(*RoomPlayerDSQ).BChessNum
        fmt.Println("已经吃掉几个B", idataB)
        if idataB == 8 {
            data.OpenIDA = res.Data().(*RoomPlayerDSQ).OpenIDA
            data.OpenIDB = strpopenid
            PlayerSendToServer(ConnDSQ, data)
            return true
        }
    }

    return false
}

//------------------------------------------------------------------------------
func SetRecord_A_B_chess(itype int) {
    // A B
    cacheDSQ.Add(itype, 0, 1)
    return
}

func GetRecord_A_B_chess(itype int) int {

    return 0
}

//------------------------------------------------------------------------------
func SetPlayerChupai(OpenID string) {
    cacheDSQ.Add(OpenID, 0, "exit")
}

func DelPlayerChupai(OpenID string) {
    cacheDSQ.Delete(OpenID)
}

func GetPlayerChupai(OpenID string) bool {
    ok := false
    _, err1 := cacheDSQ.Value(OpenID)
    if err1 == nil {
        ok = true
    }
    return ok
}

//------------------------------------------------------------------------------

func CacheSaveRoomData(iRoomID int, data *RoomPlayerDSQ, openid string) {
    fmt.Println("save data:", data)
    cacheDSQ.Add(iRoomID, 0, data)
    CacheSavePlayerUID(iRoomID, openid)
}

func CacheGetOtherPlayerByPlayerUID(iRoomID int, player string) string {
    res, err1 := cacheDSQ.Value(iRoomID)
    if err1 != nil {
        //panic("没有对应数据")
        return ""
    }
    if res.Data().(*RoomPlayerDSQ).OpenIDA == player {
        return res.Data().(*RoomPlayerDSQ).OpenIDB
    } else {
        return res.Data().(*RoomPlayerDSQ).OpenIDA
    }
    return ""
}

func CacheGetPlayerUID(iRoomID int, player string) string {
    res, err1 := cacheDSQ.Value(iRoomID)
    if err1 != nil {
        //panic("没有对应数据")
        return ""
    }
    fmt.Println("save data:", player)
    fmt.Println("save data:", res.Data().(*RoomPlayerDSQ).OpenIDA)
    fmt.Println("save data:", res.Data().(*RoomPlayerDSQ).OpenIDB)

    if res.Data().(*RoomPlayerDSQ).OpenIDA == player {
        return res.Data().(*RoomPlayerDSQ).OpenIDB
    }
    if res.Data().(*RoomPlayerDSQ).OpenIDB == player {
        return res.Data().(*RoomPlayerDSQ).OpenIDA
    }

    return ""
}

func CacheSavePlayerUID(iRoomID int, player string) {
    res, err1 := cacheDSQ.Value(iRoomID)
    if err1 != nil {
        //panic("没有对应数据")
        return
    }
    fmt.Println("result:", res.Data().(*RoomPlayerDSQ).OpenIDA)
    fmt.Println("result:", res.Data().(*RoomPlayerDSQ).OpenIDB)
    if len(res.Data().(*RoomPlayerDSQ).OpenIDA) == 0 {
        res.Data().(*RoomPlayerDSQ).OpenIDA = player
    } else {
        res.Data().(*RoomPlayerDSQ).OpenIDB = player
    }
    fmt.Println("result:", res.Data().(*RoomPlayerDSQ).OpenIDA)
    fmt.Println("result:", res.Data().(*RoomPlayerDSQ).OpenIDB)
    return
}

func CacheGetRoomDataByRoomID(iRoomID int, opneid string) ([4][4]int, bool, int) {
    res, err1 := cacheDSQ.Value(iRoomID)
    if err1 != nil {
        // panic("棋盘数据更新失败!")
        return [4][4]int{{}, {}, {}, {}}, false, 0
    }
    fmt.Println("n>1获取棋盘数据", iRoomID)
    if !res.Data().(*RoomPlayerDSQ).IsRoomID {
        return [4][4]int{{}, {}, {}, {}}, false, 0
    }

    if len(res.Data().(*RoomPlayerDSQ).OpenIDA) == 0 {
        res.Data().(*RoomPlayerDSQ).OpenIDA = opneid
        res.Data().(*RoomPlayerDSQ).OpenIDA_Seat = 1
        fmt.Println("----------------n>1获取棋盘数据res.Data().(*RoomPlayerDSQ).OpenIDB", res.Data().(*RoomPlayerDSQ).OpenIDB)
        fmt.Println("----------------n>1获取棋盘数据res.Data().(*RoomPlayerDSQ).OpenIDA", res.Data().(*RoomPlayerDSQ).OpenIDA)
        return res.Data().(*RoomPlayerDSQ).ChessData, true, 1
    }

    if len(res.Data().(*RoomPlayerDSQ).OpenIDB) == 0 {
        res.Data().(*RoomPlayerDSQ).OpenIDB = opneid
        res.Data().(*RoomPlayerDSQ).OpenIDB_Seat = 1
        fmt.Println("+++++++++++++n>1获取棋盘数据res.Data().(*RoomPlayerDSQ).OpenIDB", res.Data().(*RoomPlayerDSQ).OpenIDB)
        fmt.Println("++++++++++++++n>1获取棋盘数据res.Data().(*RoomPlayerDSQ).OpenIDA", res.Data().(*RoomPlayerDSQ).OpenIDA)
        return res.Data().(*RoomPlayerDSQ).ChessData, true, 0
    }

    return [4][4]int{{}, {}, {}, {}}, false, 0
}

func CacheGetRoomDataByPlayer(iRoomID int, opneid string) int {
    res, err1 := cacheDSQ.Value(iRoomID)
    if err1 != nil {
        //panic("棋盘数据更新失败!")
    }
    fmt.Println("n>1获取棋盘数据", iRoomID, opneid)

    if res.Data().(*RoomPlayerDSQ).OpenIDA == opneid {
        return res.Data().(*RoomPlayerDSQ).OpenIDA_Seat
    }

    if res.Data().(*RoomPlayerDSQ).OpenIDB == opneid {
        return res.Data().(*RoomPlayerDSQ).OpenIDB_Seat
    }

    if len(res.Data().(*RoomPlayerDSQ).OpenIDA) == 0 {
        res.Data().(*RoomPlayerDSQ).OpenIDA = opneid
        res.Data().(*RoomPlayerDSQ).OpenIDA_Seat = 1
        return 1
    }

    if len(res.Data().(*RoomPlayerDSQ).OpenIDB) == 0 {
        res.Data().(*RoomPlayerDSQ).OpenIDB = opneid
        res.Data().(*RoomPlayerDSQ).OpenIDB_Seat = 1
        return 0
    }
    fmt.Println("座位出错", iRoomID, opneid)
    return 0
}

func CacheUpdateRoomData(iRoomID int, Update_pos string, value int) {

    res, err1 := cacheDSQ.Value(iRoomID)
    if err1 != nil {
        //panic("棋盘数据更新失败!")
        return
    }

    ipos_x := 0
    ipos_y := 0
    strsplit := Strings_Split(Update_pos, ",")
    if len(strsplit) != 2 {
        panic("棋盘数据更新失败!")
        return
    }
    for i := 0; i < len(strsplit); i++ {
        if i == 0 {
            ipos_x = util.Str2int_LollipopGo(strsplit[i])
        } else {
            ipos_y = util.Str2int_LollipopGo(strsplit[i])
        }
    }
    fmt.Println("修改的棋盘的坐标", ipos_x, ipos_y)
    // 测试数据
    fmt.Println("result:", res.Data().(*RoomPlayerDSQ).ChessData[ipos_x][ipos_y])
    res.Data().(*RoomPlayerDSQ).ChessData[ipos_x][ipos_y] = value
    fmt.Println("result:", res.Data().(*RoomPlayerDSQ).ChessData[ipos_x][ipos_y])
    return
}

// 检查是否是七个回合没有吃棋子
func CheckIs7GoAround(iGoAround int, OpenIDA string, OpenIDB string, iRoomID int) {

    if iGoAround == 7 {
        fmt.Println("吃掉棋子去检测 --》7")
        data := &Proto2.DSQ_GameHint{
            Protocol:  Proto.G_GameDSQ_Proto,
            Protocol2: Proto2.DSQ_GameHintProto2,
            OpenIDA:   OpenIDA,
            OpenIDB:   OpenIDB,
        }
        PlayerSendToServer(ConnDSQ, data)
    } else if iGoAround == 10 {

        fmt.Println("吃掉棋子去检测 --》10")
        res, err1 := cacheDSQ.Value(iRoomID)
        if err1 != nil {
            return
        }

        // 结束
        data := &Proto2.DSQ2GW_BroadCast_GameOver{
            Protocol:  Proto.G_GameDSQ_Proto,
            Protocol2: Proto2.DSQ2GW_BroadCast_GameOverProto2,
            IsDraw:    true,
            OpenIDA:   OpenIDA,
            OpenIDB:   OpenIDB,
        }
        PlayerSendToServer(ConnDSQ, data)
        res.Data().(*RoomPlayerDSQ).GoAround = 0

        // 清除棋盘数据
        cacheDSQ.Delete(iRoomID)
    }
    return
}

// 获取重新链接数据
func CacheGetReChessData(iRoomID int) ([4][4]int, int) {

    res, err1 := cacheDSQ.Value(iRoomID)
    if err1 != nil {
        panic("棋盘数据获取数据失败!")
    }
    return res.Data().(*RoomPlayerDSQ).ReChessData, res.Data().(*RoomPlayerDSQ).LeftTime
}

// 移动期盼是否可以移动
func CacheMoveChessIsUpdateData(iRoomID int, Update_pos string, MoveDir int, stropenid string) (string, string, string) {
    res, err1 := cacheDSQ.Value(iRoomID)
    if err1 != nil {
        //panic("棋盘数据获取数据失败!")
        return "", "", ""
    }
    ipos_x := 0
    ipos_y := 0
    strsplit := Strings_Split(Update_pos, ",")
    if len(strsplit) != 2 {
        panic("棋盘数据获取数据失败!")
        return "", "", ""
    }
    for i := 0; i < len(strsplit); i++ {
        if i == 0 {
            ipos_x = util.Str2int_LollipopGo(strsplit[i])
        } else {
            ipos_y = util.Str2int_LollipopGo(strsplit[i])
        }
    }

    fmt.Println("修改的棋盘的坐标", ipos_x, ipos_y)
    iyunalaiX, iyunalaiY := ipos_x, ipos_y
    // 原来的值:
    iyuanlai := res.Data().(*RoomPlayerDSQ).ChessData[ipos_x][ipos_y]

    // 方向
    if MoveDir == Proto2.UP {
        ipos_y -= 1
    } else if MoveDir == Proto2.DOWN {
        ipos_y += 1
    } else if MoveDir == Proto2.LEFT {
        ipos_x -= 1
    } else if MoveDir == Proto2.RIGHT {
        ipos_x += 1
    }
    sendopenid, otheropenid := "", ""
    if res.Data().(*RoomPlayerDSQ).OpenIDA == stropenid {
        sendopenid = res.Data().(*RoomPlayerDSQ).OpenIDA
        otheropenid = res.Data().(*RoomPlayerDSQ).OpenIDB
    } else if res.Data().(*RoomPlayerDSQ).OpenIDB == stropenid {
        sendopenid = res.Data().(*RoomPlayerDSQ).OpenIDB
        otheropenid = res.Data().(*RoomPlayerDSQ).OpenIDA
    }
    ihoulai := res.Data().(*RoomPlayerDSQ).ChessData[ipos_x][ipos_y]
    strnewpos := util.Int2str_LollipopGo(ipos_x) + "," + util.Int2str_LollipopGo(ipos_y)
    if ihoulai == 0 {
        res.Data().(*RoomPlayerDSQ).ChessData[ipos_x][ipos_y] = iyuanlai
        res.Data().(*RoomPlayerDSQ).ChessData[iyunalaiX][iyunalaiY] = 0

        res.Data().(*RoomPlayerDSQ).ReChessData[ipos_x][ipos_y] = iyuanlai
        res.Data().(*RoomPlayerDSQ).ReChessData[iyunalaiX][iyunalaiY] = 0

        res.Data().(*RoomPlayerDSQ).GoAround++
        CheckIs7GoAround(res.Data().(*RoomPlayerDSQ).GoAround, sendopenid, otheropenid, iRoomID)

        res.Data().(*RoomPlayerDSQ).LeftTime = int(util.GetNowUnix_LollipopGo())
        return sendopenid, otheropenid, strnewpos
    }
    // 移动的位置
    bret, _ := CacheGetChessDefaultData(iRoomID, strnewpos, 1, 0)
    if !bret {
        res.Data().(*RoomPlayerDSQ).ChessData[ipos_x][ipos_y] = ihoulai
        res.Data().(*RoomPlayerDSQ).ChessData[iyunalaiX][iyunalaiY] = iyuanlai

        res.Data().(*RoomPlayerDSQ).ReChessData[ipos_x][ipos_y] = ihoulai
        res.Data().(*RoomPlayerDSQ).ReChessData[iyunalaiX][iyunalaiY] = iyuanlai

        res.Data().(*RoomPlayerDSQ).LeftTime = int(util.GetNowUnix_LollipopGo())
        return sendopenid, otheropenid, ""
    }
    // 判断是否可以吃,1 大小; 2 是都是同一方
    if iyuanlai > 8 && ihoulai > 8 {
        fmt.Println("都大于8", ipos_x, ipos_y)
        // res.Data().(*RoomPlayerDSQ).ChessData[ipos_x][ipos_y] = ihoulai
        // res.Data().(*RoomPlayerDSQ).ChessData[iyunalaiX][iyunalaiY] = iyuanlai
        return sendopenid, otheropenid, ""
    } else if iyuanlai <= 8 && ihoulai <= 8 {
        fmt.Println("都小于8", ipos_x, ipos_y)
        // res.Data().(*RoomPlayerDSQ).ChessData[ipos_x][ipos_y] = ihoulai
        // res.Data().(*RoomPlayerDSQ).ChessData[iyunalaiX][iyunalaiY] = iyuanlai
        return sendopenid, otheropenid, ""
    }

    if iyuanlai <= 8 && ihoulai > 8 {
        if iyuanlai == 1 && ihoulai-Proto2.Mouse == 8 {
            // 大象吃不了老鼠
            return sendopenid, otheropenid, ""
        }
        res.Data().(*RoomPlayerDSQ).GoAround = 0
        res.Data().(*RoomPlayerDSQ).LeftTime = int(util.GetNowUnix_LollipopGo())
        if iyuanlai == 8 && ihoulai-Proto2.Mouse == 1 {
            res.Data().(*RoomPlayerDSQ).ChessData[ipos_x][ipos_y] = iyuanlai
            res.Data().(*RoomPlayerDSQ).ChessData[iyunalaiX][iyunalaiY] = 0

            res.Data().(*RoomPlayerDSQ).ReChessData[ipos_x][ipos_y] = iyuanlai
            res.Data().(*RoomPlayerDSQ).ReChessData[iyunalaiX][iyunalaiY] = 0

            if stropenid == res.Data().(*RoomPlayerDSQ).OpenIDA {
                res.Data().(*RoomPlayerDSQ).BChessNum++
            } else {
                res.Data().(*RoomPlayerDSQ).AChessNum++
            }

            // CheckIs7GoAround(res.Data().(*RoomPlayerDSQ).GoAround, sendopenid, otheropenid, iRoomID)

            return sendopenid, otheropenid, strnewpos
        }
        if iyuanlai < ihoulai-Proto2.Mouse { // 可以吃
            res.Data().(*RoomPlayerDSQ).ChessData[ipos_x][ipos_y] = iyuanlai
            res.Data().(*RoomPlayerDSQ).ChessData[iyunalaiX][iyunalaiY] = 0

            res.Data().(*RoomPlayerDSQ).ReChessData[ipos_x][ipos_y] = iyuanlai
            res.Data().(*RoomPlayerDSQ).ReChessData[iyunalaiX][iyunalaiY] = 0
            if stropenid == res.Data().(*RoomPlayerDSQ).OpenIDA {
                res.Data().(*RoomPlayerDSQ).BChessNum++
            } else {
                res.Data().(*RoomPlayerDSQ).AChessNum++
            }
            return sendopenid, otheropenid, strnewpos

        } else if iyuanlai == ihoulai-Proto2.Mouse { // 同归于尽
            res.Data().(*RoomPlayerDSQ).ChessData[ipos_x][ipos_y] = 0
            res.Data().(*RoomPlayerDSQ).ChessData[iyunalaiX][iyunalaiY] = 0

            res.Data().(*RoomPlayerDSQ).ReChessData[ipos_x][ipos_y] = 0
            res.Data().(*RoomPlayerDSQ).ReChessData[iyunalaiX][iyunalaiY] = 0
            res.Data().(*RoomPlayerDSQ).AChessNum++
            res.Data().(*RoomPlayerDSQ).BChessNum++
            return sendopenid, otheropenid, strnewpos

        } else if iyuanlai > ihoulai-Proto2.Mouse { // 自毁
            res.Data().(*RoomPlayerDSQ).ChessData[iyunalaiX][iyunalaiY] = 0

            res.Data().(*RoomPlayerDSQ).ReChessData[iyunalaiX][iyunalaiY] = 0

            if stropenid == res.Data().(*RoomPlayerDSQ).OpenIDA {
                res.Data().(*RoomPlayerDSQ).BChessNum++
            } else {
                res.Data().(*RoomPlayerDSQ).AChessNum++
            }
            return sendopenid, otheropenid, strnewpos
        }

        return sendopenid, otheropenid, strnewpos

    } else if iyuanlai > 8 && ihoulai <= 8 {

        if iyuanlai-Proto2.Mouse == 1 && ihoulai == Proto2.Mouse {
            // 大象吃不了老鼠
            return "", "", ""
        }

        // sendopenid, otheropenid := "", ""
        // if res.Data().(*RoomPlayerDSQ).OpenIDA == stropenid {
        //  sendopenid = res.Data().(*RoomPlayerDSQ).OpenIDA
        //  otheropenid = res.Data().(*RoomPlayerDSQ).OpenIDB
        // } else if res.Data().(*RoomPlayerDSQ).OpenIDB == stropenid {
        //  sendopenid = res.Data().(*RoomPlayerDSQ).OpenIDB
        //  otheropenid = res.Data().(*RoomPlayerDSQ).OpenIDA
        // }
        res.Data().(*RoomPlayerDSQ).GoAround = 0
        res.Data().(*RoomPlayerDSQ).LeftTime = int(util.GetNowUnix_LollipopGo())
        if iyuanlai-Proto2.Mouse == 8 && ihoulai == 1 {
            res.Data().(*RoomPlayerDSQ).ChessData[ipos_x][ipos_y] = iyuanlai
            res.Data().(*RoomPlayerDSQ).ChessData[iyunalaiX][iyunalaiY] = 0

            res.Data().(*RoomPlayerDSQ).ReChessData[ipos_x][ipos_y] = iyuanlai
            res.Data().(*RoomPlayerDSQ).ReChessData[iyunalaiX][iyunalaiY] = 0
            if stropenid == res.Data().(*RoomPlayerDSQ).OpenIDA {
                res.Data().(*RoomPlayerDSQ).BChessNum++
            } else {
                res.Data().(*RoomPlayerDSQ).AChessNum++
            }
            return sendopenid, otheropenid, strnewpos
        }

        if iyuanlai-Proto2.Mouse < ihoulai { // 可以吃
            res.Data().(*RoomPlayerDSQ).ChessData[ipos_x][ipos_y] = iyuanlai
            res.Data().(*RoomPlayerDSQ).ChessData[iyunalaiX][iyunalaiY] = 0

            res.Data().(*RoomPlayerDSQ).ReChessData[ipos_x][ipos_y] = iyuanlai
            res.Data().(*RoomPlayerDSQ).ReChessData[iyunalaiX][iyunalaiY] = 0
            if stropenid == res.Data().(*RoomPlayerDSQ).OpenIDA {
                res.Data().(*RoomPlayerDSQ).BChessNum++
            } else {
                res.Data().(*RoomPlayerDSQ).AChessNum++
            }
            return sendopenid, otheropenid, strnewpos

        } else if iyuanlai-Proto2.Mouse == ihoulai { // 同归于尽
            res.Data().(*RoomPlayerDSQ).ChessData[ipos_x][ipos_y] = 0
            res.Data().(*RoomPlayerDSQ).ChessData[iyunalaiX][iyunalaiY] = 0

            res.Data().(*RoomPlayerDSQ).ReChessData[ipos_x][ipos_y] = 0
            res.Data().(*RoomPlayerDSQ).ReChessData[iyunalaiX][iyunalaiY] = 0
            res.Data().(*RoomPlayerDSQ).AChessNum++
            res.Data().(*RoomPlayerDSQ).BChessNum++
            return sendopenid, otheropenid, strnewpos

        } else if iyuanlai-Proto2.Mouse < ihoulai { // 自毁
            res.Data().(*RoomPlayerDSQ).ChessData[iyunalaiX][iyunalaiY] = 0

            res.Data().(*RoomPlayerDSQ).ReChessData[iyunalaiX][iyunalaiY] = 0

            if stropenid == res.Data().(*RoomPlayerDSQ).OpenIDA {
                res.Data().(*RoomPlayerDSQ).BChessNum++
            } else {
                res.Data().(*RoomPlayerDSQ).AChessNum++
            }
            return sendopenid, otheropenid, strnewpos
        }

        return sendopenid, otheropenid, strnewpos
    }

    return "", "", ""
}

// 获取默认棋牌数据是否翻开
// true 表示翻开了
// itype ==1 查询是否翻开
// itype ==2 修改数据
func CacheGetChessDefaultData(iRoomID int, Update_pos string, itype int, valve int) (bool, int) {
    res, err1 := cacheDSQ.Value(iRoomID)
    if err1 != nil {
        //panic("棋盘数据获取数据失败!")
        return false, -1
    }
    ipos_x := 0
    ipos_y := 0
    strsplit := Strings_Split(Update_pos, ",")
    if len(strsplit) != 2 {
        panic("棋盘数据获取数据失败!")
        return false, -1
    }
    for i := 0; i < len(strsplit); i++ {
        if i == 0 {
            ipos_x = util.Str2int_LollipopGo(strsplit[i])
        } else {
            ipos_y = util.Str2int_LollipopGo(strsplit[i])
        }
    }
    fmt.Println("修改的棋盘的坐标", ipos_x, ipos_y)
    if itype == 1 {
        // 获取
        fmt.Println("result:", res.Data().(*RoomPlayerDSQ).Default[ipos_x][ipos_y])
        idata := res.Data().(*RoomPlayerDSQ).Default[ipos_x][ipos_y]
        if idata == (2*Proto2.Mouse + 1) {
            return false, -1
        } else {
            return true, -1
        }
    } else if itype == 2 {
        // 修改翻盘结构
        fmt.Println("result:", res.Data().(*RoomPlayerDSQ).Default[ipos_x][ipos_y])
        res.Data().(*RoomPlayerDSQ).Default[ipos_x][ipos_y] = valve
        res.Data().(*RoomPlayerDSQ).LeftTime = int(util.GetNowUnix_LollipopGo())
        return true, res.Data().(*RoomPlayerDSQ).ChessData[ipos_x][ipos_y]
    }
    return false, -1
}

//------------------------------------------------------------------------------
// 初始化牌型
func InitDSQ(data1 []int) [4][4]int {

    data, erdata, j, k := data1, [4][4]int{}, 0, 0

    for i := 0; i < Proto2.Mouse*2; i++ {
        icount := util.RandInterval_LollipopGo(0, int32(len(data))-1)
        //fmt.Println("随机数:", icount)
        if len(data) == 1 {
            erdata[3][3] = data[0]
        } else {
            //------------------------------------------------------------------
            if int(icount) < len(data) {
                erdata[j][k] = data[icount]
                k++
                if k%4 == 0 {
                    j++
                    k = 0
                }
                data = append(data[:icount], data[icount+1:]...)
            } else {
                erdata[j][k] = data[icount]
                k++
                if k%4 == 0 {
                    j++
                    k = 0
                }
                data = data[:icount-1]
            }
            //------------------------------------------------------------------
        }
        //fmt.Println("生成的数据", erdata)
    }

    return erdata
}

// 判断棋子大小
// 玩家操作移动,操作协议
func CheckIsEat(fangx int, qizi int, qipan [4][4]int) (bool, int, [4][4]int) {
    if qizi > 16 || qizi < 1 {
        log.Debug("玩家发送棋子数据不对!")
        return false, Proto2.DATANOEXIT, qipan
    }
    // 1 寻找 玩家的棋子在棋牌的位置/或者这个棋子是否存在
    bret, Posx, posy := CheckChessIsExit(qizi, qipan)
    if bret {
        bret, iret, data := CheckArea(fangx, Posx, posy, qipan)
        return bret, iret, data
    } else {
        log.Debug("玩家发送棋子不存在!疑似外挂。")
        return false, Proto2.DATAERROR, qipan
    }

    return true, 0, qipan
}

// 检查棋盘中是不是存在
func CheckChessIsExit(qizi int, qipan [4][4]int) (bool, int, int) {
    for i := 0; i < 4; i++ {
        for j := 0; j < 4; j++ {
            if qipan[i][j] == qizi {
                return true, i, j
            }
        }
    }
    return false, 0, 0
}

// 边界判断
func CheckArea(fangx, iposx, iposy int, qipan [4][4]int) (bool, int, [4][4]int) {

    if fangx == Proto2.UP {
        if iposy == 0 {
            return false, Proto2.MOVEFAIL, qipan // 无法移动
        }
        data_yidong := qipan[iposx][iposy-1]
        data := qipan[iposx][iposy]
        // 判断是空地不
        if data_yidong == 0 {
            data_ret := UpdateChessData(Proto2.MOVE, iposx, iposy-1, iposx, iposy, qipan)
            return true, Proto2.MOVESUCC, data_ret // 移动成功
        }
        // 对比棋子大小
        if data < 9 {
            if data_yidong < 9 {
                return false, Proto2.TEAMMATE, qipan // 自己人
            } else {
                if data_yidong > data {
                    data_ret := UpdateChessData(Proto2.DISAPPEAR, iposx, iposy-1, iposx, iposy, qipan)
                    return true, Proto2.DISAPPEAR, data_ret // 自残
                } else if data_yidong == data {
                    data_ret := UpdateChessData(Proto2.ALLDISAPPEAR, iposx, iposy-1, iposx, iposy, qipan)
                    return true, Proto2.ALLDISAPPEAR, data_ret // 同归于尽
                } else if data_yidong < data {
                    data_ret := UpdateChessData(Proto2.BEAT, iposx, iposy-1, iposx, iposy, qipan)
                    return true, Proto2.BEAT, data_ret // 吃掉对方
                }
            }
        } else {
            if data_yidong > 9 {
                return false, Proto2.TEAMMATE, qipan // 自己人
            } else {
                if data_yidong > data {
                    data_ret := UpdateChessData(Proto2.DISAPPEAR, iposx, iposy-1, iposx, iposy, qipan)
                    return true, Proto2.DISAPPEAR, data_ret // 自残
                } else if data_yidong == data {
                    data_ret := UpdateChessData(Proto2.ALLDISAPPEAR, iposx, iposy-1, iposx, iposy, qipan)
                    return true, Proto2.ALLDISAPPEAR, data_ret // 同归于尽
                } else if data_yidong < data {
                    data_ret := UpdateChessData(Proto2.BEAT, iposx, iposy-1, iposx, iposy, qipan)
                    return true, Proto2.BEAT, data_ret // 吃掉对方
                }
            }
        }

    } else if fangx == Proto2.DOWN {

        if iposy == 3 {
            return false, Proto2.MOVEFAIL, qipan // 无法移动
        }
        data_yidong := qipan[iposx][iposy+1]
        data := qipan[iposx][iposy]
        // 判断是空地不
        if data_yidong == 0 {
            data_ret := UpdateChessData(Proto2.MOVE, iposx, iposy+1, iposx, iposy, qipan)
            return true, Proto2.MOVESUCC, data_ret // 移动成功
        }
        // 对比棋子大小
        if data < 9 {
            if data_yidong < 9 {
                return false, Proto2.TEAMMATE, qipan // 自己人
            } else {
                if data_yidong > data {
                    data_ret := UpdateChessData(Proto2.DISAPPEAR, iposx, iposy+1, iposx, iposy, qipan)
                    return true, Proto2.DISAPPEAR, data_ret // 自残
                } else if data_yidong == data {
                    data_ret := UpdateChessData(Proto2.ALLDISAPPEAR, iposx, iposy+1, iposx, iposy, qipan)
                    return true, Proto2.ALLDISAPPEAR, data_ret // 同归于尽
                } else if data_yidong < data {
                    data_ret := UpdateChessData(Proto2.BEAT, iposx, iposy+1, iposx, iposy, qipan)
                    return true, Proto2.BEAT, data_ret // 吃掉对方
                }
            }
        } else {
            if data_yidong > 9 {
                return false, Proto2.TEAMMATE, qipan // 自己人
            } else {
                if data_yidong > data {
                    data_ret := UpdateChessData(Proto2.DISAPPEAR, iposx, iposy+1, iposx, iposy, qipan)
                    return true, Proto2.DISAPPEAR, data_ret // 自残
                } else if data_yidong == data {
                    data_ret := UpdateChessData(Proto2.ALLDISAPPEAR, iposx, iposy+1, iposx, iposy, qipan)
                    return true, Proto2.ALLDISAPPEAR, data_ret // 同归于尽
                } else if data_yidong < data {
                    data_ret := UpdateChessData(Proto2.BEAT, iposx, iposy+1, iposx, iposy, qipan)
                    return true, Proto2.BEAT, data_ret // 吃掉对方
                }
            }
        }

    } else if fangx == Proto2.LEFT {
        if iposx == 0 {
            return false, Proto2.MOVEFAIL, qipan // 无法移动
        }
        data_yidong := qipan[iposx-1][iposy]
        data := qipan[iposx][iposy]
        // 判断是空地不
        if data_yidong == 0 {
            data_ret := UpdateChessData(Proto2.MOVE, iposx-1, iposy, iposx, iposy, qipan)
            return true, Proto2.MOVESUCC, data_ret // 移动成功
        }
        // 对比棋子大小
        if data < 9 {
            if data_yidong < 9 {
                return false, Proto2.TEAMMATE, qipan // 自己人
            } else {
                if data_yidong > data {
                    data_ret := UpdateChessData(Proto2.DISAPPEAR, iposx-1, iposy, iposx, iposy, qipan)
                    return true, Proto2.DISAPPEAR, data_ret // 自残
                } else if data_yidong == data {
                    data_ret := UpdateChessData(Proto2.ALLDISAPPEAR, iposx-1, iposy, iposx, iposy, qipan)
                    return true, Proto2.ALLDISAPPEAR, data_ret // 同归于尽
                } else if data_yidong < data {
                    data_ret := UpdateChessData(Proto2.BEAT, iposx-1, iposy, iposx, iposy, qipan)
                    return true, Proto2.BEAT, data_ret // 吃掉对方
                }
            }
        } else {
            if data_yidong > 9 {
                return false, Proto2.TEAMMATE, qipan // 自己人
            } else {
                if data_yidong > data {
                    data_ret := UpdateChessData(Proto2.DISAPPEAR, iposx-1, iposy, iposx, iposy, qipan)
                    return true, Proto2.DISAPPEAR, data_ret // 自残
                } else if data_yidong == data {
                    data_ret := UpdateChessData(Proto2.ALLDISAPPEAR, iposx-1, iposy, iposx, iposy, qipan)
                    return true, Proto2.ALLDISAPPEAR, data_ret // 同归于尽
                } else if data_yidong < data {
                    data_ret := UpdateChessData(Proto2.BEAT, iposx-1, iposy, iposx, iposy, qipan)
                    return true, Proto2.BEAT, data_ret // 吃掉对方
                }
            }
        }

    } else if fangx == Proto2.RIGHT {
        if iposx == 3 {
            return false, Proto2.MOVEFAIL, qipan // 无法移动
        }
        data_yidong := qipan[iposx+1][iposy]
        data := qipan[iposx][iposy]
        // 判断是空地不
        if data_yidong == 0 {
            data_ret := UpdateChessData(Proto2.MOVE, iposx+1, iposy, iposx, iposy, qipan)
            return true, Proto2.MOVESUCC, data_ret // 移动成功
        }
        // 对比棋子大小
        if data < 9 {
            if data_yidong < 9 {
                return false, Proto2.TEAMMATE, qipan // 自己人
            } else {
                if data_yidong > data {
                    data_ret := UpdateChessData(Proto2.DISAPPEAR, iposx+1, iposy, iposx, iposy, qipan)
                    return true, Proto2.DISAPPEAR, data_ret // 自残
                } else if data_yidong == data {
                    data_ret := UpdateChessData(Proto2.ALLDISAPPEAR, iposx+1, iposy, iposx, iposy, qipan)
                    return true, Proto2.ALLDISAPPEAR, data_ret // 同归于尽
                } else if data_yidong < data {
                    data_ret := UpdateChessData(Proto2.BEAT, iposx+1, iposy, iposx, iposy, qipan)
                    return true, Proto2.BEAT, data_ret // 吃掉对方
                }
            }
        } else {
            if data_yidong > 9 {
                return false, Proto2.TEAMMATE, qipan // 自己人
            } else {
                if data_yidong > data {
                    data_ret := UpdateChessData(Proto2.DISAPPEAR, iposx+1, iposy, iposx, iposy, qipan)
                    return true, Proto2.DISAPPEAR, data_ret // 自残
                } else if data_yidong == data {
                    data_ret := UpdateChessData(Proto2.ALLDISAPPEAR, iposx+1, iposy, iposx, iposy, qipan)
                    return true, Proto2.ALLDISAPPEAR, data_ret // 同归于尽
                } else if data_yidong < data {
                    data_ret := UpdateChessData(Proto2.BEAT, iposx+1, iposy, iposx, iposy, qipan)
                    return true, Proto2.BEAT, data_ret // 吃掉对方
                }
            }
        }
    }

    return false, Proto2.ITYPEINIY, qipan // 不存在的操作
}

// 更新棋盘数据
// 注:移动成功后,原来位置如何变化
//    目标的位置如何变化
//    fangxPos fangyPos表示变化的位置
//    iPosx iPosy 原来棋子的位置
func UpdateChessData(iType, fangxPos, fangyPos, iPosx, iPosy int, qipan [4][4]int) [4][4]int {
    // 保存副本数据
    data := qipan
    // 原来棋子的数据
    yd_data := data[iPosx][iPosy]
    //  更新棋盘 数据
    if iType == Proto2.MOVE { // 更新空地 ,1 更新原来棋盘的位置为0, 目标的位置为现在数据
        data[iPosx][iPosy] = 0
        data[fangxPos][fangyPos] = yd_data
    } else if iType == Proto2.DISAPPEAR { // 自残 ,1 更新原来棋盘的位置为0,目标的位置数据不变
        data[iPosx][iPosy] = 0
    } else if iType == Proto2.ALLDISAPPEAR { // 同归于尽 ,1 更新原来棋盘的位置为0,目标的位置数据为0
        data[iPosx][iPosy] = 0
        data[fangxPos][fangyPos] = 0
    } else if iType == Proto2.BEAT { // 吃掉对方 ,1 更新原来位置为0,目标位置为现在数据
        data[iPosx][iPosy] = 0
        data[fangxPos][fangyPos] = yd_data
    }
    return data
}

每天坚持学习1小时Go语言,大家加油,我是彬哥,下期见!如果文章中不同观点、意见请文章下留言或者关注下方订阅号反馈!

社区交流群:221273219

Golang语言社区论坛 :

www.Golang.Ltd

LollipopGo游戏服务器地址:

https://github.com/Golangltd/LollipopGo

社区视频课程课件GIT地址:

https://github.com/Golangltd/codeclass
LollipopGo开源游戏服务器框架--子游戏服务器源码

Golang语言社区


以上所述就是小编给大家介绍的《LollipopGo开源游戏服务器框架--子游戏服务器源码》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

科技投资新时代:TMT投资方法、趋势与热点聚焦

科技投资新时代:TMT投资方法、趋势与热点聚焦

马军、宋辉、段迎晟 / 人民邮电出版社 / 2018-3 / 69.00

中国 TMT 行业(科技、媒体及通信)起步较晚但充满朝气。2017 年,TMT 板块的IPO 数量占到了总数的四分之一;对于投资者来说,投资 TMT 的收益非常可观。那么,TMT 的投资趋势如何? TMT 行业又有哪些投资热点? 本书立足于 TMT 投资现状,在介绍了 TMT 投资的基本概念之后,作者详细讲述了TMT 投资的基本研究方法、分析视角、整体行情及趋势分析,同时从行业视角分析了包括......一起来看看 《科技投资新时代:TMT投资方法、趋势与热点聚焦》 这本书的介绍吧!

JS 压缩/解压工具
JS 压缩/解压工具

在线压缩/解压 JS 代码

图片转BASE64编码
图片转BASE64编码

在线图片转Base64编码工具

Markdown 在线编辑器
Markdown 在线编辑器

Markdown 在线编辑器