斗地主算法(4)

前面写完了牌型的判断和比牌算法 接下来就是出牌的提示算法

算法可能写的不是很好只是单纯的实现了功能, 代码中有测试代码可以用

直接贴代码

--将牌按 牌值分类 单牌 对子 三个 四个 分类
--return oneCards, twoCards, threeCards, fourCards
function getAllType(cards)
  local tmpcards = copyTab(cards)
  local kingBomb, fourCards, oneCards, twoCards, threeCards = {}, {}, {}, {}, {}
  if #cards >=2 then
    if cards[1] == 117 and cards[2] == 116 then
      kingBomb = {116, 117}
    end
    tmpcards = subTable(cards, kingBomb)
  end
  for i = 1, #tmpcards - 4 do
    if getValue(tmpcards[i]) == getValue(tmpcards[i + 1]) and getValue(tmpcards[i]) == getValue(tmpcards[i + 2]) 
      and getValue(tmpcards[i]) == getValue(tmpcards[i + 3]) then
      fourCards[#fourCards + 1] = {tmpcards[i], tmpcards[i + 1], tmpcards[i + 2], tmpcards[i + 3]}
    end
  end
  for k,v in pairs(fourCards) do
    tmpcards = subTable(tmpcards, v)
  end
  for i = 1, #tmpcards - 2 do
    if getValue(tmpcards[i]) == getValue(tmpcards[i + 1]) and getValue(tmpcards[i]) == getValue(tmpcards[i + 2])then
      threeCards[#threeCards + 1] = {tmpcards[i], tmpcards[i + 1], tmpcards[i + 2]}
    end
  end
  for k,v in pairs(threeCards) do
    tmpcards = subTable(tmpcards, v)
  end
  for i = 1, #tmpcards - 1 do
    if getValue(tmpcards[i]) == getValue(tmpcards[i + 1]) then
      twoCards[#twoCards + 1] = {tmpcards[i], tmpcards[i + 1]}
    end
  end
  for k,v in pairs(twoCards) do
    tmpcards = subTable(tmpcards, v)
  end
  for i = 1, #tmpcards do
    oneCards[#oneCards + 1] = {tmpcards[i]}
  end
  -- for k,v in pairs(threeCards) do
  --   for k,v in pairs(v) do
  --     print(k,v)
  --   end
  -- end
  oneCards = ascendingTable(oneCards)
  twoCards = ascendingTable(twoCards)
  threeCards = ascendingTable(threeCards)
  fourCards = ascendingTable(fourCards)
  return oneCards, twoCards, threeCards, fourCards, kingBomb
end

-- local cards = {114,105, 205, 305, 106, 206, 107, 407, 207, 307, 406, 209,109,110,112}
-- local cards = {114,214,313,314}
-- sortPoker(cards)
-- getAllType(cards)

--得到带的单牌 cards手上有的牌 playcards 将要出的牌
function getTakeSingle(cards,playCards, count)
  sortPoker(cards)
  local takeCards = {}
  local oneCards, twoCards, threeCards, fourCards = getAllType(cards)
  --这里是因为不想修改原来的代码所以又倒过来一次
  oneCards = ascendingTable(oneCards)
  twoCards = ascendingTable(twoCards)
  threeCards = ascendingTable(threeCards)
  fourCards = ascendingTable(fourCards)
  if #oneCards >= count then
    for i = count , 1, -1 do
      takeCards[#takeCards + 1] = oneCards[#oneCards - i + 1]
    end
  elseif #oneCards < count and (#oneCards + #twoCards) >= count then
    for i = #oneCards, 1, -1 do
      takeCards[#takeCards + 1] = oneCards[i][1]
    end
    for i = count + #twoCards -#oneCards, 1, -1 do
      takeCards[#takeCards + 1] = twoCards[i]
      takeCards[#takeCards + 1] = twoCards[i + 1]
    end
  elseif (#oneCards + #twoCards) < count and (#oneCards + #twoCards + #threeCards) >= count then
    for i = #oneCards, 1, -1 do
      takeCards[i] = oneCards[i][1]
    end
    for i = #twoCards + #oneCards, 1, -1 do
      takeCards[#takeCards + 1] = twoCards[i]
      takeCards[#takeCards + 1] = twoCards[i + 1]
    end
    for i = count + #threeCards - #twoCards - #oneCards , 1, -1 do
      takeCards[#takeCards + 1] = threeCards[i]
      takeCards[#takeCards + 1] = threeCards[i + 1]
      takeCards[#takeCards + 1] = threeCards[i + 2]
    end
  else 
    return nil
  end
  -- for k,v in pairs(takeCards) do
  --   print(k,v)
  -- end
  local tmpTakeCards = {}
  for i = count, 1, -1 do
    tmpTakeCards[#tmpTakeCards + 1] = takeCards[i]
  end
  takeCards = tmpTakeCards
  return takeCards
end

--得到带的对子 cards手上有的牌 playcards 将要出的牌
function getTakeDoubel(cards, playCards, count)
  sortPoker(cards)
  local takeCards = {}
  local oneCards, twoCards, threeCards, fourCards = getAllType(cards)
  oneCards = ascendingTable(oneCards)
  twoCards = ascendingTable(twoCards)
  threeCards = ascendingTable(threeCards)
  fourCards = ascendingTable(fourCards)
  if not twoCards then
    return 
  end
  if  #twoCards >= count then
    for i = #twoCards, 1, -1 do
      takeCards[#takeCards + 1] = {twoCards[i][1], twoCards[i][2]}
    end
  elseif #twoCards < count and (#twoCards + #threeCards) >= count then
    for i = #twoCards, 1, -1 do
      takeCards[#takeCards + 1] = {twoCards[i], twoCards[i + 1]}
    end
    for i = #threeCards, 1, -1 do
      takeCards[#takeCards + 1] = {threeCards[i], threeCards[i + 1]}
    end
  else 
    return nil
  end
  local tmpTakeCards = {}
  for i = count, 1, -1 do
    tmpTakeCards[#tmpTakeCards + 1] = takeCards[i]
  end
  takeCards = tmpTakeCards
  return takeCards
end

function addBomb(playCards,fourCards,kingBomb)
  for i = 1, #fourCards do
    playCards[#playCards + 1] = fourCards[i]
  end
  if #kingBomb == 2 then
    playCards[#playCards + 1] = kingBomb
  end
end

--单牌提示算法  cards 手上有的牌 outcards 已经打出的牌 playcards 要出的牌
function singleTip(cards, outCards)
  local oneCards, twoCards, threeCards, fourCards, kingBomb = getAllType(cards)
  local playCards = {}
  for k,v in pairs(oneCards) do
    if getValue(v[1]) > getValue(outCards[1]) then
      playCards[#playCards + 1] = v
    end
  end
  for k,v in pairs(twoCards) do
    if getValue(v[1]) > getValue(outCards[1]) then
      playCards[#playCards + 1] = {v[1]}
    end
  end
  for k,v in pairs(threeCards) do
    if getValue(v[1]) > getValue(outCards[1]) then
      playCards[#playCards + 1] = {v[1]}
    end
  end
  addBomb(playCards, fourCards, kingBomb)
  -- for k,v in pairs(playCards) do
  --   for k,v in pairs(v) do
  --     print(k,v)
  --   end
  -- end
  return playCards
end

-- local cards = {103,105, 205, 305, 106, 206, 306, 107, 407, 307, 207, 108,109,110,112}
-- local outCards = {105}
-- sortPoker(cards)
-- sortPoker(outCards)
-- singleTip(cards, outCards)

--对子提示算法 cards 手上有的牌 outcards 已经打出的牌 playcards 要出的牌
function doubleTip(cards, outCards)
  local oneCards, twoCards, threeCards, fourCards, kingBomb = getAllType(cards)
  local playCards = {}
  for k,v in pairs(twoCards) do
    if getValue(v[1]) > getValue(outCards[1]) then
      playCards[#playCards + 1] = v
    end
  end
  for k,v in pairs(threeCards) do
    if getValue(v[1]) > getValue(outCards[1]) then
      playCards[#playCards + 1] = {v[1],v[2]}
    end
  end
  addBomb(playCards, fourCards, kingBomb)
  -- for k,v in pairs(playCards) do
  --   for k,v in pairs(v) do
  --     print(k,v)
  --   end
  -- end
  return playCards
end

-- local cards = {103,105, 205, 305, 106, 306, 107, 407, 307, 207, 108,108,108,112}
-- local outCards = {105,205}
-- sortPoker(cards)
-- sortPoker(outCards)
-- doubleTip(cards, outCards)

--三不带提示算法 
function threeTip(cards, outCards)
  local oneCards, twoCards, threeCards, fourCards, kingBomb = getAllType(cards)
  local playCards = {}
  for k,v in pairs(threeCards) do
    if getValue(v[1]) > getValue(outCards[1]) then
      playCards[#playCards + 1] = v
    end
  end
  addBomb(playCards, fourCards, kingBomb)
  return playCards
end

--炸弹提示算法 
function bombTip(cards, outCards)
  local oneCards, twoCards, threeCards, fourCards, kingBomb = getAllType(cards)
  local playCards = {}
  for k,v in pairs(fourCards) do
    if getValue(v[1]) > getValue(outCards[1]) then
      playCards[#playCards + 1] = v
    end
  end
  addBomb(playCards, fourCards, kingBomb)
  return playCards
end


-- 先从手上的牌里面得到各种牌值的一个牌(如{103,105, 205, 305, 106, 206, 306}{103,205,206,})
-- 再从得到的牌组合出和outcards牌数一样的牌,再判断 组合出的牌是否是顺子
function connectTip(cards, outCards)
  local oneCards, twoCards, threeCards, fourCards, kingBomb = getAllType(cards)
  local j = 1
  local playCards = {}
  local len = #outCards
  local tmpcards = {}
  for i = 1, #cards do
    if i == 1 then
      tmpcards[j] = cards[i] 
      j = j + 1
    elseif getValue(outCards[len]) < getValue(cards[i]) and getValue(cards[i]) ~= getValue(cards[i - 1]) then 
      tmpcards[j] = cards[i] 
      j = j + 1
    end
  end
  for i = 1, #tmpcards do
    local tmp = {}
    for k = 1, len do
      if (i + len - 1) <= #tmpcards then
        tmp[k] = tmpcards[i + k - 1]
      end
    end
    -- tmp = getCardsTabValue(tmp)
    if isConnect(getCardsTabValue(tmp)) then
      playCards[#playCards + 1] = copyTab(tmp)
    end 
  end
  playCards = ascendingTable(playCards)
  addBomb(playCards, fourCards, kingBomb)
  -- for k,v in pairs(playCards) do
  --   for k,v in pairs(v) do
  --     print(k,v)
  --   end
  -- end
  return playCards
end

-- local cards = {103,105, 205, 305, 106, 206, 306, 107, 407, 307, 207, 406, 108,110,111,112,113,114,214}
-- local outCards = {103, 104, 105, 106, 207}
-- sortPoker(cards)
-- sortPoker(outCards)
-- connectTip(cards, outCards)

--对子提示算法和顺子提示算法类似
function companyTip(cards, outCards)
  local oneCards, twoCards, threeCards, fourCards, kingBomb = getAllType(cards)
  local j = 1
  local playCards = {}
  local len = #outCards / 2
  local tmpcards = {}
  for i = 1, #cards - 1 do
    if i == 1 then
      if getValue(cards[i]) == getValue(cards[i + 1]) and getValue(outCards[1]) < getValue(cards[i]) then
        tmpcards[j] = {cards[i], cards[i + 1]} 
        j = j + 1
      end
    elseif getValue(outCards[#outCards]) < getValue(cards[i]) and getValue(cards[i]) ~= getValue(cards[i - 1])  
      and getValue(cards[i]) == getValue(cards[i + 1])   then 
      tmpcards[j] = {cards[i], cards[i + 1]} 
      j = j + 1
    end
  end
  for i = 1, #tmpcards do
    local tmp = {}
    for k = 1, len do
      if (i + len - 1) <= #tmpcards  then
        tmp[#tmp + 1] = tmpcards[i + k - 1][1]
        tmp[#tmp + 1] = tmpcards[i + k - 1][2]
      end
    end
    if isCompany(getCardsTabValue(tmp)) then
      playCards[#playCards + 1] = tmp
    end 
  end
  addBomb(playCards, fourCards, kingBomb)
  return playCards
end

-- local cards = {103,105, 205, 305, 106, 206, 306, 107, 407, 307, 207, 406, 108,109,209,112,212,111,211,113,213}
-- local outCards = {103, 203, 204, 104, 205,305}
-- sortPoker(cards)
-- sortPoker(outCards)
-- companyTip(cards, outCards)


--飞机不带提示算法 
function aircraftTip(cards, outCards)
  local oneCards, twoCards, threeCards, fourCards, kingBomb = getAllType(cards)
  local j = 1
  local playCards = {}
  local len = #outCards / 3
  local tmpcards = {}
  for i = 1, #cards - 2 do
    if i == 1 then
      if getValue(cards[i]) == getValue(cards[i + 1]) and getValue(cards[i]) == getValue(cards[i + 2]) then
        tmpcards[j] = {cards[i], cards[i + 1], cards[i + 2]} 
        j = j + 1
      end
    elseif getValue(outCards[#outCards]) < getValue(cards[i]) and getValue(cards[i]) ~= getValue(cards[i - 1])  
      and getValue(cards[i]) == getValue(cards[i + 1]) and getValue(cards[i]) == getValue(cards[i + 2]) then 
      tmpcards[j] = {cards[i], cards[i + 1], cards[i + 2]} 
      j = j + 1
    end
  end
  for i = 1, #tmpcards do
    local tmp = {}
    for k = 1, len do
      if (i + len - 1) <= #tmpcards  then
        tmp[#tmp + 1] = tmpcards[i + k - 1][1]
        tmp[#tmp + 1] = tmpcards[i + k - 1][2]
        tmp[#tmp + 1] = tmpcards[i + k - 1][3]
      end
    end
    if isAircraft(getCardsTabValue(tmp)) then
      playCards[#playCards + 1] = tmp
    end 
  end
  addBomb(playCards, fourCards, kingBomb)
  return playCards
end

-- local cards = {105, 205, 306, 106, 207, 107, 407, 209, 406, 308,108,208,111,112,113,213,313,413,116,117}
-- local outCards = {105,105,305,206,206,306}
-- sortPoker(cards)
-- sortPoker(outCards)
-- aircraftTip(cards, outCards)


-- 三带单牌和对子提示算法 
-- getValue(cards[i]) ~= getValue(cards[i - 1]) 使 cards[i]是每一种牌值的第一个 103,203,204,305,105  第一个103和305
function threeTakeTip(cards, outCards)
  local outCardsValue = 0
  for i = 1, 3 do
    if getValue(outCards[i]) == getValue(outCards[i + 1])then
      outCardsValue = getValue(outCards[i])
    end
  end
  local oneCards, twoCards, threeCards, fourCards, kingBomb = getAllType(cards)
  local playCards = {}
  for k,v in pairs(threeCards) do
    if getValue(threeCards[k][1]) > outCardsValue then
      playCards[#playCards + 1] = threeCards[k]
    end
  end
  local takeCards = {}
  for i = 1, #playCards do
    if #outCards ==4 then
      takeCards = getTakeSingle(cards, playCards[i], 1)
      playCards[i][4] = takeCards[1][1]
    else 
      takeCards = getTakeDoubel(cards, playCards[i], 1)
      playCards[i][4] = takeCards[1][1]
      playCards[i][5] = takeCards[1][2]
    end
  end
  addBomb(playCards, fourCards, kingBomb)
  -- for k,v in pairs(playCards) do
  --   for k,v in pairs(v) do
  --     print(k,v)
  --   end
  -- end
  return playCards
end

-- local cards = {105, 205, 305, 106, 206, 107, 407, 207, 406, 209,109,110,112}
-- local outCards = {304, 204, 104, 206}
-- sortPoker(cards)
-- sortPoker(outCards)
-- threeTakeTip(cards, outCards)

-- 四带单牌和对子提示算法 
-- getValue(cards[i]) ~= getValue(cards[i - 1]) 使 cards[i]是每一种牌值的第一个 103,203,204,305,105  第一个103和305
function fourTakeTip(cards, outCards)
  local outCardsValue = 0
  for i = 1, #outCards - 2 do
    if getValue(outCards[i]) == getValue(outCards[i + 1]) 
      and getValue(outCards[i]) == getValue(outCards[i + 2]) then
      outCardsValue = getValue(outCards[i])
    end
  end
  local oneCards, twoCards, threeCards, fourCards, kingBomb = getAllType(cards)
  local playCards = {}
  for k,v in pairs(fourCards) do
    if getValue(fourCards[k][1]) > outCardsValue then
      playCards[#playCards + 1] = copyTab(fourCards[k])
    end
  end
  local takeCard = {}
  for i = 1, #playCards do
    if #outCards ==6 then
      takeCard = getTakeSingle(cards, playCards[i], 2)
      if not takeCard then
        return 
      end
      playCards[i][5] = takeCard[1][1]
      playCards[i][6] = takeCard[2][1]
    else 
      takeCard = getTakeDoubel(cards, playCards[i], 2)
      if not takeCard then
        return 
      end
      playCards[i][5] = takeCard[1][1]
      playCards[i][6] = takeCard[1][2]
      playCards[i][7] = takeCard[2][1]
      playCards[i][8] = takeCard[2][2]
    end
  end
  addBomb(playCards, fourCards, kingBomb)
  return playCards
end

-- local cards = {105, 205, 305, 106, 207, 107, 407, 207, 406, 210,108,110,112,113}
-- local outCards = {304, 204, 104, 404, 206,206,206,206}
-- sortPoker(cards)
-- sortPoker(outCards)
-- fourTakeTip(cards, outCards)



--飞机带牌提示算法 
function aircraftTakeTip(cards, outCards)
  local j = 1
  local playCards = {}
  local len = 0
  local isTakeSingel = true
  if #outCards % 4 == 0 then
    len = #outCards / 4
    isTakeSingel = true
  elseif #outCards % 5 == 0 then
    len = #outCards / 5 
    isTakeSingel = false
  end
  local outCardsValue = 0
  for i = 1, #outCards - 2 do
    if getValue(outCards[i]) == getValue(outCards[i + 1]) 
      and getValue(outCards[i]) == getValue(outCards[i + 2]) then
      outCardsValue = getValue(outCards[i])
    end
  end
  local oneCards, twoCards, threeCards, fourCards, kingBomb = getAllType(cards)

  for i = #threeCards, 1, -1 do
    local tmp = {}
    for k = 1, len do
      if (i + len - 1) <= #threeCards  then
        tmp[#tmp + 1] = threeCards[i + k - 1][1]
        tmp[#tmp + 1] = threeCards[i + k - 1][2]
        tmp[#tmp + 1] = threeCards[i + k - 1][3]
      end
    end
    if isAircraft(getCardsTabValue(tmp)) and outCardsValue < getValue(tmp[1]) then
      playCards[#playCards + 1] = tmp
    end 
  end

  local takeCard = {}
  if isTakeSingel then
    takeCards = getTakeSingle(cards, playCards, len)
    if not takeCard then
      return 
    end
    for j = 1, #playCards do
      for i = 1, len do
        playCards[j][6 + i] = takeCards[i][1]
      end
    end
  else 
    takeCards = getTakeDoubel(cards, playCards, len)
    if not takeCard then
      return 
    end
    for j = 1, #playCards do
      for i = 1, len do
        playCards[j][6 + i] = takeCards[i][1]
        playCards[j][8 + i] = takeCards[i][2]
      end
    end
  end
  addBomb(playCards, fourCards, kingBomb)
  -- for k,v in pairs(playCards) do
  --   for k,v in pairs(v) do
  --     print(k,v)
  --   end
  -- end
  return playCards
end


-- local cards = {105, 205, 306, 106, 207, 107, 407, 209, 406, 210,108,110,112,113,213,313,413,116,117}
-- local cards = {103,203,303,204,304,404,306,406,408,308,209,110}
-- local outCards = {304, 204, 104, 407, 208,205,205,205,307,308}
-- sortPoker(cards)
-- sortPoker(outCards)
-- aircraftTakeTip(cards, outCards)

--提示算法 根据上家出的牌得到自己手上能够出的牌
function getTips(cards, outCards)
  local tmpOutCards = outCards
  local playCards = {}
  if #tmpOutCards == 0 then
    playCards =tips(cards)
    return playCards
  end
  local cardsType = getType(getCardsTabValue(outCards))
  if cardsType == SINGLE_CARD  then
    playCards = singleTip(cards, tmpOutCards)
  elseif cardsType == DOUBLE_CARD then
    playCards = doubleTip(cards, tmpOutCards)
  elseif cardsType == THREE_CARD then
    playCards = threeTip(cards, tmpOutCards)
  elseif cardsType == THREE_TWO_CARD or cardsType == THREE_ONE_CARD then
    playCards = threeTakeTip(cards, tmpOutCards)
  elseif cardsType == BOMB_FOUR_CARD or cardsType == BOMB_TWO_CARD then
   playCards =  fourTakeTip(cards, tmpOutCards)
  elseif cardsType == CONNECT_CARD then
    playCards = connectTip(cards, tmpOutCards)
  elseif cardsType == COMPANY_CARD then
    playCards = companyTip(cards, tmpOutCards)
  elseif cardsType == AIRCRAFT_CARD then
    playCards = aircraftTip(cards, tmpOutCards)
  elseif cardsType == AIRCRAFT_WING then
    playCards = aircraftTakeTip(cards, tmpOutCards)
  elseif cardsType == BOMB_CARD then
    playCards = bombTip(cards, tmpOutCards)
  else 
    return {}
  end
  return playCards
end


-- local cards = {105, 205, 306, 106, 207, 107, 407, 209, 406, 210,108,208,111,112,113,213,313,413,116,117}
-- -- local outCards = {304, 204,104,404,105,106, 206,205}
-- local outCards = {105,106,305,205,206,306,107,108,207,208}
-- sortPoker(cards)
-- sortPoker(outCards)
-- getTips(cards, outCards)


到此斗地主中的所有牌型相关的算法都写完啦 写的不好请大家见谅 微笑

整个CardUtils类的代码下载地址



  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值