2022-07-10 00:06:48 +03:00
|
|
|
from asgiref.sync import sync_to_async
|
2022-07-27 01:24:47 +03:00
|
|
|
from termcolor import colored
|
2022-07-10 00:06:48 +03:00
|
|
|
|
2022-07-09 14:12:29 +03:00
|
|
|
from room.models import HeroInGame, Room, PlayerInRoom
|
|
|
|
|
|
|
|
|
2022-07-10 00:06:48 +03:00
|
|
|
def _check_path(f_x: int, f_y: int, x: int, y: int, room: Room, move_type: str):
|
|
|
|
if move_type == "DIAGONAL":
|
2022-07-27 01:24:47 +03:00
|
|
|
return (
|
|
|
|
HeroInGame.objects.filter(
|
|
|
|
room=room, x__range=(f_x, x), y__range=(f_y, y)
|
|
|
|
).count()
|
|
|
|
== 0
|
|
|
|
)
|
2022-07-10 00:06:48 +03:00
|
|
|
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(
|
2022-07-27 01:24:47 +03:00
|
|
|
hero_type: str,
|
|
|
|
prev_x: int,
|
|
|
|
prev_y: int,
|
|
|
|
x: int,
|
|
|
|
y: int,
|
|
|
|
room: Room,
|
|
|
|
first: bool = False, # needed for warrior
|
2022-07-10 00:06:48 +03:00
|
|
|
):
|
|
|
|
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")
|
2022-07-09 14:12:29 +03:00
|
|
|
return False
|
2022-07-10 00:06:48 +03:00
|
|
|
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
|
|
|
|
|
2022-07-09 14:12:29 +03:00
|
|
|
|
2022-07-10 00:06:48 +03:00
|
|
|
def _print_board(room: Room):
|
2022-07-30 00:00:59 +03:00
|
|
|
for y in range(1, 9):
|
2022-07-10 00:06:48 +03:00
|
|
|
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:
|
2022-08-04 16:09:21 +03:00
|
|
|
print(colored("♔", "green", attrs=["bold"]), end="")
|
2022-07-10 00:06:48 +03:00
|
|
|
else:
|
2022-08-04 16:09:21 +03:00
|
|
|
print(colored("♚", "red", attrs=["bold"]), end="")
|
2022-07-10 00:06:48 +03:00
|
|
|
elif hero.hero.type == "WIZARD":
|
|
|
|
if hero.player.first:
|
2022-08-04 16:09:21 +03:00
|
|
|
print(colored("♕", "green", attrs=["bold"]), end="")
|
2022-07-10 00:06:48 +03:00
|
|
|
else:
|
2022-08-04 16:09:21 +03:00
|
|
|
print(colored("♛", "red", attrs=["bold"]), end="")
|
2022-07-10 00:06:48 +03:00
|
|
|
elif hero.hero.type == "ARCHER":
|
|
|
|
if hero.player.first:
|
2022-08-04 16:09:21 +03:00
|
|
|
print(colored("♗", "green", attrs=["bold"]), end="")
|
2022-07-10 00:06:48 +03:00
|
|
|
else:
|
2022-08-04 16:09:21 +03:00
|
|
|
print(colored("♝", "red", attrs=["bold"]), end="")
|
2022-07-10 00:06:48 +03:00
|
|
|
else:
|
|
|
|
if hero.player.first:
|
2022-08-04 16:09:21 +03:00
|
|
|
print(colored("♙", "green", attrs=["bold"]), end="")
|
2022-07-10 00:06:48 +03:00
|
|
|
else:
|
2022-08-04 16:09:21 +03:00
|
|
|
print(colored("♟", "red", attrs=["bold"]), end="")
|
2022-07-10 00:06:48 +03:00
|
|
|
except HeroInGame.DoesNotExist:
|
|
|
|
print("*", end="")
|
|
|
|
print()
|
|
|
|
|
|
|
|
|
|
|
|
@sync_to_async
|
|
|
|
def move_handler(
|
2022-07-27 01:24:47 +03:00
|
|
|
prev_x: int, prev_y: int, x: int, y: int, room_slug: str, player: PlayerInRoom
|
2022-08-04 16:09:21 +03:00
|
|
|
) -> (bool, str):
|
2022-07-10 00:06:48 +03:00
|
|
|
room = Room.objects.get(slug=room_slug)
|
|
|
|
_print_board(room) # TODO: Remove in production
|
2022-07-09 14:12:29 +03:00
|
|
|
try:
|
|
|
|
hero = HeroInGame.objects.get(x=prev_x, y=prev_y, room=room, player=player)
|
|
|
|
except HeroInGame.DoesNotExist:
|
2022-08-04 16:09:21 +03:00
|
|
|
return False, "There is no hero"
|
2022-07-09 14:12:29 +03:00
|
|
|
|
2022-07-10 00:06:48 +03:00
|
|
|
if x == prev_x and y == prev_y:
|
2022-08-04 16:09:21 +03:00
|
|
|
return False, "Trying to move on same spot"
|
2022-07-10 00:06:48 +03:00
|
|
|
|
2022-07-09 14:12:29 +03:00
|
|
|
h_t = hero.hero.type
|
2022-07-10 00:06:48 +03:00
|
|
|
|
2022-08-04 16:09:21 +03:00
|
|
|
if h := HeroInGame.objects.filter(x=x, y=y, room=room, player=player):
|
|
|
|
if h.first().player != player:
|
|
|
|
# TODO: rpg encounter logic
|
|
|
|
return False, "Not implemented"
|
|
|
|
else:
|
|
|
|
return False, "Can't perform move on own figure"
|
|
|
|
else:
|
|
|
|
if _validate_hero_movement(h_t, prev_x, prev_y, x, y, room, first=player.first):
|
|
|
|
hero.x = x
|
|
|
|
hero.y = y
|
|
|
|
hero.save(update_fields=["x", "y"])
|
|
|
|
return True, "ok"
|
|
|
|
return False, "Such move can't be performed"
|
2022-08-01 18:22:11 +03:00
|
|
|
|