「インターフェース 2019年2月号」人工知能アルゴリズム探検隊 第25回 シミュレーションSwift化
人工知能アルゴリズム探検隊 第25回 社会科学の基本問題「囚人のジレンマ」のシミュレーションプログラムをSwift化。
Playgroundで実行可能です。
元はProcessingです。
import Cocoa
let GAMEMAX = 10
let USINGTYPE = [0, 1, 2, 3, 4, 5, 6, 7, 8]
let TYPEMAX = USINGTYPE.count
var allScore = [[Int]](repeating: [Int](repeating: 0, count: TYPEMAX), count: TYPEMAX)
var allworL = [[Int]](repeating: [Int](repeating: 0, count: TYPEMAX), count: TYPEMAX)
struct CAgent {
var score:Int = 0
var type:Int
var gameNum:Int = 0
var dflag:Bool = false
var stateA = [Bool](repeating:true, count:GAMEMAX)
var stateB = [Bool](repeating:true, count:GAMEMAX)
init(type:Int) {
self.type = type
}
mutating func game(mb:CAgent) {
stateB[0] = mb.stateA[0]
gameNum = gameNum + 1
if stateA[0] == true && stateB[0] == true {
score = score + 6 //3 //6
}
else if stateA[0] == true && stateB[0] == false {
score = score + 0
}
else if stateA[0] == false && stateB[0] == true {
score = score + 8 //5 //8
}
else if stateA[0] == false && stateB[0] == false {
score = score + 2 //1 //2
}
if stateB[0] == false {
dflag = true
}
}
mutating func updateState() {
for k in (1...GAMEMAX - 1).reversed() {
stateA[k] = stateA[k - 1]
stateB[k] = stateB[k - 1]
}
}
mutating func initCAgent() {
if type == 1 || type == 3 || type == 5 {
stateA[0] = false
}
else {
stateA[0] = true
}
score = 0
dflag = false
}
mutating func nextState() {
switch type {
case 0: //ALL-C
stateA[0] = true
case 1: //ALL-D
stateA[0] = false
case 2,3: //TFT,antiTFT
stateA[0] == stateB[1]
case 4,5: //Repeat-initC,Repeat-initD
stateA[0] = !stateA[1]
case 7: //GRIM*
if gameNum == GAMEMAX - 1 {
dflag = true
}
fallthrough
case 6: //GRIM
if dflag == false {
stateA[0] = true
}
else {
stateA[0] = false
}
case 8: //antiTFT
if gameNum > 2 && stateB[1] == false && stateB[2] == false {
stateA[0] = false
}
else {
stateA[0] = true
}
case 10: //Random
if Int.random(in: 0...1) < 1 {
stateA[0] = true
}
else {
stateA[0] = false
}
default:
break
}
}
}
var mAgentA:[CAgent] = []
var mAgentB:[CAgent] = []
func setup() {
for i in 0..<TYPEMAX {
mAgentA.append(CAgent(type: USINGTYPE[i]))
mAgentB.append(CAgent(type: USINGTYPE[i]))
}
allGame()
disp()
}
func allGame() {
for i in 0..<TYPEMAX {
for j in 0..<TYPEMAX {
mAgentA[i].initCAgent()
mAgentB[j].initCAgent()
for _ in 0..<GAMEMAX {
mAgentA[i].game(mb: mAgentB[j])
mAgentB[j].game(mb: mAgentA[i])
mAgentA[i].updateState()
mAgentB[j].updateState()
mAgentA[i].nextState()
mAgentB[j].nextState()
}
//利得の保存
allScore[i][j] = mAgentA[i].score
//勝敗の保存
if mAgentA[i].score < mAgentB[j].score {
allworL[i][j] = -1
}
else if mAgentA[i].score > mAgentB[j].score {
allworL[i][j] = 1
}
else {
allworL[i][j] = 0
}
}
}
}
func disp() {
print("Score----------")
for i in 0..<TYPEMAX {
for j in 0..<TYPEMAX {
print("\(allScore[i][j])\t", separator: "", terminator: "")
}
print()
}
print("Win or Loose----------")
for i in 0..<TYPEMAX {
for j in 0..<TYPEMAX {
print("\(allworL[i][j])\t", separator: "", terminator: "")
}
print()
}
}
setup()
Result
Score---------- 60 0 60 0 30 30 60 54 60 80 20 80 20 50 50 26 26 32 60 0 60 0 30 30 60 60 60 80 20 80 20 50 50 26 26 32 70 10 70 10 40 40 22 22 70 70 10 70 10 40 40 16 16 64 60 18 60 18 46 48 60 60 60 62 18 60 18 46 48 60 60 60 60 16 60 16 30 32 60 60 60 Win or Loose---------- 0 -1 0 -1 -1 -1 0 -1 0 1 0 1 0 1 1 1 1 1 0 -1 0 -1 -1 -1 0 0 0 1 0 1 0 1 1 1 1 1 1 -1 1 -1 0 0 -1 -1 1 1 -1 1 -1 0 0 -1 -1 1 0 -1 0 -1 1 1 0 0 0 1 -1 0 -1 1 1 0 0 0 0 -1 0 -1 -1 -1 0 0 0






