82 lines
2.0 KiB
Crystal
82 lines
2.0 KiB
Crystal
module GameOfGame
|
|
|
|
# Always cooperate
|
|
class Cooperative < Ai
|
|
def bet(rounds : GameHistory) : Float64
|
|
1.0
|
|
end
|
|
end
|
|
|
|
# Always cheat
|
|
class Cheater < Ai
|
|
def bet(rounds : GameHistory) : Float64
|
|
0.0
|
|
end
|
|
end
|
|
|
|
# Give and take cooperate round 1, then copy the worse opponent.
|
|
class GiveAndTake < Ai
|
|
def bet(rounds : GameHistory) : Float64
|
|
last_round = rounds.last_round
|
|
return 1.0 if last_round.nil?
|
|
|
|
return 0.0 if last_round.bets.reject(me).values.includes?(0.0)
|
|
1.0
|
|
end
|
|
end
|
|
|
|
# Nemesis cheat first round, then he cooperate if someone cheated.
|
|
class Nemesis < Ai
|
|
def bet(rounds : GameHistory) : Float64
|
|
last_round = rounds.last_round
|
|
return 0.0 if last_round.nil?
|
|
|
|
return 1.0 if last_round.bets.reject(me).values.includes?(0.0)
|
|
0.0
|
|
end
|
|
end
|
|
|
|
# The fool is random
|
|
class TheFool < Ai
|
|
SAMPLER = {1.0, 0.0}
|
|
def bet(rounds : GameHistory) : Float64
|
|
SAMPLER.sample
|
|
end
|
|
end
|
|
|
|
# Macron cheat the first round and every round by default.
|
|
# Then he looks if half of the people cheated and stop cheating only if 50%>
|
|
# people are cheating too.
|
|
class Macron < Ai
|
|
def bet(rounds : GameHistory) : Float64
|
|
last_round = rounds.last_round
|
|
return 0.0 if last_round.nil?
|
|
return 1.0 if last_round.bets.reject(me).select { |_, v| v == 0.0 }.size > last_round.bets.size / 2
|
|
return 0.0
|
|
end
|
|
end
|
|
|
|
# The statistician roll a dice and compare the result with the average bet
|
|
# as a probability
|
|
class Statistician < Ai
|
|
def bet(rounds : GameHistory) : Float64
|
|
last_round = rounds.last_round
|
|
return 1.0 if last_round.nil?
|
|
|
|
bets_amount = 0
|
|
bets_cooperated = 0
|
|
while !last_round.nil?
|
|
bets = last_round.bets.reject(me)
|
|
bets_amount += bets.size
|
|
bets_cooperated += bets.values.count { |v| v == 1.0 }
|
|
last_round = last_round.previous
|
|
end
|
|
|
|
thresold = bets_cooperated.to_f64 / bets_amount.to_f64
|
|
return 1.0 if rand >= thresold
|
|
0.0
|
|
end
|
|
end
|
|
|
|
end
|