「インターフェース 2019年2月号」人工知能アルゴリズム探検隊 第25回 シミュレーションSwift化

人工知能アルゴリズム探検隊 第25回 社会科学の基本問題「囚人のジレンマ」のシミュレーションプログラムをSwift化。
Playgroundで実行可能です。
元はProcessingです。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
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