css3 rseat属性_” 2012 ” 一月

上周末写了一个德州牌桌demo,桌子有点大,所以我把一个桌子分成了两半,一半是处理用户请求的,包括:加注、看牌、弃牌、跟注、all in等。一半是牌桌自己事件,包括:抽取庄家位,发底牌,发翻牌,发转牌,发河牌,算奖等。其实大部分方法来说都是一两句代码,分出方法是为了维护方便,也是为了能好意思贴出来。

先看这个牌桌这半个类吧,写了这么几年代码,总结来说:1、代码应该简洁;2、代码要有思想;3、代码逻辑性强;4、代码模块要独立。虽然我不敢说自己的代码真能做到,但我一直是往这些方面靠拢。感觉这个牌桌有这么几点自我感觉还行:1、游戏每个事件都有不同方法;2、游戏中几乎没有跟游戏无关的代码(除了事件监听和发送)。其实做事件的目的是为了通知用户赛桌的变化和对赛事包括牌谱持久化,牌谱分析统计等等。

代码中存在一些如M、I的模块,还有Config等涉及公司机密,就不方便贴出来了,M是定义的事件类型;I是定义的消息中的参数名。Config中包括一些状态定义等等,缺少也不会影响代码阅读,自己补充一点点就能跑起来。

先看一下,牌桌测试程序吧,这个就是常说的测试案例,有这么一个代码就好了,你可以随意修改服务,修改完成运行一次就可以知道服务有么有什么问题:

gserv = Game.GameServer.getInstance()

t = Game.Table.Table('id123', 6, 5)

t.match_type = Game.Config.IMMEDIATE

t.init_event()

t.user_join({'u1' : [1000, 1],

'u2' : [1000, 2],

'u3' : [1000, 3],

'u4' : [1000, 4],

'u5' : [1000, 5]})

gserv.start().join_table(t)

n, j = 2, 1

while not Object.END_EVENT.isSet():

if t.wait_next_uid != 0 and n>0:

gserv.do_event(t.table_id, t.wait_next_uid, M.CALL, {})

n -= 1

if t.status == 'turn' and j == 1:

gserv.do_event(t.table_id, t.wait_next_uid, M.RAISE, {'chips':100})

j = 0

time.sleep(1)

代码贴的实在是有点多了,关于GameServer我就再写一篇来描述消息接收和游戏轮询做介绍吧

#coding=gbk

import time

import logging

import M, I

import Code

import Event

import Config

import Poker

import TableUser

import EventHelper

class Table(TableUser.TableUser):

def __init__(self, table_id, seat_num = 6, action_time = 20):

TableUser.TableUser.__init__(self)

self.table_id = table_id #桌子id

self.table_name = '' #桌子名称

self.table_desc = '' #桌子简介

self.table_poker = [] #桌上当前牌

self.match_id = None #牌桌所属赛事id

self.match_type = None #牌桌所属赛事类型

self.seat_num = seat_num #当前桌子座位数

self.action_time = action_time #玩家行动超时时间

self._poker = None #扑克牌队列

self.table_info = { #牌桌相关信息

'bblind':100, 'sblind':50, 'ante':0, 'dealer_uid':0,

'bblind_uid':0, 'sblind_uid':0, 'dealer_uid':0}

self.status_list = [Config.START_STATUS, Config.BLIND_STATUS, Config.PREFLOP_STATUS,

Config.FLOP_STATUS, Config.TURN_STATUS, Config.DRIVE_STATUS,

Config.PRIZE_STATUS, Config.GAMEOVER_STATUS]

self.free_seat = range(1, seat_num+1) #空座位列表[座位号]

self.pot_info = [] #奖池信息

self.pot_uinfo = [] #奖池对应的用户信息

self.status = Config.INIT_STATUS #初始化状态

def init_event(self):

'''初始化事件'''

TableUser.TableUser.init_event(self)

self.event.add_event_listener(Event.PREFLOP_COMPLETE, EventHelper.on_preflop_msg)

self.event.add_event_listener(Event.FLOP_COMPLETE, EventHelper.on_flop_msg)

self.event.add_event_listener(Event.TURN_COMPLETE, EventHelper.on_turn_msg)

self.event.add_event_listener(Event.DRIVE_COMPLETE, EventHelper.on_drive_msg)

self.event.add_event_listener(Event.BLIND_COMPLETE, EventHelper.on_blind_msg)

self.event.add_event_listener(Event.READY_COMPLETE, EventHelper.on_table_ready)

return self

def reset(self):

'''重置桌子信息'''

self.table_poker = []

self.wait_next_uid = 0

self.user_max_chips = 0

self._poker = Poker.get_poker_queue()

def get_dealer_uid(self):

