-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathgreedy_agent.py
227 lines (182 loc) · 6.54 KB
/
greedy_agent.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
# small network game that has differnt blobs
# moving around the screen
from asyncio.windows_events import NULL
import contextlib
from distutils.command.build_scripts import first_line_re
from turtle import distance
with contextlib.redirect_stdout(None):
import pygame
from client import Network
import random
import os
import math
pygame.font.init()
# Constants
PLAYER_RADIUS = 10
START_VEL = 9
BALL_RADIUS = 5
AGENT_RANGE_SIGHT = 800
W, H = 1600, 830
NAME_FONT = pygame.font.SysFont("comicsans", 20)
TIME_FONT = pygame.font.SysFont("comicsans", 30)
SCORE_FONT = pygame.font.SysFont("comicsans", 26)
COLORS = [(255,0,0), (255, 128, 0), (255,255,0), (128,255,0),(0,255,0),(0,255,128),(0,255,255),(0, 128, 255), (0,0,255), (0,0,255), (128,0,255),(255,0,255), (255,0,128),(128,128,128), (0,0,0)]
# Dynamic Variables
players = {}
balls = []
# FUNCTIONS
def convert_time(t):
"""
converts a time given in seconds to a time in
minutes
:param t: int
:return: string
"""
if type(t) == str:
return t
if int(t) < 60:
return str(t) + "s"
else:
minutes = str(t // 60)
seconds = str(t % 60)
if int(seconds) < 10:
seconds = "0" + seconds
return minutes + ":" + seconds
def redraw_window(players, balls, game_time, score):
"""
draws each frame
:return: None
"""
WIN.fill((255,255,255)) # fill screen white, to clear old frames
# draw all the orbs/balls
for ball in balls:
pygame.draw.circle(WIN, ball[2], (ball[0], ball[1]), BALL_RADIUS)
# draw each player in the list
for player in sorted(players, key=lambda x: players[x]["score"]):
p = players[player]
pygame.draw.circle(WIN, p["color"], (p["x"], p["y"]), PLAYER_RADIUS + round(p["score"]))
pygame.draw.circle(WIN, (255,0,0) , (p["x"], p["y"]), AGENT_RANGE_SIGHT + round(p["score"]),2)
# render and draw name for each player
text = NAME_FONT.render(p["name"], 1, (0,0,0))
WIN.blit(text, (p["x"] - text.get_width()/2, p["y"] - text.get_height()/2))
# draw scoreboard
sort_players = list(reversed(sorted(players, key=lambda x: players[x]["score"])))
title = TIME_FONT.render("Scoreboard", 1, (0,0,0))
start_y = 25
x = W - title.get_width() - 10
WIN.blit(title, (x, 5))
ran = min(len(players), 3)
for count, i in enumerate(sort_players[:ran]):
text = SCORE_FONT.render(str(count+1) + ". " + str(players[i]["name"]), 1, (0,0,0))
WIN.blit(text, (x, start_y + count * 20))
# draw time
text = TIME_FONT.render("Time: " + convert_time(game_time), 1, (0,0,0))
WIN.blit(text,(10,10))
# draw score
text = TIME_FONT.render("Score: " + str(round(score)),1,(0,0,0))
WIN.blit(text,(10,15 + text.get_height()))
def main(name):
"""
function for running the game,
includes the main loop of the game
:param players: a list of dicts represting a player
:return: None
"""
global players
# start by connecting to the network
server = Network()
current_id = server.connect(name)
balls, players, game_time = server.send("get")
# setup the clock, limit to 30fps
clock = pygame.time.Clock()
mode = 0 #mode 0 = eating , 1 = hunting, 2 = escapando
run = True
while run:
if balls == []:
break
clock.tick(30) # 30 fps max
player = players[current_id]
enemies = players
del enemies[current_id]
vel = START_VEL - round(player["score"]/14)
if vel <= 1:
vel = 1
# get key presses
keys = pygame.key.get_pressed()
'''
Part of my implementation of a simple agar bot that follows pelet
'''
ball_candidates = {}
for enemy in enemies:
enemy = enemies[enemy]
dist = math.sqrt((enemy["x"] - player["x"])**2 + (enemy["y"]-player["y"])**2)
if dist <= AGENT_RANGE_SIGHT + player["score"]:
if enemy["score"] < player["score"]: #HUNTING MODE
mode = 1
if enemy["x"] - player["x"] > 0 and player["x"] - vel - PLAYER_RADIUS - player["score"] >= 0:
player["x"] = player["x"] + vel
elif enemy["x"] - player["x"] < 0 and player["x"] + vel + PLAYER_RADIUS + player["score"] <= W:
player["x"] = player["x"] - vel
if enemy["y"] - player["y"] > 0 and player["y"] - vel - PLAYER_RADIUS - player["score"] >= 0:
player["y"] = player["y"] + vel
elif enemy["y"] - player["y"] < 0 and player["y"] + vel + PLAYER_RADIUS + player["score"] <= H:
player["y"] = player["y"] - vel
break
else: #ESCAPING MODE
mode = 2
if enemy["x"] - player["x"] > 0 and player["x"] - vel - PLAYER_RADIUS - player["score"] >= 0:
player["x"] = player["x"] - vel
elif enemy["x"] - player["x"] < 0 and player["x"] + vel + PLAYER_RADIUS + player["score"] <= W:
player["x"] = player["x"] + vel
if enemy["y"] - player["y"] > 0 and player["y"] - vel - PLAYER_RADIUS - player["score"] >= 0:
player["y"] = player["y"] - vel
elif enemy["y"] - player["y"] < 0 and player["y"] + vel + PLAYER_RADIUS + player["score"] <= H:
player["y"] = player["y"] + vel
break
else:
mode = 0
if mode == 0:
for ball in balls:
dist = math.sqrt((ball[0] - player["x"])**2 + (ball[1]-player["y"])**2)
ball_candidates[ball] = dist
if ball_candidates:
next_ball = min(ball_candidates, key=ball_candidates.get)
if next_ball[0] - player["x"] > 0 and player["x"] - vel - PLAYER_RADIUS - player["score"] >= -100:
player["x"] = player["x"] + vel
elif next_ball[0] - player["x"] < 0 and player["x"] + vel + PLAYER_RADIUS + player["score"] <= W + 100:
player["x"] = player["x"] - vel
if next_ball[1] - player["y"] > 0 and player["y"] - vel - PLAYER_RADIUS - player["score"] >= -100:
player["y"] = player["y"] + vel
elif next_ball[1] - player["y"] < 0 and player["y"] + vel + PLAYER_RADIUS + player["score"] <= H + 100:
player["y"] = player["y"] - vel
#####################3
data = ""
data = "move " + str(player["x"]) + " " + str(player["y"])
# send data to server and recieve back all players information
balls, players, game_time = server.send(data)
for event in pygame.event.get():
# if user hits red x button close window
if event.type == pygame.QUIT:
run = False
if event.type == pygame.KEYDOWN:
# if user hits a escape key close program
if event.key == pygame.K_ESCAPE:
run = False
# redraw window then update the frame
redraw_window(players, balls, game_time, player["score"])
pygame.display.update()
print("\n\n")
print("Tiempo del agente: " , game_time)
print("\n\n")
server.disconnect()
pygame.quit()
quit()
# get users name
name = "Agent_V1"
# make window start in top left hand corner
os.environ['SDL_VIDEO_WINDOW_POS'] = "%d,%d" % (0,30)
# setup pygame window
WIN = pygame.display.set_mode((W,H))
pygame.display.set_caption("Blobs")
# start game
main(name)