local FuncNormalExtra = {}
local NormalBingoType = {
Horizontal1 = 1,
Horizontal2 = 2,
Horizontal3 = 3,
Horizontal4 = 4,
Horizontal5 = 5,
Vertical1 = 6,
Vertical2 = 7,
Vertical3 = 8,
Vertical4 = 9,
Vertical5 = 10,
LT_RB = 11,
RT_LB = 12,
Corner = 13,
Count = 14 - 1
}
FuncNormalExtra.NormalBingoType = NormalBingoType
function FuncNormalExtra:checkIsBingo(card, excludeCheckTypes , assumeDaubCells)
local data = {}
for x = 1, 5 do
data[x] = {}
for y = 1, 5 do
data[x][y] = card[(x - 1) * 5 + y]
end
end
local bingoResult = { }
for i = 1, NormalBingoType.Count, 1 do
bingoResult[i] = false
end
local function checkIsMark( flag, i, j )
if assumeDaubCells then
for _, cellConfig in pairs(assumeDaubCells or { }) do
if cellConfig[1] == i and cellConfig[2] == j then
return true
end
end
end
if flag[i][j] == 1 then
return true
end
return false
end
local isBingo = false
for i=1,5 do
if not excludeCheckTypes or not excludeCheckTypes[i] then
isBingo = true
for j=1,5 do
if not checkIsMark(data,i,j) then
isBingo = false
break
end
end
if isBingo then
bingoResult[i] = true
end
end
end
for i=1,5 do
if not excludeCheckTypes or not excludeCheckTypes[i + 5] then
isBingo = true
for j=1,5 do
if not checkIsMark(data,j,i) then
isBingo = false
break
end
end
if isBingo then
bingoResult[i + 5] = true
end
end
end
if not excludeCheckTypes or not excludeCheckTypes[11] then
isBingo = true
for i=1,5 do
if not checkIsMark(data,i,i) then
isBingo = false
break
end
end
if isBingo then
bingoResult[11] = true
end
end
if not excludeCheckTypes or not excludeCheckTypes[12] then
isBingo = true
for i=1,5 do
if not checkIsMark(data,i,6-i) then
isBingo = false
break
end
end
if isBingo then
bingoResult[12] = true
end
end
if not excludeCheckTypes or not excludeCheckTypes[13] then
if checkIsMark(data,1,1) and
checkIsMark(data,1,5) and
checkIsMark(data,5,1) and
checkIsMark(data,5,5) then
bingoResult[13] = true
end
end
return bingoResult
end
local BASE_PROBABILITY = 80
local ADD_PROBABILITY = 5
local MARK_PROBABILITY = 28
local ROUND_BALL_COUNT = 1
local LoopCount = 1000
local DebugOut = false
if DebugOut then
LoopCount = 1
end
local MaxY = 5
local MaxX = 5
local CellCount = MaxY * MaxX
local function grid2Pos(grid)
return (grid - 1) % MaxY + 1, math.ceil(grid / MaxX)
end
local function pos2Grid(x, y)
return (y - 1) * MaxX + x
end
local function dump_value_(v)
if type(v) == "string" then
v = "\"" .. v .. "\""
end
return tostring(v)
end
local function dump(value, description, nesting)
if type(nesting) ~= "number" then nesting = 3 end
local lookupTable = {}
local result = {}
local function dump_(value, description, indent, nest, keylen)
description = description or "<var>"
local spc = ""
if type(keylen) == "number" then
spc = string.rep(" ", keylen - string.len(dump_value_(description)))
end
if type(value) ~= "table" then
result[#result +1 ] = string.format("%s%s%s = %s", indent, dump_value_(description), spc, dump_value_(value))
elseif lookupTable[tostring(value)] then
result[#result +1 ] = string.format("%s%s%s = *REF*", indent, dump_value_(description), spc)
else
lookupTable[tostring(value)] = true
if nest > nesting then
result[#result +1 ] = string.format("%s%s = *MAX NESTING*", indent, dump_value_(description))
else
result[#result +1 ] = string.format("%s%s = {", indent, dump_value_(description))
local indent2 = indent.." "
local keys = {}
local keylen = 0
local values = {}
for k, v in pairs(value) do
keys[#keys + 1] = k
local vk = dump_value_(k)
local vkl = string.len(vk)
if vkl > keylen then keylen = vkl end
values[k] = v
end
table.sort(keys, function(a, b)
if type(a) == "number" and type(b) == "number" then
return a < b
else
return tostring(a) < tostring(b)
end
end)
for i, k in ipairs(keys) do
dump_(values[k], k, indent2, nest + 1, keylen)
end
result[#result +1] = string.format("%s}", indent)
end
end
end
dump_(value, description, "- ", 1)
for i, line in ipairs(result) do
print(line)
end
end
local function shuffleTable(t, startIndex, endIndex)
if startIndex == nil then
startIndex = 1
end
if endIndex == nil then
endIndex = #t
end
for i = startIndex, endIndex do
local randomIndex = math.random(startIndex, endIndex)
local tempValue = t[i]
t[i] = t[randomIndex]
t[randomIndex] = tempValue
end
end
function table.nums(t)
local count = 0
for k, v in pairs(t) do
count = count + 1
end
return count
end
math.randomseed(os.time())
local function simulateBlackout()
local boardConfig = {}
local markList = {}
local waitBallList = {}
for i = 1, CellCount do
boardConfig[i] = i
waitBallList[i] = i
markList[i] = 0
end
shuffleTable(boardConfig)
local curProbability = BASE_PROBABILITY
local curRound = 0
local capCount = 0
local bingoCount = 0
local bingoNeed = {}
local function markOne()
curRound = curRound + 1
for count = 1, ROUND_BALL_COUNT do
if math.random(1, 100) <= curProbability then
if math.random(1, 100) <= MARK_PROBABILITY then
curProbability = BASE_PROBABILITY
local index = table.remove(waitBallList, 1)
markList[index] = 1
else
curProbability = curProbability + ADD_PROBABILITY
capCount = capCount + 1
end
else
curProbability = curProbability + ADD_PROBABILITY
end
local result = FuncNormalExtra:checkIsBingo(markList)
local count = 0
for i = 1, #result, 1 do
if result[i] then
count = count + 1
end
end
if bingoCount ~= count then
bingoNeed[count] = curRound
end
bingoCount = count
if #waitBallList == 0 then
break
end
end
end
while true do
markOne()
if #waitBallList == 0 then
break
end
end
if DebugOut then
print("标记所有数字需要%d局", curRound)
print("标记完产生的帽子球", capCount)
print("bingo类型对应局输", bingoNeed[1] or 0, bingoNeed[2] or 0, bingoNeed[3] or 0, bingoNeed[13] or 0)
end
return waitBallList, curRound, capCount, bingoNeed
end
local blackout = 0
local blackoutCap = 0
local blackoutBingo = {}
for count = 1, LoopCount do
local waitBallList, curRound, capCount, bingoNeed = simulateBlackout()
blackout = blackout + curRound
blackoutCap = blackoutCap + capCount
blackoutBingo[1] = (blackoutBingo[1] or 0) + (bingoNeed[1] or 0)
blackoutBingo[2] = (blackoutBingo[2] or 0) + (bingoNeed[2] or 0)
blackoutBingo[3] = (blackoutBingo[3] or 0) + (bingoNeed[3] or 0)
blackoutBingo[13] = (blackoutBingo[13] or 0) + (bingoNeed[13] or 0)
end
print("平均标记完需要局数", blackout / LoopCount)
print("平均标记完转换帽子数", blackoutCap / LoopCount)
print("平均每种bingo类型数", blackoutBingo[1] / LoopCount, blackoutBingo[2] / LoopCount, blackoutBingo[3] / LoopCount, blackoutBingo[13] / LoopCount)