Commit 9fe46fb1 authored by 张振华's avatar 张振华

guess

parent e22ff037
......@@ -242,8 +242,8 @@ func guessQuery(cmd *cobra.Command, args []string) {
gameIDs, _ := cmd.Flags().GetString("gameIDs")
var params types.Query4Cli
params.Execer = pkt.PokerBullX
req := &pkt.QueryPBGameInfo{
params.Execer = pkt.GuessX
req := &pkt.QueryGuessGameInfo{
GameId: gameID,
Addr: address,
Status: int32(status),
......@@ -252,7 +252,7 @@ func guessQuery(cmd *cobra.Command, args []string) {
params.Payload = req
if gameID != "" {
params.FuncName = pkt.FuncName_QueryGameById
var res pkt.ReplyPBGame
var res pkt.ReplyGuessGameInfo
ctx := jsonrpc.NewRpcCtx(rpcLaddr, "Chain33.Query", params, &res)
ctx.Run()
} else if address != "" {
......@@ -272,7 +272,7 @@ func guessQuery(cmd *cobra.Command, args []string) {
gameIDsS = append(gameIDsS, gameIDs)
req := &pkt.QueryPBGameInfos{gameIDsS}
params.Payload = req
var res pkt.ReplyPBGameList
var res pkt.ReplyGuessGameInfos
ctx := jsonrpc.NewRpcCtx(rpcLaddr, "Chain33.Query", params, &res)
ctx.Run()
} else {
......
......@@ -41,7 +41,7 @@ func (c *PokerBull) updateIndex(log *pkt.ReceiptPBGame) (kvs []*types.KeyValue)
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, addGuessGameAddrIndexKey(log.Status, v, log.GameId, log.Index))
}
kvs = append(kvs, delPBGameAddrIndexKey(v, log.PrevIndex))
}
......
......@@ -65,25 +65,21 @@ func calcGuessGameStatusKey(status int32, index int64) []byte {
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)
func calcGuessGameStatusAndPlayerKey(category string, status, index int64) []byte {
key := fmt.Sprintf("LODB-guess-category-status:%s:%d:%018d", category, status, index)
return []byte(key)
}
func calcPBGameStatusAndPlayerPrefix(status, player int32, value int64) []byte {
func calcGuessGameStatusAndPlayerPrefix(category string, status int32) []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)
}
key = fmt.Sprintf("LODB-guess-category-status:%s:%d", category, status)
return []byte(key)
}
func addPBGameStatusIndexKey(status int32, gameID string, index int64) *types.KeyValue {
func addGuessGameStatusIndexKey(status int32, gameID string, index int64) *types.KeyValue {
kv := &types.KeyValue{}
kv.Key = calcPBGameStatusKey(status, index)
kv.Key = calcGuessGameStatusKey(status, index)
record := &pkt.PBGameIndexRecord{
GameId: gameID,
Index: index,
......@@ -92,16 +88,16 @@ func addPBGameStatusIndexKey(status int32, gameID string, index int64) *types.Ke
return kv
}
func delPBGameStatusIndexKey(status int32, index int64) *types.KeyValue {
func delGuessGameStatusIndexKey(status int32, index int64) *types.KeyValue {
kv := &types.KeyValue{}
kv.Key = calcPBGameStatusKey(status, index)
kv.Key = calcGuessGameStatusKey(status, index)
kv.Value = nil
return kv
}
func addPBGameAddrIndexKey(status int32, addr, gameID string, index int64) *types.KeyValue {
func addGuessGameAddrIndexKey(status int32, addr, gameID string, index int64) *types.KeyValue {
kv := &types.KeyValue{}
kv.Key = calcPBGameAddrKey(addr, index)
kv.Key = calcGuessGameAddrKey(addr, index)
record := &pkt.PBGameRecord{
GameId: gameID,
Status: status,
......@@ -111,16 +107,16 @@ func addPBGameAddrIndexKey(status int32, addr, gameID string, index int64) *type
return kv
}
func delPBGameAddrIndexKey(addr string, index int64) *types.KeyValue {
func delGuessGameAddrIndexKey(addr string, index int64) *types.KeyValue {
kv := &types.KeyValue{}
kv.Key = calcPBGameAddrKey(addr, index)
kv.Key = calcGuessGameAddrKey(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)
kv.Key = calcGuessGameStatusAndPlayerKey(status, player, value, index)
record := &pkt.PBGameIndexRecord{
GameId: gameId,
Index: index,
......@@ -131,7 +127,7 @@ func addPBGameStatusAndPlayer(status int32, player int32, value, index int64, ga
func delPBGameStatusAndPlayer(status int32, player int32, value, index int64) *types.KeyValue {
kv := &types.KeyValue{}
kv.Key = calcPBGameStatusAndPlayerKey(status, player, value, index)
kv.Key = calcGuessGameStatusAndPlayerKey(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
}
......@@ -6,22 +6,22 @@ package executor
import (
"github.com/33cn/chain33/types"
pkt "github.com/33cn/plugin/plugin/dapp/pokerbull/types"
pkt "github.com/33cn/plugin/plugin/dapp/guess/types"
)
func (g *PokerBull) Query_QueryGameListByIds(in *pkt.QueryPBGameInfos) (types.Message, error) {
func (g *Guess) Query_QueryGameListByIds(in *pkt.QueryGuessGameInfos) (types.Message, error) {
return Infos(g.GetStateDB(), in)
}
func (g *PokerBull) Query_QueryGameById(in *pkt.QueryPBGameInfo) (types.Message, error) {
func (g *Guess) Query_QueryGameById(in *pkt.QueryGuessGameInfo) (types.Message, error) {
game, err := readGame(g.GetStateDB(), in.GetGameId())
if err != nil {
return nil, err
}
return &pkt.ReplyPBGame{game}, nil
return &pkt.ReplyGuessGameInfo{game}, nil
}
func (g *PokerBull) Query_QueryGameByAddr(in *pkt.QueryPBGameInfo) (types.Message, error) {
func (g *Guess) Query_QueryGameByAddr(in *pkt.QueryGuessGameInfo) (types.Message, error) {
gameIds, err := getGameListByAddr(g.GetLocalDB(), in.Addr, in.Index)
if err != nil {
return nil, err
......@@ -30,7 +30,7 @@ func (g *PokerBull) Query_QueryGameByAddr(in *pkt.QueryPBGameInfo) (types.Messag
return gameIds, nil
}
func (g *PokerBull) Query_QueryGameByStatus(in *pkt.QueryPBGameInfo) (types.Message, error) {
func (g *Guess) Query_QueryGameByStatus(in *pkt.QueryGuessGameInfo) (types.Message, error) {
gameIds, err := getGameListByStatus(g.GetLocalDB(), in.Status, in.Index)
if err != nil {
return nil, err
......
......@@ -8,28 +8,30 @@ package types;
message GuessGame {
string gameId = 1; //游戏ID
uint32 status = 2; //游戏的状态:创建->投注->截止投注->开奖
int64 startTime = 3; //创建游戏的时间
string startTxHash = 4; //创建游戏的交易hash
string topic = 5; //主题
string category = 6; //分类
string options = 7; //选项
string maxTime = 8; //截止下注时间
int64 maxHeight = 9; //截止下注的块高
string symbol = 10; //bty或者具体token
string exec = 11; //coins或者token
uint32 oneBet = 12; //一注等于多少bty或者token
uint32 maxBets = 13; //单次可以下多少注,默认100
uint32 maxBetsNumber = 14; //最多可以下多少注
uint32 fee = 15; //收取费用,不带则表示不收费
string feeAddr = 16; //收费地址
string expire = 17; //游戏过期时间
int64 expireHeight = 18; //游戏过期区块高度
string adminAddr = 19; //游戏创建者地址,只有该地址可以开奖
uint32 betsNumber = 20; //已下注数,如果数量达到maxBetsNumber,则不允许再下注
repeated GuessPlayer plays = 21; //参与游戏下注的玩家投注信息
string result = 22;
repeated GuessBet bets = 23;
int64 index = 24;
uint32 preStatus = 3;
int64 startTime = 4; //创建游戏的时间
string startTxHash = 5; //创建游戏的交易hash
string topic = 6; //主题
string category = 7; //分类
string options = 8; //选项
string maxTime = 9; //截止下注时间
int64 maxHeight = 10; //截止下注的块高
string symbol = 11; //bty或者具体token
string exec = 12; //coins或者token
uint32 oneBet = 13; //一注等于多少bty或者token
uint32 maxBets = 14; //单次可以下多少注,默认100
uint32 maxBetsNumber = 15; //最多可以下多少注
uint32 fee = 16; //收取费用,不带则表示不收费
string feeAddr = 17; //收费地址
string expire = 18; //游戏过期时间
int64 expireHeight = 19; //游戏过期区块高度
string adminAddr = 20; //游戏创建者地址,只有该地址可以开奖
uint32 betsNumber = 21; //已下注数,如果数量达到maxBetsNumber,则不允许再下注
repeated GuessPlayer plays = 22; //参与游戏下注的玩家投注信息
string result = 23;
repeated GuessBet bets = 24;
int64 index = 25;
int64 preIndex = 26;
}
message GuessPlayer {
......@@ -40,6 +42,10 @@ message GuessPlayer {
message GuessBet {
string option = 1;
uint32 betsNumber = 2;
bool isWinner = 3;
uint32 profit = 4;
int64 index = 5;
int64 preIndex = 6;
}
......@@ -224,6 +230,25 @@ message ReplyPBGameList {
repeated PokerBull games = 1;
}
message QueryGuessGameInfo {
string gameId = 1;
string addr = 2;
int32 status = 3;
int64 index = 4;
}
message ReplyGuessGameInfo {
GuessGame game = 1;
}
message QueryGuessGameInfos {
repeated string gameIds = 1;
}
message ReplyGuessGameInfos {
repeated GuessGame games = 1;
}
message ReceiptPBGame {
string gameId = 1;
int32 status = 2;
......
......@@ -93,11 +93,11 @@ func (c *Jrpc) GuessPublishTx(parm *pb.GuessPublishTxReq, result *interface{}) e
return nil
}
func (c *Jrpc) PokerBullQueryTx(parm *pb.PBQueryReq, result *interface{}) error {
func (c *Jrpc) GuessQueryTx(parm *pb.PBQueryReq, result *interface{}) error {
if parm == nil {
return types.ErrInvalidParam
}
head := &pb.PBGameQuery{
head := &pb.GuessGameQuery{
GameId: parm.GameId,
}
reply, err := c.cli.Show(context.Background(), head)
......
......@@ -6,21 +6,14 @@ 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/guess/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},
Value: &pb.GuessGameAction_Start{head},
}
tx, err := types.CreateFormatTx(pb.GuessX, types.Encode(val))
if err != nil {
......@@ -69,12 +62,12 @@ func (c *channelClient) GuessPublish(ctx context.Context, head *pb.GuessGamePubl
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},
func (c *channelClient) Show(ctx context.Context, head *pb.GuessGameQuery) (*types.UnsignTx, error) {
val := &pb.GuessGameAction{
Ty: pb.GuessGameActionQuery,
Value: &pb.GuessGameAction_Query{head},
}
tx, err := types.CreateFormatTx(pb.PokerBullX, types.Encode(val))
tx, err := types.CreateFormatTx(pb.GuessX, types.Encode(val))
if err != nil {
return nil, err
}
......
......@@ -13,10 +13,16 @@ const (
GuessGameActionStart = iota + 1
GuessGameActionBet
GuessGameActionStopBet
GuessGameActionAbort
GuessGameActionPublish
GuessGameActionTimeOut
GuessGameActionQuery
GuessGameStatusStart = iota + 1
GuessGameStatusBet
GuessGameStatusStopBet
GuessGameStatusAbort
GuessGameStatusPublish
GuessGameStatusTimeOut
)
const (
......@@ -43,10 +49,6 @@ const (
//建议用github的组织名称,或者用户名字开头, 再加上自己的插件的名字
//如果发生重名,可以通过配置文件修改这些名字
var (
JRPCName = "pokerbull"
PokerBullX = "pokerbull"
ExecerPokerBull = []byte(PokerBullX)
JRPCName = "guess"
GuessX = "guess"
ExecerGuess = []byte(GuessX)
......@@ -58,4 +60,6 @@ const (
FuncName_QueryGameById = "QueryGameById"
FuncName_QueryGameByAddr = "QueryGameByAddr"
FuncName_QueryGameByStatus = "QueryGameByStatus"
//FuncName_QueryGameByAdminAddr = "QueryGameByAdminAddr"
//FuncName_QueryGameByCategory = "QueryGameByCategory"
)
This diff is collapsed.
......@@ -38,6 +38,7 @@ func (t *GuessType) GetTypeMap() map[string]int32 {
"Bet": GuessGameActionBet,
"Abort": GuessGameActionAbort,
"Publish": GuessGameActionPublish,
"Query": GuessGameActionQuery,
}
}
......
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