-
Notifications
You must be signed in to change notification settings - Fork 0
/
TimedGameMaster.py
174 lines (156 loc) · 6.09 KB
/
TimedGameMaster.py
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
'''TimedGameMaster.py based on GameMaster.py which in turn is
based on code from RunKInARow.py
S. Tanimoto, April 29, 2015.
'''
# Specify details of a match here:
from __future__ import print_function
import stellastKInARow as player1
import chen2016KInARow as player2
from FiveInARowGameType import K, NAME, INITIAL_STATE
#from TicTacToeGameType import K, NAME, INITIAL_STATE
TIME_PER_MOVE = 10
USE_HTML = True
from winTesterForK import winTesterForK
if USE_HTML: import gameToHTML
CURRENT_PLAYER = 'X'
N = len(INITIAL_STATE[0]) # height of board
M = len(INITIAL_STATE[0][0]) # width of board
FINISHED = False
def runGame():
currentState = INITIAL_STATE
print(INITIAL_STATE)
print('The Gamemaster says, "Players, introduce yourselves."')
print(' (Playing X:) '+player1.introduce())
print(' (Playing O:) '+player2.introduce())
if USE_HTML:
gameToHTML.startHTML(player1.nickname(), player2.nickname(), NAME, 1)
try:
p1comment = player1.prepare(INITIAL_STATE, K, 'X', player2.nickname())
except:
report = 'Player 1 ('+player1.nickname()+' failed to prepare, and loses by default.'
print(report)
if USE_HTML: gameToHTML.reportResult(report)
report = 'Congratulations to Player 2 ('+player2.nickname()+')!'
print(report)
if USE_HTML: gameToHTML.reportResult(report)
if USE_HTML: gameToHTML.endHTML()
return
try:
p2comment = player2.prepare(INITIAL_STATE, K, 'O', player1.nickname())
except:
report = 'Player 2 ('+player2.nickname()+' failed to prepare, and loses by default.'
print(report)
if USE_HTML: gameToHTML.reportResult(report)
report = 'Congratulations to Player 1 ('+player1.nickname()+')!'
print(report)
if USE_HTML: gameToHTML.reportResult(report)
if USE_HTML: gameToHTML.endHTML()
return
return
print('The Gamemaster says, "Let\'s Play!"')
print('The initial state is...')
currentRemark = "The game is starting."
if USE_HTML: gameToHTML.stateToHTML(currentState)
XsTurn = True
name = None
global FINISHED
FINISHED = False
turnCount = 0
printState(currentState)
while not FINISHED:
who = currentState[1]
global CURRENT_PLAYER
CURRENT_PLAYER = who
if XsTurn:
playerResult = timeout(player1.makeMove,args=(currentState, currentRemark, TIME_PER_MOVE), kwargs={}, timeout_duration=TIME_PER_MOVE, default=(None,"I give up!"));
name = player1.nickname()
XsTurn = False
#print(playerResult)
else:
playerResult = timeout(player2.makeMove,args=(currentState, currentRemark, TIME_PER_MOVE), kwargs={}, timeout_duration=TIME_PER_MOVE, default=(None,"I give up!"));
name = player2.nickname()
XsTurn = True
#print(playerResult)
moveAndState, currentRemark = playerResult
#print(who)
#print(moveAndState)
if moveAndState==None:
FINISHED = True; continue
move, currentState = moveAndState
moveReport = "Move is by "+who+" to "+str(move)
print(moveReport)
utteranceReport = name +' says: '+currentRemark
print(utteranceReport)
if USE_HTML: gameToHTML.reportResult(moveReport)
if USE_HTML: gameToHTML.reportResult(utteranceReport)
possibleWin = winTesterForK(currentState, move, K)
if possibleWin != "No win":
FINISHED = True
printState(currentState)
if USE_HTML: gameToHTML.stateToHTML(currentState, finished=True)
print(possibleWin)
if USE_HTML: gameToHTML.reportResult(possibleWin)
if USE_HTML: gameToHTML.endHTML()
return
printState(currentState)
if USE_HTML: gameToHTML.stateToHTML(currentState)
turnCount += 1
#if turnCount == 9: FINISHED=True
printState(currentState)
if USE_HTML: gameToHTML.stateToHTML(currentState)
who = currentState[1]
print("Game over.")
if USE_HTML: gameToHTML.reportResult("Game Over; it's a draw")
if USE_HTML: gameToHTML.endHTML()
def printState(s):
global FINISHED
board = s[0]
who = s[1]
horizontalBorder = "+"+3*N*"-"+"+"
print(horizontalBorder)
for row in board:
print("|",end="")
for item in row:
print(" "+item+" ",end="")
print("|")
print(horizontalBorder)
if not FINISHED:
print("It is "+who+"'s turn to move.\n")
import sys
import time
def timeout(func, args=(), kwargs={}, timeout_duration=1, default=None):
'''This function will spawn a thread and run the given function using the args, kwargs and
return the given default value if the timeout_duration is exceeded
'''
import threading
class PlayerThread(threading.Thread):
def __init__(self):
threading.Thread.__init__(self)
self.result = default
def run(self):
try:
self.result = func(*args, **kwargs)
except:
print("Seems there was a problem with the time.")
print(sys.exc_info())
self.result = default
pt = PlayerThread()
print("timeout_duration = "+str(timeout_duration))
pt.start()
started_at = time.time()
#print("makeMove started at: " + str(started_at))
pt.join(timeout_duration)
ended_at = time.time()
#print("makeMove ended at: " + str(ended_at))
diff = ended_at - started_at
#print("Time used in makeMove: %0.4f seconds" % diff)
if pt.isAlive():
print("Took too long.")
print("We are now terminating the game.")
print("Player "+CURRENT_PLAYER+" loses.")
if USE_HTML: gameToHTML.reportResult("Player "+CURRENT_PLAYER+" took too long (%04f seconds) and thus loses." % diff)
if USE_HTML: gameToHTML.endHTML()
exit()
else:
return pt.result
runGame()