'''获取庄家位子'''

import random

return random.choice(self.cplayer_list)

def first_blind_uid(self):

'''第一次设置大小盲'''

dealer_uid = self.get_dealer_uid()

plen = len(self.cplayer_list)

dindex = self.cplayer_list.index(dealer_uid)

bindex = (dindex+2) % plen

self.table_info['sblind_uid'] = self.cplayer_list[(dindex+1) % plen]

self.table_info['bblind_uid'] = self.cplayer_list[(dindex+2) % plen]

self.table_info['dealer_uid'] = dealer_uid

self.iplayer_list = self.cplayer_list[bindex+1:] + self.cplayer_list[0:bindex+1]

def set_blind_uid(self):

'''设置盲注相关信息'''

lbb = self.table_info['bblind_uid']

if not lbb: #如果是第一手

self.first_blind_uid()

return None

bblind_uid = sblind_uid = 0

if lbb in self.cplayer_list:

sblind_uid = lbb

else: #如果上一手的大盲离开

sblind_uid = 0

bindex = (self.cplayer_list.index(lbb) + 1) % len(self.cplayer_list)

bblind_uid = self.cplayer_list[bindex]

self.table_info['sblind_uid'] = sblind_uid

self.table_info['bblind_uid'] = bblind_uid

dindex = (self.cplayer_list.index(sblind_uid) - 1) % len(self.cplayer_list)

self.table_info['dealer_uid'] = self.cplayer_list[dindex]

self.iplayer_list = self.cplayer_list[bindex+1:] + self.cplayer_list[0:bindex+1]

def start(self):

'''开始游戏'''

#检查是否可以开始比赛

self.cplayer_list = self.get_player_list()

if len(self.cplayer_list) < self.min_player_num:

self.status = Config.INIT_STATUS

return False

logging.info('[%s] start game!', self.table_id)

self.reset()

self.status = Config.BLIND_STATUS

event_content = { 'cplayer_list':self.cplayer_list,

'player_dict' :self.player_dict,

'table_id' :self.table_id}

self.event.dispatch_event(Event.READY_COMPLETE, content = event_content)

return False

def blind(self):

'''设置大小盲注'''

self.set_blind_uid()

logging.info('[%s] set blind over!:%s', self.table_id, self.table_info)

return False

def cut_card(self):

'''切牌'''

ret = self._poker.get()

logging.debug('[cut_card]:%s', ret)

return ret

def pre_flop(self):

'''底牌圈'''

self.cut_card()

for pos in self.cplayer_list:

self.player_dict[pos].poker_list = [self._poker.get(), self._poker.get()]

event_content = {'cplayer_list':self.cplayer_list,

'player_dict' :self.player_dict,

'table_id' :self.table_id}

self.event.dispatch_event(Event.PREFLOP_COMPLETE, content = event_content)

self.do_blind_chips() #扣除大小盲

return True

def flop(self):

'''翻牌圈'''

self.cut_card()

self.table_poker.extend([self._poker.get(), self._poker.get(), self._poker.get()])

event_content = {'cplayer_list':self.cplayer_list,

'table_poker':self.table_poker,

'table_id' :self.table_id}

self.event.dispatch_event(Event.FLOP_COMPLETE, content = event_content)

return True

def turn(self):

'''转牌圈'''

self.cut_card()

self.table_poker.append(self._poker.get())

event_content = {'cplayer_list':self.cplayer_list,

'table_poker':self.table_poker,

'table_id' :self.table_id}

self.event.dispatch_event(Event.TURN_COMPLETE, content = event_content)

return True

def drive(self):

'''河牌圈'''

self.cut_card()

self.table_poker.append(self._poker.get())

event_content = {'cplayer_list':self.cplayer_list,

'table_poker':self.table_poker,

'table_id' :self.table_id}

self.event.dispatch_event(Event.DRIVE_COMPLETE, content = event_content)

return True

def prize(self):

'''派奖'''

_uinfo = {}

for uid in self.cplayer_list:

_player = self.player_dict[uid]

if _player.status != Config.FOLD:

_uinfo[uid] = _player.poker_list + self.table_poker

ret = None

if len(_uinfo) > 1:

ret = Poker.compare(_uinfo)

print _uinfo

logging.info('[%s] prize :%s', self.table_id, ret)

return False

def game_over(self):

'''游戏结束'''

for i in self.cplayer_list:

player = self.player_dict[i]

player.poker_list = []

logging.info('game_over!')

return False

def _do_blind_chips(self, type, uchips = None):

'''扣除盲注'''

player = self.player_dict[self.table_info[type+'_uid']]

bchips = uchips and uchips or self.table_info[type]

info = {'chips':bchips}

self.user_raise(self.table_info[type+'_uid'], info)

