bot can now calculate where the ball is going to hit it's side

This commit is contained in:
2024-10-08 10:51:22 +02:00
parent 5fb0870c95
commit 7401ea3c17
5 changed files with 115 additions and 58 deletions

View File

@ -6,7 +6,7 @@
# By: tomoron <tomoron@student.42.fr> +#+ +:+ +#+ #
# +#+#+#+#+#+ +#+ #
# Created: 2024/10/06 03:24:10 by tomoron #+# #+# #
# Updated: 2024/10/06 17:22:46 by tomoron ### ########.fr #
# Updated: 2024/10/08 10:00:22 by tomoron ### ########.fr #
# #
# **************************************************************************** #
@ -65,7 +65,6 @@ class Ball:
pos2 = self.pos[0] +self.vel[0], self.pos[1] + self.vel[1]
slope = 0
if(abs(pos1[1]) <= (GameSettings.wallWidth / 2) + GameSettings.ballRadius):
print("inside")
return(None)
if(pos1[0] - pos2[0] == 0):
slope=100
@ -80,13 +79,9 @@ class Ball:
if(pos1[1] < 0):
wallSide *= -1
hitPos = (wallSide - offset) / slope
print(f'{hitPos=}')
relPos = wpos - hitPos
print("relative position : ", relPos)
print("max colision : ", (GameSettings.wallLength / 2) + GameSettings.ballRadius)
if(abs(relPos) < (GameSettings.wallLength / 2) + GameSettings.ballRadius):
return(hitPos)
print("not in wall 1")
return(None)
def check_collision_obstacles(self):
@ -141,24 +136,26 @@ class Ball:
def twoPointsDistance(self, pos1, pos2):
return(math.sqrt(((pos2[0] - pos1[0]) ** 2) + ((pos2[1] - pos1[1]) ** 2)))
def checkJumpersDistance(self, ballPos, p1, p2):
def checkJumpersDistance(self, ballPos, p1, p2, noMsg):
for i in range(0, len(self.obstacles)):
if(self.obstacles[i]["type"] != 1):
continue;
continue
if(self.obstacles[i]["isUp"] != self.up):
continue
if(self.twoPointsDistance((self.obstacles[i]["pos"]["x"], self.obstacles[i]["pos"]["z"]), ballPos) < GameSettings.jumperRadius):
if(p1.socket != None and not noMsg):
p1.socket.sync_send({"type":"game", "content":{"action":8,"name":self.obstacles[i]["name"]}})
if(p2.socket != None and not noMsg):
p2.socket.sync_send({"type":"game", "content":{"action":8,"name":self.obstacles[i]["name"]}})
self.up = not self.up
def checkWallsColision(self, ballPos):
for i in range(0, len(self.obstacles)):
if(self.obstacles[i]["type"] != 2):
continue;
continue
if(self.obstacles[i]["isUp"] != self.up):
continue;
if(abs(ballPos[1]) <= (GameSettings.wallWidth / 2) + GameSettings.ballRadius):
continue
if(abs(ballPos[1]) <= (GameSettings.wallWidth / 2) + GameSettings.ballRadius + 0.001):
if(abs(self.obstacles[i]["pos"]["x"] - ballPos[0]) < (GameSettings.wallLength / 2) + GameSettings.ballRadius):
return(True)
return(False)
@ -168,28 +165,31 @@ class Ball:
self.vel[1] += (GameSettings.bounceSpeedIncrease * (self.vel[1] / self.speed))
self.speed += GameSettings.bounceSpeedIncrease
async def update(self, delta, p1, p2):
print("AAAAAAAAAAAAAAAAAAAAAAA update")
async def update(self, delta, p1, p2, p1Hit = False):
self.pos[0] += (delta * self.vel[0])
self.pos[1] += (delta * self.vel[1])
if(self.pos[1] <= GameSettings.limits["back"] or self.pos[1] >= GameSettings.limits["front"]):
if(self.pos[1] <= GameSettings.limits["back"] + 0.001 or self.pos[1] >= GameSettings.limits["front"] - 0.001):
player = p2.pos if self.pos[1] < 0 else p1.pos
if(self.pos[1] > 0 and p1Hit):
return(1)
playerDistance = self.getPlayerDistance(player, self.pos)
if(playerDistance >= -(GameSettings.playerLength / 2) and playerDistance <= GameSettings.playerLength / 2 and player["up"] == self.up):
self.vel[0] = -((self.speed * 0.80) * (playerDistance / (GameSettings.playerLength / 2)))
self.vel[1] = self.speed - abs(self.vel[0])
if(self.pos[1] > 0):
self.vel[1] = -self.vel[1]
if(p1.socket != None and not p1Hit):
p1.socket.sync_send({"type":"game","content":{"action":4, "is_opponent": self.pos[1] < 0}})
if(p2.socket != None and not p1Hit):
p2.socket.sync_send({"type":"game","content":{"action":4, "is_opponent": self.pos[1] > 0}})
else:
elif(not p1Hit):
return(1 if self.pos[1] < 0 else 2)
elif(self.pos[0] <= GameSettings.limits["left"] or self.pos[0] >= GameSettings.limits["right"]):
else:
return(0)
elif(self.pos[0] <= GameSettings.limits["left"] + 0.001 or self.pos[0] >= GameSettings.limits["right"] - 0.001):
self.vel[0] = -self.vel[0]
elif(self.checkWallsColision(self.pos)):
self.vel[1] = -self.vel[1]
self.checkJumpersDistance(self.pos, p1, p2)
self.checkJumpersDistance(self.pos, p1, p2, p1Hit)
self.increaseSpeed()
return(0)
#AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAa

