Lots of stuff happened
[progcomp2013.git] / qchess / player.py
1 import subprocess
2 import select
3 import platform
4
5 agent_timeout = -1.0 # Timeout in seconds for AI players to make moves
6                         # WARNING: Won't work for windows based operating systems
7
8 if platform.system() == "Windows":
9         agent_timeout = -1 # Hence this
10
11 # A player who can't play
12 class Player():
13         def __init__(self, name, colour):
14                 self.name = name
15                 self.colour = colour
16
17 # Player that runs from another process
18 class AgentPlayer(Player):
19
20
21         def __init__(self, name, colour):
22                 Player.__init__(self, name, colour)
23                 self.p = subprocess.Popen(name, stdin=subprocess.PIPE, stdout=subprocess.PIPE,stderr=subprocess.PIPE)
24                 
25                 self.send_message(colour)
26
27         def send_message(self, s):
28                 if agent_timeout > 0.0:
29                         ready = select.select([], [self.p.stdin], [], agent_timeout)[1]
30                 else:
31                         ready = [self.p.stdin]
32                 if self.p.stdin in ready:
33                         #print "Writing to p.stdin"
34                         try:
35                                 self.p.stdin.write(s + "\n")
36                         except:
37                                 raise Exception("UNRESPONSIVE")
38                 else:
39                         raise Exception("UNRESPONSIVE")
40
41         def get_response(self):
42                 if agent_timeout > 0.0:
43                         ready = select.select([self.p.stdout], [], [], agent_timeout)[0]
44                 else:
45                         ready = [self.p.stdout]
46                 if self.p.stdout in ready:
47                         #print "Reading from p.stdout"
48                         try:
49                                 return self.p.stdout.readline().strip("\r\n")
50                         except: # Exception, e:
51                                 raise Exception("UNRESPONSIVE")
52                 else:
53                         raise Exception("UNRESPONSIVE")
54
55         def select(self):
56
57                 self.send_message("SELECTION?")
58                 line = self.get_response()
59                 
60                 try:
61                         result = map(int, line.split(" "))
62                 except:
63                         raise Exception("GIBBERISH \"" + str(line) + "\"")
64                 return result
65
66         def update(self, result):
67                 #print "Update " + str(result) + " called for AgentPlayer"
68                 self.send_message(result)
69
70
71         def get_move(self):
72                 
73                 self.send_message("MOVE?")
74                 line = self.get_response()
75                 
76                 try:
77                         result = map(int, line.split(" "))
78                 except:
79                         raise Exception("GIBBERISH \"" + str(line) + "\"")
80                 return result
81
82         def quit(self, final_result):
83                 try:
84                         self.send_message("QUIT " + final_result)
85                 except:
86                         self.p.kill()
87
88 # So you want to be a player here?
89 class HumanPlayer(Player):
90         def __init__(self, name, colour):
91                 Player.__init__(self, name, colour)
92                 
93         # Select your preferred account
94         def select(self):
95                 if isinstance(graphics, GraphicsThread):
96                         # Basically, we let the graphics thread do some shit and then return that information to the game thread
97                         graphics.cond.acquire()
98                         # We wait for the graphics thread to select a piece
99                         while graphics.stopped() == False and graphics.state["select"] == None:
100                                 graphics.cond.wait() # The difference between humans and machines is that humans sleep
101                         select = graphics.state["select"]
102                         
103                         
104                         graphics.cond.release()
105                         if graphics.stopped():
106                                 return [-1,-1]
107                         return [select.x, select.y]
108                 else:
109                         # Since I don't display the board in this case, I'm not sure why I filled it in...
110                         while True:
111                                 sys.stdout.write("SELECTION?\n")
112                                 try:
113                                         p = map(int, sys.stdin.readline().strip("\r\n ").split(" "))
114                                 except:
115                                         sys.stderr.write("ILLEGAL GIBBERISH\n")
116                                         continue
117         # It's your move captain
118         def get_move(self):
119                 if isinstance(graphics, GraphicsThread):
120                         graphics.cond.acquire()
121                         while graphics.stopped() == False and graphics.state["dest"] == None:
122                                 graphics.cond.wait()
123                         graphics.cond.release()
124                         
125                         return graphics.state["dest"]
126                 else:
127
128                         while True:
129                                 sys.stdout.write("MOVE?\n")
130                                 try:
131                                         p = map(int, sys.stdin.readline().strip("\r\n ").split(" "))
132                                 except:
133                                         sys.stderr.write("ILLEGAL GIBBERISH\n")
134                                         continue
135
136         # Are you sure you want to quit?
137         def quit(self, final_result):
138                 if graphics == None:            
139                         sys.stdout.write("QUIT " + final_result + "\n")
140
141         # Completely useless function
142         def update(self, result):
143                 if isinstance(graphics, GraphicsThread):
144                         pass
145                 else:
146                         sys.stdout.write(result + "\n") 
147
148
149 # Player that makes random moves
150 class AgentRandom(Player):
151         def __init__(self, name, colour):
152                 Player.__init__(self, name, colour)
153                 self.choice = None
154
155                 self.board = Board(style = "agent")
156
157         def select(self):
158                 while True:
159                         self.choice = self.board.pieces[self.colour][random.randint(0, len(self.board.pieces[self.colour])-1)]
160                         all_moves = []
161                         # Check that the piece has some possibility to move
162                         tmp = self.choice.current_type
163                         if tmp == "unknown": # For unknown pieces, try both types
164                                 for t in self.choice.types:
165                                         if t == "unknown":
166                                                 continue
167                                         self.choice.current_type = t
168                                         all_moves += self.board.possible_moves(self.choice)
169                         else:
170                                 all_moves = self.board.possible_moves(self.choice)
171                         self.choice.current_type = tmp
172                         if len(all_moves) > 0:
173                                 break
174                 return [self.choice.x, self.choice.y]
175
176         def get_move(self):
177                 moves = self.board.possible_moves(self.choice)
178                 move = moves[random.randint(0, len(moves)-1)]
179                 return move
180
181         def update(self, result):
182                 #sys.stderr.write(sys.argv[0] + " : Update board for AgentRandom\n")
183                 self.board.update(result)
184                 self.board.verify()
185
186         def quit(self, final_result):
187                 pass

UCC git Repository :: git.ucc.asn.au