mirror of
https://github.com/evgen-app/chess_rpg_backend.git
synced 2024-11-25 19:14:02 +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()
|
return self.get_heroes()
|
||||||
|
|
||||||
def score(self):
|
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:
|
class Meta:
|
||||||
db_table = "deck"
|
db_table = "deck"
|
||||||
|
|
|
@ -5,6 +5,8 @@ import django
|
||||||
from asgiref.sync import sync_to_async
|
from asgiref.sync import sync_to_async
|
||||||
from channels.generic.websocket import AsyncWebsocketConsumer
|
from channels.generic.websocket import AsyncWebsocketConsumer
|
||||||
|
|
||||||
|
from room.services.game_logic import move_handler
|
||||||
|
|
||||||
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "chess_backend.settings")
|
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "chess_backend.settings")
|
||||||
django.setup()
|
django.setup()
|
||||||
|
|
||||||
|
@ -286,9 +288,16 @@ class RoomConsumer(BaseConsumer):
|
||||||
await self.send_message("ERROR", message="data is not JSON serializable")
|
await self.send_message("ERROR", message="data is not JSON serializable")
|
||||||
|
|
||||||
if data:
|
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):
|
if not await self.start(data):
|
||||||
await self.send_message("ERROR", message="opponent is offline")
|
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):
|
async def start(self, data):
|
||||||
if self.scope["opponent_channel"] and self.scope["opponent_online"]:
|
if self.scope["opponent_channel"] and self.scope["opponent_online"]:
|
||||||
|
@ -302,6 +311,22 @@ class RoomConsumer(BaseConsumer):
|
||||||
return True
|
return True
|
||||||
return False
|
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
|
# info type group message handler
|
||||||
async def info(self, event):
|
async def info(self, event):
|
||||||
message = event["message"]
|
message = event["message"]
|
||||||
|
@ -327,13 +352,6 @@ class RoomConsumer(BaseConsumer):
|
||||||
|
|
||||||
await self.send(text_data=json.dumps(msg))
|
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):
|
async def channel(self, event):
|
||||||
channel = event["channel"]
|
channel = event["channel"]
|
||||||
self.scope["opponent_channel"] = channel
|
self.scope["opponent_channel"] = channel
|
||||||
|
@ -352,6 +370,19 @@ class RoomConsumer(BaseConsumer):
|
||||||
)
|
)
|
||||||
self.scope["opponent_online"] = status
|
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):
|
async def check_origin(self):
|
||||||
if not self.scope["player"]:
|
if not self.scope["player"]:
|
||||||
await self.send(
|
await self.send(
|
||||||
|
|
|
@ -1,25 +1,111 @@
|
||||||
|
from asgiref.sync import sync_to_async
|
||||||
|
|
||||||
from room.models import HeroInGame, Room, PlayerInRoom
|
from room.models import HeroInGame, Room, PlayerInRoom
|
||||||
|
|
||||||
|
|
||||||
def _check_move_position(x: int, y: int, room: Room, p_first: bool):
|
def _check_path(f_x: int, f_y: int, x: int, y: int, room: Room, move_type: str):
|
||||||
hero = HeroInGame.objects.filter(x=x, y=y, room=room)
|
if move_type == "DIAGONAL":
|
||||||
if not hero.exists():
|
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
|
return False
|
||||||
elif hero.first()
|
|
||||||
|
|
||||||
|
|
||||||
def move_handler(prev_x: int, prev_y: int, x: int, y: int, room: Room, player: PlayerInRoom):
|
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_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 _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:
|
try:
|
||||||
hero = HeroInGame.objects.get(x=prev_x, y=prev_y, room=room, player=player)
|
hero = HeroInGame.objects.get(x=prev_x, y=prev_y, room=room, player=player)
|
||||||
except HeroInGame.DoesNotExist:
|
except HeroInGame.DoesNotExist:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
h_t = hero.hero.type
|
if x == prev_x and y == prev_y:
|
||||||
if h_t == "KING":
|
|
||||||
if abs(prev_x - x) != 1 or abs(prev_y - y) != 1:
|
|
||||||
return False
|
return False
|
||||||
elif h_t == "WARRIOR":
|
|
||||||
if player.first:
|
h_t = hero.hero.type
|
||||||
if x - prev_x == 1 and y - prev_y == 0:
|
|
||||||
_check_move_position(x, y, room, True)
|
_print_board(room) # TODO: Remove in production
|
||||||
|
|
||||||
|
|
|
@ -37,14 +37,24 @@ def create_room(
|
||||||
first=first_player == 2,
|
first=first_player == 2,
|
||||||
)
|
)
|
||||||
for p, d_id in [(p1, deck_id_1), (p2, deck_id_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")
|
GameState.objects.create(
|
||||||
for hero in Deck.objects.get(id=d_id).heroes.all():
|
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:
|
if p.first:
|
||||||
HeroInGame.objects.create(
|
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:
|
else:
|
||||||
HeroInGame.objects.create(
|
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
|
return room.slug
|
||||||
|
|
Loading…
Reference in New Issue
Block a user