斗地主算法(2)

上篇文章写了斗地主牌型判断的几个简单的牌型的判断,现在来写剩下的几个复杂的牌型

本人小菜鸟,算法写的不好之处请大家不吝赐教

注意下面所有的判断都是先将数字去掉花色之后的判断

--顺子 只要判断相邻的数字数值是否差1就可以
function isConnect(cards)
  if not CardUtils.isCards(cards) or 5 > #cards then 
      return false
  end
  table.sort(cards)
  --2和大小王不能加入顺子
  if cards[#cards] > 14 then
    return false
  end
  for i = 1, (#cards - 1) do
    if cards[i] ~= cards[i+1] -1 then
      return false
    end
  end
  return true
end

-- 连对 33445566 1和2 3和4 5和6 7和8 相等 ,2和3 4和5 6和7 相差1 
function isCompany(cards)
  if not CardUtils.isCards(cards) or 6 > #cards or (#cards % 2) ==1 then 
      return false
  end
  table.sort(cards)
  local len = #cards
  for i = 1, (len - 1) do
    if (i % 2) ==1 then
      if cards[i] ~= cards[i + 1]  then
        return false
      end 
    else
      if cards[i] ~= cards[i + 1] - 1 then
        return false
      end
    end
  end
  return true
end

-- 飞机不带  
-- 遍历到三个一组中的第一个的时候判断这组的值是否都相等
-- 遍历到三个一组中的最后一个的时候判断和下一组的数值是不是差一
function isAircraft(cards)
  if not CardUtils.isCards(cards) or 6 > #cards or (#cards % 3) ~=0 then 
      return false
  end 
  table.sort(cards)
  local len = #cards
  for i = 1, (len - 1) do
    if (i % 3) ==1 then
      if cards[i] ~= cards[i + 1] or cards[i + 1] ~= cards[i + 2] then
        return false
      end 
    elseif (i % 3) == 0 then
      if cards[i] ~= cards[i + 1] - 1 then
        return false
      end
    end
  end
  return true 
end



-- 4带2
function isBombTwo(cards)
  if not CardUtils.isCards(cards) or 8 < #cards or #cards < 6 or (#cards % 2) ~=0 then 
      return false
  end 

  table.sort(cards)
  local tmpTable1 = {} --存放炸弹牌
  local tmpTable2 = {}  --存放炸弹带的牌
  local tmppos = 0
   -- 先从牌中抽出炸弹不带的牌
  for pos = 1, (#cards - 3)  do
    if cards[pos] == cards[pos + 1] and cards[pos] == cards[pos + 2] and cards[pos + 2]  == cards[pos + 3] then
      table.insert(tmpTable1, cards[pos])
      table.insert(tmpTable1, cards[pos + 1])
      table.insert(tmpTable1, cards[pos + 2])
      table.insert(tmpTable1, cards[pos + 3])
      tmppos = pos
    end
  end
   -- 再得到带的牌
  for k,v in pairs(cards) do
    if v ~= cards[tmppos] then
      table.insert(tmpTable2, v)
    end
  end
  if CardUtils.isBomb(tmpTable1) then
    if 2 == #tmpTable2 then
      return true
    elseif 4 == #tmpTable2 then
      table.sort(tmpTable2)
      if tmpTable2[1] == tmpTable2[2] and tmpTable2[3] == tmpTable2[4] then
        return true
      end
    end
  end

  return false
end

-- 飞机带翅膀
function isAircraftWing(cards)
  if not CardUtils.isCards(cards) or 8 > #cards  then 
      return false
  end 
  if (#cards % 4) ~=0 and (#cards % 5) ~= 0 then
    return false
  end
  -- 先判断有没有炸弹插成三带一的情况如果有那么将其中一个替换为扑克中没有的数(如 19)
  table.sort(cards)
  local tmp = 0 --记录有几个炸弹 防止有多个炸插成三带一
  for k = 1, (#cards - 4) do
    if cards[k] == cards[k + 1] and cards[k + 1] == cards[k + 2] and cards[k + 2] == cards[k + 3] then
      cards[k + 3] = 19 + tmp
      tmp = tmp + 1
    end
  end

  local aircraftCount = math.floor(#cards / 4)
  table.sort(cards)
  local tmpTable1 = {} --存放飞机的牌
  local tmpTable2 = {}  --存放飞机带的牌
  -- 先从牌中抽出飞机不带
  for pos = 1, #cards - 2 do
    if cards[pos] == cards[pos + 1] and cards[pos] == cards[pos + 2] then
      table.insert(tmpTable1, cards[pos])
      table.insert(tmpTable1, cards[pos + 1])
      table.insert(tmpTable1, cards[pos + 2])
      tmppos = pos
    end
  end 
   -- 再得到带的牌
  for k1, v1 in pairs(cards) do
    local count = 0
    for i = 1, aircraftCount do
      if v1 == tmpTable1[i * 3] then
        count = count + 1
      end
    end
    if  count == 0 then
        table.insert(tmpTable2, v1)
    end 
  end

  if not CardUtils.isAircraft(tmpTable1) then
    return false
  end
  if #tmpTable2 == aircraftCount * 2 then
    for i = 1, #tmpTable2, 2 do
      if tmpTable2[i] ~= tmpTable2[i + 1] then
        return false
      end
    end
  end

  return true
end


function getType(postcards)
  --如果传递进来的cards没有去掉花色的话就先去掉花色( %100 )再判断
  local cards = CardUtils.copyTab(postcards)
  for i = 1, #cards do
    cards[i] = CardUtils.getValue(cards[i])
  end
  local len = #cards
  if len <= 5 and len > 0 then
    if CardUtils.isSingle(cards) then 
      return SINGLE_CARD
    elseif CardUtils.isDouble(cards) then
      return DOUBLE_CARD 
    elseif CardUtils.isBomb(cards) then
      return BOMB_CARD 
    elseif CardUtils.isKingBomb(cards) then
      return KINGBOMB_CARD 
    elseif CardUtils.isThree(cards) then
      return THREE_CARD 
    elseif CardUtils.isThreeOne(cards) then
      return THREE_ONE_CARD 
    elseif CardUtils.isConnect(cards) then
      return CONNECT_CARD 
    elseif CardUtils.isThreeTwo(cards) then
      return THREE_TWO_CARD 
    end
  elseif len < 20 and len > 5 then 
    if CardUtils.isConnect(cards) then
      return CONNECT_CARD 
    elseif CardUtils.isAircraft(cards) then
      return AIRCRAFT_CARD 
    elseif CardUtils.isCompany(cards) then
      return COMPANY_CARD 
    elseif CardUtils.isBombTwo(cards) then
      return BOMB_TWO_CARD 
    elseif CardUtils.isAircraftWing(cards) then
      return AIRCRAFT_WING
    end
  end
  return ERROR_CARDS
end



  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Unity地主算法是指在Unity游戏引擎中实现的地主游戏的核心算法地主是一种扑克牌游戏,其规则包括发牌、叫分、出牌、抢地主等环节。在Unity地主游戏中,算法主要负责随机发牌、牌型判断、分数计算、叫分和抢地主等操作。 在Unity地主游戏中,随机发牌的算法采用了洗牌、发牌和排序三个步骤。因为地主需要将54张牌均分成三份,所以洗牌的随机性和准确性非常重要。在发牌和排序阶段,算法需要保证每个玩家得到17张牌,且牌的大小和花色是随机的,同时牌的组合方式也要考虑游戏的规则。 牌型判断的算法是指判断出每个玩家所出的牌型,以便计算分数和判断胜负。这个算法需要对牌型进行分类,如单牌、对子、三张等,同时还需要考虑牌型的组合和大小,例如顺子、连对、飞机等。算法需要准确判断出每个玩家所出的牌型并进行比对,依此来判断胜负。 分数计算需要根据游戏规则进行计算,包括分数的基本计算、炸弹的额外分值和特殊情况下的倍数加成等。算法需要按照游戏规则进行计算,计算每个玩家所得分数。 叫分和抢地主算法是玩家对游戏的一次选择,需要根据当前发牌的情况和已知牌型进行判断。算法需要对每个玩家的叫分和抢地主进行判断和比对,以此判断最终的地主和游戏规则。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值