Skip to content

Instantly share code, notes, and snippets.

@DarkKor
Last active April 4, 2018 02:27
Show Gist options
  • Save DarkKor/866d2e44937209eb07a0ffb3e780de70 to your computer and use it in GitHub Desktop.
Save DarkKor/866d2e44937209eb07a0ffb3e780de70 to your computer and use it in GitHub Desktop.
// MARK: - Soldout bets
private extension InGameBetsPresenter {
// Здесь везде сумма выкупа или ненулевое число, или 0 если выкупить нельзя, или -1, если локально посчитать сумму выкупа нельзя.
// В случае с -1 мы должны в UI отобразить знак вопроса и дать возможность узнать сумму выкупа у сервера. Но это не тема этого гиста.
// Так как lineId нам недоступно в этом случае, искать линию, соответствующую данной ставке, мы будем довольно утино. Другого варианта нет(
func findLine(forBet: BetLine, event: Event) -> Line? {
return event.lines.values.first(where: { $0.koefStr == forBet.koefAdditional && $0.favorite == forBet.favorite && Int32($0.type) == forBet.type })
}
// MARK: Ordinar
func soldoutValue(ordinar: BetHistory) -> Double {
let betLine = ordinar.lines[0]
guard let event = DataStore.shared.events[betLine.eventId] else {
return 0
}
let line = findLine(forBet: betLine, event: event)
if let currentLine = line {
let index = Int(betLine.xOfVx) - 1
let currentKoef = Double(currentLine.vx[index]) / 100.0
if currentKoef > 1 {
let betKoef = Double(betLine.koef)
let betValue = ordinar.betValue
let saleAmount = (betValue * betKoef -
(betKoef * betValue / (1.0 / (1.05 - 1.0 / currentKoef))) - betValue * 0.025)
var saleAmount2: Double = -1.0
if currentKoef >= betKoef {
saleAmount2 = (betValue * betKoef / currentKoef - betValue * 0.125);
} else {
saleAmount2 = (betValue * betKoef / currentKoef - betValue * betKoef / currentKoef * 0.125)
}
if (saleAmount >= saleAmount2) {
if (saleAmount2 < 0) {
return 0.0
} else {
return saleAmount2
}
} else {
if saleAmount > 0 {
return saleAmount
}
}
}
} else {
if [1111116666, 1111116667, 283].contains(Int(betLine.type)) {
return -1.0
} else {
let marketType = Int(DataStore.shared.markets[betLine.type]!.type)
if (event.inLive != 0 || event.inLive == 0 && [1, 2, 3, 4, 5, 6, 7, 8, 15].contains(marketType)) {
return 0.0
} else {
return -1.0
}
}
}
return 0.0
}
// MARK: Express
// Это обычный кортеж, он нам нужен для накопления информации по мере прохода по массиву ставок экспресса
// Как мы помним, расчет экспресса основан на умножении коэффициентов входящих в него ставок.
// Точно так же и тут, ничего нового. Разве что информации, необходимой для расчета суммы выкупа, немного больше
// Поле flag в данном кортеже означает, что мы не смогли рассчитать сумму выкупа, и следует вообще говоря запрашивать ее у сервера
// Если не смогли, но выкупить можно, то дальше считать сумму экспресса нет смысла.
typealias LineParams = (winKoefs: Double, noWinKoefs: Double, betsKoefs: Double, linesKoefs: Double, countWin: Int, flag: Int)
func soldoutValue(express: BetHistory) -> Double {
var lineParams = LineParams(winKoefs: 1, noWinKoefs: 1, betsKoefs: 1, linesKoefs: 1, countWin: 0, flag: 0)
for i in 0..<express.lines.count {
let line = express.lines[i];
let params = setLineParam(line, lineParams);
if params == nil {
return 0.0
}
else if params!.flag != 0 {
return -1.0
}
else {
lineParams = params!
}
}
return getSaleAmount(express.lines, lineParams, express.betValue)
}
func setLineParam(_ line: BetLine, _ lineParams: LineParams) -> LineParams? {
guard let event = DataStore.shared.events[line.eventId] else {
return nil
}
var currentKoef: Double = 0.0
if line.state == 1 {
currentKoef = line.koefWin;
} else {
var currentLine = findLine(forBet: line, event: event)
if currentLine == nil {
if [1111116666, 1111116667, 283].contains(Int(line.type)) {
var params = lineParams
params.flag = 1
return params
} else {
let marketType = Int(DataStore.shared.markets[line.type]!.type)
if (event.inLive != 0 || event.inLive == 0 && [1, 2, 3, 4, 5, 6, 7, 8, 15].contains(marketType)) {
return nil
} else {
var params = lineParams
params.flag = 1
return params
}
}
}
let index = Int(line.xOfVx) - 1
currentKoef = Double(currentLine!.vx[index]) / 100.0
}
if currentKoef <= 1 {
var params = lineParams
params.flag = 1
return params
}
var params = lineParams
params.betsKoefs = lineParams.betsKoefs * line.koef;
switch (line.state) {
case 0:
params.linesKoefs = lineParams.linesKoefs * currentKoef
params.noWinKoefs = lineParams.noWinKoefs * line.koef
case 1:
params.winKoefs = lineParams.winKoefs * line.koef
params.countWin = lineParams.countWin + 1
default:
break
}
return params
}
func getSaleAmount(_ lines: [BetLine], _ lineParams: LineParams, _ betTotal: Double) -> Double {
var saleAmount: Double = 0, saleAmount2: Double = 0
if lineParams.betsKoefs >= 1000 || lineParams.linesKoefs >= 1000 {
return 0.0
}
if lineParams.countWin == lines.count {
saleAmount = betTotal * lineParams.winKoefs * 0.125
return saleAmount
}
if lineParams.countWin + 1 == lines.count {
saleAmount = betTotal * lineParams.winKoefs * lineParams.noWinKoefs - (lineParams.noWinKoefs * betTotal *
lineParams.winKoefs / (1.0 / (1.05 - 1.0 / lineParams.linesKoefs))) - 0.025 * betTotal * lineParams.winKoefs
if lineParams.linesKoefs >= lineParams.noWinKoefs {
saleAmount2 = betTotal * lineParams.winKoefs * lineParams.noWinKoefs / lineParams.linesKoefs - betTotal *
lineParams.winKoefs * 0.125
} else {
saleAmount2 = betTotal * lineParams.winKoefs * lineParams.noWinKoefs / lineParams.linesKoefs - betTotal *
lineParams.winKoefs * lineParams.noWinKoefs / lineParams.linesKoefs * 0.125
}
if saleAmount >= saleAmount2 {
if saleAmount2 < 0 {
return 0.0
} else {
return saleAmount2
}
} else {
if saleAmount > 0 {
return saleAmount
}
}
}
if lines.count - lineParams.countWin <= 3 {
if lineParams.linesKoefs >= lineParams.noWinKoefs {
saleAmount2 = betTotal * lineParams.winKoefs * lineParams.noWinKoefs / lineParams.linesKoefs - betTotal *
lineParams.winKoefs * 0.4
} else {
saleAmount2 = betTotal * lineParams.winKoefs * lineParams.noWinKoefs / lineParams.linesKoefs - betTotal *
lineParams.winKoefs * lineParams.noWinKoefs / lineParams.linesKoefs * 0.25
}
return saleAmount2 < 0 ? 0 : saleAmount2
}
if lineParams.linesKoefs >= lineParams.noWinKoefs {
saleAmount2 = betTotal * lineParams.winKoefs * lineParams.noWinKoefs / lineParams.linesKoefs - betTotal *
lineParams.winKoefs * 0.6
} else {
saleAmount2 = betTotal * lineParams.winKoefs * lineParams.noWinKoefs / lineParams.linesKoefs - betTotal *
lineParams.winKoefs * lineParams.noWinKoefs / lineParams.linesKoefs * 0.5
}
return saleAmount2 < 0 ? 0 : saleAmount2
}
// MARK: System
// Расчет суммы выкупа для системы основывается на предыдущих методах расчета экспресса, только нужно выудить все комбинации ставок
func soldoutValue(system: BetHistory) -> Double {
let num = Int(system.eventsCountInSystem)
let systemVariants = combosOfLength(n: system.lines.count, m: num).count
let expressTotal = system.betValue / Double(systemVariants)
var exit: Bool = false
var saleAmount: Double = 0
let bets = comboBets(bet: system, num: num, total: system.lines.count)
bets.forEach { (lines) in
if exit {
return
}
var lineParams = LineParams(winKoefs: 1, noWinKoefs: 1, betsKoefs: 1, linesKoefs: 1, countWin: 0, flag: 0)
lines.forEach({ (line) in
let params = setLineParam(line, lineParams)
if params == nil {
exit = true
return
}
else if params!.flag != 0 {
exit = true
return
}
else {
lineParams = params!
}
})
saleAmount += getSaleAmount(lines, lineParams, expressTotal)
}
if exit {
return -1
}
return saleAmount
}
// Получение всех возможных сочетаний в выбранной системе
// (например, рассматриваем систему 2 из 3, получим здесь массив следующих ставок - [1,2], [2,3], [1,3])
// В java-коде эти методы будут иметь реализацию отличную от приведенной здесь
func comboBets(bet: BetHistory, num: Int, total: Int) -> [[BetLine]] {
let combinedIndices = combosOfLength(n: total, m: num)
var bets = [[BetLine]]()
combinedIndices.forEach { (indices) in
bets.append(indices.map({ (index) -> BetLine in
return bet.lines[index]
}))
}
return bets
}
func addCombo(prevCombo: [Int], pivotList: [Int]) -> [([Int], [Int])] {
var pivotList = pivotList
return (0..<pivotList.count)
.map {
_ -> ([Int], [Int]) in
(prevCombo + [pivotList.remove(at: 0)], pivotList)
}
}
func combosOfLength(n: Int, m: Int) -> [[Int]] {
return [Int](1...m)
.reduce([([Int](), [Int](0..<n))]) {
(accum, _) in
accum.flatMap(addCombo)
}.map {
$0.0
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment