斗地主算法(4)

来源:互联网 发布:电影推荐算法数据集 编辑:程序博客网 时间:2024/04/26 02:56

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

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

直接贴代码

--将牌按 牌值分类 单牌 对子 三个 四个 分类--return oneCards, twoCards, threeCards, fourCardsfunction 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, kingBombend-- 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 takeCardsend--得到带的对子 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 takeCardsendfunction addBomb(playCards,fourCards,kingBomb)  for i = 1, #fourCards do    playCards[#playCards + 1] = fourCards[i]  end  if #kingBomb == 2 then    playCards[#playCards + 1] = kingBomb  endend--单牌提示算法  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 playCardsend-- 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 playCardsend-- 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 playCardsend--炸弹提示算法 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 playCardsend-- 先从手上的牌里面得到各种牌值的一个牌(如{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 playCardsend-- 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 playCardsend-- 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 playCardsend-- 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和305function 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 playCardsend-- 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和305function 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 playCardsend-- 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 playCardsend-- 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 playCardsend-- 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 0