「インターフェース 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