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

Swift

Posted by shi-n