mirror of
https://github.com/evgen-app/chess_rpg_backend.git
synced 2024-11-25 11:04:03 +03:00
updated movement logic and validation
This commit is contained in:
parent
79a4d75730
commit
86c35b3d02
|
@ -129,7 +129,7 @@ class Deck(models.Model):
|
|||
return self.get_heroes()
|
||||
|
||||
def score(self):
|
||||
return sum([x.attack + x.health + x.speed for x in self.get_heroes()])
|
||||
return sum([x.hero.attack + x.hero.health + x.hero.speed for x in self.get_heroes()])
|
||||
|
||||
class Meta:
|
||||
db_table = "deck"
|
||||
|
|
|
@ -5,6 +5,8 @@ import django
|
|||
from asgiref.sync import sync_to_async
|
||||
from channels.generic.websocket import AsyncWebsocketConsumer
|
||||
|
||||
from room.services.game_logic import move_handler
|
||||
|
||||
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "chess_backend.settings")
|
||||
django.setup()
|
||||
|
||||
|
@ -286,9 +288,16 @@ class RoomConsumer(BaseConsumer):
|
|||
await self.send_message("ERROR", message="data is not JSON serializable")
|
||||
|
||||
if data:
|
||||
if data["type"] == "start":
|
||||
if "type" not in data:
|
||||
await self.send_message("ERROR", message="incorrect data typing")
|
||||
elif data["type"] == "start":
|
||||
if not await self.start(data):
|
||||
await self.send_message("ERROR", message="opponent is offline")
|
||||
elif data["type"] == "move":
|
||||
if all(x in data for x in ["x", "y", "px", "py"]):
|
||||
await self.perform_move(data)
|
||||
else:
|
||||
await self.send_message("ERROR", message="incorrect data typing")
|
||||
|
||||
async def start(self, data):
|
||||
if self.scope["opponent_channel"] and self.scope["opponent_online"]:
|
||||
|
@ -302,6 +311,22 @@ class RoomConsumer(BaseConsumer):
|
|||
return True
|
||||
return False
|
||||
|
||||
async def perform_move(self, data):
|
||||
await move_handler(data["px"], data["py"], data["x"], data["y"], self.room_name, self.scope["player_in_room"])
|
||||
if self.scope["opponent_channel"] and self.scope["opponent_online"]:
|
||||
await self.channel_layer.send(
|
||||
self.scope["opponent_channel"],
|
||||
{
|
||||
"type": "move",
|
||||
"x": data["x"],
|
||||
"y": data["y"],
|
||||
"px": data["px"],
|
||||
"py": data["py"],
|
||||
},
|
||||
)
|
||||
return True
|
||||
return False
|
||||
|
||||
# info type group message handler
|
||||
async def info(self, event):
|
||||
message = event["message"]
|
||||
|
@ -327,13 +352,6 @@ class RoomConsumer(BaseConsumer):
|
|||
|
||||
await self.send(text_data=json.dumps(msg))
|
||||
|
||||
# Receive message from room group
|
||||
async def chat_message(self, event):
|
||||
message = event["message"]
|
||||
|
||||
# Send message to WebSocket
|
||||
await self.send(text_data=json.dumps({"lot": message}))
|
||||
|
||||
async def channel(self, event):
|
||||
channel = event["channel"]
|
||||
self.scope["opponent_channel"] = channel
|
||||
|
@ -352,6 +370,19 @@ class RoomConsumer(BaseConsumer):
|
|||
)
|
||||
self.scope["opponent_online"] = status
|
||||
|
||||
async def move(self, event):
|
||||
await self.send(
|
||||
text_data=json.dumps(
|
||||
{
|
||||
"type": "MOVE",
|
||||
"x": event["x"],
|
||||
"y": event["y"],
|
||||
"px": event["px"],
|
||||
"py": event["py"]
|
||||
}
|
||||
)
|
||||
)
|
||||
|
||||
async def check_origin(self):
|
||||
if not self.scope["player"]:
|
||||
await self.send(
|
||||
|
|
|
@ -1,25 +1,111 @@
|
|||
from asgiref.sync import sync_to_async
|
||||
|
||||
from room.models import HeroInGame, Room, PlayerInRoom
|
||||
|
||||
|
||||
def _check_move_position(x: int, y: int, room: Room, p_first: bool):
|
||||
hero = HeroInGame.objects.filter(x=x, y=y, room=room)
|
||||
if not hero.exists():
|
||||
def _check_path(f_x: int, f_y: int, x: int, y: int, room: Room, move_type: str):
|
||||
if move_type == "DIAGONAL":
|
||||
return HeroInGame.objects.filter(room=room, x__range=(f_x, x), y__range=(f_y, y)).count() == 0
|
||||
elif move_type == "HORIZONTAL":
|
||||
return HeroInGame.objects.filter(room=room, x=x, y__range=(f_y, y)).count() == 0
|
||||
elif move_type == "VERTICAL":
|
||||
return HeroInGame.objects.filter(room=room, x__range=(f_x, x), y=y).count() == 0
|
||||
return False
|
||||
|
||||
|
||||
def _validate_hero_movement(
|
||||
hero_type: str,
|
||||
prev_x: int,
|
||||
prev_y: int,
|
||||
x: int,
|
||||
y: int,
|
||||
room: Room,
|
||||
first: bool = False, # needed for warrior
|
||||
):
|
||||
if hero_type == "KING":
|
||||
if abs(x - prev_x) > 1 or abs(y - prev_y) > 1:
|
||||
return False
|
||||
elif hero_type == "WIZARD":
|
||||
if abs(x - prev_x) == abs(y - prev_y):
|
||||
return _check_path(prev_x, prev_y, x, y, room, "DIAGONAL")
|
||||
elif x == prev_x and y != prev_y:
|
||||
return _check_path(prev_x, prev_y, x, y, room, "HORIZONTAL")
|
||||
elif x != prev_x and y == prev_y:
|
||||
return _check_path(prev_x, prev_y, x, y, room, "VERTICAL")
|
||||
return False
|
||||
elif hero.first()
|
||||
elif hero_type == "ARCHER":
|
||||
if abs(x - prev_x) == abs(y - prev_y):
|
||||
return _check_path(prev_x, prev_y, x, y, room, "DIAGONAL")
|
||||
return False
|
||||
elif hero_type == "WARRIOR":
|
||||
if first:
|
||||
if x == prev_x and y - prev_y == 1:
|
||||
return True
|
||||
elif abs(x - prev_x) == 1 and y - prev_y == 1:
|
||||
return True
|
||||
else:
|
||||
if x == prev_x and prev_y - y == 1:
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
def move_handler(prev_x: int, prev_y: int, x: int, y: int, room: Room, player: PlayerInRoom):
|
||||
def _print_board(room: Room):
|
||||
class color:
|
||||
PURPLE = '\033[95m'
|
||||
CYAN = '\033[96m'
|
||||
DARKCYAN = '\033[36m'
|
||||
BLUE = '\033[94m'
|
||||
GREEN = '\033[92m'
|
||||
YELLOW = '\033[93m'
|
||||
RED = '\033[91m'
|
||||
BOLD = '\033[1m'
|
||||
UNDERLINE = '\033[4m'
|
||||
END = '\033[0m'
|
||||
|
||||
for y in range(1, 8):
|
||||
for x in range(1, 9):
|
||||
try:
|
||||
hero = HeroInGame.objects.get(x=x, y=y, room=room)
|
||||
if hero.hero.type == "KING":
|
||||
if hero.player.first:
|
||||
print("♔", end="")
|
||||
else:
|
||||
print("♚", end="")
|
||||
elif hero.hero.type == "WIZARD":
|
||||
if hero.player.first:
|
||||
print("♕", end="")
|
||||
else:
|
||||
print("♛", end="")
|
||||
elif hero.hero.type == "ARCHER":
|
||||
if hero.player.first:
|
||||
print("♗", end="")
|
||||
else:
|
||||
print("♝", end="")
|
||||
else:
|
||||
if hero.player.first:
|
||||
print("♙", end="")
|
||||
else:
|
||||
print("♟", end="")
|
||||
except HeroInGame.DoesNotExist:
|
||||
print("*", end="")
|
||||
print()
|
||||
|
||||
|
||||
@sync_to_async
|
||||
def move_handler(
|
||||
prev_x: int, prev_y: int, x: int, y: int, room_slug: str, player: PlayerInRoom
|
||||
):
|
||||
room = Room.objects.get(slug=room_slug)
|
||||
_print_board(room) # TODO: Remove in production
|
||||
try:
|
||||
hero = HeroInGame.objects.get(x=prev_x, y=prev_y, room=room, player=player)
|
||||
except HeroInGame.DoesNotExist:
|
||||
return False
|
||||
|
||||
h_t = hero.hero.type
|
||||
if h_t == "KING":
|
||||
if abs(prev_x - x) != 1 or abs(prev_y - y) != 1:
|
||||
return False
|
||||
elif h_t == "WARRIOR":
|
||||
if player.first:
|
||||
if x - prev_x == 1 and y - prev_y == 0:
|
||||
_check_move_position(x, y, room, True)
|
||||
if x == prev_x and y == prev_y:
|
||||
return False
|
||||
|
||||
h_t = hero.hero.type
|
||||
|
||||
_print_board(room) # TODO: Remove in production
|
||||
|
||||
|
|
|
@ -37,14 +37,24 @@ def create_room(
|
|||
first=first_player == 2,
|
||||
)
|
||||
for p, d_id in [(p1, deck_id_1), (p2, deck_id_2)]:
|
||||
GameState.objects.create(room=room, player=p, round=0, message="Game started")
|
||||
for hero in Deck.objects.get(id=d_id).heroes.all():
|
||||
GameState.objects.create(
|
||||
room=room, player=p.player, round=0, message="Game started"
|
||||
)
|
||||
for hero_in_deck in Deck.objects.get(id=d_id).heroes():
|
||||
if p.first:
|
||||
HeroInGame.objects.create(
|
||||
hero=hero, player=p, room=room, x=hero.x, y=hero.y
|
||||
hero=hero_in_deck.hero,
|
||||
player=p,
|
||||
room=room,
|
||||
x=hero_in_deck.x,
|
||||
y=hero_in_deck.y,
|
||||
)
|
||||
else:
|
||||
HeroInGame.objects.create(
|
||||
hero=hero, player=p, room=room, x=hero.x, y=8 - hero.y
|
||||
hero=hero_in_deck.hero,
|
||||
player=p,
|
||||
room=room,
|
||||
x=hero_in_deck.x,
|
||||
y=8 - hero_in_deck.y,
|
||||
)
|
||||
return room.slug
|
||||
|
|
Loading…
Reference in New Issue
Block a user