WUT_Computer_Science/Programming/EARIN/lab2/main.py

582 lines
22 KiB
Python
Raw Normal View History

"""
2023-04-08 19:00:23 +02:00
Program that plays draughts (checkers) with user on 8x8 board using min-max with alpha-beta pruning
"""
2023-04-08 19:54:56 +02:00
import re
import copy
import math
2023-04-10 06:19:56 +02:00
import sys
class Game:
"""Game"""
def __init__(self, size):
self.board_size = size
self.white_positions = self.initialize_white()
self.black_positions = self.initialize_black()
def initialize_white(self):
"""Initialize white pieces"""
white_positions = []
for y_coordinate in range(math.floor((self.board_size - 2) / 2)):
for x_coordinate in range(self.board_size):
if y_coordinate % 2 == 0:
if x_coordinate % 2 == 1:
2023-04-10 22:32:51 +02:00
white_positions.append((x_coordinate, y_coordinate, False))
else:
if x_coordinate % 2 == 0:
2023-04-10 22:32:51 +02:00
white_positions.append((x_coordinate, y_coordinate, False))
return white_positions
def initialize_black(self):
"""Initialize black pieces"""
black_positions = []
2023-04-10 22:32:51 +02:00
for y_coordinate in range(
self.board_size - math.floor((self.board_size - 2) / 2), self.board_size
):
for x_coordinate in range(self.board_size):
if y_coordinate % 2 == 0:
if x_coordinate % 2 == 1:
2023-04-10 22:32:51 +02:00
black_positions.append((x_coordinate, y_coordinate, False))
else:
if x_coordinate % 2 == 0:
2023-04-10 22:32:51 +02:00
black_positions.append((x_coordinate, y_coordinate, False))
return black_positions
2023-04-08 19:54:56 +02:00
def check_move_out_of_bounds(self, to_):
2023-04-08 17:50:31 +02:00
"""Check if the move destination is out of the bounds of the board"""
2023-04-08 19:54:56 +02:00
if to_[0] < 0 or to_[0] > self.board_size - 1:
2023-04-08 17:50:31 +02:00
# print(f"Illegal move! Final x coordinate must be between 0 and {self.board_size-1}!")
return True
2023-04-08 19:54:56 +02:00
if to_[1] < 0 or to_[1] > self.board_size - 1:
2023-04-08 17:50:31 +02:00
# print(f"Illegal move! Final y coordinate must be between 0 and {self.board_size-1}!")
return True
return False
def check_piece_exists(self, coords, color):
"""Check if a piece of given color exists at a given spot"""
if color == "white":
2023-04-10 22:32:51 +02:00
if any(
piece in self.white_positions
for piece in ((*coords, False), (*coords, True))
):
return True
else:
2023-04-10 22:32:51 +02:00
if any(
piece in self.black_positions
for piece in ((*coords, False), (*coords, True))
):
return True
return False
def check_piece_king(self, coords, color):
2023-04-08 19:54:56 +02:00
"""Check if a piece of in a given spot and of a given color is a king.
Return false if no piece is found"""
if color == "white":
return (*coords, True) in self.white_positions
2023-04-08 19:54:56 +02:00
if color == "black":
return (*coords, True) in self.black_positions
2023-04-08 19:54:56 +02:00
return False
# https://stackoverflow.com/a/2191707
2023-04-08 19:54:56 +02:00
def check_move_piece_capable(self, from_, to_, color):
"""Check if the move is exactly one square diagonally"""
2023-04-08 19:54:56 +02:00
if abs(to_[0] - from_[0]) == 1:
if self.check_piece_king(from_, color):
return True
2023-04-08 19:54:56 +02:00
if color == "white":
return to_[1] == from_[1] + 1
if color == "black":
return to_[1] == from_[1] - 1
return False
2023-04-08 19:54:56 +02:00
def check_capture(self, from_, to_, color):
"""Check if a piece was captured for a given move.
Return captured piece coordinates or None"""
# captures can only happen if the player moved twice-diagonally
2023-04-08 19:00:23 +02:00
2023-04-10 22:32:51 +02:00
if abs(to_[0] - from_[0]) != 2 or abs(to_[1] - from_[1]) != 2:
return None
2023-04-10 22:32:51 +02:00
middle = (abs(to_[0] + from_[0]) // 2, abs(to_[1] + from_[1]) // 2)
if color == "white" and self.check_piece_exists(middle, "black"):
return middle
2023-04-08 19:54:56 +02:00
if color == "black" and self.check_piece_exists(middle, "white"):
return middle
return None
2023-04-08 19:54:56 +02:00
def check_move_legal(self, from_, to_, color, give_feedback=False):
"""Check if a move is legal. Return a boolean or coordinates of captured piece"""
2023-04-08 19:54:56 +02:00
if self.check_move_out_of_bounds(to_):
2023-04-08 19:00:23 +02:00
if give_feedback:
2023-04-08 17:50:31 +02:00
print("Illegal move! Final position is out of the bounds of the board")
return False
if not self.check_piece_exists(from_, color):
2023-04-08 19:00:23 +02:00
if give_feedback:
2023-04-08 17:50:31 +02:00
print(
2023-04-08 19:54:56 +02:00
"Illegal move! There is no piece on the "
2023-04-10 22:32:51 +02:00
"starting position that belongs to the player"
)
return False
2023-04-10 22:32:51 +02:00
if self.check_piece_exists(to_, "white") or self.check_piece_exists(
to_, "black"
):
2023-04-08 19:00:23 +02:00
if give_feedback:
2023-04-08 17:50:31 +02:00
print("Illegal move! Cannot move to position taken by another piece")
return False
2023-04-08 19:54:56 +02:00
capture = self.check_capture(from_, to_, color)
if capture is None:
if self.check_move_piece_capable(from_, to_, color):
return True
2023-04-08 19:54:56 +02:00
if give_feedback:
2023-04-10 22:32:51 +02:00
print("Illegal move! You can only move diagonally")
2023-04-08 19:54:56 +02:00
return False
return capture
2023-04-08 19:54:56 +02:00
def make_move(self, from_, to_, color):
"""Move a piece on the board and remove any captured pieces"""
2023-04-08 19:54:56 +02:00
move_legal = self.check_move_legal(from_, to_, color)
if move_legal is False:
return False
2023-04-08 19:54:56 +02:00
capture = move_legal if isinstance(move_legal, tuple) else None
king = self.check_piece_king(from_, color)
2023-04-08 19:54:56 +02:00
if color == "white":
self.white_positions.remove((*from_, king))
2023-04-08 19:54:56 +02:00
if capture:
captured_king = self.check_piece_king(capture, "black")
self.black_positions.remove((*move_legal, captured_king))
2023-04-10 22:32:51 +02:00
if to_[1] == self.board_size - 1:
2023-04-08 19:54:56 +02:00
self.white_positions.append((*to_, True))
2023-04-08 19:00:23 +02:00
else:
2023-04-08 19:54:56 +02:00
self.white_positions.append((*to_, king))
else:
self.black_positions.remove((*from_, king))
2023-04-08 19:54:56 +02:00
if capture:
captured_king = self.check_piece_king(capture, "white")
self.white_positions.remove((*move_legal, captured_king))
2023-04-08 19:54:56 +02:00
if to_[1] == 0:
self.black_positions.append((*to_, True))
2023-04-08 19:00:23 +02:00
else:
2023-04-08 19:54:56 +02:00
self.black_positions.append((*to_, king))
2023-04-08 19:00:23 +02:00
return True
2023-04-08 20:37:01 +02:00
def print_board(self, rotate=False):
2023-04-08 17:50:31 +02:00
"""Print the board in the console"""
2023-04-08 19:54:56 +02:00
2023-04-08 20:37:01 +02:00
def print_letters():
"""Print the letters above or under the board"""
print(" ", end="")
for col in range(self.board_size):
if rotate:
print(f" {chr(ord('a')+self.board_size-1-col)}", end=" ")
else:
print(f" {chr(ord('a')+col)}", end=" ")
def get_square_code(pos, background):
"""Return the code of a given square on the board"""
2023-04-08 19:54:56 +02:00
if (*pos, False) in self.white_positions:
return "w"
if (*pos, True) in self.white_positions:
return "W"
if (*pos, False) in self.black_positions:
return "b"
if (*pos, True) in self.black_positions:
return "B"
return background
2023-04-08 20:37:01 +02:00
print_letters()
2023-04-08 17:50:31 +02:00
print(" ")
2023-04-08 20:37:01 +02:00
2023-04-10 22:32:51 +02:00
row_range = (
range(self.board_size * 4)
if not rotate
else reversed(range(self.board_size * 4))
)
2023-04-08 17:50:31 +02:00
line = 0
2023-04-08 20:37:01 +02:00
for row in row_range:
2023-04-08 19:54:56 +02:00
for col in range(self.board_size):
2023-04-10 22:32:51 +02:00
background = "#" if (col % 2 == (row // 4) % 2) != rotate else " "
checker = (
get_square_code((col, row // 4), background)
if not rotate
else get_square_code(
(self.board_size - 1 - col, row // 4), background
)
)
2023-04-08 19:54:56 +02:00
if col == 0:
if line % 4 == 2:
print(f"{row//4:3d}", end="")
2023-04-08 17:50:31 +02:00
else:
print(" ", end="")
match line % 4:
case 0:
print("+---", end="")
case 1 | 3:
2023-04-08 19:54:56 +02:00
print(f"|{3*background}", end="")
2023-04-08 17:50:31 +02:00
case 2:
2023-04-08 19:54:56 +02:00
print(f"|{background}{checker}{background}", end="")
if line % 4 == 0:
2023-04-08 17:50:31 +02:00
print("+")
2023-04-08 16:07:55 +02:00
else:
2023-04-08 19:54:56 +02:00
print(f"|{row//4}" if line % 4 == 2 else "|")
2023-04-08 17:50:31 +02:00
line += 1
print(" ", end="")
2023-04-08 19:54:56 +02:00
for col in range(self.board_size):
2023-04-08 17:50:31 +02:00
print("+---", end="")
2023-04-08 20:37:01 +02:00
print("+")
print_letters()
2023-04-08 17:50:31 +02:00
print()
2023-04-10 22:32:51 +02:00
# Ran first in the code
2023-04-08 19:00:23 +02:00
def get_possible_moves_capture(self, from_, color):
2023-04-08 19:54:56 +02:00
"""Return all possible captures for a piece"""
2023-04-08 17:50:31 +02:00
# all capturing moves:
legal_moves = []
move_down_left_two = (from_[0] + 2, from_[1] - 2)
move_down_right_two = (from_[0] + 2, from_[1] + 2)
move_up_left_two = (from_[0] - 2, from_[1] - 2)
move_up_right_two = (from_[0] - 2, from_[1] + 2)
2023-04-08 19:54:56 +02:00
if self.check_move_legal(from_, move_down_left_two, color) is not False:
2023-04-08 17:50:31 +02:00
legal_moves.append((from_, move_down_left_two))
2023-04-08 19:54:56 +02:00
if self.check_move_legal(from_, move_down_right_two, color) is not False:
2023-04-08 17:50:31 +02:00
legal_moves.append((from_, move_down_right_two))
2023-04-08 19:54:56 +02:00
if self.check_move_legal(from_, move_up_left_two, color) is not False:
2023-04-08 17:50:31 +02:00
legal_moves.append((from_, move_up_left_two))
2023-04-08 19:54:56 +02:00
if self.check_move_legal(from_, move_up_right_two, color) is not False:
2023-04-08 17:50:31 +02:00
legal_moves.append((from_, move_up_right_two))
return legal_moves
2023-04-08 19:00:23 +02:00
def get_possible_moves_non_capture(self, from_, color):
2023-04-08 19:54:56 +02:00
"""Return all possible moves that are not captures for a piece"""
2023-04-08 17:50:31 +02:00
# all non-capturing moves
legal_moves = []
move_down_left_one = (from_[0] + 1, from_[1] - 1)
move_down_right_one = (from_[0] + 1, from_[1] + 1)
move_up_left_one = (from_[0] - 1, from_[1] - 1)
move_up_right_one = (from_[0] - 1, from_[1] + 1)
2023-04-08 19:54:56 +02:00
if self.check_move_legal(from_, move_down_left_one, color) is not False:
2023-04-08 17:50:31 +02:00
legal_moves.append((from_, move_down_left_one))
2023-04-08 19:54:56 +02:00
if self.check_move_legal(from_, move_down_right_one, color) is not False:
2023-04-08 17:50:31 +02:00
legal_moves.append((from_, move_down_right_one))
2023-04-08 19:54:56 +02:00
if self.check_move_legal(from_, move_up_left_one, color) is not False:
2023-04-08 17:50:31 +02:00
legal_moves.append((from_, move_up_left_one))
2023-04-08 19:54:56 +02:00
if self.check_move_legal(from_, move_up_right_one, color) is not False:
2023-04-08 17:50:31 +02:00
legal_moves.append((from_, move_up_right_one))
return legal_moves
2023-04-08 16:07:55 +02:00
def get_possible_moves(self, color):
2023-04-08 19:54:56 +02:00
"""Return all possible moves for a given piece color"""
2023-04-08 17:50:31 +02:00
legal_moves = []
captures = []
if color == "white":
for white_position in self.white_positions:
# print((white_position[0], white_position[1]))
2023-04-08 19:00:23 +02:00
legal_moves += self.get_possible_moves_non_capture(
2023-04-10 22:32:51 +02:00
(white_position[0], white_position[1]), color
)
2023-04-08 19:00:23 +02:00
captures += self.get_possible_moves_capture(
2023-04-10 22:32:51 +02:00
(white_position[0], white_position[1]), color
)
2023-04-08 17:50:31 +02:00
elif color == "black":
for black_position in self.black_positions:
2023-04-08 19:00:23 +02:00
legal_moves += self.get_possible_moves_non_capture(
2023-04-10 22:32:51 +02:00
(black_position[0], black_position[1]), color
)
2023-04-08 19:00:23 +02:00
captures += self.get_possible_moves_capture(
2023-04-10 22:32:51 +02:00
(black_position[0], black_position[1]), color
)
2023-04-08 19:00:23 +02:00
if len(captures) > 0:
return (captures, True)
return (legal_moves + captures, False)
2023-04-08 17:50:31 +02:00
2023-04-08 19:54:56 +02:00
def alpha_beta(self, depth, alpha_beta, color, current_color=None):
"""Do alpha beta pruning for given parameters
and return the best move and its evaluated points"""
if current_color is None:
2023-04-08 19:00:23 +02:00
current_color = color
2023-04-08 17:50:31 +02:00
if depth == 0:
2023-04-08 19:00:23 +02:00
return self.evaluate(color), None
2023-04-08 17:50:31 +02:00
2023-04-08 19:54:56 +02:00
alpha, beta = alpha_beta
2023-04-10 22:32:51 +02:00
opposite_color = "white" if current_color == "black" else "black"
2023-04-08 19:00:23 +02:00
if current_color == color:
2023-04-10 22:32:51 +02:00
max_eval = float("-inf")
2023-04-08 17:50:31 +02:00
best_move = None
for move in self.get_possible_moves(current_color)[0]:
2023-04-08 17:50:31 +02:00
new_state = copy.deepcopy(self)
2023-04-08 19:00:23 +02:00
new_state.make_move(*move, current_color)
2023-04-08 19:54:56 +02:00
eval_, _ = new_state.alpha_beta(
2023-04-10 22:32:51 +02:00
depth - 1, alpha_beta, color, opposite_color
)
2023-04-08 17:50:31 +02:00
2023-04-08 19:54:56 +02:00
if eval_ > max_eval:
max_eval = eval_
2023-04-08 17:50:31 +02:00
best_move = move
2023-04-08 19:54:56 +02:00
alpha = max(alpha, eval_)
2023-04-08 17:50:31 +02:00
if alpha >= beta:
break
return max_eval, best_move
2023-04-08 19:54:56 +02:00
if opposite_color == color:
2023-04-10 22:32:51 +02:00
min_eval = float("inf")
2023-04-08 17:50:31 +02:00
best_move = None
for move in self.get_possible_moves(current_color)[0]:
2023-04-08 17:50:31 +02:00
new_state = copy.deepcopy(self)
2023-04-08 19:00:23 +02:00
new_state.make_move(*move, current_color)
2023-04-08 19:54:56 +02:00
eval_, _ = new_state.alpha_beta(
2023-04-10 22:32:51 +02:00
depth - 1, alpha_beta, color, opposite_color
)
2023-04-08 17:50:31 +02:00
2023-04-08 19:54:56 +02:00
if eval_ < min_eval:
min_eval = eval_
2023-04-08 17:50:31 +02:00
best_move = move
2023-04-08 19:54:56 +02:00
beta = min(beta, eval_)
2023-04-08 17:50:31 +02:00
if beta <= alpha:
break
return min_eval, best_move
2023-04-08 19:54:56 +02:00
return None
2023-04-08 17:50:31 +02:00
2023-04-08 19:00:23 +02:00
def evaluate(self, color):
2023-04-08 19:54:56 +02:00
"""Evaluates the state of the board for a given color"""
2023-04-08 17:50:31 +02:00
white_score = 0
black_score = 0
2023-04-08 16:07:55 +02:00
for white_position in self.white_positions:
2023-04-08 17:50:31 +02:00
if white_position[2]:
white_score += 10
else:
white_score += 5
2023-04-08 16:07:55 +02:00
for black_position in self.black_positions:
2023-04-08 17:50:31 +02:00
if black_position[2]:
black_score += 10
else:
black_score += 5
2023-04-10 22:32:51 +02:00
return (
white_score - black_score if color == "white" else black_score - white_score
)
2023-04-08 19:54:56 +02:00
def input_to_coordinates(self, user_input):
"""Change input from a1 form to tuple form"""
2023-04-10 22:32:51 +02:00
pos_x = ord(user_input[0]) - ord("a")
2023-04-08 19:54:56 +02:00
pos_y = int(user_input[1::])
2023-04-08 17:50:31 +02:00
return pos_x, pos_y
2023-04-08 16:03:47 +02:00
2023-04-08 16:07:55 +02:00
def handle_player_move(self, color):
2023-04-08 19:54:56 +02:00
"""Prompt player to move, validate their input and make move"""
2023-04-08 16:07:55 +02:00
has_moved = False
possible_moves = self.get_possible_moves(color)[0]
2023-04-08 16:07:55 +02:00
while not has_moved:
2023-04-08 20:00:00 +02:00
user_input = input(
2023-04-10 22:32:51 +02:00
f"You are {color}. How do you want to move? (format: d6 e5)\n"
)
2023-04-08 17:50:31 +02:00
regex = r"^[a-z]\d+\s[a-z]\d+$"
2023-04-08 16:07:55 +02:00
match = re.search(regex, user_input)
if not match:
2023-04-10 22:32:51 +02:00
print("Invalid input, try again")
2023-04-08 16:07:55 +02:00
continue
2023-04-10 22:32:51 +02:00
[move_from, move_to] = user_input.split(" ")
2023-04-08 16:07:55 +02:00
from_coordinates = self.input_to_coordinates(move_from)
to_coordinates = self.input_to_coordinates(move_to)
2023-04-08 19:00:23 +02:00
if not (from_coordinates, to_coordinates) in possible_moves:
legal_no_captures = self.check_move_legal(
2023-04-10 22:32:51 +02:00
from_coordinates, to_coordinates, color, True
)
2023-04-08 19:00:23 +02:00
if legal_no_captures:
print("Invalid move! You can capture a piece")
continue
has_moved = self.make_move(from_coordinates, to_coordinates, color)
2023-04-10 22:32:51 +02:00
self.print_board(color == "white")
2023-04-10 22:32:51 +02:00
def start_game(self, player_color="black", algorithm_depth=5):
2023-04-08 19:54:56 +02:00
"""Start the main loop of the game"""
2023-04-10 22:32:51 +02:00
if player_color not in ("black", "white"):
print("Invalid color! Color can be black or white")
2023-04-08 19:00:23 +02:00
return
2023-04-10 22:32:51 +02:00
ai_color = "black" if player_color == "white" else "white"
2023-04-08 19:00:23 +02:00
2023-04-10 22:32:51 +02:00
game.print_board(player_color == "white")
if player_color == "white":
game.handle_player_move("white")
2023-04-08 19:00:23 +02:00
while True:
ai_turn = True
2023-04-10 22:32:51 +02:00
while ai_turn:
possible_moves_ai = game.get_possible_moves(ai_color)
if len(possible_moves_ai[0]) == 0:
2023-04-10 22:32:51 +02:00
print(f"Game over, {player_color} wins")
return
_, ai_move = game.alpha_beta(algorithm_depth, (5, 10), ai_color)
game.make_move(*ai_move, ai_color)
print(
"AI's move: "
f"{chr(ord('a')+ai_move[0][0])}{ai_move[0][1]} "
2023-04-10 22:32:51 +02:00
f"{chr(ord('a')+ai_move[1][0])}{ai_move[1][1]}"
)
game.print_board(player_color == "white")
ai_turn = game.get_possible_moves(ai_color)[1] and possible_moves_ai[1]
player_turn = True
while player_turn:
possible_moves_player = game.get_possible_moves(player_color)
if len(possible_moves_player[0]) == 0:
2023-04-10 22:32:51 +02:00
print(f"Game over, {ai_color} wins")
return
game.handle_player_move(player_color)
2023-04-10 22:32:51 +02:00
player_turn = (
game.get_possible_moves(player_color)[1]
and possible_moves_player[1]
)
2023-04-08 19:00:23 +02:00
2023-04-10 06:19:56 +02:00
def ai_turn(self, ai_color, algorithm_depth, possible_moves_ai, print_info):
2023-04-10 22:32:51 +02:00
""" Calculates ai move and makes it """
2023-04-10 06:19:56 +02:00
if len(possible_moves_ai) == 0:
if print_info:
2023-04-10 22:32:51 +02:00
print(f"Game over, {ai_color} loses")
2023-04-10 06:19:56 +02:00
return True
_, ai_move = game.alpha_beta(algorithm_depth, (5, 10), ai_color)
2023-04-10 22:32:51 +02:00
if ai_move is None:
2023-04-10 06:19:56 +02:00
ai_move = possible_moves_ai[0]
game.make_move(*ai_move, ai_color)
2023-04-10 22:32:51 +02:00
if print_info:
2023-04-10 06:19:56 +02:00
print(
"AI's move: "
f"{chr(ord('a')+ai_move[0][0])}{ai_move[0][1]} "
2023-04-10 22:32:51 +02:00
f"{chr(ord('a')+ai_move[1][0])}{ai_move[1][1]}"
)
2023-04-10 06:19:56 +02:00
game.print_board(True)
return False
2023-04-10 22:32:51 +02:00
2023-04-10 06:19:56 +02:00
def auto_game(self, white_depth, black_depth):
"""Auto game mode between two bots"""
2023-04-10 22:32:51 +02:00
game_turn = 0
2023-04-10 06:19:56 +02:00
max_turns = 250
2023-04-10 22:32:51 +02:00
while game_turn < max_turns:
2023-04-10 06:19:56 +02:00
bot_white_turn = True
while bot_white_turn:
2023-04-10 22:32:51 +02:00
possible_moves_ai = game.get_possible_moves("white")
if self.ai_turn("white", white_depth, possible_moves_ai[0], False):
return "white"
bot_white_turn = (
game.get_possible_moves("white")[1] and possible_moves_ai[1]
)
2023-04-10 06:19:56 +02:00
bot_black_turn = True
while bot_black_turn:
2023-04-10 22:32:51 +02:00
possible_moves_ai = game.get_possible_moves("black")
if self.ai_turn("black", black_depth, possible_moves_ai[0], False):
return "black"
bot_black_turn = (
game.get_possible_moves("black")[1] and possible_moves_ai[1]
)
2023-04-10 06:19:56 +02:00
game_turn += 1
if game_turn >= max_turns:
print(f"Game ended after {max_turns} turns!")
2023-04-10 22:32:51 +02:00
return ""
return ""
def auto_simulation(white_depth, black_depth, iterations):
"""Runs iterations amount of simulations"""
print(
f"""Running {iterations} simulations with
white depth = {white_depth},black depth = {black_depth}"""
)
white_wins = 0
black_wins = 0
white_pieces_captured = 0
black_pieces_captured = 0
current_iteration = 0
while current_iteration < iterations:
result = game.auto_game(white_depth, black_depth)
if result == "white":
black_wins += 1
if result == "black":
white_wins += 1
if result == "":
break
white_pieces_captured += 16 - len(game.white_positions)
black_pieces_captured += 16 - len(game.black_positions)
current_iteration += 1
print(
f"""White wins = {white_wins}, Black wins = {black_wins},
white pieces captured in total = {white_pieces_captured},
black pieces captured in total = {black_pieces_captured}"""
)
print()
2023-04-10 06:19:56 +02:00
def print_help():
"""prints help"""
print(
2023-04-10 22:32:51 +02:00
"""python main.py [algorithm_depth] - play the game against the bot as black,
if no algorithm depth is specified the default (5) will be set
2023-04-10 06:19:56 +02:00
python main.py -h --help print this prompt
2023-04-10 22:32:51 +02:00
python main.py -t --test [max_white_depth] [max_black_depth] non interactive
(does not print moves) for testing how different bot depth play against eachother,
if depths are not provided default value of 5 is set
2023-04-10 06:19:56 +02:00
compares heuristic speed and path length
2023-04-10 22:32:51 +02:00
python main.py -w --white [algorithm_depth] play as white pieces,
if no algorithm depth is specified the default (5) will be set
python main.py -b --black [algorithm_depth] play as black pieces,
if no algorithm depth is specified the default (5) will be set
2023-04-10 06:19:56 +02:00
"""
)
2023-04-10 22:32:51 +02:00
def default(color="black", algorithm_depth=5):
2023-04-10 06:19:56 +02:00
"""default program function -> allows to play a game against bot (by default as black)"""
game.start_game(color, algorithm_depth)
2023-04-08 15:48:55 +02:00
# Ran first in the code
if __name__ == "__main__":
game = Game(8)
2023-04-10 06:19:56 +02:00
if len(sys.argv) > 1:
if sys.argv[1] == "-h" or sys.argv[1] == "--help":
print_help()
sys.exit()
if sys.argv[1] == "-t" or sys.argv[1] == "--test":
2023-04-10 22:32:51 +02:00
MAX_WHITE_DEPTH = 4
MAX_BLACK_DEPTH = 4
2023-04-10 06:19:56 +02:00
if len(sys.argv) > 2:
2023-04-10 22:32:51 +02:00
MAX_WHITE_DEPTH = int(sys.argv[2])
2023-04-10 06:19:56 +02:00
if len(sys.argv) > 3:
2023-04-10 22:32:51 +02:00
MAX_BLACK_DEPTH = int(sys.argv[3])
for i in range(MAX_WHITE_DEPTH + 1):
for j in range(MAX_BLACK_DEPTH + 1):
2023-04-10 06:19:56 +02:00
game = Game(8)
2023-04-10 22:32:51 +02:00
auto_simulation(i, j, 10)
2023-04-10 06:19:56 +02:00
sys.exit()
if sys.argv[1] == "-w" or sys.argv[1] == "--white":
2023-04-10 22:32:51 +02:00
ALGORITHM_DEPTH = 5
2023-04-10 06:19:56 +02:00
if len(sys.argv) > 2:
2023-04-10 22:32:51 +02:00
ALGORITHM_DEPTH = int(sys.argv[2])
default("white", ALGORITHM_DEPTH)
2023-04-10 06:19:56 +02:00
sys.exit()
if sys.argv[1] == "-b" or sys.argv[1] == "--black":
2023-04-10 22:32:51 +02:00
ALGORITHM_DEPTH = 5
2023-04-10 06:19:56 +02:00
if len(sys.argv) > 2:
2023-04-10 22:32:51 +02:00
ALGORITHM_DEPTH = int(sys.argv[2])
default("black", ALGORITHM_DEPTH)
2023-04-10 06:19:56 +02:00
sys.exit()
if len(sys.argv) > 1:
2023-04-10 22:32:51 +02:00
default("black", int(sys.argv[1]))
2023-04-10 06:19:56 +02:00
default()