return bchips

def do_blind_chips(self):

'''扣除大小盲注'''

schips = self._do_blind_chips('sblind') #扣除小盲注

splayer = self.player_dict[self.table_info['sblind_uid']]

#当前只有大小盲,且小盲all in

if len(self.cplayer_list) == 2 and splayer.status == Config.ALL_IN:

bchips = self._do_blind_chips('bblind', schips) #扣除大盲注

else:

bchips = self._do_blind_chips('bblind') #扣除大盲注

event_content = {'cplayer_list':self.cplayer_list,

'table_info' :self.table_info,

'blind_info' :{self.table_info['bblind_uid']:bchips,

self.table_info['sblind_uid']:schips},

'table_id' :self.table_id}

self.event.dispatch_event(Event.BLIND_COMPLETE, content = event_content)

def check(self, data = {}):

'''服务检查'''

if self.status == Config.INIT_STATUS: #初始态

return None

if data.get('uid', None): #用户有请求

self.player_bet(data['uid'], data['event'], data['info'])

if self.wait_next_uid == 0 : #做游戏事情

if self._check_game_over():

self.status = Config.PRIZE_STATUS

if not hasattr(self, self.status):

self.error('error status attr:%s', self.status)

return None

if getattr(self, self.status)():

self._turn_player(self._get_wait_next())

self.status = self._get_next_status() #跳转到下一状态

else: #判断用户状态

player = self.player_dict[self.wait_next_uid]

if time.time() > player.out_time: #超时

player.status = Config.NURSE

if player.status == Config.NURSE: #托管中

self.user_nurse(self.wait_next_uid)

def error(self, msg = ''):

logging.info('error:%s', msg)

####################################################################################

def _check_game_over(self):

'''判断游戏是否完成'''

if len(self.iplayer_list) - self.fold_unum == 1: #只剩下一个用户

return True

return False

def _get_next_status(self):

'''获取下一个游戏状态'''

if self.status == self.status_list[-1]:

return self.status

sindex = self.status_list.index(self.status)

return self.status_list[sindex + 1]

下面在来看一下,上面类中继承的TableUser.py模块,该模块主要为了响应用户事件,包括用户超时自动设为托管状态等。

#coding=gbk

import time

import logging

import M, I

import Code

import Event

import Player

import Config

import EventHelper

class TableUser:

'''桌上玩家动作'''

def __init__(self):

self.player_dict = {} #当前牌桌用户列表 {玩家uid:player}

self.cplayer_list = [] #当前玩家列表[玩家uid]

self.nplayer_list = [] #新加入玩家list[玩家uid]

self.iplayer_list = [] #当前说话玩家顺序

self.fold_unum = 0 #弃牌用户数

self.wait_next_uid = 0 #等待的出价玩家uid

self.user_max_chips = 0 #用户最大出价

self.min_player_num = 2 #最小玩家数

self.free_seat = [] #空座位列表[座位号]

self.event = Event.Event() #相关事件句柄

self.user_method_conf = {M.CALL:self.user_call, M.RAISE:self.user_raise,

M.FOLD:self.user_fold, M.CHECK:self.user_check,

M.ALL_IN:self.user_all_in}

def init_event(self):

'''初始化事件'''

self.event.add_event_listener(Event.USER_JOIN, EventHelper.on_user_join)

def get_player_list(self):

'''初始化当前玩家列表'''

_cplayer_list = []

for uid, player in self.player_dict.items():

if player.chips > 0 : #取出有筹码的用户

player.unplay_times = 0

_cplayer_list.append(uid)

else:

player.unplay_times += 1

if self.cplayer_list: #不是第一手,就有新手列表

self.nplayer_list = set(_cplayer_list) - set(self.cplayer_list)

_cplayer_list.sort(cmp=lambda x,y:self.player_dict[x].seat_pos-self.player_dict[y].seat_pos)

return _cplayer_list

def _user_join(self, uid, chips=0, seat_pos=None):

'''玩家加入牌桌'''

if not self.free_seat: #没有空座

return Code.NOFREE_SEAT

if not seat_pos: #分配座位号

seat_pos = self.free_seat[0]

elif seat_pos not in self.free_seat: #座位已经被占用

return Code.EXIST_PLAYER

player = Player.Player(uid, chips, Config.OK)

player.seat_pos = seat_pos

self.player_dict[uid] = player

self.free_seat.remove(seat_pos)

event_content = {'info' :player,

'player_dict':self.player_dict,

'player_dict' :self.player_dict,

'table_id' :self.table_id}

self.event.dispatch_event(Event.USER_JOIN, content = event_content)

return Code.OK

def user_join(self, userdict = {'uid':['chips', 'seat_pos']}):

