-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathnaive_game.py
More file actions
193 lines (164 loc) · 5.23 KB
/
naive_game.py
File metadata and controls
193 lines (164 loc) · 5.23 KB
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
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
# -*- coding: utf-8 -*-
"""
Created on Wed Nov 15 14:13:35 2017
@author: sjxn2423
任务: 实现MCTS_player这个类
"""
from __future__ import print_function
from logic.mcts import MCTSLogic
from logic.qlearning import Q_Learning
import interface
class Board(interface.Status):
"""
board for game
"""
def __init__(self, **kwargs):
self.width = int(kwargs.get('width', 4))
self.height = int(kwargs.get('height', 4))
self.max_rounds = int(kwargs.get('rounds', 50))
self.pos = (0,0)
self.availables = self._get_availables()
self.states={0:1}
self.player = 1
self.rounds=0
def perform(self, action):
if action not in self.availables:
raise ValueError
if action == 0:
self.pos = (self.pos[0]-1, self.pos[1])
elif action == 1:
self.pos = (self.pos[0]+1, self.pos[1])
elif action == 2:
self.pos = (self.pos[0], self.pos[1]-1)
elif action == 3:
self.pos = (self.pos[0], self.pos[1]+1)
elif action == 4:
pass
self.states = {self.pos[0]+self.pos[1]*self.width:1}
self.rounds += 1
self.availables = self._get_availables()
self.player = 3 - self.player
def _get_availables(self):
availables = [4]
if self.pos[0] > 0:
availables.append(0)
if self.pos[0] < self.width-1:
availables.append(1)
if self.pos[1] > 0:
availables.append(2)
if self.pos[1] < self.height-1:
availables.append(3)
return availables
def is_terminal(self) -> bool:
if self.pos[0] >= self.width - 1 and self.pos[1]>=self.height-1 and self.rounds<self.max_rounds:
self.terminal = True
self.winner = 1
elif self.rounds >= self.max_rounds:
self.terminal = True
self.winner = 2
else:
self.terminal = False
return self.terminal
def get_result_score(self, player_idx=None):
if self.terminal:
return self.winner
else:
raise ValueError("Not terminated yet!")
def game_end(self):
terminated = self.is_terminal()
if terminated:
return True, self.get_result_score()
return False, -1
def get_current_player_idx(self):
return self.player
def get_available_actions(self):
return self._get_availables()
def to_number(self):
return self.pos
class MCTS_Player(interface.Player):
"""TODO: 实现这个MCTS player"""
def __init__(self, player, logic=None):
self.player = player
if logic is None:
raise ValueError('`logic` must be specified.')
self.logic = logic
def get_action(self, board):
sensible_moves = board.availables
if len(sensible_moves) > 0:
move = self.logic.get_action(board, self.player-1)
print("AI move: %d\n" % (move))
return move
else:
print("WARNING: the board is full")
def __str__(self):
return "MCTS"
class Human(interface.Player):
"""
human player
"""
def __init__(self, player):
self.player = player
def get_action(self, board):
try:
move = int(input("Your move: "))
# move = board.location_to_move(location)
except Exception as e:
move = -1
if move == -1 or move not in board.availables:
print("invalid move")
move = self.get_action(board)
return move
def __str__(self):
return "Human"
class Game(interface.Game):
"""
game server
"""
def __init__(self, board, **kwargs):
self.board = board
def start(self):
ai = MCTS_Player(1, Q_Learning(space_width=self.board.width*self.board.height, action_num=5, player_num=2))
# human = MCTS_Player(p2, MCTS_logic())
human = Human(1)
human1 = Human(2)
players = [ai, human1]
ai.logic.train(self.board, 1000)
self.graphic(self.board)
i = 0
while(1):
print('Player %d' % (i+1))
move = players[i].get_action(self.board)
i = 1 - i
self.board.perform(move)
self.graphic(self.board)
end, winner = self.board.game_end()
if end:
if winner != -1:
print("Game end. Winner is %d" % winner)
else:
print("Game end. Tie")
break
def get_player_num(self):
return 2
def set_player(self, idx, player):
pass
def graphic(self, board):
"""
Draw the board and show game info
"""
for j in range(board.height):
out = ''
for i in range(board.width):
out += '-' if (i,j)!=board.pos else 'x'
print(out)
def run():
# 可以先在 width=3, height=3, n=3 这种最简单的case下开发实验
# 这种case下OK之后,再测试下 width=6, height=6, n=4 这种情况
try:
board = Board()
game = Game(board)
game.start()
except KeyboardInterrupt:
print('\n\rquit')
if __name__ == '__main__':
run()