View File

@ -6,10 +6,51 @@
# By: tomoron <tomoron@student.42.fr> +#+ +:+ +#+ #
# +#+#+#+#+#+ +#+ #
# Created: 2024/10/05 03:54:20 by tomoron #+# #+# #
# Updated: 2024/10/05 03:55:31 by tomoron ### ########.fr #
# Updated: 2024/10/08 10:20:50 by tomoron ### ########.fr #
# #
# **************************************************************************** #
from .Ball import Ball
from .Player import Player
from .DummySocket import DummySocket
from .GameSettings import GameSettings
import asyncio
class Bot(Player):
def __init__(self):
print("I am a bot boop boop beep boop")
def __init__(self, game):
self.socket = DummySocket(game)
self.game = game
self.ready = True
self.pos = {"pos":0, "up": False}
self.skin = 0
asyncio.create_task(self.updateLoop())
print("I am a bot, boop boop beep boop")
def createTempBall(self):
res = Ball()
res.setObstacles(self.game.obstacles)
res.vel = self.game.ball.vel.copy()
res.pos = self.game.ball.pos.copy()
res.up = self.game.ball.up
res.speed = self.game.ball.speed
return(res)
async def getExpectedPos(self):
tempBall = self.createTempBall()
hit = 0
i = 0
while(not hit):
sleepTime = tempBall.getSleepTime()
hit = await tempBall.update(sleepTime, self, self.game.p2, True)
i += 1
if(i == 50):
print("too many bounces")
return;
print("p1 hit at :", tempBall.pos[0])
self.game.move(self.socket, tempBall.pos[0], tempBall.up)
async def updateLoop(self):
while not self.game.end:
pos = await self.getExpectedPos()
await asyncio.sleep(1)

View File

@ -0,0 +1,23 @@
# **************************************************************************** #
# #
# ::: :::::::: #
# DummySocket.py :+: :+: :+: #
# +:+ +:+ +:+ #
# By: tomoron <marvin@42.fr> +#+ +:+ +#+ #
# +#+#+#+#+#+ +#+ #
# Created: 2024/10/08 07:33:29 by tomoron #+# #+# #
# Updated: 2024/10/08 08:25:06 by tomoron ### ########.fr #
# #
# **************************************************************************** #
class DummySocket:
def __init__(self, game):
self.id = 0
self.username = "bot"
self.game = game
def sync_send(*args):
pass
def sendError(*args):
pass

