-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathhost-demo.py
More file actions
146 lines (126 loc) · 5.34 KB
/
host-demo.py
File metadata and controls
146 lines (126 loc) · 5.34 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
from queue import Queue
from time import sleep
from random import choice, randint
import threading
from threading import Event
class CmdPack():
def __init__(self, cmd, *args):
self.pack = [cmd,args]
def __str__(self):
cmd, args = self.pack[0], self.pack[1]
if len(args):
return "'%s', %s" % (cmd, str(args))
else:
return "'%s'" % cmd
def getCmd(self):
return self.pack[0]
def getArgs(self):
return self.pack[1]
class GameCtrl():
def __init__(self): # TODO add player
self._pipes_from = [Queue(),Queue()]
self._pipes_to = [Queue(),Queue()]
self._actived = [Event(), Event()]
self._cmds = ["action","end"]
self._next = Event() # signal for turn next player
self._gameOver = Event() # signal for game over
self.p1_loop = threading.Thread(target=self.playerLoop, args=[0])
self.p2_loop = threading.Thread(target=self.playerLoop, args=[1])
self.p1_loop.start()
self.p2_loop.start()
def send(self, pid, cmdPack):
print("[info] GameCtrl.send(p%d, %s) " % (pid,cmdPack))
self._pipes_to[pid].put(cmdPack)
def update(self,pid, *args):
self.send(pid, CmdPack("update",*args))
def recvTestCmd(self, pid, cmdPack): # test
# print("[test] GameCtrl.recvTestCmd(%s) " % cmdPack) # debug
self._pipes_from[pid].put(cmdPack)
def actionEventHandler(self, pid, *args):
# TODO comlete it
if len(args):
print("[info] action_event_handler: pid=%d args=%s " % (pid,str(args)))
else:
print("[info] action_event_handler: pid=%d " % pid)
# rule system check and make result
# update game status
other_pid = (pid+1) % 2
self.update(other_pid, *args)
def endEventHandler(self, pid):
print("[info] end_event_handler: pid=%d " % pid)
self._actived[pid].clear()
self._next.set()
def forceEndEventHandler(self, pid):
print("[info] forceEnd_event_handler: pid=%d " % pid)
self._actived[pid].clear()
self._next.set()
def setGameOver(self):
self._gameOver.set()
def playerActionTest(self, pid): # test
print("[test] playerAction waiting pid=%d " % pid)
self._actived[pid].wait()
print("[test] playerAction_start pid=%d " % pid)
n = randint(1,5) # cmd
t = randint(5,10) / n # sec
print("[test] playerAction pid=%d n=%d t=%.1fs " % (pid,n,t))
# TODO add more action
cmds = ["action" for i in range(n)]
cmds.append("end")
print("[test] playerAction cmds=%s " % str(cmds))
for cmd in cmds:
if self._actived[pid].is_set():
self.recvTestCmd(pid,CmdPack(cmd))
sleep(t)
else:
print("[erro] playerAction_end pid=%d " % pid)
return
print("[test] playerAction_end pid=%d " % pid)
# sleep(1) # wait signal off
def playerLoop(self, pid): # run on thread, controled by signal
while True:
print("[info] playerLoop waiting pid=%d " % pid)
self._actived[pid].wait()
print("[info] playerLoop_start pid=%d " % pid)
while self._actived[pid].is_set():
cmdPack = self._pipes_from[pid].get() # block=True
print("[info] GameCtrl.recv(p%d, %s) " % (pid, cmdPack))
cmd, args = cmdPack.getCmd(), cmdPack.getArgs()
# TODO add more
if cmd is "action":
self.actionEventHandler(pid,*args)
elif cmd is "end":
self.endEventHandler(pid)
else:
print("[warm] playerLoop: unsupported_cmd %s " % cmd)
print("[info] playerLoop_end pid=%d " % pid)
def playerTurn(self, pid):
print("[info] playerTurn_start pid=%d " % pid)
print("[debug] playerTurn: clear _next pid=%d " % pid)
self._next.clear()
self.send(pid, "start")
print("[debug] playerTurn: set _actived pid=%d " % pid)
self._actived[pid].set() # turn on loop
self.update(pid, "draw_card")
forceEnd_countDown = threading.Timer(7, self.forceEndEventHandler, [pid])
# player_loop = threading.Thread(target=self.playerLoop, args=[pid])
# player_loop.start()
player_action_tester = threading.Thread(target=self.playerActionTest, args=[pid])
player_action_tester.start()
forceEnd_countDown.start()
self._next.wait()
forceEnd_countDown.cancel() # end, cancel timer
print("[info] playerTurn_end pid=%d " % pid)
def gameLoop(self):
print("[info] gameLoop_start ")
self._gameOver.clear()
gameOver_countDown = threading.Timer(22, self.setGameOver) # test
gameOver_countDown.start()
active_pid = 0 # first active player
while self._gameOver.is_set() is False:
self.playerTurn(active_pid)
active_pid = (active_pid+1) % 2 # change player
print("[info] gameLoop: change_player pid=%d " % active_pid)
print("[info] gameLoop_end ")
g = GameCtrl()
# g.playerTurn(0)
g.gameLoop()