--- --- Created by 谌建军. --- DateTime: 2017/12/13 11:28 --- local TwoDouDiZhu_Protocol = import(".TwoDouDiZhu_Protocol") local TwoDouDiZhu_GameEvent = import(".TwoDouDiZhu_GameEvent") local TwoDouDiZhu_CardType = import(".TwoDouDiZhu_CardType") local TwoDouDiZhu_PutError = { "必须先出最小的牌", "出牌不符合规定牌型 ", "下家报单,请出最大的牌 ", "炸弹不能拆" } local TwoDouDiZhu_GameController = {} local M = TwoDouDiZhu_GameController function M.new() setmetatable(M, {__index = GameController}) local self = setmetatable({}, {__index = M}) self:init("二人斗地主") self.class = "TwoDouDiZhu_GameController" return self end function M:init(name) GameController.init(self, name) self:RegisterEvt() end -- 事件注册 function M:RegisterEvt() self._eventmap[TwoDouDiZhu_Protocol.TwoDouDiZhu_Ming_Card] = self.OnMingCard self._eventmap[TwoDouDiZhu_Protocol.TwoDouDiZhu_Init_Card] = self.OnInitCard self._eventmap[TwoDouDiZhu_Protocol.TwoDouDiZhu_Options] = self.OnOptions self._eventmap[TwoDouDiZhu_Protocol.TwoDouDiZhu_Index_Move] = self.OnIndexMove self._eventmap[TwoDouDiZhu_Protocol.TwoDouDiZhu_Play_Succ] = self.OnPlaySucc self._eventmap[TwoDouDiZhu_Protocol.TwoDouDiZhu_Put_Error] = self.OnPutError self._eventmap[TwoDouDiZhu_Protocol.TwoDouDiZhu_Pass_Succ] = self.OnPassSucc self._eventmap[TwoDouDiZhu_Protocol.TwoDouDiZhu_Result] = self.OnResult self._eventmap[TwoDouDiZhu_Protocol.TwoDouDiZhu_Bomb_Score] = self.OnBombScore self._eventmap[TwoDouDiZhu_Protocol.TwoDouDiZhu_Piao_Tip] = self.OnPiaoTip self._eventmap[TwoDouDiZhu_Protocol.TwoDouDiZhu_Piao_Action] = self.OnPiaoAction self._eventmap[TwoDouDiZhu_Protocol.TwoDouDiZhu_ConfirmToNextGameSucc] = self.OnConfrimToNextGameSucc --self._eventmap[TwoDouDiZhu_Protocol.TwoDouDiZhu_Oener] = self.Oener -- self._eventmap[Protocol.GAME_EVT_PLAYER_JOIN] = self.OnEventPlayerEnter self._eventmap[TwoDouDiZhu_Protocol.PT_GAMETUOGUAN] = self.Game_TuoGuan -- GAME_EVT_ALERT_JIAO_DIZHU = "2041", --通知玩家叫地主 -- GAME_EVT_USER_JAIO_DIZHU_REQ = "2042", --玩家叫地主 叫/不叫 -- GAME_EVT_USER_ALERT_QIANG_DIZHU = "2043", --通知玩家抢地主 -- GAME_EVT_USER_QIANG_DIZHU_REQ = "2044", --玩家抢地主 抢/不抢 self._eventmap[TwoDouDiZhu_Protocol.GAME_EVT_ALERT_JIAO_DIZHU] = self.OnAlertJiaoDiZhu self._eventmap[TwoDouDiZhu_Protocol.GAME_EVT_USER_ALERT_QIANG_DIZHU] = self.OnUserAlertQiangDiZhu self._eventmap[TwoDouDiZhu_Protocol.GAME_EVT_USEr_JIAO_DIZHU_RSP] = self.OnUserJiaoDiZhu self._eventmap[TwoDouDiZhu_Protocol.GAME_EVT_USER_QIANG_DIZHU_RSP] = self.OnUserQiangDiZhu self._eventmap[TwoDouDiZhu_Protocol.GAME_EVT_DIZHU_INFO] = self.OnDiZhuInfo self._eventmap[TwoDouDiZhu_Protocol.GAME_EVT_DIZHU_RANG_XIAN_RSP] = self.OnRangXian end -- function M:Oener(evt_data) -- local seat = evt_data["owner"] -- self._cacheEvent:Enqueue(function() -- DispatchEvent(self._dispatcher,TwoDouDiZhu_GameEvent.Oener,seat) -- end) -- end -- function M:OnEventPlayerEnter(evt_data) -- local p = self._room:NewPlayer() -- local _user -- _user = User.new() -- _user.account_id = evt_data["aid"] -- _user.host_ip = evt_data["ip"] -- _user.nick_name = evt_data["nick"] -- _user.head_url = evt_data["portrait"] -- _user.sex = evt_data["sex"] -- _user.location = Location.new(evt_data["pos"] or "") -- p.seat = evt_data["seat"] -- p.ready = evt_data["ready"] == 1 and true or false -- p.self_user = _user -- p.line_state = 1 -- p.total_score=evt_data["score"] -- p.hp_info = evt_data["hp_info"] -- -- p.total_score=self._room.room_config.energyTab==0 and evt_data["score"] or evt_data["score"]/10 -- DataManager.CurrenRoom:AddPlayer(p) -- DispatchEvent(self._dispatcher,GameEvent.PlayerEnter, p) -- end function M:SendCard(cards,currentCard) local _data = {} _data["card"] = cards _data["all_card"] = currentCard printlog("出牌==========================") pt(_data) local _client = ControllerManager.GameNetClinet _client:send(TwoDouDiZhu_Protocol.TwoDouDiZhu_Send_Card, _data) end function M:SendPiao(piao) local _data = {} _data["id"] = piao local _client = ControllerManager.GameNetClinet _client:send(TwoDouDiZhu_Protocol.TwoDouDiZhu_Send_Piao, _data) end function M:SendPass() local _client = ControllerManager.GameNetClinet _client:send(TwoDouDiZhu_Protocol.TwoDouDiZhu_Send_Guo) end function M:SendInitCardEnd() local _client = ControllerManager.GameNetClinet _client:send(TwoDouDiZhu_Protocol.TwoDouDiZhu_Init_Card_End) end function M:SendUserJiaoDiZhu(jiao) local _data = {} _data["jiao"] = jiao local _client = ControllerManager.GameNetClinet _client:send(TwoDouDiZhu_Protocol.GAME_EVT_USER_JAIO_DIZHU_REQ, _data) end function M:SendUserQiangDiZhu(qiang) local _data = {} _data["qiang"] = qiang local _client = ControllerManager.GameNetClinet _client:send(TwoDouDiZhu_Protocol.GAME_EVT_USER_QIANG_DIZHU_REQ, _data) end function M:SendUserRangXian() local _client = ControllerManager.GameNetClinet _client:send(TwoDouDiZhu_Protocol.GAME_EVT_DIZHU_RANG_XIAN) end function M:OnAlertJiaoDiZhu(evt_data) printlog("通知叫地主================================") local seat = evt_data["seat"] self._cacheEvent:Enqueue( function() DispatchEvent(self._dispatcher, TwoDouDiZhu_GameEvent.OnAlertJiaoDiZhu,seat) end ) end function M:OnUserJiaoDiZhu(evt_data) printlog("玩家叫地主广播 座位 jiao: 0-不叫 1-叫 count: 抢/叫次数================================") local seat = evt_data["seat"] local jiao = evt_data["jiao"] local count = evt_data["count"] local curMul = evt_data["curMul"] self._cacheEvent:Enqueue( function() DispatchEvent(self._dispatcher, TwoDouDiZhu_GameEvent.OnUserJiaoDiZhu, seat,jiao,count,curMul) end ) end function M:OnUserAlertQiangDiZhu(evt_data) printlog("通知玩家抢地主===========================") local seat = evt_data["seat"] self._cacheEvent:Enqueue( function() DispatchEvent(self._dispatcher, TwoDouDiZhu_GameEvent.OnUserAlertQiangDiZhu, seat) end ) end function M:OnUserQiangDiZhu(evt_data) printlog("玩家抢地主广播 seat:座位号 qiang: 0-不抢 1-抢 count: 抢/叫次数================================") local seat = evt_data["seat"] local qiang = evt_data["qiang"] local count = evt_data["count"] local rangCount = evt_data["rangCount"] local leftCount = evt_data["leftCount"] local curMul = evt_data["curMul"] self._cacheEvent:Enqueue( function() DispatchEvent(self._dispatcher, TwoDouDiZhu_GameEvent.OnUserQiangDiZhu, seat,qiang,count,rangCount,leftCount,curMul) end ) end function M:OnDiZhuInfo(evt_data) printlog("定地主================================") local seat = evt_data["seat"] local cards = evt_data["cards"] local mul = evt_data["mul"] local rangCount = evt_data["rangCount"] local curMul = evt_data["curMul"] self._cacheEvent:Enqueue( function() DispatchEvent(self._dispatcher, TwoDouDiZhu_GameEvent.OnDiZhuInfo, seat,cards,mul,rangCount,curMul) end ) end function M:OnRangXian(evt_data) local seat = evt_data["seat"] local rangCount = evt_data["rangCount"] local curMul = evt_data["curMul"] local leftCount = evt_data["leftCount"] self._cacheEvent:Enqueue( function() DispatchEvent(self._dispatcher, TwoDouDiZhu_GameEvent.OnRangXian, seat,rangCount,curMul,leftCount) end ) end function M:ConformToNextGame() local _client = ControllerManager.GameNetClinet _client:send(TwoDouDiZhu_Protocol.TwoDouDiZhu_ConfirmToNextGame) end function M:OnMingCard(evt_data) if ViewManager.GetCurrenView().dview_class == LobbyView then self:ReturnToRoom() return end local card = evt_data["mingpai"] self._cacheEvent:Enqueue( function() self._room.ming_card = card DispatchEvent(self._dispatcher, TwoDouDiZhu_GameEvent.OnMingCard, card) end ) end function M:OnInitCard(evt_data) if ViewManager.GetCurrenView().dview_class == LobbyView then self:ReturnToRoom() return end local cardlist = evt_data["cards"] local round = evt_data["round"] self._cacheEvent:Enqueue( function() for _, player in ipairs(self._room.player_list) do player:Clear() player.hand_count = #cardlist end self._room.curren_round = round DispatchEvent(self._dispatcher, TwoDouDiZhu_GameEvent.OnInitCard, round, cardlist) end ) end function M:OnBombScore(evt_data) local scoreList = evt_data["gold_list"] self._cacheEvent:Enqueue( function() for i = 1, #scoreList do local score = scoreList[i].bom_score local player = self._room:GetPlayerById(scoreList[i].aid) player.total_score = player.total_score + score end DispatchEvent(self._dispatcher, TwoDouDiZhu_GameEvent.OnBombScore, scoreList) end ) end function M:OnPlaySucc(evt_data) local seat = evt_data["player"] local card_obj = evt_data["card_obj"] local cards = card_obj["card_list"] local remain = evt_data["remain"] -- 报单 local curMul = evt_data["curMul"] local rangCount = evt_data["rangCount"] local leftCount = evt_data["leftCount"] printlog("出牌成功==========================") pt(evt_data) self._cacheEvent:Enqueue( function() local otherList = self:GetOtherSeatList(seat) local player = self._room:GetPlayerBySeat(seat) local out_card_list = self:ChangeCodeByFrom(cards, true) player.hand_count = remain local card_type, number, length, plan_three_count = self:GetCardListInfo(out_card_list) player.out_card_list = self:GetSortOutCardList(out_card_list, card_type, number, plan_three_count) DispatchEvent(self._dispatcher, TwoDouDiZhu_GameEvent.OnPlaySucc, player, remain, card_type, number, otherList,length,rangCount,leftCount,curMul) end ) end function M:OnPassSucc(evt_data) printlog("pass成功=================================") local seat = evt_data["seat"] self._cacheEvent:Enqueue( function() local p = self._room:GetPlayerBySeat(seat) p.out_card_list = {0} DispatchEvent(self._dispatcher, TwoDouDiZhu_GameEvent.OnPassSucc, p) end ) end function M:OnPutError(evt_data) local code = evt_data["error"] printlog("出牌异常========================") pt(evt_data) self._cacheEvent:Enqueue( function() local error_str = self:GetErrorStr(code) DispatchEvent(self._dispatcher, TwoDouDiZhu_GameEvent.OnErrorTip, error_str) end ) end function M:TuoGuan(isTuo) local _data = {} _data["tuoguan"] = isTuo local _client = ControllerManager.GameNetClinet _client:send(TwoDouDiZhu_Protocol.SEND_TUOGUAN, _data) end function M:Game_TuoGuan(evt_data) local tuoguan = evt_data["tuoguan"] local seat = evt_data["seat"] self._cacheEvent:Enqueue(function() DispatchEvent(self._dispatcher, TwoDouDiZhu_GameEvent.Game_TuoGuan, tuoguan, seat) end) end function M:OnIndexMove(evt_data) local seat = evt_data["index"] self._cacheEvent:Enqueue( function() self._room.curren_turn_seat = seat self._room.is_new_bout = self:GetIsNewBout(seat) DispatchEvent(self._dispatcher, TwoDouDiZhu_GameEvent.OnIndexMove, seat) end ) end function M:OnOptions(evt_data) local play = evt_data["play"] local pass = evt_data["pass"] local rang = evt_data["rang"] local isCanPass = evt_data["isCanPass"] local rangCount = evt_data["rangCount"] local leftCount = evt_data["leftCount"] printlog("出牌提示==========================") pt(evt_data) self._cacheEvent:Enqueue( function() local lastCardList = self:GetLastCardList(self._room.self_player.seat) local cardType, cardNum, cardLength = self:GetCardListInfo(lastCardList) DispatchEvent(self._dispatcher, TwoDouDiZhu_GameEvent.OnOptions, play, cardType, cardNum, cardLength, pass,rang,isCanPass,rangCount,leftCount) end ) end function M:OnPiaoTip(evt_data) if ViewManager.GetCurrenView().dview_class == LobbyView then self:ReturnToRoom() return end local piao = evt_data["piao"] local reload = evt_data["reload"] self._cacheEvent:Enqueue( function() DispatchEvent(self._dispatcher, TwoDouDiZhu_GameEvent.OnPiaoTips, piao,reload) end ) end function M:OnPiaoAction(evt_data) local seat = evt_data["seat"] local piao = evt_data["piao"] self._cacheEvent:Enqueue( function() DispatchEvent(self._dispatcher, TwoDouDiZhu_GameEvent.OnPiaoAction, seat,piao) end ) end function M:OnResult(evt_data) local result_type = evt_data["type"] local info = evt_data["info"] local winseat = evt_data["winseat"] local remaincards = evt_data["remaincards"] local feiCards = evt_data["feiCards"] printlog("结算====================================") pt(evt_data) if result_type == 1 then local over = 1 ControllerManager.SetGameNetClient(nil, true) self._cacheEvent:Enqueue( function() for i = 1, #info do local p = self._room:GetPlayerBySeat(info[i]["seat"]) p.total_score = info[i]["score"] info[i]["self_user"] = p.self_user end DispatchEvent(self._dispatcher, TwoDouDiZhu_GameEvent.OnResult, over, info, winseat, remaincards,feiCards) end ) elseif result_type == 0 then local over = 0 self._cacheEvent:Enqueue( function() for i = 1, #info do local p = self._room:GetPlayerBySeat(info[i]["seat"]) p.total_score = info[i]["score"] info[i]["self_user"] = p.self_user end DispatchEvent(self._dispatcher, TwoDouDiZhu_GameEvent.OnResult, over, info, winseat, remaincards,feiCards) end ) else local dissolve = 1 ControllerManager.SetGameNetClient(nil, true) for i = 1, #info do local p = self._room:GetPlayerBySeat(info[i]["seat"]) p.total_score = info[i]["score"] info[i]["self_user"] = p.self_user end -- ControllerManager.ChangeController(LoddyController) DispatchEvent(self._dispatcher, TwoDouDiZhu_GameEvent.OnResultByDissolve, over, info, winseat, dissolve) end end function M:OnConfrimToNextGameSucc(evt_data) local aid = evt_data["aid"] self._cacheEvent:Enqueue( function() DispatchEvent(self._dispatcher, TwoDouDiZhu_GameEvent.OnConfrimToNextGameSucc, aid) end ) end function M:Game_TuoGuan(evt_data) local tuoguan = evt_data["tuoguan"] local seat = evt_data["seat"] self._cacheEvent:Enqueue(function() DispatchEvent(self._dispatcher, TwoDouDiZhu_GameEvent.Game_TuoGuan, tuoguan, seat) end) end function M:ChangeCodeByFrom(cardList, isSort) isSort = isSort or false local new_card_list = {} for i = 1, #cardList do local flower = math.floor(cardList[i] / 100) local number = cardList[i] % 100 if number == 2 then number = 15 end local card = number * 10 + flower new_card_list[#new_card_list + 1] = card end return isSort == true and table.sort(new_card_list) or new_card_list end function M:GetOtherSeatList(seat) local list = {} for i = 1, self._room.room_config.people_num do if seat ~= i then list[#list + 1] = i end end return list end -- function M:GetIsNewBout(seat) local passCount = 0 for i = 1, #self._room.player_list do local player = self._room.player_list[i] if seat ~= player.seat then local isPass = self:GetIsPass(player.out_card_list) if isPass then passCount = passCount + 1 end end end if passCount == self._room.room_config.people_num - 1 then return true else return false end end function M:GetLastSeat(seat) local last_seat = seat - 1 if last_seat < 1 then last_seat = last_seat + self._room.room_config.people_num end return last_seat end function M:GetLastCardList(seat) local last_seat = self:GetLastSeat(seat) local player = self._room:GetPlayerBySeat(last_seat) local isPass = self:GetIsPass(player.out_card_list) if isPass then if self._room.room_config.people_num == 2 then return {} end local last_seat_2 = self:GetLastSeat(last_seat) local player_2 = self._room:GetPlayerBySeat(last_seat_2) local isPass_2 = self:GetIsPass(player_2.out_card_list) if isPass_2 then return {} else return player_2.out_card_list end else return player.out_card_list end end function M:GetErrorStr(code) return TwoDouDiZhu_PutError[code + 1] end function M:GetSortOutCardList(outCardList, cardType, cardNumber, plan_three_count) if cardType == 3 or cardType == 5 or cardType == 6 then local removeList = {} for i = #outCardList, 1, -1 do local card = outCardList[i] if math.floor(card / 10) == cardNumber then removeList[#removeList + 1] = card table.remove(outCardList, i) end end for i = 1, #removeList do table.insert(outCardList, 1, removeList[i]) end elseif cardType >= 7 and cardType <= 9 then local removeList = {} for i = #outCardList, 1, -1 do local card = outCardList[i] if math.floor(card / 10) <= cardNumber and math.floor(card / 10) > cardNumber - plan_three_count then removeList[#removeList + 1] = card table.remove(outCardList, i) end end for i = 1, #removeList do table.insert(outCardList, 1, removeList[i]) end end return outCardList end --None = 0, --OneCard = 1, --OnePair = 2, --Three = 3, --Pairs = 4, --ThreeAndTwo = 5, --ThreeAndOne = 6, --Plane = 7, --PlaneAndTwo = 8, --PlaneAndOne = 9, --Straight = 10, --Bomb = 11 -- 牌型,大小, 长度 function M:GetCardListInfo(cardlist) if #cardlist == 0 then return 0, 0, 0, 0 end -- 检测牌型 local card_type, card_num, card_length, plan_three_count = TwoDouDiZhu_CardType.None, 0, #cardlist, 0 local card_map = self:GetCardMapByList(cardlist) if #cardlist == 1 then card_type = TwoDouDiZhu_CardType.OneCard card_num = math.floor(cardlist[1] / 10) elseif #cardlist == 2 then card_type = TwoDouDiZhu_CardType.OnePair if (cardlist[1]) == 165 or (cardlist[1])==176 then card_type = TwoDouDiZhu_CardType.HuoJian end card_num = math.floor(cardlist[1] / 10) elseif #cardlist == 3 then card_num = math.floor(cardlist[1] / 10) if card_num==14 and DataManager.CurrenRoom.room_config.threeA==1 then -- body card_type = TwoDouDiZhu_CardType.Bomb else card_type = TwoDouDiZhu_CardType.Three end elseif #cardlist == 4 then local max_key = 0 for k, v in pairs(card_map) do if #v == 4 then card_type = TwoDouDiZhu_CardType.Bomb card_num = k elseif #v == 3 then card_type = TwoDouDiZhu_CardType.ThreeAndOne card_num = k elseif #v == 2 then if k > max_key then max_key = k end card_type = TwoDouDiZhu_CardType.Pairs card_num = max_key end end elseif #cardlist == 5 then local count, max_key = 0, 0 for k, v in pairs(card_map) do if #v >= 3 then card_type = TwoDouDiZhu_CardType.ThreeAndTwo card_num = k elseif #v == 1 then count = count + 1 if k > max_key then max_key = k end if count == 5 then card_type = TwoDouDiZhu_CardType.Straight card_num = max_key end end end elseif #cardlist == 7 then local count, max_key = 0, 0 for k, v in pairs(card_map) do if #v >= 4 then card_type = TwoDouDiZhu_CardType.FourAndtThree card_num = k elseif #v == 1 then count = count + 1 if k > max_key then max_key = k end if count == 7 then card_type = TwoDouDiZhu_CardType.Straight card_num = max_key end end end else local one_count, two_count, three_count = 0, 0, 0 local max_one_key, max_two_key, max_three_key = 0, 0, 0 for k, v in pairs(card_map) do if #v == 2 then if k > max_two_key then max_two_key = k end two_count = two_count + 1 if two_count == #cardlist / 2 then card_type = TwoDouDiZhu_CardType.Pairs card_num = max_two_key end elseif #v == 1 then if k > max_one_key then max_one_key = k end one_count = one_count + 1 if one_count == #cardlist then card_type = TwoDouDiZhu_CardType.Straight card_num = max_one_key end elseif #v == 3 then if max_three_key == 0 then max_three_key = k three_count = three_count + 1 elseif k > max_three_key and k == max_three_key + 1 then max_three_key = k three_count = three_count + 1 elseif k < max_three_key and k == max_three_key - 1 then max_three_key = k three_count = three_count + 1 -- else -- max_three_key = k end --three_count = three_count + 1 end end -- plan_three_count = three_count -- if three_count * 5 >= #cardlist then -- card_type = TwoDouDiZhu_CardType.PlaneAndTwo -- card_num = max_three_key -- elseif three_count * 4 >= #cardlist then -- card_type = TwoDouDiZhu_CardType.PlaneAndOne -- card_num = max_three_key -- elseif three_count * 3 >= #cardlist then -- card_type = TwoDouDiZhu_CardType.Plane -- card_num = max_three_key -- end plan_three_count = three_count if three_count * 3 == #cardlist then card_type = TwoDouDiZhu_CardType.Plane card_num = max_three_key elseif three_count * 4 >= #cardlist and #cardlist%4==0 then card_type = TwoDouDiZhu_CardType.PlaneAndOne card_num = max_three_key elseif three_count * 5 >= #cardlist and #cardlist%5==0 then card_type = TwoDouDiZhu_CardType.PlaneAndTwo card_num = max_three_key end end return card_type, card_num, card_length, plan_three_count end function M:GetCardMapByList(cardlist) local card_map = {} for i = 1, #cardlist do local card = cardlist[i] local card_num = math.floor(cardlist[i] / 10) if card_map[card_num] == nil then card_map[card_num] = {card} else card_map[card_num][#card_map[card_num] + 1] = card end end return card_map end function M:GetIsPass(cardlist) if #cardlist == 0 then return true end if cardlist[1] ~= nil and cardlist[1] == 0 then return true end return false end --请求离开房间 function M:LevelRoom(callBack) local _client = ControllerManager.GameNetClinet if not _client then return end _client:send( Protocol.GAME_EXIT_ROOM, nil, function(res) if res.ReturnCode == 0 then ControllerManager.ChangeController(LoddyController) elseif res.ReturnCode == 27 then ViewUtil.ErrorTip(res.ReturnCode, "退出房间失败!") end callBack(res) end ) end return M