-
Notifications
You must be signed in to change notification settings - Fork 1
/
userinput.py
289 lines (269 loc) · 14.7 KB
/
userinput.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
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
import pygame
import constants as c
import pieces as p
import geometricfunctions as gf
def get_rect_from_player(player, rectList):
# Loop until the user clicks on a vertex
validClick = False
while not validClick:
# Make sure no other events are on the queue
pygame.event.clear()
# Prompt the user for a click and wait for two events
if player:
print("{} please click an option.".format(player.name))
else:
print("Please click an option.")
chosenRect = None
eventA = pygame.event.wait()
eventB = pygame.event.wait()
# If the next two events are the mouse being pressed down and then released, move forward
if eventA.type == pygame.MOUSEBUTTONDOWN and eventB.type == pygame.MOUSEBUTTONUP:
posA = eventA.__dict__['pos']
posB = eventB.__dict__['pos']
# If the mouse actions (pressed down, released) were no more than 10 pixels apart, move forward
if gf.pp_distance(posA, posB) < 10:
# Loop through the rects to see if the click occurred inside one
for rect in rectList:
# If both mouse actions occurred inside the current hex, move forward
if gf.is_within_rect(rect, posA) and gf.is_within_rect(rect, posB):
# Record the rect, switch the boolean to end the while loop, and break the rect loop
chosenRect = rect
validClick = True
break
if not validClick:
print("That click was not inside a rect. Please try again.")
else:
print("The mouse moved while pressed down. Please try again.")
return chosenRect
# A function to get a vertex chosen by the player
# Takes the player choosing and the list of vertices
def get_vertex_from_player(player, vertexList, playerKey):
# Check if the player is an AI or human
if player.isAI:
pass
else:
# Loop until the user clicks on a vertex
validClick = False
while not validClick:
# Make sure no other events are on the queue
pygame.event.clear()
# Prompt the user for a click and wait for two events
print("{} please click a vertex. Or click the Player Key to select nothing.".format(player.name))
eventA = pygame.event.wait()
eventB = pygame.event.wait()
# If the next two events are the mouse being pressed down and then released, move forward
if eventA.type == pygame.MOUSEBUTTONDOWN and eventB.type == pygame.MOUSEBUTTONUP:
# Get the coordinates of the clicks
posA = eventA.__dict__['pos']
posB = eventB.__dict__['pos']
# Get the coordinates of each vertex on the board
vertexCoords = [v.coordinates for v in vertexList]
# Get coordinates of the vertices closest to where the mouse was pressed down and where it was released
verCoordA = gf.get_closest_point(vertexCoords, posA)
verCoordB = gf.get_closest_point(vertexCoords, posB)
# If the two coordinates are the same and both events happened within 10 pixels each other, move forward
if verCoordA[0] == verCoordB[0] and abs(verCoordA[1] - verCoordB[1]) < 10:
# If the click was inside the Player Key, return to the previous menu without a selection
if gf.is_within_rect(playerKey.box, posA) and gf.is_within_rect(playerKey.box, posB):
closestVertex = None
validClick = True
print("{} did not choose a vertex.".format(player.name))
else:
# If the mouse action (pressed down, released) happened within 10 pixels of
# the closest vertex, move forward
if verCoordA[1] <= 10 and verCoordB[1] <= 10:
# With all conditions satisfied, find the vertex corresponding to the coordinates found
closestVertex = vertexList[vertexCoords.index(verCoordA[0])]
validClick = True
else:
print("That click was not close enough to a vertex. Please try again.")
else:
print("The mouse moved while pressed down. Please try again.")
return closestVertex
# A function to get a hex chosen by the player
# Takes the player choosing and the list of board hexes
def get_hex_from_player(player, hexList, playerKey):
# Check if the player is an AI or human
if player.isAI:
pass
else:
# Loop until the user clicks on a vertex
validClick = False
while not validClick:
# Make sure no other events are on the queue
pygame.event.clear()
# Prompt the user for a click and wait for two events
print("{} please click a hex. Or click the Player Key to select nothing.".format(player.name))
chosenHex = None
eventA = pygame.event.wait()
eventB = pygame.event.wait()
# If the next two events are the mouse being pressed down and then released, move forward
if eventA.type == pygame.MOUSEBUTTONDOWN and eventB.type == pygame.MOUSEBUTTONUP:
posA = eventA.__dict__['pos']
posB = eventB.__dict__['pos']
# If the mouse actions (pressed down, released) were no more than 10 pixels apart, move forward
if gf.pp_distance(posA, posB) < 10:
# If the click was inside the Player Key, return to the previous menu without a selection
if gf.is_within_rect(playerKey.box, posA) and gf.is_within_rect(playerKey.box, posB):
chosenHex = None
validClick = True
print("{} did not choose a hex.".format(player.name))
else:
# Loop through the hexes to see if the click occurred inside one
for hexTile in hexList:
# If both mouse actions occurred inside the current hex, move forward
if gf.is_within_hex(hexTile, posA) and gf.is_within_hex(hexTile, posB):
# Record the hex, switch the boolean to end the while loop, and break the hex loop
chosenHex = hexTile
validClick = True
break
if not validClick:
print("That click was not inside a hex. Please try again.")
else:
print("The mouse moved while pressed down. Please try again.")
return chosenHex
def present_menu(player, menuDict, titleContent, surface, titleFont, infoFont):
if player.isAI:
pass
else:
chosenOpt = present_graphical_menu(player, menuDict, titleContent, surface, titleFont, infoFont)
choice = menuDict[chosenOpt]
surface.fill(c.white)
pygame.display.update(surface.get_rect())
return choice
def present_graphical_menu(player, menuDict, titleContent, surface, titleFont, infoFont):
surface.fill(c.white)
pygame.display.update(surface.get_rect())
surfaceWidth = surface.get_width()
titleLabel = titleFont.render(titleContent, 1, c.black)
surface.blit(titleLabel, (25, 7))
menuOpts = list(menuDict.keys())
menuOptSurfaces = [surface.subsurface(pygame.Rect((0, 47 + i*25), (surfaceWidth, 25)))
for i in range(len(menuOpts))]
for i, optSurface in enumerate(menuOptSurfaces):
optLabel = infoFont.render(menuOpts[i], 1, c.black)
optSurface.blit(optLabel, (10, 2))
pygame.display.update(surface.get_rect())
rectList = [pygame.Rect(oS.get_abs_offset(), (oS.get_rect().width, oS.get_rect().height)) for oS in menuOptSurfaces]
chosenRect = get_rect_from_player(player, rectList)
chosenOpt = menuOpts[rectList.index(chosenRect)]
return chosenOpt
def create_players():
# Pygame initialization
pygame.init()
# opens the window with the size specifications given
inputScreen = pygame.display.set_mode(c.screenSize)
inputScreen.fill(c.white)
subsurfaceHeight = c.oceanHeight / 5
interiorSpacing = 4
exteriorSpacing = 5
baseY = 25
typeX = 50
typeSpacing = 30
nameX = 250
nameBoxSize = (150, 30)
colorX = 500
availableColors = list(c.playerColorsList)
arialFont = pygame.font.SysFont("Arial", 15)
pygame.event.set_allowed(None)
pygame.event.set_allowed([pygame.MOUSEBUTTONUP, pygame.MOUSEBUTTONDOWN, pygame.KEYDOWN, pygame.KEYUP, pygame.QUIT])
playerList = []
for playerI in range(4):
adjustedY = baseY + playerI * subsurfaceHeight
'''
typeMessage = arialFont.render("Choose the player type", 1, c.black)
inputScreen.blit(typeMessage, (typeX, adjustedY))
humanText = arialFont.render("Human", 1, c.black)
humanButton = pygame.Rect((typeX, adjustedY + typeMessage.get_size()[1] + exteriorSpacing),
(humanText.get_size()[0] + interiorSpacing * 2,
humanText.get_size()[1] + interiorSpacing * 2))
pygame.draw.rect(inputScreen, c.black, humanButton, 1)
inputScreen.blit(humanText, (typeX + interiorSpacing,
adjustedY + typeMessage.get_size()[1] + exteriorSpacing + interiorSpacing))
aiText = arialFont.render("AI", 1, c.black)
aiButton = pygame.Rect((typeX + humanText.get_size()[0] + typeSpacing,
adjustedY + typeMessage.get_size()[1] + exteriorSpacing),
(aiText.get_size()[0] + interiorSpacing * 2, aiText.get_size()[1] + interiorSpacing * 2))
pygame.draw.rect(inputScreen, c.black, aiButton, 1)
inputScreen.blit(aiText, (typeX + humanText.get_size()[0] + typeSpacing + interiorSpacing,
adjustedY + typeMessage.get_size()[1] + exteriorSpacing + interiorSpacing))
pygame.display.flip()
chosenButton = get_rect_from_player(None, [humanButton, aiButton])
if chosenButton == humanButton:
playerIsAI = False
else:
playerIsAI = True
'''
playerIsAI = False
nameMessage = arialFont.render("Enter a name", 1, c.black)
inputScreen.blit(nameMessage, (nameX, adjustedY))
textBox = pygame.Rect((nameX, adjustedY + nameMessage.get_size()[1] + exteriorSpacing), nameBoxSize)
pygame.draw.rect(inputScreen, c.black, textBox, 1)
arialFont.set_bold(True)
okText = arialFont.render("OK", 1, c.forestGreen)
okButton = pygame.Rect((nameX, adjustedY + nameMessage.get_size()[1] + nameBoxSize[1] + exteriorSpacing * 2),
(okText.get_size()[0] + interiorSpacing * 2, okText.get_size()[1] + interiorSpacing * 2))
pygame.draw.rect(inputScreen, c.black, okButton, 1)
inputScreen.blit(okText, (nameX + interiorSpacing,
adjustedY + nameMessage.get_size()[1] + nameBoxSize[1] + exteriorSpacing * 2 +
interiorSpacing))
arialFont.set_bold(False)
pygame.display.flip()
playerName = ""
clickedOK = False
lastEvent = None
pygame.event.clear()
while not clickedOK:
thisEvent = pygame.event.wait()
if thisEvent.type == pygame.MOUSEBUTTONDOWN:
pass
elif thisEvent.type == pygame.MOUSEBUTTONUP and lastEvent and lastEvent.type == pygame.MOUSEBUTTONDOWN:
downPosition = thisEvent.__dict__['pos']
upPosition = lastEvent.__dict__['pos']
if gf.is_within_rect(okButton, downPosition) and gf.is_within_rect(okButton, upPosition):
clickedOK = True
elif thisEvent.type == pygame.KEYDOWN:
pass
elif thisEvent.type == pygame.KEYUP and lastEvent and lastEvent.type == pygame.KEYDOWN:
if thisEvent.__dict__['key'] == lastEvent.__dict__['key']:
asciiValue = thisEvent.__dict__['key']
if 97 <= asciiValue <= 122:
modValue = thisEvent.__dict__['mod']
print(thisEvent.__dict__)
if modValue == 1 or modValue == 2 or modValue == 8192:
asciiValue -= 32
char = chr(asciiValue)
playerName += char
pygame.draw.rect(inputScreen, c.white, textBox, 0)
pygame.draw.rect(inputScreen, c.black, textBox, 1)
nameLabel = arialFont.render(playerName, 1, c.black)
inputScreen.blit(nameLabel, (nameX + interiorSpacing, adjustedY + nameMessage.get_size()[1] +
exteriorSpacing + interiorSpacing))
pygame.display.flip()
elif asciiValue == 8:
playerName = playerName[:-1]
pygame.draw.rect(inputScreen, c.white, textBox, 0)
pygame.draw.rect(inputScreen, c.black, textBox, 1)
nameLabel = arialFont.render(playerName, 1, c.black)
inputScreen.blit(nameLabel, (nameX + interiorSpacing, adjustedY + nameMessage.get_size()[1] +
exteriorSpacing + interiorSpacing))
pygame.display.flip()
elif asciiValue == 13:
clickedOK = True
lastEvent = thisEvent
colorMessage = arialFont.render("Choose a color", 1, c.black)
inputScreen.blit(colorMessage, (colorX, adjustedY))
defaultColorBox = pygame.Rect((colorX, adjustedY + colorMessage.get_size()[1] + exteriorSpacing),
(c.colorBoxEdgeLength, c.colorBoxEdgeLength))
colorBoxes = [defaultColorBox.move(i * 20, 0) for i in range(len(availableColors))]
for i, color in enumerate(availableColors):
if color == c.white:
pygame.draw.rect(inputScreen, c.black, colorBoxes[i], 1)
else:
pygame.draw.rect(inputScreen, color, colorBoxes[i], 0)
pygame.display.flip()
chosenBox = get_rect_from_player(None, colorBoxes)
playerColor = availableColors.pop(colorBoxes.index(chosenBox))
playerList.append(p.Player(playerName, playerColor, playerIsAI))
pygame.quit()
return playerList