local Theme253Const = {}
Theme253Const.PROP_COUNT = {10, 2, 2}
Theme253Const.BINGO_TARGET = 4
local CollectHistoryRound = 15
local MaxClickCount = 25
local LoopAllCount = 10000
local DEBUG_BOARD_COUNT = 10
local DEBUG = false
local DRAW_BOARD = true
local CollectCount = 0
local MAX_ROW = 5
local MAX_COL = 5
local BingoRateMap = {}
local RunHistory = {}
local PropMap = {}
local PropInfo = {}
local colFlags = {}
local Score = 0
Theme253Const.PROP_ENUM = {
NONE = 0,
FIRECRACKER = 1,
FIRECRACKER_2 = 2,
FIREWORK = 3,
}
Theme253Const.MAX_ROW = MAX_ROW
Theme253Const.MAX_COL = MAX_COL
local BreakFlag = false
local function clone(object)
local lookup_table = {}
local function _copy(object)
if type(object) ~= "table" then
return object
elseif lookup_table[object] then
return lookup_table[object]
end
local newObject = {}
lookup_table[object] = newObject
for key, value in pairs(object) do
newObject[_copy(key)] = _copy(value)
end
return setmetatable(newObject, getmetatable(object))
end
return _copy(object)
end
table.keys = function (tab)
local list = {}
for k in pairs(tab) do
table.insert(list, k)
end
return list
end
table.indexof = function (tab, tmp)
for i, v in pairs(tab) do
if v == tmp then
return i
end
end
return false
end
local printDebug = function (...)
if DEBUG then
print(...)
end
end
local Theme253Helper = {}
function Theme253Helper.posToKey(r, c)
if type(r) == "table" then
return string.format("%d_%d", r[1], r[2])
else
return string.format("%d_%d", r, c)
end
end
function Theme253Helper.keyToPos(posKey)
local r = tonumber(string.sub(posKey, 1, 1))
local c = tonumber(string.sub(posKey, 3, 3))
return r, c
end
function Theme253Helper.getLeftPos(map)
local list = {}
for r = 1, Theme253Const.MAX_ROW do
for c = 1, Theme253Const.MAX_COL do
if map[r][c] == 0 then
table.insert(list, {r, c})
end
end
end
return list
end
function Theme253Helper.getUnclickedPos(map)
local list = {}
for r = 1, Theme253Const.MAX_ROW do
for c = 1, Theme253Const.MAX_COL do
if map[r][c] ~= -1 then
table.insert(list, {r, c})
end
end
end
return list
end
function Theme253Helper.randomTable(tab, remove)
local index = math.random(1, #tab)
if remove then
return table.remove(tab, index), index
else
return tab[index], index
end
end
Theme253Helper.main = function()
RunHistory = {}
Theme253Helper.genCellsPos()
local flagBoard = Theme253Helper.genEmptyBoard()
for i = 1, MaxClickCount do
local r, c = Theme253Helper.clickCardCell(flagBoard)
flagBoard[r][c] = -1
table.insert(RunHistory, "")
table.insert(RunHistory, string.format("---- click ---- %s, %s", r, c))
Theme253Helper.removeGrid(r, c)
if Theme253Helper.checkBingo(PropMap) then
if i < CollectHistoryRound then
CollectCount = CollectCount + Score
end
BingoRateMap[i] = (BingoRateMap[i] or 0) + 1
break
end
if i == CollectHistoryRound then
CollectCount = CollectCount + Score
end
if i >= MaxClickCount then
print(string.format("------ %d个格子点完都没bingo !!!!!!", MaxClickCount))
printHistory(true)
return
end
end
printHistory()
printDebug("================================================= finish ====")
printDebug("")
end
Theme253Helper.checkBingo = function(board)
local cnt = 0
for col = 1, Theme253Const.MAX_COL do
local flag = true
for row = 1, Theme253Const.MAX_ROW do
if board[row][col] ~= -1 then
flag = false
break
end
end
if flag then
cnt = cnt + 1
end
end
if cnt >= Theme253Const.BINGO_TARGET then
return true
end
return false
end
Theme253Helper.genCellsPos = function()
PropMap = Theme253Helper.genEmptyBoard()
Score = 0
colFlags = {}
local firecrackerCnt = Theme253Const.PROP_COUNT[Theme253Const.PROP_ENUM.FIRECRACKER]
local colList = {1, 2, 3, 4, 5}
for i = 1, math.min(5, firecrackerCnt) do
local random = math.random(1, #colList)
local col = table.remove(colList, random)
local row = math.random(1, Theme253Const.MAX_ROW)
PropMap[row][col] = Theme253Const.PROP_ENUM.FIRECRACKER
end
if firecrackerCnt > 5 then
firecrackerCnt = firecrackerCnt - 5
else
firecrackerCnt = 0
end
local cntList = clone(Theme253Const.PROP_COUNT)
cntList[1] = firecrackerCnt
local posList = Theme253Helper.getLeftPos(PropMap)
for pType, cnt in ipairs(cntList) do
for i = 1, cnt do
local pos = Theme253Helper.randomTable(posList, true)
local posKey = Theme253Helper.posToKey(pos)
PropMap[pos[1]][pos[2]] = pType
end
end
table.insert(RunHistory, "----------- 道具初始化位置 ")
table.insert(RunHistory, {
type = 1,
board = clone(PropMap),
})
end
Theme253Helper.history_1 = function (data)
printTable(data.board)
end
Theme253Helper.removeGrid = function (r, c)
if PropMap[r][c] == -1 then
return false
end
local propType = PropMap[r][c]
PropMap[r][c] = -1
table.insert(RunHistory, "-----------------------------------")
if propType ~= 0 then
table.insert(RunHistory, "------ 触发了道具:"..propType)
end
if not colFlags[c] then
local flag = true
for i = 1, Theme253Const.MAX_ROW do
if PropMap[i][c] ~= -1 then
flag = false
break
end
end
if flag then
colFlags[c] = true
if propType ~= Theme253Const.PROP_ENUM.FIRECRACKER then
local backup = propType
propType = Theme253Const.PROP_ENUM.FIRECRACKER
local leftPosList = Theme253Helper.getLeftPos(PropMap)
if #leftPosList > 0 then
local pos = Theme253Helper.randomTable(leftPosList, true)
PropMap[pos[1]][pos[2]] = backup
end
end
end
end
if propType == Theme253Const.PROP_ENUM.FIRECRACKER then
local row = -1
for i = Theme253Const.MAX_ROW, 1, -1 do
if PropMap[i][c] ~= -1 then
row = i
break
end
end
if row ~= -1 then
Theme253Helper.removeGrid(row, c)
Score = Score + 1
end
elseif propType == Theme253Const.PROP_ENUM.FIRECRACKER_2 then
local colList = {}
for i = 1, Theme253Const.MAX_COL do
local left = c - i
local right = c + i
if left > 0 and PropMap[r][left] ~= -1 then
table.insert(colList, left)
end
if right <= Theme253Const.MAX_COL and PropMap[r][right] ~= -1 then
table.insert(colList, right)
end
end
for _, _c in ipairs(colList) do
Theme253Helper.removeGrid(r, _c)
end
elseif propType == Theme253Const.PROP_ENUM.FIREWORK then
local leftPosList = Theme253Helper.getUnclickedPos(PropMap)
for i = 1, 2 do
if #leftPosList > 0 then
local pos = Theme253Helper.randomTable(leftPosList, true)
if pos then
table.insert(RunHistory, "------ 礼炮:"..pos[1].." "..pos[2])
Theme253Helper.removeGrid(pos[1], pos[2])
end
end
end
end
table.insert(RunHistory, {
type = 1,
board = clone(PropMap)
})
end
function Theme253Helper.propExchangePos()
end
Theme253Helper.genEmptyBoard = function ()
local board = {}
for row = 1, MAX_ROW do
board[row] = {}
for col = 1, MAX_COL do
board[row][col] = Theme253Const.PROP_ENUM.NONE
end
end
return board
end
Theme253Helper.clickCardCell = function(flagBoard)
local emptyList = Theme253Helper.getLeftPos(flagBoard)
local pos = Theme253Helper.randomTable(emptyList)
return pos[1], pos[2]
end
function printTable(tab)
local row = #tab
local col = #tab[1]
local str = ""
for i = 1, row do
local d = tab[i]
for j = 1, col do
str = str.."\t"..tab[i][j]
end
str = str.."\n"
end
print(str)
end
function printHistory(focus)
if not DEBUG and not focus then
return
end
for i, info in ipairs(RunHistory) do
if type(info) == "string" then
print(info)
else
local funcName = "history_"..info.type
if Theme253Helper[funcName] then
Theme253Helper[funcName](info)
end
end
end
end
print("调试开关:", DEBUG)
print("格子打印开关:", DRAW_BOARD)
print("----------------------------")
if DEBUG then
for i = 1, DEBUG_BOARD_COUNT do
Theme253Helper.main()
end
else
print("总测试次数:", LoopAllCount)
print("----------------------------")
for i = 1, LoopAllCount do
Theme253Helper.main()
if BreakFlag then
print("!!!!!!!!!!!!! break run")
return
end
end
local totalBingo = {}
for i = 1, MaxClickCount do
local info = BingoRateMap[i]
if not info then
BingoRateMap[i] = 0
end
if i == 1 then
totalBingo[i] = BingoRateMap[i]
else
totalBingo[i] = totalBingo[i - 1] + BingoRateMap[i]
end
if info then
local total = totalBingo[i]
print("总共标记次数:"..i..", 该标记次数下总共的bingo次数:"..info..", bingo的比例:"..(info/LoopAllCount)..", 累计bingo次数:"..total.." , 累计bingo比例:"..(total/LoopAllCount) )
end
end
print("----------------------------")
print("标记格子数量发生bingo:", table.concat(BingoRateMap, ", "))
print("标记累计发生bingo数量:", table.concat(totalBingo, ", "))
print(string.format("%d 次标记时收集物:%s, 平均:%0.2f", CollectHistoryRound, CollectCount, CollectCount / LoopAllCount))
end