bot now has normal movements, fix colisions when ball is perfectly straight
This commit is contained in:
@ -6,7 +6,7 @@
|
|||||||
# By: tomoron <tomoron@student.42.fr> +#+ +:+ +#+ #
|
# By: tomoron <tomoron@student.42.fr> +#+ +:+ +#+ #
|
||||||
# +#+#+#+#+#+ +#+ #
|
# +#+#+#+#+#+ +#+ #
|
||||||
# Created: 2024/10/06 03:24:10 by tomoron #+# #+# #
|
# Created: 2024/10/06 03:24:10 by tomoron #+# #+# #
|
||||||
# Updated: 2024/10/08 10:00:22 by tomoron ### ########.fr #
|
# Updated: 2024/10/09 09:02:37 by tomoron ### ########.fr #
|
||||||
# #
|
# #
|
||||||
# **************************************************************************** #
|
# **************************************************************************** #
|
||||||
|
|
||||||
@ -27,7 +27,7 @@ class Ball:
|
|||||||
self.vel[1] = -self.vel[1]
|
self.vel[1] = -self.vel[1]
|
||||||
|
|
||||||
def default(self):
|
def default(self):
|
||||||
self.pos = [0, 0]
|
self.pos = [-1, 1]
|
||||||
self.up = False
|
self.up = False
|
||||||
self.vel = [0, 0]
|
self.vel = [0, 0]
|
||||||
self.speed = GameSettings.startSpeed
|
self.speed = GameSettings.startSpeed
|
||||||
@ -35,41 +35,34 @@ class Ball:
|
|||||||
def setObstacles(self, obstacles):
|
def setObstacles(self, obstacles):
|
||||||
self.obstacles = obstacles
|
self.obstacles = obstacles
|
||||||
|
|
||||||
def solve_quadratic(self, a, b, c):
|
|
||||||
disc = (b ** 2) - (4 * a * c)
|
|
||||||
if(disc < 0):
|
|
||||||
return None
|
|
||||||
res = (((-b) + math.sqrt(disc)) / ( 2 * a )) + (((-b) - math.sqrt(disc)) / ( 2 * a ))
|
|
||||||
return(res / 2)
|
|
||||||
|
|
||||||
def check_jumper_colision(self, jumper):
|
def jumperCollisionDistanceX(self, jumper):
|
||||||
jpos = (jumper["pos"]["x"], jumper["pos"]["z"])
|
jpos = (jumper["pos"]["x"], jumper["pos"]["z"])
|
||||||
pos1 = self.pos
|
pos1 = self.pos
|
||||||
pos2 = self.pos[0] + self.vel[0], self.pos[1] + self.vel[1]
|
pos2 = self.pos[0] + self.vel[0], self.pos[1] + self.vel[1]
|
||||||
slope = 0
|
slope = 0
|
||||||
if(pos1[0] - pos2[0] == 0):
|
slope = (pos1[1] - pos2[1])/(pos1[0] - pos2[0])
|
||||||
slope=100
|
|
||||||
else:
|
|
||||||
slope = (pos1[1] - pos2[1])/(pos1[0] - pos2[0])
|
|
||||||
offset = pos1[1] - (slope * pos1[0])
|
offset = pos1[1] - (slope * pos1[0])
|
||||||
|
|
||||||
#salagadou la menchikabou la bibidi bobidi bou
|
#salagadou la menchikabou la bibidi bobidi bou
|
||||||
a = 1 + (slope ** 2)
|
a = 1 + (slope ** 2)
|
||||||
b = ((-jpos[0]) * 2) + (2 * (slope * (-jpos[1] + offset)))
|
b = ((-jpos[0]) * 2) + (2 * (slope * (-jpos[1] + offset)))
|
||||||
c = (((-jpos[0]) ** 2) + (((-jpos[1]) + offset) ** 2)) - (GameSettings.jumperRadius ** 2)
|
c = (((-jpos[0]) ** 2) + (((-jpos[1]) + offset) ** 2)) - (GameSettings.jumperRadius ** 2)
|
||||||
return(self.solve_quadratic(a, b ,c))
|
|
||||||
|
|
||||||
def check_wall_colision(self, wall):
|
disc = (b ** 2) - (4 * a * c)
|
||||||
|
if(disc < 0):
|
||||||
|
return None
|
||||||
|
res = (((-b) + math.sqrt(disc)) / ( 2 * a )) + (((-b) - math.sqrt(disc)) / ( 2 * a ))
|
||||||
|
return(res / 2)
|
||||||
|
|
||||||
|
def wallColisionDistanceX(self, wall):
|
||||||
wpos = wall["pos"]["x"]
|
wpos = wall["pos"]["x"]
|
||||||
pos1 = self.pos
|
pos1 = self.pos
|
||||||
pos2 = self.pos[0] +self.vel[0], self.pos[1] + self.vel[1]
|
pos2 = self.pos[0] +self.vel[0], self.pos[1] + self.vel[1]
|
||||||
slope = 0
|
slope = 0
|
||||||
if(abs(pos1[1]) <= (GameSettings.wallWidth / 2) + GameSettings.ballRadius):
|
if(abs(pos1[1]) <= (GameSettings.wallWidth / 2) + GameSettings.ballRadius):
|
||||||
return(None)
|
return(None)
|
||||||
if(pos1[0] - pos2[0] == 0):
|
slope = (pos1[1] - pos2[1])/(pos1[0] - pos2[0])
|
||||||
slope=100
|
|
||||||
else:
|
|
||||||
slope = (pos1[1] - pos2[1])/(pos1[0] - pos2[0])
|
|
||||||
offset = pos1[1] - (slope * pos1[0])
|
offset = pos1[1] - (slope * pos1[0])
|
||||||
|
|
||||||
if(slope == 0):
|
if(slope == 0):
|
||||||
@ -84,16 +77,16 @@ class Ball:
|
|||||||
return(hitPos)
|
return(hitPos)
|
||||||
return(None)
|
return(None)
|
||||||
|
|
||||||
def check_collision_obstacles(self):
|
def colisionTimeX(self):
|
||||||
min_time = -1
|
min_time = -1
|
||||||
for x in self.obstacles:
|
for x in self.obstacles:
|
||||||
if x["isUp"] != self.up:
|
if x["isUp"] != self.up:
|
||||||
continue
|
continue
|
||||||
pos = None
|
pos = None
|
||||||
if x["type"] == 1:
|
if x["type"] == 1:
|
||||||
pos = self.check_jumper_colision(x)
|
pos = self.jumperCollisionDistanceX(x)
|
||||||
elif x["type"] == 2:
|
elif x["type"] == 2:
|
||||||
pos = self.check_wall_colision(x)
|
pos = self.wallColisionDistanceX(x)
|
||||||
if(pos == None):
|
if(pos == None):
|
||||||
continue
|
continue
|
||||||
dist = pos - self.pos[0]
|
dist = pos - self.pos[0]
|
||||||
@ -103,13 +96,17 @@ class Ball:
|
|||||||
else:
|
else:
|
||||||
time = -1
|
time = -1
|
||||||
if(time > 0):
|
if(time > 0):
|
||||||
if(min_time == -1):
|
if(min_time < 0):
|
||||||
min_time = time
|
min_time = time
|
||||||
else:
|
else:
|
||||||
min_time = (min(min_time, time))
|
min_time = (min(min_time, time))
|
||||||
return(min_time)
|
|
||||||
|
|
||||||
def getTimeUntilColision(self, limitNeg, limitPos, position, velocity):
|
wallsTime = self.getTimeUntilWallColision("left","right", self.pos[0], self.vel[0])
|
||||||
|
if(wallsTime < 0):
|
||||||
|
return(min_time)
|
||||||
|
return(min(min_time, wallsTime))
|
||||||
|
|
||||||
|
def getTimeUntilWallColision(self, limitNeg, limitPos, position, velocity):
|
||||||
if(not velocity):
|
if(not velocity):
|
||||||
return(-1)
|
return(-1)
|
||||||
limit = GameSettings.limits[limitNeg] if velocity < 0 else GameSettings.limits[limitPos]
|
limit = GameSettings.limits[limitNeg] if velocity < 0 else GameSettings.limits[limitPos]
|
||||||
@ -117,17 +114,64 @@ class Ball:
|
|||||||
colision_time = wallDistance / abs(velocity)
|
colision_time = wallDistance / abs(velocity)
|
||||||
return(colision_time)
|
return(colision_time)
|
||||||
|
|
||||||
|
def wallColisionDistanceY(self, wall):
|
||||||
|
wallSide = (GameSettings.wallWidth / 2) + GameSettings.ballRadius
|
||||||
|
if(self.pos[1] < 0):
|
||||||
|
wallSide *= -1
|
||||||
|
relPos = wall["pos"]["x"] - self.pos[0]
|
||||||
|
if(abs(relPos) < (GameSettings.wallLength / 2) + GameSettings.ballRadius):
|
||||||
|
return(wallSide)
|
||||||
|
return(None)
|
||||||
|
|
||||||
|
def jumperColisionDistanceY(self, jumper):
|
||||||
|
relPos = jumper["pos"]["x"] - self.pos[0]
|
||||||
|
if(abs(relPos) <= GameSettings.jumperRadius):
|
||||||
|
return(jumper["pos"]["z"])
|
||||||
|
return(None)
|
||||||
|
|
||||||
|
|
||||||
|
def colisionTimeY(self, checkObstacles):
|
||||||
|
wallsTime = self.getTimeUntilWallColision("back","front", self.pos[1], self.vel[1])
|
||||||
|
if(not checkObstacles):
|
||||||
|
return(wallsTime)
|
||||||
|
|
||||||
|
min_time = -1
|
||||||
|
for x in self.obstacles:
|
||||||
|
if x["isUp"] != self.up:
|
||||||
|
continue
|
||||||
|
pos = None
|
||||||
|
if x["type"] == 1:
|
||||||
|
pos = self.jumperColisionDistanceY(x)
|
||||||
|
elif x["type"] == 2:
|
||||||
|
pos = self.wallColisionDistanceY(x)
|
||||||
|
if(pos == None):
|
||||||
|
continue
|
||||||
|
dist = pos - self.pos[1]
|
||||||
|
time = 0
|
||||||
|
if(self.vel[1] != 0):
|
||||||
|
time = dist / self.vel[1]
|
||||||
|
else:
|
||||||
|
time = -1
|
||||||
|
if(time > 0):
|
||||||
|
if(min_time < 0):
|
||||||
|
min_time = time
|
||||||
|
else:
|
||||||
|
min_time = (min(min_time, time))
|
||||||
|
if(min_time < 0):
|
||||||
|
return(wallsTime)
|
||||||
|
return(min(wallsTime,min_time))
|
||||||
|
|
||||||
def getSleepTime(self):
|
def getSleepTime(self):
|
||||||
time_x = self.getTimeUntilColision("left","right", self.pos[0], self.vel[0])
|
try:
|
||||||
time_z = self.getTimeUntilColision("back","front", self.pos[1], self.vel[1])
|
timeX = self.colisionTimeX()
|
||||||
time_objects = self.check_collision_obstacles()
|
except ZeroDivisionError:
|
||||||
if(time_objects != -1):
|
timeX = -1
|
||||||
time_x = min(time_x, time_objects)
|
timeY = self.colisionTimeY(timeX < 0)
|
||||||
if(time_x == -1):
|
if(timeX < 0):
|
||||||
return(time_z)
|
return(timeY)
|
||||||
if(time_z == -1):
|
if(timeY < 0):
|
||||||
return(time_x)
|
return(timeX)
|
||||||
return(min(time_x, time_z))
|
return(min(timeX, timeY))
|
||||||
|
|
||||||
def getPlayerDistance(self, player, ballPos):
|
def getPlayerDistance(self, player, ballPos):
|
||||||
playerPos = player["pos"]
|
playerPos = player["pos"]
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
# By: tomoron <tomoron@student.42.fr> +#+ +:+ +#+ #
|
# By: tomoron <tomoron@student.42.fr> +#+ +:+ +#+ #
|
||||||
# +#+#+#+#+#+ +#+ #
|
# +#+#+#+#+#+ +#+ #
|
||||||
# Created: 2024/10/05 03:54:20 by tomoron #+# #+# #
|
# Created: 2024/10/05 03:54:20 by tomoron #+# #+# #
|
||||||
# Updated: 2024/10/08 10:20:50 by tomoron ### ########.fr #
|
# Updated: 2024/10/09 07:24:54 by tomoron ### ########.fr #
|
||||||
# #
|
# #
|
||||||
# **************************************************************************** #
|
# **************************************************************************** #
|
||||||
|
|
||||||
@ -15,6 +15,7 @@ from .Player import Player
|
|||||||
from .DummySocket import DummySocket
|
from .DummySocket import DummySocket
|
||||||
from .GameSettings import GameSettings
|
from .GameSettings import GameSettings
|
||||||
import asyncio
|
import asyncio
|
||||||
|
import time
|
||||||
|
|
||||||
class Bot(Player):
|
class Bot(Player):
|
||||||
def __init__(self, game):
|
def __init__(self, game):
|
||||||
@ -22,8 +23,10 @@ class Bot(Player):
|
|||||||
self.game = game
|
self.game = game
|
||||||
self.ready = True
|
self.ready = True
|
||||||
self.pos = {"pos":0, "up": False}
|
self.pos = {"pos":0, "up": False}
|
||||||
|
self.objective = {"pos":0, "up": False}
|
||||||
self.skin = 0
|
self.skin = 0
|
||||||
asyncio.create_task(self.updateLoop())
|
#asyncio.create_task(self.updateLoop())
|
||||||
|
#asyncio.create_task(self.goToObjectiveLoop())
|
||||||
print("I am a bot, boop boop beep boop")
|
print("I am a bot, boop boop beep boop")
|
||||||
|
|
||||||
def createTempBall(self):
|
def createTempBall(self):
|
||||||
@ -44,13 +47,26 @@ class Bot(Player):
|
|||||||
hit = await tempBall.update(sleepTime, self, self.game.p2, True)
|
hit = await tempBall.update(sleepTime, self, self.game.p2, True)
|
||||||
i += 1
|
i += 1
|
||||||
if(i == 50):
|
if(i == 50):
|
||||||
print("too many bounces")
|
return
|
||||||
return;
|
self.objective = {"pos":tempBall.pos[0], "up":tempBall.up}
|
||||||
print("p1 hit at :", tempBall.pos[0])
|
|
||||||
self.game.move(self.socket, tempBall.pos[0], tempBall.up)
|
|
||||||
|
|
||||||
async def updateLoop(self):
|
async def updateLoop(self):
|
||||||
while not self.game.end:
|
while not self.game.end:
|
||||||
pos = await self.getExpectedPos()
|
await self.getExpectedPos()
|
||||||
await asyncio.sleep(1)
|
await asyncio.sleep(1)
|
||||||
|
|
||||||
|
async def goToObjectiveLoop(self):
|
||||||
|
lastUpdate = time.time()
|
||||||
|
while not self.game.end:
|
||||||
|
if(self.pos["pos"] != self.objective["pos"] or self.pos["up"] != self.objective["up"]):
|
||||||
|
self.pos["up"] = self.objective["up"]
|
||||||
|
|
||||||
|
maxDistance = GameSettings.maxPlayerSpeed * (time.time() - lastUpdate)
|
||||||
|
lastUpdate = time.time()
|
||||||
|
travel = self.objective["pos"] - self.pos["pos"]
|
||||||
|
if(travel >= 0):
|
||||||
|
travel = min(self.objective["pos"] - self.pos["pos"], GameSettings.maxPlayerSpeed)
|
||||||
|
else:
|
||||||
|
travel = max(self.objective["pos"] - self.pos["pos"], -GameSettings.maxPlayerSpeed)
|
||||||
|
self.game.move(self.socket, self.pos["pos"] + travel, self.pos["up"])
|
||||||
|
await asyncio.sleep(1 / 20)
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
# By: tomoron <marvin@42.fr> +#+ +:+ +#+ #
|
# By: tomoron <marvin@42.fr> +#+ +:+ +#+ #
|
||||||
# +#+#+#+#+#+ +#+ #
|
# +#+#+#+#+#+ +#+ #
|
||||||
# Created: 2024/10/08 07:33:29 by tomoron #+# #+# #
|
# Created: 2024/10/08 07:33:29 by tomoron #+# #+# #
|
||||||
# Updated: 2024/10/08 08:25:06 by tomoron ### ########.fr #
|
# Updated: 2024/10/09 07:03:46 by tomoron ### ########.fr #
|
||||||
# #
|
# #
|
||||||
# **************************************************************************** #
|
# **************************************************************************** #
|
||||||
|
|
||||||
@ -15,6 +15,7 @@ class DummySocket:
|
|||||||
self.id = 0
|
self.id = 0
|
||||||
self.username = "bot"
|
self.username = "bot"
|
||||||
self.game = game
|
self.game = game
|
||||||
|
self.pfp = "/static/img/robot_pfp.jpg"
|
||||||
|
|
||||||
def sync_send(*args):
|
def sync_send(*args):
|
||||||
pass
|
pass
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
# By: edbernar <edbernar@student.42angouleme. +#+ +:+ +#+ #
|
# By: edbernar <edbernar@student.42angouleme. +#+ +:+ +#+ #
|
||||||
# +#+#+#+#+#+ +#+ #
|
# +#+#+#+#+#+ +#+ #
|
||||||
# Created: 2024/09/13 16:20:58 by tomoron #+# #+# #
|
# Created: 2024/09/13 16:20:58 by tomoron #+# #+# #
|
||||||
# Updated: 2024/10/08 17:44:34 by edbernar ### ########.fr #
|
# Updated: 2024/10/09 07:06:00 by tomoron ### ########.fr #
|
||||||
# #
|
# #
|
||||||
# **************************************************************************** #
|
# **************************************************************************** #
|
||||||
|
|
||||||
@ -42,7 +42,7 @@ class Game:
|
|||||||
self.lastWin = 2
|
self.lastWin = 2
|
||||||
|
|
||||||
self.opponentLock = opponent
|
self.opponentLock = opponent
|
||||||
if(withBot):
|
if(1 or withBot):
|
||||||
self.p1 = Bot(self)
|
self.p1 = Bot(self)
|
||||||
self.join(socket, skinId)
|
self.join(socket, skinId)
|
||||||
elif(opponent != None):
|
elif(opponent != None):
|
||||||
@ -73,7 +73,7 @@ class Game:
|
|||||||
|
|
||||||
def genObstacles(self):
|
def genObstacles(self):
|
||||||
for x in GameSettings.wallsPos:
|
for x in GameSettings.wallsPos:
|
||||||
if random.randint(1, 100) < 70:
|
if random.randint(1, 100) < 100:
|
||||||
self.obstacles.append(x)
|
self.obstacles.append(x)
|
||||||
i = 0
|
i = 0
|
||||||
down = False
|
down = False
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
# By: tomoron <tomoron@student.42.fr> +#+ +:+ +#+ #
|
# By: tomoron <tomoron@student.42.fr> +#+ +:+ +#+ #
|
||||||
# +#+#+#+#+#+ +#+ #
|
# +#+#+#+#+#+ +#+ #
|
||||||
# Created: 2024/10/06 16:33:56 by tomoron #+# #+# #
|
# Created: 2024/10/06 16:33:56 by tomoron #+# #+# #
|
||||||
# Updated: 2024/10/06 16:34:24 by tomoron ### ########.fr #
|
# Updated: 2024/10/09 07:03:19 by tomoron ### ########.fr #
|
||||||
# #
|
# #
|
||||||
# **************************************************************************** #
|
# **************************************************************************** #
|
||||||
|
|
||||||
@ -52,3 +52,5 @@ class GameSettings:
|
|||||||
wallWidth = 0.05
|
wallWidth = 0.05
|
||||||
bounceSpeedIncrease = 0.2
|
bounceSpeedIncrease = 0.2
|
||||||
maxScore = 5
|
maxScore = 5
|
||||||
|
|
||||||
|
maxPlayerSpeed = 0.4
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
# By: tomoron <tomoron@student.42.fr> +#+ +:+ +#+ #
|
# By: tomoron <tomoron@student.42.fr> +#+ +:+ +#+ #
|
||||||
# +#+#+#+#+#+ +#+ #
|
# +#+#+#+#+#+ +#+ #
|
||||||
# Created: 2024/09/09 16:10:26 by tomoron #+# #+# #
|
# Created: 2024/09/09 16:10:26 by tomoron #+# #+# #
|
||||||
# Updated: 2024/10/04 17:10:39 by tomoron ### ########.fr #
|
# Updated: 2024/10/09 00:53:25 by tomoron ### ########.fr #
|
||||||
# #
|
# #
|
||||||
# **************************************************************************** #
|
# **************************************************************************** #
|
||||||
|
|
||||||
@ -24,6 +24,9 @@ from .gameActions.ping import ping
|
|||||||
# 1 : opponent : tell the client the name of the opponent
|
# 1 : opponent : tell the client the name of the opponent
|
||||||
# - id : 0 if it's a bot
|
# - id : 0 if it's a bot
|
||||||
# - username
|
# - username
|
||||||
|
# - skin : id of the skin
|
||||||
|
# - opponentSkin : eddy is wierd
|
||||||
|
# - selfSkin : eddy is wierd
|
||||||
#
|
#
|
||||||
# 2 : go : the game started
|
# 2 : go : the game started
|
||||||
#
|
#
|
||||||
|
BIN
docker-compose/requirements/nginx/static/img/robot_pfp.jpg
Normal file
BIN
docker-compose/requirements/nginx/static/img/robot_pfp.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 816 KiB |
Reference in New Issue
Block a user