View File

@ -6,7 +6,7 @@
# By: edbernar <edbernar@student.42angouleme. +#+ +:+ +#+ #
# +#+#+#+#+#+ +#+ #
# Created: 2024/09/13 16:20:58 by tomoron #+# #+# #
# Updated: 2024/10/06 17:40:23 by tomoron ### ########.fr #
# Updated: 2024/10/08 10:50:47 by tomoron ### ########.fr #
# #
# **************************************************************************** #
@ -14,6 +14,7 @@ from asgiref.sync import sync_to_async
from .Player import Player
from .models import GameResults, User
from .GameSettings import GameSettings
from .Bot import Bot
from .Ball import Ball
import time
import json
@ -22,7 +23,6 @@ import random
import math
class Game:
waitingForPlayerLock = False
waitingForPlayer = None
def __init__(self, socket, withBot, skinId = 0, opponent = None):
@ -43,10 +43,11 @@ class Game:
self.opponentLock = opponent
if(withBot):
self.p1 = Bot(self)
self.join(socket, skinId)
elif(opponent != None):
if(opponent not in socket.onlinePlayers):
return;
return
opponentGame = socket.onlinePlayers[opponent].game
if (opponentGame != None and opponentGame.opponentLock != None and opponentGame.opponentLock == socket.id):
socket.onlinePlayers[opponent].game.join(socket, skinId)
@ -54,9 +55,6 @@ class Game:
self.join(socket, skinId)
socket.onlinePlayers[opponent].sync_send({"type":"invitation","content":{"invitor":socket.id, "username":socket.username}})
else:
while(Game.waitingForPlayerLock):
continue
Game.waitingForPlayerLock = True
if(Game.waitingForPlayer == None):
Game.waitingForPlayer = self
socket.sync_send({"type":"game","content":{"action":0}})
@ -64,7 +62,6 @@ class Game:
else:
Game.waitingForPlayer.join(socket, skinId)
Game.waitingForPlayer = None
Game.waitingForPlayerLock = False
def __del__(self):
print("game destroy")
@ -107,7 +104,7 @@ class Game:
else:
if(self.opponentLock != None and self.opponentLock != socket.id):
socket.sendError("You are not invited to this game", 9103)
return;
return
print("joined game, set as player 2")
self.p2 = Player(socket, self)
self.p2.skin = skin
@ -146,13 +143,9 @@ class Game:
self.left = 1
else:
self.left = 2
while(Game.waitingForPlayerLock):
time.sleeep(0.05)
Game.waitingForPlayerLock = True
if(Game.waitingForPlayer == self):
Game.waitingForPlayer = None;
Game.waitingForPlayerLock = False
if(self.started):
Game.waitingForPlayer = None
if(self.p2 != None):
self.endGame(1 if self.left == 2 else 2)
self.end=True
@ -165,9 +158,9 @@ class Game:
opponent = self.p1.socket if socket != self.p1.socket else self.p2.socket
if(socket == self.p1.socket):
self.p1.pos["pos"] = pos
self.p1.pos["up"] = up;
self.p1.pos["up"] = up
else:
self.p2.pos["pos"] = -pos;
self.p2.pos["pos"] = -pos
self.p2.pos["up"] = up
if(opponent != None):
opponent.sync_send({"type":"game","content":{"action":3, "pos":-pos, "up":up, "is_opponent":True}})
@ -211,7 +204,7 @@ class Game:
self.prepareGame(True)
await asyncio.sleep(3)
self.prepareGame()
return;
return
def prepareGame(self, stop = False):
self.speed = GameSettings.startSpeed

View File

@ -6,7 +6,7 @@
# By: tomoron <tomoron@student.42.fr> +#+ +:+ +#+ #
# +#+#+#+#+#+ +#+ #
# Created: 2024/10/05 03:22:32 by tomoron #+# #+# #
# Updated: 2024/10/06 16:16:26 by tomoron ### ########.fr #
# Updated: 2024/10/08 07:47:31 by tomoron ### ########.fr #
# #
# **************************************************************************** #