'''用户加入牌桌'''

code = Code.OK

for uid, uinfo in userdict.items():

code = self._user_join(uid, uinfo[0], uinfo[1])

if self.status == Config.INIT_STATUS and self.match_type == Config.IMMEDIATE:

self.start() #开始比赛

return code

def player_bet(self, uid, event, info):

'''玩家下注'''

if self.wait_next_uid != uid:

return Code.NOTURN_YOU #还没轮到该用户

if uid not in self.cplayer_list:

return Code.NOPLAYER #用户非法

if self.player_dict[uid].status in [Config.FOLD, Config.ALL_IN]:

return Code.NOPRIM_DO #没有说话权利

if not self.user_method_conf.has_key(event):

return Code.DO_ERROR #没有该玩家事件

ret = self.user_method_conf[event](uid, info)

if ret is not True:

return ret

self.check_game(uid)

return True

def check_game(self, uid):

'''做系统判断'''

if self._check_street(uid):

self._reset_street() #重置这一街情况

self.wait_next_uid = 0

return None

next_uid = self._get_wait_next()

self._turn_player(next_uid)

def user_call(self, uid, info = None):

'''玩家跟注'''

player = self.player_dict[uid]

uchip = sum(player.bid_list)

ichips = 0

if player.chips+uchip > self.user_max_chips:

ichips = self.user_max_chips - uchip

player.chips -= ichips

player.bid_list.append(ichips)

logging.info('[%s][%s] call :%s', self.table_id, uid, ichips)

else: #筹码不够,all in

self.user_all_in(uid)

return True

def user_raise(self, uid, info = None):

'''玩家加注'''

player = self.player_dict[uid]

chips = info.get('chips')

if player.chips > chips:

player.chips -= chips

player.bid_list.append(chips)

self.user_max_chips = max(chips, self.user_max_chips)

logging.info('[%s][%s] raise :%s', self.table_id, uid, chips)

else: #筹码不够,all in

self.user_all_in(uid)

return True

def user_fold(self, uid, info = None):

'''玩家弃牌'''

self.player_dict[uid].status = Config.FOLD

self.fold_unum += 1

logging.info('[%s][%s] fold!', self.table_id, uid)

return True

def user_check(self, uid, info = None):

'''玩家看牌'''

player = self.player_dict[uid]

uchip = sum(player.bid_list)

print 'user_check test[%s, %s, %s]' % (uid, uchip, self.user_max_chips)

if uchip >= self.user_max_chips:

logging.info('[%s][%s] check!', self.table_id, uid)

return True

return Code.NOPRIM_CHECK #没有权限看牌

def user_all_in(self, uid, info = None):

'''玩家ALL IN'''

player = self.player_dict[uid]

chips = player.chips

player.chips = 0

player.status = Config.ALL_IN

player.bid_list.append(chips)

self.user_max_chips = max(chips, self.user_max_chips)

logging.info('[%s][%s] all in :%s', self.table_id, uid, chips)

return True

def user_nurse(self, uid):

'''玩家智能托管'''

player = self.player_dict[uid]

if self.user_check(uid) is not True: #看牌失败

self.user_fold(uid)

self.check_game(uid)

####################################################################

def _turn_player(self, uid):

'''轮到某玩家说话'''

logging.info('status:%s, wait:%s', self.status, uid)

self.wait_next_uid = uid

if uid == 0:

return uid

player = self.player_dict[uid]

player.out_time = time.time()+self.action_time

def _reset_street(self):

'''一街完成重置'''

self.user_max_chips = 0

uchips = 0 #统计底池

for i in self.cplayer_list:

player = self.player_dict[i]

uchips += sum(player.bid_list)

player.bid_list = []

self.pot_info.append(uchips)

def _check_street(self, uid):

'''检查一街是否完成'''

if uid != self.iplayer_list[-1]:

return False

for i in self.cplayer_list:

player = self.player_dict[i]

if player.status in [Config.FOLD, Config.ALL_IN]:

continue

if sum(player.bid_list) < self.user_max_chips:

return False

return True

def _get_wait_next(self):

'''设置当前轮到下一玩家'''

index = 0

if self.wait_next_uid:

index = (self.iplayer_list.index(self.wait_next_uid)+1) % len(self.iplayer_list)

next_uid = 0

print 'iplayer_list:%s, index:%s, nuid:%s ' % (self.iplayer_list, index, self.wait_next_uid)

for uid in self.iplayer_list[index:]+self.iplayer_list[0:index]:

player = self.player_dict[uid]

if player.status not in [Config.FOLD, Config.ALL_IN]:

next_uid = uid

break

if self.wait_next_uid == next_uid:

next_uid = 0

return next_uid

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值