Commit 6ed5261f authored by 张振华's avatar 张振华

guess

parent d467a916
// Copyright Fuzamei Corp. 2018 All Rights Reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package commands
import (
"fmt"
"go.uber.org/zap"
"strconv"
jsonrpc "github.com/33cn/chain33/rpc/jsonclient"
"github.com/33cn/chain33/types"
pkt "github.com/33cn/plugin/plugin/dapp/guess/types"
"github.com/spf13/cobra"
)
func GuessCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "guess",
Short: "guess game management",
Args: cobra.MinimumNArgs(1),
}
cmd.AddCommand(
GuessStartRawTxCmd(),
GuessBetRawTxCmd(),
GuessAbortRawTxCmd(),
GuessQueryRawTxCmd(),
GuessPublishRawTxCmd(),
)
return cmd
}
func GuessStartRawTxCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "start",
Short: "start a new guess game",
Run: guessStart,
}
addGuessStartFlags(cmd)
return cmd
}
func addGuessStartFlags(cmd *cobra.Command) {
cmd.Flags().StringP("topic", "t", "", "topic")
cmd.MarkFlagRequired("topic")
cmd.Flags().StringP("options", "o", "", "options")
cmd.MarkFlagRequired("options")
cmd.Flags().Uint32P("maxHeight", "h", 0, "max height to bet")
cmd.MarkFlagRequired("maxHeight")
cmd.Flags().StringP("symbol", "s", "bty", "token symbol")
cmd.Flags().StringP("exec", "e", "coins", "excutor name")
cmd.Flags().Uint32P("oneBet", "b", 0, "one bet number")
cmd.MarkFlagRequired("oneBet")
cmd.Flags().Uint32P("maxBets", "m", 0, "max bets one time")
cmd.MarkFlagRequired("maxBets")
cmd.Flags().Uint32P("maxBetsNumber", "n", 100, "max bets number")
cmd.MarkFlagRequired("maxBetsNumber")
cmd.Flags().Float64P("fee", "f", 0, "fee")
cmd.Flags().StringP("feeAddr", "a", "", "fee address")
}
func guessStart(cmd *cobra.Command, args []string) {
rpcLaddr, _ := cmd.Flags().GetString("rpc_laddr")
topic, _ := cmd.Flags().GetString("topic")
options, _ := cmd.Flags().GetString("options")
maxHeight, _ := cmd.Flags().GetUint32("maxHeight")
symbol, _ := cmd.Flags().GetString("symbol")
exec, _ := cmd.Flags().GetString("exec")
oneBet, _ := cmd.Flags().GetUint32("oneBet")
maxBets, _ := cmd.Flags().GetUint32("maxBets")
maxBetsNumber, _ := cmd.Flags().GetUint32("maxBetsNumber")
fee, _ := cmd.Flags().GetFloat64("fee")
feeAddr, _ := cmd.Flags().GetString("feeAddr")
feeInt64 := uint64(fee * 1e4)
params := &pkt.GuessStartTxReq{
Topic: topic,
Options: options,
MaxHeight: maxHeight,
Symbol: symbol,
Exec: exec,
OneBet: oneBet,
MaxBets: maxBets,
MaxBetsNumber: maxBetsNumber,
Fee: feeInt64,
FeeAddr: feeAddr,
}
var res string
ctx := jsonrpc.NewRpcCtx(rpcLaddr, "guess.GuessStartTx", params, &res)
ctx.RunWithoutMarshal()
}
func GuessBetRawTxCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "bet",
Short: "bet for one option in a guess game",
Run: guessBet,
}
addGuessBetFlags(cmd)
return cmd
}
func addGuessBetFlags(cmd *cobra.Command) {
cmd.Flags().StringP("gameId", "g", "", "game ID")
cmd.MarkFlagRequired("gameId")
cmd.Flags().StringP("option", "o", "", "option")
cmd.MarkFlagRequired("option")
cmd.Flags().Uint32P("betsNumber", "b", 1, "bets number for one option in a guess game")
cmd.MarkFlagRequired("betsNumber")
}
func guessBet(cmd *cobra.Command, args []string) {
rpcLaddr, _ := cmd.Flags().GetString("rpc_laddr")
gameId, _ := cmd.Flags().GetString("gameId")
option, _ := cmd.Flags().GetString("option")
betsNumber, _ := cmd.Flags().GetUint32("betsNumber")
params := &pkt.GuessBetTxReq{
GameId: gameId,
Option: option,
Bets: betsNumber,
}
var res string
ctx := jsonrpc.NewRpcCtx(rpcLaddr, "guess.GuessBetTx", params, &res)
ctx.RunWithoutMarshal()
}
func GuessAbortRawTxCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "abort",
Short: "abort a guess game",
Run: guessAbort,
}
addGuessAbortFlags(cmd)
return cmd
}
func addGuessAbortFlags(cmd *cobra.Command) {
cmd.Flags().StringP("gameId", "g", "", "game Id")
cmd.MarkFlagRequired("gameId")
}
func guessAbort(cmd *cobra.Command, args []string) {
rpcLaddr, _ := cmd.Flags().GetString("rpc_laddr")
gameId, _ := cmd.Flags().GetString("gameId")
params := &pkt.GuessAbortTxReq{
GameId: gameId,
}
var res string
ctx := jsonrpc.NewRpcCtx(rpcLaddr, "guess.GuessAbortTx", params, &res)
ctx.RunWithoutMarshal()
}
func GuessPublishRawTxCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "publish",
Short: "publish the result of a guess game",
Run: guessPublish,
}
addGuessPublishFlags(cmd)
return cmd
}
func addGuessPublishFlags(cmd *cobra.Command) {
cmd.Flags().StringP("gameId", "g", "", "game Id of a guess game")
cmd.MarkFlagRequired("gameId")
cmd.Flags().StringP("result", "r", "", "result of a guess game")
cmd.MarkFlagRequired("result")
}
func guessPublish(cmd *cobra.Command, args []string) {
rpcLaddr, _ := cmd.Flags().GetString("rpc_laddr")
gameId, _ := cmd.Flags().GetString("gameId")
result, _ := cmd.Flags().GetString("result")
params := &pkt.GuessPublishTxReq{
GameId: gameId,
Result: result,
}
var res string
ctx := jsonrpc.NewRpcCtx(rpcLaddr, "guess.GuessPublishTx", params, &res)
ctx.RunWithoutMarshal()
}
func GuessQueryRawTxCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "query",
Short: "Query result",
Run: guessQuery,
}
addGuessQueryFlags(cmd)
return cmd
}
func addGuessQueryFlags(cmd *cobra.Command) {
cmd.Flags().StringP("gameID", "g", "", "game ID")
cmd.Flags().StringP("address", "a", "", "address")
cmd.Flags().StringP("index", "i", "", "index")
cmd.Flags().StringP("status", "s", "", "status")
cmd.Flags().StringP("gameIDs", "d", "", "gameIDs")
}
func guessQuery(cmd *cobra.Command, args []string) {
rpcLaddr, _ := cmd.Flags().GetString("rpc_laddr")
gameID, _ := cmd.Flags().GetString("gameID")
address, _ := cmd.Flags().GetString("address")
statusStr, _ := cmd.Flags().GetString("status")
status, _ := strconv.ParseInt(statusStr, 10, 32)
indexstr, _ := cmd.Flags().GetString("index")
index, _ := strconv.ParseInt(indexstr, 10, 64)
gameIDs, _ := cmd.Flags().GetString("gameIDs")
var params types.Query4Cli
params.Execer = pkt.PokerBullX
req := &pkt.QueryPBGameInfo{
GameId: gameID,
Addr: address,
Status: int32(status),
Index: index,
}
params.Payload = req
if gameID != "" {
params.FuncName = pkt.FuncName_QueryGameById
var res pkt.ReplyPBGame
ctx := jsonrpc.NewRpcCtx(rpcLaddr, "Chain33.Query", params, &res)
ctx.Run()
} else if address != "" {
params.FuncName = pkt.FuncName_QueryGameByAddr
var res pkt.PBGameRecords
ctx := jsonrpc.NewRpcCtx(rpcLaddr, "Chain33.Query", params, &res)
ctx.Run()
} else if statusStr != "" {
params.FuncName = pkt.FuncName_QueryGameByStatus
var res pkt.PBGameRecords
ctx := jsonrpc.NewRpcCtx(rpcLaddr, "Chain33.Query", params, &res)
ctx.Run()
} else if gameIDs != "" {
params.FuncName = pkt.FuncName_QueryGameListByIds
var gameIDsS []string
gameIDsS = append(gameIDsS, gameIDs)
gameIDsS = append(gameIDsS, gameIDs)
req := &pkt.QueryPBGameInfos{gameIDsS}
params.Payload = req
var res pkt.ReplyPBGameList
ctx := jsonrpc.NewRpcCtx(rpcLaddr, "Chain33.Query", params, &res)
ctx.Run()
} else {
fmt.Println("Error: requeres at least one of gameID, address or status")
cmd.Help()
}
}
// Copyright Fuzamei Corp. 2018 All Rights Reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package executor
/*
区块链卡牌游戏:斗牛
一、玩法简介:
游戏可以由2-5人进行,总共52张牌(除大小王),系统将随机发给玩家每人5张牌,并根据5张牌进行排列组合,进行大小比较确定胜负。
支持两种游戏玩法,普通玩法和庄家玩法
普通玩法:没有庄家,所有玩家直接比大小,最大的玩家赢得所有筹码
庄家玩法:玩家只和庄家比大小,比庄家大则赢得庄家筹码,反之则输给庄家筹码,庄家有创建者开始按加入游戏的顺序轮换
二、发牌和洗牌
1、洗牌由游戏创建者发起交易的区块时间blocktime作为随机数因子,所以排序链上可见
2、发牌使用各玩家加入游戏所在交易的hash作为随机数因子,由于nonce的存在,txhash本身具有随机性,且每个玩家每一局的txhash都不一样,可以保证发牌具有随机性
三、制胜策略
将玩家a的5张牌分为两组(3+2)后,与玩家b进行大小比较。
1、第一组3张牌的比较规则:要求将5张牌中取出任意3张组成10、20、30的整数(加法运算)。数字A-10的扑克牌数字代表其大小,JQK统一以10计算。
若玩家a和b有那么三张牌能凑成10或20或30的整数,我们称之为有牛,那么则进行第2组两张牌的大小比较。若玩家a或b有某人无法使用3张牌凑成10或20
或30的整数,我们称之为没牛,同时该玩家判定为输。
2、第二组牌的比较则把剩下的两张牌按照加法计算,10的整数倍数最大,1最小,若大于10小于20则取个位数计算。数字越大则牌型越大,数字越小则牌型
越小。若第2组牌数字为1我们称之为牛一,若第2组数字为10或20我们称之为牛牛,其他以牛二、牛三等名称称呼。牌型从小到大排序为:没牛-牛一-牛二……牛八-牛九-牛牛。
3、若玩家a和b都无法使用3张牌凑成10或20或30的整数,即两家均无牛,则此时进行5张牌中最大一张牌的比较,大小次序为K-Q-J-10-9……A,若最大一
张牌也相同则根据花色进行比较,大小次序为黑桃、红桃、梅花、方片。
4、牌型翻倍
没牛、牛1-6: 1倍
牛7-9: 2倍
牛牛: 3倍
四花: 4倍
五花: 5倍
四、游戏过程和状态
1、充值,往pokerbull合约对应的合约账户充值
2、玩家指定游戏人数和筹码加入游戏,如果有等待状态的游戏,直接加入,如果没有,创建新游戏
3、等待指定游戏人数的玩家加入,等待期间,可发送quit交易退出
4、最后一名玩家加入,游戏开始、发牌,计算结果
5、根据结果,划转筹码
6、合约账户提现到真实账户
7、状态:start->continue->quit
*/
// Copyright Fuzamei Corp. 2018 All Rights Reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package executor
import (
"github.com/33cn/chain33/types"
pkt "github.com/33cn/plugin/plugin/dapp/guess/types"
)
func (c *Guess) Exec_Start(payload *pkt.GuessGameStart, tx *types.Transaction, index int) (*types.Receipt, error) {
action := NewAction(c, tx, index)
return action.GameStart(payload)
}
func (c *Guess) Exec_Continue(payload *pkt.PBGameContinue, tx *types.Transaction, index int) (*types.Receipt, error) {
action := NewAction(c, tx, index)
return action.GameContinue(payload)
}
func (c *Guess) Exec_Quit(payload *pkt.PBGameQuit, tx *types.Transaction, index int) (*types.Receipt, error) {
action := NewAction(c, tx, index)
return action.GameQuit(payload)
}
\ No newline at end of file
// Copyright Fuzamei Corp. 2018 All Rights Reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package executor
import (
"github.com/33cn/chain33/types"
pkt "github.com/33cn/plugin/plugin/dapp/pokerbull/types"
)
func (g *PokerBull) rollbackIndex(log *pkt.ReceiptPBGame) (kvs []*types.KeyValue) {
kvs = append(kvs, delPBGameStatusAndPlayer(log.Status, log.PlayerNum, log.Value, log.Index))
kvs = append(kvs, addPBGameStatusAndPlayer(log.PreStatus, log.PlayerNum, log.PrevIndex, log.Value, log.GameId))
kvs = append(kvs, delPBGameStatusIndexKey(log.Status, log.Index))
kvs = append(kvs, addPBGameStatusIndexKey(log.PreStatus, log.GameId, log.PrevIndex))
for _, v := range log.Players {
kvs = append(kvs, delPBGameAddrIndexKey(v, log.Index))
kvs = append(kvs, addPBGameAddrIndexKey(log.PreStatus, v, log.GameId, log.PrevIndex))
}
return kvs
}
func (g *PokerBull) execDelLocal(receiptData *types.ReceiptData) (*types.LocalDBSet, error) {
dbSet := &types.LocalDBSet{}
if receiptData.GetTy() != types.ExecOk {
return dbSet, nil
}
for _, log := range receiptData.Logs {
switch log.GetTy() {
case pkt.TyLogPBGameStart, pkt.TyLogPBGameContinue, pkt.TyLogPBGameQuit:
receiptGame := &pkt.ReceiptPBGame{}
if err := types.Decode(log.Log, receiptGame); err != nil {
return nil, err
}
kv := g.rollbackIndex(receiptGame)
dbSet.KV = append(dbSet.KV, kv...)
}
}
return dbSet, nil
}
func (g *PokerBull) ExecDelLocal_Start(payload *pkt.PBGameStart, tx *types.Transaction, receiptData *types.ReceiptData, index int) (*types.LocalDBSet, error) {
return g.execDelLocal(receiptData)
}
func (g *PokerBull) ExecDelLocal_Continue(payload *pkt.PBGameContinue, tx *types.Transaction, receiptData *types.ReceiptData, index int) (*types.LocalDBSet, error) {
return g.execDelLocal(receiptData)
}
func (g *PokerBull) ExecDelLocal_Quit(payload *pkt.PBGameQuit, tx *types.Transaction, receiptData *types.ReceiptData, index int) (*types.LocalDBSet, error) {
return g.execDelLocal(receiptData)
}
// Copyright Fuzamei Corp. 2018 All Rights Reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package executor
import (
"github.com/33cn/chain33/types"
pkt "github.com/33cn/plugin/plugin/dapp/pokerbull/types"
)
func (c *PokerBull) updateIndex(log *pkt.ReceiptPBGame) (kvs []*types.KeyValue) {
//先保存本次Action产生的索引
kvs = append(kvs, addPBGameStatusAndPlayer(log.Status, log.PlayerNum, log.Value, log.Index, log.GameId))
kvs = append(kvs, addPBGameStatusIndexKey(log.Status, log.GameId, log.Index))
kvs = append(kvs, addPBGameAddrIndexKey(log.Status, log.Addr, log.GameId, log.Index))
/*
//状态更新
if log.Status == pkt.PBGameActionStart {
kvs = append(kvs, delPBGameStatusAndPlayer(pkt.PBGameActionStart, log.PlayerNum, log.Value, log.PrevIndex))
kvs = append(kvs, delPBGameStatusIndexKey(pkt.PBGameActionStart, log.PrevIndex))
}
if log.Status == pkt.PBGameActionContinue {
kvs = append(kvs, delPBGameStatusAndPlayer(pkt.PBGameActionStart, log.PlayerNum, log.Value, log.PrevIndex))
kvs = append(kvs, delPBGameStatusAndPlayer(pkt.PBGameActionContinue, log.PlayerNum, log.Value, log.PrevIndex))
kvs = append(kvs, delPBGameStatusIndexKey(pkt.PBGameActionStart, log.PrevIndex))
kvs = append(kvs, delPBGameStatusIndexKey(pkt.PBGameActionContinue, log.PrevIndex))
}
if log.Status == pkt.PBGameActionQuit {
kvs = append(kvs, delPBGameStatusAndPlayer(pkt.PBGameActionStart, log.PlayerNum, log.Value, log.PrevIndex))
kvs = append(kvs, delPBGameStatusAndPlayer(pkt.PBGameActionContinue, log.PlayerNum, log.Value, log.PrevIndex))
kvs = append(kvs, delPBGameStatusIndexKey(pkt.PBGameActionStart, log.PrevIndex))
kvs = append(kvs, delPBGameStatusIndexKey(pkt.PBGameActionContinue, log.PrevIndex))
}*/
//结束一局,更新所有玩家地址状态
if !log.IsWaiting {
for _, v := range log.Players {
if v != log.Addr {
kvs = append(kvs, addPBGameAddrIndexKey(log.Status, v, log.GameId, log.Index))
}
kvs = append(kvs, delPBGameAddrIndexKey(v, log.PrevIndex))
}
kvs = append(kvs, delPBGameStatusAndPlayer(log.PreStatus, log.PlayerNum, log.Value, log.PrevIndex))
kvs = append(kvs, delPBGameStatusIndexKey(log.PreStatus, log.PrevIndex))
}
return kvs
}
func (c *PokerBull) execLocal(receipt *types.ReceiptData) (*types.LocalDBSet, error) {
dbSet := &types.LocalDBSet{}
if receipt.GetTy() != types.ExecOk {
return dbSet, nil
}
for i := 0; i < len(receipt.Logs); i++ {
item := receipt.Logs[i]
if item.Ty == pkt.TyLogPBGameStart || item.Ty == pkt.TyLogPBGameContinue || item.Ty == pkt.TyLogPBGameQuit {
var Gamelog pkt.ReceiptPBGame
err := types.Decode(item.Log, &Gamelog)
if err != nil {
panic(err) //数据错误了,已经被修改了
}
kv := c.updateIndex(&Gamelog)
dbSet.KV = append(dbSet.KV, kv...)
}
}
return dbSet, nil
}
func (c *PokerBull) ExecLocal_Start(payload *pkt.PBGameStart, tx *types.Transaction, receiptData *types.ReceiptData, index int) (*types.LocalDBSet, error) {
return c.execLocal(receiptData)
}
func (c *PokerBull) ExecLocal_Continue(payload *pkt.PBGameContinue, tx *types.Transaction, receiptData *types.ReceiptData, index int) (*types.LocalDBSet, error) {
return c.execLocal(receiptData)
}
func (c *PokerBull) ExecLocal_Quit(payload *pkt.PBGameQuit, tx *types.Transaction, receiptData *types.ReceiptData, index int) (*types.LocalDBSet, error) {
return c.execLocal(receiptData)
}
// Copyright Fuzamei Corp. 2018 All Rights Reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package executor
import (
"fmt"
log "github.com/33cn/chain33/common/log/log15"
drivers "github.com/33cn/chain33/system/dapp"
"github.com/33cn/chain33/types"
pkt "github.com/33cn/plugin/plugin/dapp/guess/types"
)
var logger = log.New("module", "execs.guess")
func Init(name string, sub []byte) {
drivers.Register(newGuessGame().GetName(), newGuessGame, types.GetDappFork(driverName, "Enable"))
}
var driverName = pkt.GuessX
func init() {
ety := types.LoadExecutorType(driverName)
ety.InitFuncList(types.ListMethod(&Guess{}))
}
type Guess struct {
drivers.DriverBase
}
func newGuessGame() drivers.Driver {
t := &Guess{}
t.SetChild(t)
t.SetExecutorType(types.LoadExecutorType(driverName))
return t
}
func GetName() string {
return newGuessGame().GetName()
}
func (g *Guess) GetDriverName() string {
return pkt.GuessX
}
func calcPBGameAddrPrefix(addr string) []byte {
key := fmt.Sprintf("LODB-guess-addr:%s:", addr)
return []byte(key)
}
func calcPBGameAddrKey(addr string, index int64) []byte {
key := fmt.Sprintf("LODB-guess-addr:%s:%018d", addr, index)
return []byte(key)
}
func calcPBGameStatusPrefix(status int32) []byte {
key := fmt.Sprintf("LODB-guess-status-index:%d:", status)
return []byte(key)
}
func calcPBGameStatusKey(status int32, index int64) []byte {
key := fmt.Sprintf("LODB-guess-status-index:%d:%018d", status, index)
return []byte(key)
}
func calcPBGameStatusAndPlayerKey(status, player int32, value, index int64) []byte {
key := fmt.Sprintf("LODB-guess-status:%d:%d:%d:%018d", status, player, value, index)
return []byte(key)
}
func calcPBGameStatusAndPlayerPrefix(status, player int32, value int64) []byte {
var key string
if value == 0 {
key = fmt.Sprintf("LODB-guess-status:%d:%d:", status, player)
} else {
key = fmt.Sprintf("LODB-guess-status:%d:%d:%d", status, player, value)
}
return []byte(key)
}
func addPBGameStatusIndexKey(status int32, gameID string, index int64) *types.KeyValue {
kv := &types.KeyValue{}
kv.Key = calcPBGameStatusKey(status, index)
record := &pkt.PBGameIndexRecord{
GameId: gameID,
Index: index,
}
kv.Value = types.Encode(record)
return kv
}
func delPBGameStatusIndexKey(status int32, index int64) *types.KeyValue {
kv := &types.KeyValue{}
kv.Key = calcPBGameStatusKey(status, index)
kv.Value = nil
return kv
}
func addPBGameAddrIndexKey(status int32, addr, gameID string, index int64) *types.KeyValue {
kv := &types.KeyValue{}
kv.Key = calcPBGameAddrKey(addr, index)
record := &pkt.PBGameRecord{
GameId: gameID,
Status: status,
Index: index,
}
kv.Value = types.Encode(record)
return kv
}
func delPBGameAddrIndexKey(addr string, index int64) *types.KeyValue {
kv := &types.KeyValue{}
kv.Key = calcPBGameAddrKey(addr, index)
kv.Value = nil
return kv
}
func addPBGameStatusAndPlayer(status int32, player int32, value, index int64, gameId string) *types.KeyValue {
kv := &types.KeyValue{}
kv.Key = calcPBGameStatusAndPlayerKey(status, player, value, index)
record := &pkt.PBGameIndexRecord{
GameId: gameId,
Index: index,
}
kv.Value = types.Encode(record)
return kv
}
func delPBGameStatusAndPlayer(status int32, player int32, value, index int64) *types.KeyValue {
kv := &types.KeyValue{}
kv.Key = calcPBGameStatusAndPlayerKey(status, player, value, index)
kv.Value = nil
return kv
}
This diff is collapsed.
// Copyright Fuzamei Corp. 2018 All Rights Reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package executor
import (
"fmt"
"math/rand"
"sort"
"github.com/33cn/plugin/plugin/dapp/pokerbull/types"
)
var POKER_CARD_NUM = 52 //4 * 13 不带大小王
var COLOR_OFFSET uint32 = 8
var COLOR_BIT_MAST = 0xFF
var COLOR_NUM = 4
var CARD_NUM_PER_COLOR = 13
var CARD_NUM_PER_GAME = 5
const (
POKERBULL_RESULT_X1 = 1
POKERBULL_RESULT_X2 = 2
POKERBULL_RESULT_X3 = 3
POKERBULL_RESULT_X4 = 4
POKERBULL_RESULT_X5 = 5
POKERBULL_LEVERAGE_MAX = POKERBULL_RESULT_X1
)
func NewPoker() *types.PBPoker {
poker := new(types.PBPoker)
poker.Cards = make([]int32, POKER_CARD_NUM)
poker.Pointer = int32(POKER_CARD_NUM - 1)
for i := 0; i < POKER_CARD_NUM; i++ {
color := i / CARD_NUM_PER_COLOR
num := i%CARD_NUM_PER_COLOR + 1
poker.Cards[i] = int32(color<<COLOR_OFFSET + num)
}
return poker
}
// 洗牌
func Shuffle(poker *types.PBPoker, rng int64) {
rndn := rand.New(rand.NewSource(rng))
for i := 0; i < POKER_CARD_NUM; i++ {
idx := rndn.Intn(POKER_CARD_NUM - 1)
tmpV := poker.Cards[idx]
poker.Cards[idx] = poker.Cards[POKER_CARD_NUM-i-1]
poker.Cards[POKER_CARD_NUM-i-1] = tmpV
}
poker.Pointer = int32(POKER_CARD_NUM - 1)
}
// 发牌
func Deal(poker *types.PBPoker, rng int64) []int32 {
if poker.Pointer < int32(CARD_NUM_PER_GAME) {
logger.Error(fmt.Sprintf("Wait to be shuffled: deal cards [%d], left [%d]", CARD_NUM_PER_GAME, poker.Pointer+1))
Shuffle(poker, rng+int64(poker.Cards[0]))
}
rndn := rand.New(rand.NewSource(rng))
res := make([]int32, CARD_NUM_PER_GAME)
for i := 0; i < CARD_NUM_PER_GAME; i++ {
idx := rndn.Intn(int(poker.Pointer))
tmpV := poker.Cards[poker.Pointer]
res[i] = poker.Cards[idx]
poker.Cards[idx] = tmpV
poker.Cards[poker.Pointer] = res[i]
poker.Pointer--
}
return res
}
// 计算斗牛结果
func Result(cards []int32) int32 {
temp := 0
r := -1 //是否有牛标志
pk := newcolorCard(cards)
//花牌等于10
cardsC := make([]int, len(cards))
for i := 0; i < len(pk); i++ {
if pk[i].num > 10 {
cardsC[i] = 10
} else {
cardsC[i] = pk[i].num
}
}
//斗牛算法
result := make([]int, 10)
var offset = 0
for x := 0; x < 3; x++ {
for y := x + 1; y < 4; y++ {
for z := y + 1; z < 5; z++ {
if (cardsC[x]+cardsC[y]+cardsC[z])%10 == 0 {
for j := 0; j < len(cardsC); j++ {
if j != x && j != y && j != z {
temp += cardsC[j]
}
}
if temp%10 == 0 {
r = 10 //若有牛,且剩下的两个数也是牛十
} else {
r = temp % 10 //若有牛,剩下的不是牛十
}
result[offset] = r
offset++
}
}
}
}
//没有牛
if r == -1 {
return -1
}
return int32(result[0])
}
// 计算结果倍数
func Leverage(hand *types.PBHand) int32 {
result := hand.Result
// 小牛 [1, 6]
if result < 7 {
return POKERBULL_RESULT_X1
}
// 大牛 [7, 9]
if result >= 7 && result < 10 {
return POKERBULL_RESULT_X2
}
var flowers = 0
if result == 10 {
for _, card := range hand.Cards {
if (int(card) & COLOR_BIT_MAST) > 10 {
flowers++
}
}
// 牛牛
if flowers < 4 {
return POKERBULL_RESULT_X3
}
// 四花
if flowers == 4 {
return POKERBULL_RESULT_X4
}
// 五花
if flowers == 5 {
return POKERBULL_RESULT_X5
}
}
return POKERBULL_RESULT_X1
}
type pokerCard struct {
num int
color int
}
type colorCardSlice []*pokerCard
func (p colorCardSlice) Len() int {
return len(p)
}
func (p colorCardSlice) Swap(i, j int) {
p[i], p[j] = p[j], p[i]
}
func (p colorCardSlice) Less(i, j int) bool {
if i >= p.Len() || j >= p.Len() {
logger.Error("length error. slice length:", p.Len(), " compare lenth: ", i, " ", j)
}
if p[i] == nil || p[j] == nil {
logger.Error("nil pointer at ", i, " ", j)
}
return p[i].num < p[j].num
}
func newcolorCard(a []int32) colorCardSlice {
var cardS []*pokerCard
for i := 0; i < len(a); i++ {
num := int(a[i]) & COLOR_BIT_MAST
color := int(a[i]) >> COLOR_OFFSET
cardS = append(cardS, &pokerCard{num, color})
}
return cardS
}
func CompareResult(i, j *types.PBHand) bool {
if i.Result < j.Result {
return true
}
if i.Result == j.Result {
return Compare(i.Cards, j.Cards)
}
return false
}
func Compare(a []int32, b []int32) bool {
cardA := newcolorCard(a)
cardB := newcolorCard(b)
if !sort.IsSorted(cardA) {
sort.Sort(cardA)
}
if !sort.IsSorted(cardB) {
sort.Sort(cardB)
}
maxA := cardA[len(a)-1]
maxB := cardB[len(b)-1]
if maxA.num != maxB.num {
return maxA.num < maxB.num
}
return maxA.color < maxB.color
}
// Copyright Fuzamei Corp. 2018 All Rights Reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package executor
import (
"github.com/33cn/chain33/types"
pkt "github.com/33cn/plugin/plugin/dapp/pokerbull/types"
)
func (g *PokerBull) Query_QueryGameListByIds(in *pkt.QueryPBGameInfos) (types.Message, error) {
return Infos(g.GetStateDB(), in)
}
func (g *PokerBull) Query_QueryGameById(in *pkt.QueryPBGameInfo) (types.Message, error) {
game, err := readGame(g.GetStateDB(), in.GetGameId())
if err != nil {
return nil, err
}
return &pkt.ReplyPBGame{game}, nil
}
func (g *PokerBull) Query_QueryGameByAddr(in *pkt.QueryPBGameInfo) (types.Message, error) {
gameIds, err := getGameListByAddr(g.GetLocalDB(), in.Addr, in.Index)
if err != nil {
return nil, err
}
return gameIds, nil
}
func (g *PokerBull) Query_QueryGameByStatus(in *pkt.QueryPBGameInfo) (types.Message, error) {
gameIds, err := getGameListByStatus(g.GetLocalDB(), in.Status, in.Index)
if err != nil {
return nil, err
}
return gameIds, nil
}
// Copyright Fuzamei Corp. 2018 All Rights Reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package guess
import (
"github.com/33cn/chain33/pluginmgr"
"github.com/33cn/plugin/plugin/dapp/guess/commands"
"github.com/33cn/plugin/plugin/dapp/guess/executor"
"github.com/33cn/plugin/plugin/dapp/guess/rpc"
"github.com/33cn/plugin/plugin/dapp/guess/types"
)
func init() {
pluginmgr.Register(&pluginmgr.PluginBase{
Name: types.PokerBullX,
ExecName: executor.GetName(),
Exec: executor.Init,
Cmd: commands.GuessCmd,
RPC: rpc.Init,
})
}
all:
sh ./create_protobuf.sh
#!/bin/sh
protoc --go_out=plugins=grpc:../types ./*.proto --proto_path=. --proto_path="../../../../vendor/github.com/33cn/chain33/types/proto/"
syntax = "proto3";
import "transaction.proto";
package types;
//竞猜游戏内容
message GuessGame {
string gameId = 1; //游戏ID
uint32 status = 2; //游戏的状态:创建->投注->截止投注->开奖
int64 startTime = 3; //创建游戏的时间
string startTxHash = 4; //创建游戏的交易hash
string topic = 5; //主题
string options = 6; //选项
int64 stopTime = 7; //截止下注时间
uint32 maxHeight = 8; //截止下注的块高
string symbol = 9; //bty或者具体token
string exec = 10; //coins或者token
uint32 oneBet = 11; //一注等于多少bty或者token
uint32 maxBets = 12; //单次可以下多少注,默认100
uint32 maxBetsNumber = 13; //最多可以下多少注
uint32 fee = 14; //收取费用,不带则表示不收费
string feeAddr = 15; //收费地址
string adminAddr = 16; //游戏创建者地址,只有该地址可以开奖
uint32 betsNumber = 17; //已下注数,如果数量达到maxBetsNumber,则不允许再下注
repeated GuessPlayer plays = 18; //参与游戏下注的玩家投注信息
string result = 19;
repeated GuessBet bets = 20;
}
message GuessPlayer {
string addr = 1;
repeated GuessBet bets = 2;
}
message GuessBet {
string option = 1;
uint32 betsNumber = 2;
}
//斗牛游戏内容
message PokerBull {
string gameId = 1; //默认是由创建这局游戏的txHash作为gameId
int32 status = 2; // Start 1 -> Continue 2 -> Quit 3
int64 startTime = 3; //开始时间
string startTxHash = 4; //游戏启动交易hash
int64 value = 5; //赌注
PBPoker poker = 6; //扑克牌
repeated PBPlayer players = 7; //玩家历史牌和结果集
int32 playerNum = 8; //玩家数
repeated PBResult results = 9; //游戏结果集
int64 index = 10; //索引
int64 prevIndex = 11; //上级索引
int64 quitTime = 12; //游戏结束时间
string quitTxHash = 13; //游戏结束交易hash
string dealerAddr = 14; //下局庄家地址
bool isWaiting = 15; //游戏是否处于等待状态
int32 preStatus = 16; //上一index的状态
}
//一把牌
message PBHand {
repeated int32 cards = 1; //一把牌,五张
int32 result = 2; //斗牛结果 (没牛:0, 牛1-9:1-9, 牛牛:10)
string address = 3; //玩家地址
bool isWin = 4; //是否赢庄家
int32 leverage = 5; //赌注倍数
}
//玩家
message PBPlayer {
repeated PBHand hands = 1; //历史发牌和斗牛结果
string address = 2; //玩家地址
int64 txHash = 3; //发牌随机数因子txhash的整数格式
bool ready = 4; // continue状态下,是否ready
}
//本局游戏结果
message PBResult {
repeated PBHand hands = 1; //本局所有玩家的牌和结果,按牛大小升序排序
string winner = 2; //赢家地址
int32 leverage = 3; //赢得赌注倍数
string dealer = 4; //庄家
int32 dealerLeverage = 5; //庄家赌注倍数
}
//扑克牌
message PBPoker {
repeated int32 cards = 1; // 52张牌
int32 pointer = 2; //已发牌偏移
}
//游戏状态
message PBGameAction {
oneof value {
PBGameStart start = 1;
PBGameContinue continue = 2;
PBGameQuit quit = 3;
PBGameQuery query = 4;
}
int32 ty = 10;
}
//游戏启动
message PBGameStart {
int64 value = 1;
int32 playerNum = 2;
}
//游戏继续
message PBGameContinue {
string gameId = 1;
}
//游戏结束
message PBGameQuit {
string gameId = 1;
}
//查询游戏结果
message PBGameQuery {
string gameId = 1;
}
//游戏状态
message GuessGameAction {
oneof value {
GuessGameStart start = 1;
GuessGameBet bet = 2;
GuessGameAbort abort = 3;
GuessGamePublish publish = 4;
GuessGameQuery query = 5;
}
uint32 ty = 6;
}
//游戏启动
message GuessGameStart{
string topic = 1;
string options = 2;
uint32 maxHeight = 3;
string symbol = 4;
string exec = 5;
uint32 oneBet = 6;
uint32 maxBets = 7;
uint32 maxBetsNumber = 8;
uint64 fee = 9;
string feeAddr = 10;
}
//参与游戏下注
message GuessGameBet{
string gameId = 1;
string option = 2;
uint32 betsNum = 3;
}
//游戏异常终止,退还下注
message GuessGameAbort{
string gameId = 1;
}
//游戏结果揭晓
message GuessGamePublish{
string gameId = 1;
string result = 2;
}
//查询游戏结果
message GuessGameQuery{
string gameId = 1;
uint32 ty = 2;
}
//根据状态和游戏人数查找
message QueryPBGameListByStatusAndPlayerNum {
int32 status = 1;
int32 playerNum = 2;
int64 index = 3;
}
// 索引value值
message PBGameRecord {
string gameId = 1;
int32 status = 2;
int64 index = 3;
}
message PBGameIndexRecord {
string gameId = 1;
int64 index = 2;
}
message PBGameRecords {
repeated PBGameRecord records = 1;
}
message QueryPBGameInfo {
string gameId = 1;
string addr = 2;
int32 status = 3;
int64 index = 4;
}
message ReplyPBGame {
PokerBull game = 1;
}
message QueryPBGameInfos {
repeated string gameIds = 1;
}
message ReplyPBGameList {
repeated PokerBull games = 1;
}
message ReceiptPBGame {
string gameId = 1;
int32 status = 2;
string addr = 3;
int64 index = 4;
int64 prevIndex = 5;
int32 playerNum = 6;
int64 value = 7;
bool isWaiting = 8;
repeated string players = 9;
int32 preStatus = 10;
}
message GuessStartTxReq {
string topic = 1;
string options = 2;
int64 startTime = 3;
int64 stopTime = 4;
uint32 maxHeight = 5;
string symbol = 6;
string exec = 7;
uint32 oneBet = 8;
uint32 maxBets = 9;
uint32 maxBetsNumber = 10;
uint64 fee = 11;
string feeAddr = 12;
}
message GuessBetTxReq {
string gameId = 1;
string option = 2;
uint32 bets = 3;
}
message GuessAbortTxReq {
string gameId = 1;
}
message GuessPublishTxReq {
string gameId = 1;
string result = 2;
}
message PBContinueTxReq {
string gameId = 1;
int64 fee = 2;
}
message PBQuitTxReq {
string gameId = 1;
int64 fee = 2;
}
message PBQueryReq {
string gameId = 1;
int64 fee = 2;
}
// pokerbull 对外提供服务的接口
service guess {
//游戏开始
rpc GuessStart(GuessGameStart) returns (UnsignTx) {}
//游戏下注
rpc GuessBet(GuessGameBet) returns (UnsignTx) {}
//游戏异常终止
rpc GuessAbort(GuessGameAbort) returns (UnsignTx) {}
//游戏结束
rpc GuessPublish(GuessGamePublish) returns (UnsignTx) {}
}
// Copyright Fuzamei Corp. 2018 All Rights Reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package rpc
import (
"context"
"encoding/hex"
"github.com/33cn/chain33/types"
pb "github.com/33cn/plugin/plugin/dapp/guess/types"
)
func (c *Jrpc) GuessStartTx(parm *pb.GuessStartTxReq, result *interface{}) error {
if parm == nil {
return types.ErrInvalidParam
}
head := &pb.GuessGameStart{
Topic: parm.Topic,
Options: parm.Options,
MaxHeight: parm.MaxHeight,
Symbol: parm.Symbol,
Exec: parm.Exec,
OneBet: parm.OneBet,
MaxBets: parm.MaxBets,
MaxBetsNumber: parm.MaxBetsNumber,
Fee: parm.Fee,
FeeAddr: parm.FeeAddr,
}
reply, err := c.cli.GuessStart(context.Background(), head)
if err != nil {
return err
}
*result = hex.EncodeToString(reply.Data)
return nil
}
func (c *Jrpc) GuessBetTx(parm *pb.GuessBetTxReq, result *interface{}) error {
if parm == nil {
return types.ErrInvalidParam
}
head := &pb.GuessGameBet{
GameId: parm.GameId,
Option: parm.Option,
BetsNum: parm.Bets,
}
reply, err := c.cli.GuessBet(context.Background(), head)
if err != nil {
return err
}
*result = hex.EncodeToString(reply.Data)
return nil
}
func (c *Jrpc) GuessAbortTx(parm *pb.GuessAbortTxReq, result *interface{}) error {
if parm == nil {
return types.ErrInvalidParam
}
head := &pb.GuessGameAbort{
GameId: parm.GameId,
}
reply, err := c.cli.GuessAbort(context.Background(), head)
if err != nil {
return err
}
*result = hex.EncodeToString(reply.Data)
return nil
}
func (c *Jrpc) GuessPublishTx(parm *pb.GuessPublishTxReq, result *interface{}) error {
if parm == nil {
return types.ErrInvalidParam
}
head := &pb.GuessGamePublish{
GameId: parm.GameId,
Result: parm.Result,
}
reply, err := c.cli.GuessPublish(context.Background(), head)
if err != nil {
return err
}
*result = hex.EncodeToString(reply.Data)
return nil
}
func (c *Jrpc) PokerBullQueryTx(parm *pb.PBQueryReq, result *interface{}) error {
if parm == nil {
return types.ErrInvalidParam
}
head := &pb.PBGameQuery{
GameId: parm.GameId,
}
reply, err := c.cli.Show(context.Background(), head)
if err != nil {
return err
}
*result = hex.EncodeToString(reply.Data)
return nil
}
// Copyright Fuzamei Corp. 2018 All Rights Reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package rpc_test
import (
"strings"
"testing"
commonlog "github.com/33cn/chain33/common/log"
"github.com/33cn/chain33/rpc/jsonclient"
"github.com/33cn/chain33/types"
"github.com/33cn/chain33/util/testnode"
pty "github.com/33cn/plugin/plugin/dapp/pokerbull/types"
"github.com/stretchr/testify/assert"
_ "github.com/33cn/chain33/system"
_ "github.com/33cn/plugin/plugin"
)
func init() {
commonlog.SetLogLevel("error")
}
func TestJRPCChannel(t *testing.T) {
// 启动RPCmocker
mocker := testnode.New("--notset--", nil)
defer func() {
mocker.Close()
}()
mocker.Listen()
jrpcClient := mocker.GetJsonC()
assert.NotNil(t, jrpcClient)
testCases := []struct {
fn func(*testing.T, *jsonclient.JSONClient) error
}{
{fn: testStartRawTxCmd},
{fn: testContinueRawTxCmd},
{fn: testQuitRawTxCmd},
{fn: testQueryGameById},
{fn: testQueryGameByAddr},
}
for index, testCase := range testCases {
err := testCase.fn(t, jrpcClient)
if err == nil {
continue
}
assert.NotEqualf(t, err, types.ErrActionNotSupport, "test index %d", index)
if strings.Contains(err.Error(), "rpc: can't find") {
assert.FailNowf(t, err.Error(), "test index %d", index)
}
}
}
func testStartRawTxCmd(t *testing.T, jrpc *jsonclient.JSONClient) error {
params := pty.PBStartTxReq{}
var res string
return jrpc.Call("pokerbull.PokerBullStartTx", params, &res)
}
func testContinueRawTxCmd(t *testing.T, jrpc *jsonclient.JSONClient) error {
params := pty.PBContinueTxReq{}
var res string
return jrpc.Call("pokerbull.PokerBullContinueTx", params, &res)
}
func testQuitRawTxCmd(t *testing.T, jrpc *jsonclient.JSONClient) error {
params := pty.PBContinueTxReq{}
var res string
return jrpc.Call("pokerbull.PokerBullQuitTx", params, &res)
}
func testQueryGameById(t *testing.T, jrpc *jsonclient.JSONClient) error {
var rep interface{}
var params types.Query4Cli
req := &pty.QueryPBGameInfo{}
params.Execer = "pokerbull"
params.FuncName = "QueryGameById"
params.Payload = req
rep = &pty.ReplyPBGame{}
return jrpc.Call("Chain33.Query", params, rep)
}
func testQueryGameByAddr(t *testing.T, jrpc *jsonclient.JSONClient) error {
var rep interface{}
var params types.Query4Cli
req := &pty.QueryPBGameInfo{}
params.Execer = "pokerbull"
params.FuncName = "QueryGameByAddr"
params.Payload = req
rep = &pty.PBGameRecords{}
return jrpc.Call("Chain33.Query", params, rep)
}
// Copyright Fuzamei Corp. 2018 All Rights Reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package rpc
import (
"context"
"fmt"
"github.com/33cn/chain33/types"
pb "github.com/33cn/plugin/plugin/dapp/guess/types"
"github.com/33cn/plugin/plugin/dapp/pokerbull/executor"
)
func (c *channelClient) GuessStart(ctx context.Context, head *pb.GuessGameStart) (*types.UnsignTx, error) {
if head.MaxBetsNumber > executor.MaxBetsNumber {
return nil, fmt.Errorf("Max Bets Number Should Be Maximum %d", executor.MaxBetsNumber)
}
val := &pb.GuessGameAction{
Ty: pb.GuessGameActionStart,
Value: &pb.GuessGameAction_Start{head},
}
tx, err := types.CreateFormatTx(pb.GuessX, types.Encode(val))
if err != nil {
return nil, err
}
data := types.Encode(tx)
return &types.UnsignTx{Data: data}, nil
}
func (c *channelClient) GuessBet(ctx context.Context, head *pb.GuessGameBet) (*types.UnsignTx, error) {
val := &pb.GuessGameAction{
Ty: pb.GuessGameActionBet,
Value: &pb.GuessGameAction_Bet{head},
}
tx, err := types.CreateFormatTx(pb.GuessX, types.Encode(val))
if err != nil {
return nil, err
}
data := types.Encode(tx)
return &types.UnsignTx{Data: data}, nil
}
func (c *channelClient) GuessAbort(ctx context.Context, head *pb.GuessGameAbort) (*types.UnsignTx, error) {
val := &pb.GuessGameAction{
Ty: pb.GuessGameActionAbort,
Value: &pb.GuessGameAction_Abort{head},
}
tx, err := types.CreateFormatTx(pb.GuessX, types.Encode(val))
if err != nil {
return nil, err
}
data := types.Encode(tx)
return &types.UnsignTx{Data: data}, nil
}
func (c *channelClient) GuessPublish(ctx context.Context, head *pb.GuessGamePublish) (*types.UnsignTx, error) {
val := &pb.GuessGameAction{
Ty: pb.GuessGameActionPublish,
Value: &pb.GuessGameAction_Publish{head},
}
tx, err := types.CreateFormatTx(pb.GuessX, types.Encode(val))
if err != nil {
return nil, err
}
data := types.Encode(tx)
return &types.UnsignTx{Data: data}, nil
}
func (c *channelClient) Show(ctx context.Context, head *pb.PBGameQuery) (*types.UnsignTx, error) {
val := &pb.PBGameAction{
Ty: pb.PBGameActionQuery,
Value: &pb.PBGameAction_Query{head},
}
tx, err := types.CreateFormatTx(pb.PokerBullX, types.Encode(val))
if err != nil {
return nil, err
}
data := types.Encode(tx)
return &types.UnsignTx{Data: data}, nil
}
// Copyright Fuzamei Corp. 2018 All Rights Reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package rpc
type PokerBullStartTx struct {
Value int64 `json:"value"`
PlayerNum int32 `json:"playerNum"`
Fee int64 `json:"fee"`
}
type PBContinueTxReq struct {
GameId string `json:"gameId"`
Fee int64 `json:"fee"`
}
type PBQuitTxReq struct {
GameId string `json:"gameId"`
Fee int64 `json:"fee"`
}
type PBQueryReq struct {
GameId string `json:"GameId"`
Fee int64 `json:"fee"`
}
// Copyright Fuzamei Corp. 2018 All Rights Reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package rpc
import (
"github.com/33cn/chain33/rpc/types"
)
type Jrpc struct {
cli *channelClient
}
type Grpc struct {
*channelClient
}
type channelClient struct {
types.ChannelClient
}
func Init(name string, s types.RPCServer) {
cli := &channelClient{}
grpc := &Grpc{channelClient: cli}
cli.Init(name, s, &Jrpc{cli: cli}, grpc)
}
// Copyright Fuzamei Corp. 2018 All Rights Reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package types
//game action ty
const (
PBGameActionStart = iota + 1
PBGameActionContinue
PBGameActionQuit
PBGameActionQuery
GuessGameActionStart = iota + 1
GuessGameActionBet
GuessGameActionAbort
GuessGameActionPublish
)
const (
PlayStyleDefault = iota + 1
PlayStyleDealer
)
const (
//log for PBgame
TyLogPBGameStart = 721
TyLogPBGameContinue = 722
TyLogPBGameQuit = 723
TyLogPBGameQuery = 724
TyLogGuessGameStart = 901
TyLogGuessGameBet = 902
TyLogGuessGameDraw = 903
TyLogGuessGameClose = 904
)
//包的名字可以通过配置文件来配置
//建议用github的组织名称,或者用户名字开头, 再加上自己的插件的名字
//如果发生重名,可以通过配置文件修改这些名字
var (
JRPCName = "pokerbull"
PokerBullX = "pokerbull"
ExecerPokerBull = []byte(PokerBullX)
JRPCName = "guess"
GuessX = "guess"
ExecerGuess = []byte(GuessX)
)
const (
//查询方法名
FuncName_QueryGameListByIds = "QueryGameListByIds"
FuncName_QueryGameById = "QueryGameById"
FuncName_QueryGameByAddr = "QueryGameByAddr"
FuncName_QueryGameByStatus = "QueryGameByStatus"
)
This diff is collapsed.
// Copyright Fuzamei Corp. 2018 All Rights Reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package types
import (
"reflect"
"github.com/33cn/chain33/types"
)
func init() {
// init executor type
types.RegistorExecutor(GuessX, NewType())
types.AllowUserExec = append(types.AllowUserExec, ExecerGuess)
types.RegisterDappFork(GuessX, "Enable", 0)
}
// exec
type PokerBullType struct {
types.ExecTypeBase
}
func NewType() *PokerBullType {
c := &PokerBullType{}
c.SetChild(c)
return c
}
func (t *PokerBullType) GetPayload() types.Message {
return &PBGameAction{}
}
func (t *PokerBullType) GetTypeMap() map[string]int32 {
return map[string]int32{
"Start": PBGameActionStart,
"Continue": PBGameActionContinue,
"Quit": PBGameActionQuit,
"Query": PBGameActionQuery,
}
}
func (t *PokerBullType) GetLogMap() map[int64]*types.LogInfo {
return map[int64]*types.LogInfo{
TyLogPBGameStart: {reflect.TypeOf(ReceiptPBGame{}), "TyLogPBGameStart"},
TyLogPBGameContinue: {reflect.TypeOf(ReceiptPBGame{}), "TyLogPBGameContinue"},
TyLogPBGameQuit: {reflect.TypeOf(ReceiptPBGame{}), "TyLogPBGameQuit"},
TyLogPBGameQuery: {reflect.TypeOf(ReceiptPBGame{}), "TyLogPBGameQuery"},
}
}
// exec
type GuessType struct {
types.ExecTypeBase
}
func NewType() *GuessType {
c := &GuessType{}
c.SetChild(c)
return c
}
func (t *GuessType) GetPayload() types.Message {
return &GuessGameAction{}
}
func (t *GuessType) GetTypeMap() map[string]int32 {
return map[string]int32{
"Start": PBGameActionStart,
"Continue": PBGameActionContinue,
"Quit": PBGameActionQuit,
"Query": PBGameActionQuery,
}
}
func (t *PokerBullType) GetLogMap() map[int64]*types.LogInfo {
return map[int64]*types.LogInfo{
TyLogPBGameStart: {reflect.TypeOf(ReceiptPBGame{}), "TyLogPBGameStart"},
TyLogPBGameContinue: {reflect.TypeOf(ReceiptPBGame{}), "TyLogPBGameContinue"},
TyLogPBGameQuit: {reflect.TypeOf(ReceiptPBGame{}), "TyLogPBGameQuit"},
TyLogPBGameQuery: {reflect.TypeOf(ReceiptPBGame{}), "TyLogPBGameQuery"},
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment