main
this is the engine of the gameunknown
python
2 years ago
22 kB
28
Indexable
import blessed, math, os, time
from ai_agent import get_AI_orders
def file_to_data_structure(path):
if not os.path.exists(path):
return "This path doesn't exist"
with open(path) as file:
lines = file.readlines()
dimension_board = [int(x) for x in lines[1].split()]
home_1, home_2 = lines[3].split(), lines[4].split()
player_1_pos, player_2_pos = [int(home_1[1]) - 1, int(home_1[2]) - 1], [int(home_2[1]) - 1, int(home_2[2]) - 1]
if home_1[0] != "1":
player_1_pos, player_2_pos = player_2_pos, player_1_pos
player_1, player_2 = [500, [], player_1_pos], [500, [], player_2_pos]
game_board = [[{"case_color": "#EEEEEE", "emoji": "null", "nb_magic": "null", "type": "empty"} for _ in
range(dimension_board[0])] for _ in range(dimension_board[1])]
for magic in lines[6:]:
magic_list = list(map(int, magic.split()))
if magic_list[0] > dimension_board[0] or magic_list[1] > dimension_board[1]:
print("This box can't be an element of the board")
else:
game_board[magic_list[1] - 1][magic_list[0] - 1] = {"case_color": "#EEEEEE", "emoji": "🪄",
"nb_magic": magic_list[2], "type": "magic"}
return dimension_board, player_1, player_2, game_board
def is_neighbour(pos,new_position):
possible_positions = ([pos[0],pos[1]],[pos[0]+1,pos[1]+1],[pos[0]+1,pos[1]],[pos[0]+1,pos[1]-1],[pos[0],pos[1]-1],[pos[0],pos[1]+1],[pos[0]-1,pos[1]-1],[pos[0]-1,pos[1]],[pos[0]-1,pos[1]+1])
if new_position in possible_positions:
return 1
else:
return 0
def coloring_box(j, i, box):
# the terminal of where we will play the game
term = blessed.Terminal()
# box size
box_width = 6
box_height = 3
# getting the content of the box
# get the color from the content of the box and transform it from Hexadecimal to RGB value
box_color_rgb = hex_to_rgb(str(box["case_color"]))
# get the type
box_type = str(box["type"])
# get the number of magic
box_nb_magic = str(box["nb_magic"])
# the right coordonate position of the box
x = box_width * j
# the bottom coordonate position of the box
y = box_height * i
# point the cursor in the right bottom of the box
print(term.move_xy(x, y))
# coloring all the units of the box
# horizintal units
for unit_x in range((x + (j * 2) - box_width) + 2, x + (j * 2) + 2):
# vertical units
for unit_y in range((y + i - box_height) + 1, y + i + 1):
# coloring the unit
print(term.move_xy(unit_x, unit_y) + term.on_color_rgb(box_color_rgb[0], box_color_rgb[1],
box_color_rgb[2]) + ' ' + term.normal, flush=True)
# insert emojis depending to the type of the box
# if the box is ghost box
if box_type == "ghost":
# insert ghost emoji
print(
term.move_xy((x + (j * 2) - box_width) + 4, (y + i - box_height) + 2) + term.on_color_rgb(box_color_rgb[0],
box_color_rgb[1],
box_color_rgb[
2]) + "👻" + term.normal,
flush=True)
# if number of magic of the ghost is more than 99 and magic points if exists
if int(box_nb_magic) > 99:
# insert the number of magic
print(term.move_xy((x + (j * 2) - box_width) + 6 - 1, (y + i - box_height) + 3) + term.on_color_rgb(
box_color_rgb[0], box_color_rgb[1], box_color_rgb[2]) + term.color_rgb(255, 255, 255) + str(
box_nb_magic) + term.normal, flush=True)
# if number of magic is less than 99
else:
# insert the number of magic
print(term.move_xy((x + (j * 2) - box_width) + 6, (y + i - box_height) + 3) + term.on_color_rgb(
box_color_rgb[0], box_color_rgb[1], box_color_rgb[2]) + term.color_rgb(255, 255, 255) + str(
box_nb_magic) + term.normal, flush=True)
# if the box is home boxhome
elif box_type == "home":
# insert home emoji
print(
term.move_xy((x + (j * 2) - box_width) + 4, (y + i - box_height) + 2) + term.on_color_rgb(box_color_rgb[0],
box_color_rgb[1],
box_color_rgb[
2]) + "⌂" + term.normal,
flush=True)
# if the box is magic box
elif box_type == "magic":
# insert ghost emoji
print(
term.move_xy((x + (j * 2) - box_width) + 4, (y + i - box_height) + 2) + term.on_color_rgb(box_color_rgb[0],
box_color_rgb[1],
box_color_rgb[
2]) + "🪄" + term.normal,
flush=True)
# if number of magic is more than 99
if int(box_nb_magic) > 99:
# insert the number of magic
print(term.move_xy((x + (j * 2) - box_width) + 6 - 1, (y + i - box_height) + 3) + term.on_color_rgb(
box_color_rgb[0], box_color_rgb[1], box_color_rgb[2]) + term.color_rgb(41, 52, 98) + str(
box_nb_magic) + term.normal, flush=True)
# if number of magic is less than 99
else:
# insert the number of magic
print(term.move_xy((x + (j * 2) - box_width) + 6, (y + i - box_height) + 3) + term.on_color_rgb(
box_color_rgb[0], box_color_rgb[1], box_color_rgb[2]) + term.color_rgb(41, 52, 98) + str(
box_nb_magic) + term.normal, flush=True)
# if the box type is a fusion between magic and ghost
elif box_type == "magic+ghost":
# split nb_magic points of the magic and nb_magic points of the ghost
box_nb_magic = box_nb_magic.split("+")
# insert the nb_maigc_points of the magic
print(
term.move_xy((x + (j * 2) - box_width) + 2, (y + i - box_height) + 1) + term.on_color_rgb(box_color_rgb[0],
box_color_rgb[1],
box_color_rgb[
2]) + term.color_rgb(
255, 255, 255) + str(box_nb_magic[0]) + term.normal, flush=True)
# insert ghost emoji
print(
term.move_xy((x + (j * 2) - box_width) + 4, (y + i - box_height) + 2) + term.on_color_rgb(box_color_rgb[0],
box_color_rgb[1],
box_color_rgb[
2]) + "👻" + term.normal,
flush=True)
# if number of magic of the ghost if more than 99 and magic points if exists
if int(box_nb_magic[1]) > 99:
# insert the number of magic
print(term.move_xy((x + (j * 2) - box_width) + 6 - 1, (y + i - box_height) + 3) + term.on_color_rgb(
box_color_rgb[0], box_color_rgb[1], box_color_rgb[2]) + term.color_rgb(255, 255, 255) + str(
box_nb_magic[1]) + term.normal, flush=True)
# if number of magic of the ghost if less than 99
else:
# insert the number of magic
print(term.move_xy((x + (j * 2) - box_width) + 6, (y + i - box_height) + 3) + term.on_color_rgb(
box_color_rgb[0], box_color_rgb[1], box_color_rgb[2]) + term.color_rgb(255, 255, 255) + str(
box_nb_magic[1]) + term.normal, flush=True)
# if the box is empty box
else:
# don't insert anything
print("")
def hex_to_rgb(value: str) -> tuple:
# Remove the '#' character from the value of color
value = value.lstrip('#')
# Convert the hex color code to an RGB tuple
red = int(value[0:2], 16)
green = int(value[2:4], 16)
blue = int(value[4:6], 16)
return red, green, blue
def decorate_game_board(game_board):
for i, line in enumerate(game_board, start=1):
for j, box_dict in enumerate(line, start=1):
box = dict(box_dict)
coloring_box(j, i, box)
def display_game_informations(dimension_board, player_1, player_2, nb_turn):
# initialize blessed Terminal
term = blessed.Terminal()
# set box height and height space
box_height = 3
height_space = 1
# display player 1 information
player_1_text = 'Player 1 : {}'.format(player_1[0])
print(term.move_xy(4, ((box_height + height_space) * dimension_board[1] + 2)) +
term.on_color_rgb(214, 28, 78) + player_1_text + term.normal, flush=True, end="")
# display player 2 information
player_2_text = 'Player 2 : {}'.format(player_2[0])
print(term.move_xy(23, ((box_height + height_space) * dimension_board[1] + 2)) +
term.on_color_rgb(41, 52, 98) + player_2_text + term.normal, flush=True,end="")
# display turn information
turn_text = 'Turn : {}'.format(nb_turn)
print(term.move_xy(42, ((box_height + height_space) * dimension_board[1] + 2)) +
term.on_color_rgb(255, 255, 255) + term.color_rgb(41, 52, 98) + turn_text + term.normal, flush=True)
def change_player_nb_magic_points(player_info,nb_magic):
player_info[0] += nb_magic
return player_info
def change_ghost_nb_magic_points(game_board, ghost_position, nb_magic):
box_info = game_board[ghost_position[1]][ghost_position[0]]
current_points = box_info.get("nb_magic", 0)
if isinstance(current_points, str) and "+" in current_points:
magic_p, current_points = current_points.split("+")
result = int(current_points) + nb_magic
new_points = f"{magic_p}+{result}"
else:
new_points = str(int(current_points) + nb_magic)
game_board[ghost_position[1]][ghost_position[0]] = {
"case_color": box_info["case_color"],
"emoji": box_info["emoji"],
"type": "ghost",
"nb_magic": new_points,
}
return game_board
def is_empty_box(game_board,box_position):
case = game_board[box_position[1]][box_position[0]]
if case["type"] not in ["ghost"]:
return 1
else:
return 0
def move_ghost(game_board, player_info, current_position, new_position):
def get_box(position):
return game_board[position[1]][position[0]]
def set_box(position, box):
game_board[position[1]][position[0]] = box
current_box = get_box(current_position)
new_box = get_box(new_position)
if current_box["type"] not in ["ghost", "magic+ghost"]:
return
if is_empty_box(game_board, new_position) == 0 and not (current_box["type"] in ["ghost", "magic+ghost"] and new_box["type"] == "magic"):
return
if is_neighbour(current_position, new_position) == 0:
return
if current_box["type"] == "magic+ghost":
magic_points = str(current_box["nb_magic"]).split("+")
magic_box = {"case_color": "#EEEEEE", "emoji": "🪄", "nb_magic": magic_points[0], "type": "magic"}
ghost_box = {"case_color": current_box["case_color"], "emoji": current_box["emoji"], "nb_magic": magic_points[1], "type": "ghost"}
if new_box["type"] == "magic":
new_nb_magic = str(new_box["nb_magic"]) + "+" + str(current_box["nb_magic"])
new_type = str(new_box["type"]) + "+" + str(current_box["type"])
else:
new_nb_magic = current_box["nb_magic"]
new_type = current_box["type"]
set_box(new_position, {"case_color": ghost_box["case_color"], "emoji": ghost_box["emoji"], "nb_magic": new_nb_magic, "type": new_type})
set_box(current_position, magic_box)
else:
if new_box["type"] == "magic":
new_nb_magic = str(new_box["nb_magic"]) + "+" + str(current_box["nb_magic"])
new_type = new_box["type"] + "+" + current_box["type"]
else:
new_nb_magic = current_box["nb_magic"]
new_type = current_box["type"]
set_box(new_position, {"case_color": current_box["case_color"], "emoji": current_box["emoji"], "nb_magic": new_nb_magic, "type": new_type})
set_box(current_position, {"case_color": "#EEEEEE", "emoji": "null", "nb_magic": "null", "type": "empty"})
ghosts = player_info[1]
ghost_index = next((i for i, g in enumerate(ghosts) if g[1:3] == current_position), None)
if ghost_index is not None:
ghosts[ghost_index][1:3] = new_position
player_info[1] = ghosts
coloring_box(current_position[0] + 1, current_position[1] + 1, get_box(current_position))
coloring_box(new_position[0] + 1, new_position[1] + 1, get_box(new_position))
return game_board, player_info
def create_ghost(game_board, player_info, color):
magic_points = int(player_info[0])
if magic_points >= 300:
x, y = player_info[2]
if is_empty_box(game_board, (x, y)):
new_ghost = [len(player_info[1]), x, y]
player_info[1].append(new_ghost)
game_board[y][x] = {
"case_color": color,
"emoji": "👻",
"type": "ghost",
"nb_magic": 100,
}
change_player_nb_magic_points(player_info, -300)
else:
print("The case is already full. You can't create a ghost here.")
return game_board, player_info
def is_ghost_exists(game_board,ghost):
return game_board[ ghost[1] ][ ghost[0] ] == "ghost"
def attack(game_board, ghost_attacker, ghost_attacked, player_attacker, player_attacked):
if not is_ghost_exists(game_board, ghost_attacked):
return game_board, player_attacker, player_attacked
if not is_neighbour(ghost_attacker, ghost_attacked):
return game_board, player_attacker, player_attacked
change_ghost_nb_magic_points(game_board, ghost_attacked, -10)
coloring_box(ghost_attacked[0] + 1, ghost_attacked[1] + 1, game_board[ghost_attacked[1]][ghost_attacked[0]])
change_player_nb_magic_points(player_attacker, 10)
if not is_dead(game_board, ghost_attacked):
return game_board, player_attacker, player_attacked
game_board[ghost_attacked[1]][ghost_attacked[0]] = {"case_color": "#EEEEEE", "emoji": "null", "nb_magic": "null",
"type": "empty"}
coloring_box(ghost_attacked[0] + 1, ghost_attacked[1] + 1, game_board[ghost_attacked[1]][ghost_attacked[0]])
for i, ghost in enumerate(player_attacked[1]):
if ghost[1:] == ghost_attacked:
del player_attacked[1][i]
break
return game_board, player_attacker, player_attacked
def execute_orders(orders, game_board, player_info, current_player, second_player):
if not orders:
return game_board, player_info
orders_list = orders.strip().split()
for order in orders_list:
try:
if order == "ghost":
color = "#D61C4E" if current_player == 1 else "#293462"
create_ghost(game_board, player_info, color)
else:
order_parts = order.split(":")
ghost_pos = tuple(map(int, order_parts[0].split("-")))
operation = order_parts[1][0]
target_pos = tuple(map(int, order_parts[1][1:].split("-")))
box_info = game_board[ghost_pos[1]-1][ghost_pos[0]-1]
if operation == "x":
attack(game_board, ghost_pos, target_pos, player_info, second_player)
elif operation == "@":
move_ghost(game_board, player_info, ghost_pos, target_pos)
elif operation == "$":
nb_magic, recolting_magic = map(int, box_info["nb_magic"].split("+"))
player_info = change_player_nb_magic_points(player_info, nb_magic)
game_board[ghost_pos[1]-1][ghost_pos[0]-1] = {
"case_color": box_info["case_color"],
"emoji": box_info["emoji"],
"type": "ghost",
"nb_magic": str(recolting_magic),
}
coloring_box(ghost_pos[0], ghost_pos[1], game_board[ghost_pos[1]-1][ghost_pos[0]-1])
elif operation == "+":
nb_magic = int(box_info["nb_magic"])
game_board[ghost_pos[1]-1][ghost_pos[0]-1]["nb_magic"] = str(nb_magic + int(order_parts[1][1:]))
player_info = change_player_nb_magic_points(player_info, -2 * int(order_parts[1][1:]))
except:
pass
decorate_game_board(game_board)
return game_board, player_info
def is_dead(game_board,ghost_coordonate):
return int(game_board[ghost_coordonate[1]][ghost_coordonate[0]]["nb_magic"]) <= 0
def is_winner(player_1 , player_2):
if player_1[0] > player_2[0]:
return 1
elif player_1[0] < player_2[0]:
return 2
return 0
def change_player(player):
if player == 1 :
return 2
else :
return 1
def one_order_by_ghost(orders):
used_ghosts = []
orders = str(orders).split()
cpt = 0
for order in orders:
if order == "ghost":
cpt += 1
elif ":" in order:
order_sides = order.split(":")
if order_sides[0] in used_ghosts :
del orders[cpt]
else :
if "@" in order_sides[1]:
right_side = order_sides[1]
used_ghosts.append(right_side[1:])
else:
used_ghosts.append(order_sides[0])
cpt += 1
orders_str = ""
for order in orders:
orders_str += str(order) + " "
return orders_str
def play_game(map_path, type_1, type_2):
term = blessed.Terminal()
print(term.clear())
nb_turns = 1
player_1_color = "#D61C4E"
player_2_color = "#293462"
dimension_board, player_1, player_2, game_board = file_to_data_structure(map_path)
player_1[0] = 500
player_2[0] = 500
decorate_game_board(game_board)
time.sleep(1)
game_board, player_1 = create_ghost(game_board, player_1, player_1_color)
decorate_game_board(game_board)
time.sleep(1)
game_board, player_2 = create_ghost(game_board, player_2, player_2_color)
decorate_game_board(game_board)
time.sleep(1)
current_player = 1
while nb_turns <= 200 and len(player_1[1]) > 0 and len(player_2[1]) > 0:
print(term.clear())
decorate_game_board(game_board)
display_game_informations(
dimension_board, player_1, player_2, nb_turns
)
if type_1 == "human" and type_2 == "human":
if current_player == 1:
orders = input("Player 1: enter the orders please: ")
orders = one_order_by_ghost(orders)
execute_orders(orders, game_board, player_1, 1, player_2)
else:
orders = input("Player 2: enter the orders please: ")
orders = one_order_by_ghost(orders)
execute_orders(orders, game_board, player_2, 2, player_1)
display_game_informations(
dimension_board, player_1, player_2, nb_turns
)
current_player = change_player(current_player)
elif type_1 == "human" and type_2 == "ai":
if current_player == 1:
orders = get_AI_orders(game_board, player_2, 2)
input("Order taken")
orders = one_order_by_ghost(orders)
execute_orders(orders, game_board, player_2, 2, player_1)
else:
orders = input("Player 1: enter the orders please: ")
orders = one_order_by_ghost(orders)
execute_orders(orders, game_board, player_1, 1, player_2)
display_game_informations(
dimension_board, player_1, player_2, nb_turns
)
current_player = change_player(current_player)
change_player_nb_magic_points(player_1, 10 + len(player_1[1]))
change_player_nb_magic_points(player_2, 10 + len(player_2[1]))
nb_turns += 1
time.sleep(1)
if nb_turns > 200:
winner_number = is_winner(player_1, player_2)
if winner_number == 1:
winner_text = "the Player 1 is winner 🏆"
elif winner_number == 2:
winner_text = "the Player 2 is winner 🏆"
print(winner_text)
play_game("./map.txt","human","human")
Editor is loading...