def hide_hint(): console.echo(message='Hint disabled. Removing highlights...', level=3) if self.highlight_checkers_move: self.highlight_checkers_move = False if self.highlight_checkers_attack: self.highlight_checkers_attack = False
def __init__(self): self.__mode = 0 self.__prev = 0 self.clockface = clockface.Clockface() self.collection = { 0: setup.build_main_menu(), # Main menu 1: setup.build_settings_menu(), # Settings menu 2: setup.build_active_game(), # Active game UI 3: setup.build_paused_game(), # Paused game UI 4: setup.build_start_new_confirmation( ), # Start new confirmation menu 5: setup.build_end_current_confirmation( ), # End current confirmation menu 6: setup.build_game_won(), # Game statistics UI (game won) 7: setup.build_game_lost(), # Game statistics UI (game lost) 8: setup.build_quit_confirmation(), # App quit confirmation menu 9: setup.build_game_draw(), # Game statistics UI (game draw) } self.__show_clockface = False console.echo(message='Initialized UI', level=1) for preset in self.collection: preset_name = mapping.PRESET_NAMES[preset] for ui_element in self.collection[preset]: console.echo( message='Created {object}{position} {collection}'.format( object=ui_element, position=f' at {ui_element.position}' if isinstance( ui_element, button.Button) else '', collection=f'at {preset_name}'), level=2)
def try_moving(): if self.active_checker.can_kill: try_attacking() else: if self.__player_must_attack(): console.echo( message= 'Unable to move current checker. There is a checker that can attack!', level=3) deselect_checker() force_hint() else: if clicked_position in self.active_checker.move_list: self.active_checker.move(clicked_position) self.__board_update() self.__next_player_turn() deselect_checker() else: console.echo( message= 'Unable to move to {position}. Position {position} is out of reach' .format(position=convert. board_position_to_alphanumeric_index( clicked_position)), level=3) deselect_checker()
def __init__(self): super().__init__(width=settings.GAME_WINDOW_WIDTH, height=settings.GAME_WINDOW_HEIGHT, title=settings.GAME_WINDOW_TITLE, fullscreen=settings.GAME_WINDOW_FULLSCREEN, resizable=settings.GAME_WINDOW_RESIZABLE, update_rate=settings.GAME_WINDOW_UPDATE_RATE, antialiasing=settings.GAME_WINDOW_ANTIALIASING) console.echo( message= 'Initializing application game window ({width}x{height}px)...'. format(width=self.width, height=self.height)) self.__dev_mode = session.DEV_MODE self.__test_mode = session.TEST_MODE self.__debug_mode = session.DEBUG_MODE self.board = board.Board() self.player = None self.ui = ui.UI() self.active_player = 1 # 1 = White, 2 = Black; self.active_checker = None # None, if deselected; self.highlight_checkers_move = False self.highlight_checkers_attack = False self.display_checkers = False self.game_running = False self.game_paused = False
def promote(self): if not self.queen: self.queen = True console.echo( message='{color} checker at {position} is promoted to Queen-type!'.format( color=self.color.capitalize(), position=self.index), level=1)
def show_hint(): console.echo( message='Hint enabled. Highlighting possible moves...', level=3) if not self.highlight_checkers_move: self.highlight_checkers_move = True if not self.highlight_checkers_attack: self.highlight_checkers_attack = True
def checker(spawn_position: list, spawn_color: str, spawn_queen: bool = False): if spawn_color in ('White', 'Black'): spawned_checker = __checker_predefined(spawn_position, spawn_color, spawn_queen) else: spawned_checker = __checker_undefined(spawn_position) console.echo(message='Spawned {checker} at {position}'.format( checker=spawned_checker, position=convert.board_position_to_alphanumeric_index( conv_position=spawn_position)), level=2) return spawned_checker
def __player_cannot_move(self): cannot_move = True move_checkers = get.checkers_that_can_move() for checker in move_checkers: if checker.color == self.__player_color(): if checker.can_move: cannot_move = False break if cannot_move: console.echo(message='Player {index} is unable to move'.format( index=self.active_player), level=2) return cannot_move
def __next_player_turn(self): self.active_player = 2 if self.active_player == 1 else 1 console.echo(message='Switched to player {index} turn'.format( index=self.active_player), level=1) if self.__player_cannot_move(): if self.__player_has_no_checkers(): if self.active_player == 1: self.ui.set_mode(mode=7) else: self.ui.set_mode(mode=6) else: self.ui.set_mode(mode=9) self.stop_game()
def __player_has_no_checkers(self): no_checkers = True for row in mapping.SURFACE_GRID: for column in mapping.SURFACE_GRID[row]: position = [row, column] checker = get.checker_by_position(position) if checker is not None: if checker.color == self.__player_color(): no_checkers = False if no_checkers: console.echo( message='Player {index} has no checkers remaining on the board!' .format(index=self.active_player), level=3) return no_checkers
def move(checker_object, new_position): console.echo( message='{checker} moved from {old_position} to {new_position}'.format( checker=checker_object, old_position=convert.board_position_to_alphanumeric_index(checker_object.position), new_position=convert.board_position_to_alphanumeric_index(new_position)), level=1) tiles_between = __between(old_position=checker_object.position, new_position=new_position) if len(tiles_between) > 0: for position in tiles_between: console.echo( message='Removed {checker} from {position}'.format( checker=str(get.checker_by_position(check_position=position)).lower(), position=convert.board_position_to_alphanumeric_index(conv_position=position)), level=2) row, column = position[0], position[1] mapping.SURFACE_GRID[row][column] = None # Moving the checker from old to new positions: mapping.SURFACE_GRID[checker_object.position[0]][checker_object.position[1]] = None # Delete old instance mapping.SURFACE_GRID[new_position[0]][new_position[1]] = checker_object # Move instance to position checker_object.set_position(new_position)
def try_attacking(): if clicked_position in self.active_checker.kill_list: self.active_checker.move(clicked_position) self.__board_update() console.echo(message='Checking if player can attack...', level=1) if not self.active_checker.can_kill: console.echo( message= 'Player {index} is unable to continue attacking!'. format(index=self.active_player), level=2) self.__next_player_turn() deselect_checker() else: position_index = convert.board_position_to_alphanumeric_index( clicked_position) error_reason = 'Checker must attack first!' if clicked_position not in self.active_checker.move_list: error_reason = f'Position {position_index} is out of reach!' console.echo( message='Unable to move to {position}. {reason}'. format(position=position_index, reason=error_reason), level=3)
def __board_reset(self): console.echo(message='Resetting board surface...', level=2) self.board.update() self.__board_clear() self.__board_fill() self.__board_update()
def deselect_checker(): if self.active_checker is not None: self.active_checker = None console.echo(message='Deselected current checker', level=2)
def select_checker(checker_object): self.active_checker = checker_object console.echo(message='Selected new checker', level=3)
def force_hint(): if self.highlight_checkers_move: self.highlight_checkers_move = False self.highlight_checkers_attack = True console.echo(message='Highlighting possible moves...', level=2)
def handle_board_click(coordinates): def force_hint(): if self.highlight_checkers_move: self.highlight_checkers_move = False self.highlight_checkers_attack = True console.echo(message='Highlighting possible moves...', level=2) def select_checker(checker_object): self.active_checker = checker_object console.echo(message='Selected new checker', level=3) def deselect_checker(): if self.active_checker is not None: self.active_checker = None console.echo(message='Deselected current checker', level=2) def assert_player_owns_checker(checker_object): result = False if self.__player_color() == checker_object.color: result = True return result def try_moving(): if self.active_checker.can_kill: try_attacking() else: if self.__player_must_attack(): console.echo( message= 'Unable to move current checker. There is a checker that can attack!', level=3) deselect_checker() force_hint() else: if clicked_position in self.active_checker.move_list: self.active_checker.move(clicked_position) self.__board_update() self.__next_player_turn() deselect_checker() else: console.echo( message= 'Unable to move to {position}. Position {position} is out of reach' .format(position=convert. board_position_to_alphanumeric_index( clicked_position)), level=3) deselect_checker() def try_attacking(): if clicked_position in self.active_checker.kill_list: self.active_checker.move(clicked_position) self.__board_update() console.echo(message='Checking if player can attack...', level=1) if not self.active_checker.can_kill: console.echo( message= 'Player {index} is unable to continue attacking!'. format(index=self.active_player), level=2) self.__next_player_turn() deselect_checker() else: position_index = convert.board_position_to_alphanumeric_index( clicked_position) error_reason = 'Checker must attack first!' if clicked_position not in self.active_checker.move_list: error_reason = f'Position {position_index} is out of reach!' console.echo( message='Unable to move to {position}. {reason}'. format(position=position_index, reason=error_reason), level=3) if test.coordinates_are_valid(coordinates): if test.coordinates_in_board_boundaries(coordinates): self.__remove_all_highlights() checker_clicked = get.checker_by_coordinates(coordinates) if checker_clicked is None: console.echo(message='Empty tile clicked', level=2) if self.active_checker is not None: clicked_position = convert.coordinates_to_board_position( coordinates) if self.active_checker.can_move or self.active_checker.can_kill: try_moving() else: console.echo( message='{checker} clicked at {position}'.format( checker=checker_clicked, position=checker_clicked.index), level=2) if not assert_player_owns_checker(checker_clicked): console.echo( message='Unable to select opponent\'s checker!', level=3) deselect_checker() else: if checker_clicked == self.active_checker: deselect_checker() else: select_checker(checker_clicked)
def clear(): console.echo( message='Cleared board surface', level=1) mapping.clear()
def fill(): console.echo( message='Filling board surface with checker objects...', level=1) mapping.fill()
def console_echo_button_click(button_caption: str): console.echo(message='Button {caption} clicked'.format( caption=button_caption), level=2)
def __board_update(self): console.echo(message='Updating board checkers...', level=2) self.board.update()
def on_mouse_press(self, x: float, y: float, button: int, modifiers: int): def handle_board_click(coordinates): def force_hint(): if self.highlight_checkers_move: self.highlight_checkers_move = False self.highlight_checkers_attack = True console.echo(message='Highlighting possible moves...', level=2) def select_checker(checker_object): self.active_checker = checker_object console.echo(message='Selected new checker', level=3) def deselect_checker(): if self.active_checker is not None: self.active_checker = None console.echo(message='Deselected current checker', level=2) def assert_player_owns_checker(checker_object): result = False if self.__player_color() == checker_object.color: result = True return result def try_moving(): if self.active_checker.can_kill: try_attacking() else: if self.__player_must_attack(): console.echo( message= 'Unable to move current checker. There is a checker that can attack!', level=3) deselect_checker() force_hint() else: if clicked_position in self.active_checker.move_list: self.active_checker.move(clicked_position) self.__board_update() self.__next_player_turn() deselect_checker() else: console.echo( message= 'Unable to move to {position}. Position {position} is out of reach' .format(position=convert. board_position_to_alphanumeric_index( clicked_position)), level=3) deselect_checker() def try_attacking(): if clicked_position in self.active_checker.kill_list: self.active_checker.move(clicked_position) self.__board_update() console.echo(message='Checking if player can attack...', level=1) if not self.active_checker.can_kill: console.echo( message= 'Player {index} is unable to continue attacking!'. format(index=self.active_player), level=2) self.__next_player_turn() deselect_checker() else: position_index = convert.board_position_to_alphanumeric_index( clicked_position) error_reason = 'Checker must attack first!' if clicked_position not in self.active_checker.move_list: error_reason = f'Position {position_index} is out of reach!' console.echo( message='Unable to move to {position}. {reason}'. format(position=position_index, reason=error_reason), level=3) if test.coordinates_are_valid(coordinates): if test.coordinates_in_board_boundaries(coordinates): self.__remove_all_highlights() checker_clicked = get.checker_by_coordinates(coordinates) if checker_clicked is None: console.echo(message='Empty tile clicked', level=2) if self.active_checker is not None: clicked_position = convert.coordinates_to_board_position( coordinates) if self.active_checker.can_move or self.active_checker.can_kill: try_moving() else: console.echo( message='{checker} clicked at {position}'.format( checker=checker_clicked, position=checker_clicked.index), level=2) if not assert_player_owns_checker(checker_clicked): console.echo( message='Unable to select opponent\'s checker!', level=3) deselect_checker() else: if checker_clicked == self.active_checker: deselect_checker() else: select_checker(checker_clicked) def handle_board_click_dev(coordinates): def spawn_checker(): new_checker = spawn.checker(spawn_position=clicked_position, spawn_color='White', spawn_queen=False) new_checker.dev = True mapping.SURFACE_GRID[clicked_row][clicked_column] = new_checker def switch_color(checker_object): checker_object.color = 'White' if checker_object.color == 'Black' else 'Black' def promote_checker(checker_object): checker_object.promote() def remove_checker(): mapping.SURFACE_GRID[clicked_row][clicked_column] = None if test.coordinates_are_valid(coordinates): if test.coordinates_in_board_boundaries(coordinates): checker_clicked = get.checker_by_coordinates(coordinates) clicked_position = convert.coordinates_to_board_position( coordinates) if test.position_can_be_used(clicked_position): clicked_row, clicked_column = clicked_position if checker_clicked is None: spawn_checker() else: if checker_clicked.queen: if checker_clicked.color == 'White': switch_color(checker_clicked) else: remove_checker() else: if checker_clicked.color == 'White': switch_color(checker_clicked) else: switch_color(checker_clicked) promote_checker(checker_clicked) self.board.update() def handle_panel_click(coordinates): def show_hint(): console.echo( message='Hint enabled. Highlighting possible moves...', level=3) if not self.highlight_checkers_move: self.highlight_checkers_move = True if not self.highlight_checkers_attack: self.highlight_checkers_attack = True def hide_hint(): console.echo(message='Hint disabled. Removing highlights...', level=3) if self.highlight_checkers_move: self.highlight_checkers_move = False if self.highlight_checkers_attack: self.highlight_checkers_attack = False def hint_enabled(): hint_status = False if self.highlight_checkers_move and self.highlight_checkers_attack: hint_status = True return hint_status def console_echo_button_click(button_caption: str): console.echo(message='Button {caption} clicked'.format( caption=button_caption), level=2) for ui_element in self.ui.collection[self.ui.active_mode]: if isinstance(ui_element, Button): if click.coordinates_in_button_boundaries( coordinates, ui_element): # Main menu: if self.ui.active_mode == 0: if ui_element.ID == settings.BUTTON_ID_START_GAME: console_echo_button_click(ui_element.caption) self.ui.set_mode(mode=2) self.start_game() self.display_checkers = True elif ui_element.ID == settings.BUTTON_ID_SETTINGS: self.ui.hide_clockface() console_echo_button_click(ui_element.caption) self.ui.set_mode(mode=1) elif ui_element.ID == settings.BUTTON_ID_QUIT: console_echo_button_click(ui_element.caption) self.ui.set_mode(mode=8) # Settings menu: elif self.ui.active_mode == 1: if ui_element.ID == settings.BUTTON_ID_BACK: console_echo_button_click(ui_element.caption) if not self.game_running: self.ui.set_mode(mode=0) else: self.ui.set_mode(mode=3) # Active game mode: elif self.ui.active_mode == 2: if ui_element.ID == settings.BUTTON_ID_PAUSE: console_echo_button_click(ui_element.caption) self.ui.set_mode(mode=3) self.game_paused = True self.ui.clockface.stopwatch.pause() self.ui.hide_clockface() elif ui_element.ID == settings.BUTTON_ID_HINT: console_echo_button_click(ui_element.caption) if hint_enabled(): hide_hint() else: show_hint() elif ui_element.ID == settings.BUTTON_ID_UNDO: console_echo_button_click(ui_element.caption) pass # TODO: Add undo function: # Paused game mode: elif self.ui.active_mode == 3: if ui_element.ID == settings.BUTTON_ID_RESUME: console_echo_button_click(ui_element.caption) self.ui.set_mode(mode=2) if self.game_paused: self.game_paused = False self.ui.show_clockface() self.ui.clockface.stopwatch.unpause() elif ui_element.ID == settings.BUTTON_ID_RESTART_GAME: console_echo_button_click(ui_element.caption) self.ui.set_mode(mode=4) elif ui_element.ID == settings.BUTTON_ID_SETTINGS: console_echo_button_click(ui_element.caption) self.ui.set_mode(mode=1) elif ui_element.ID == settings.BUTTON_ID_MAIN_MENU: console_echo_button_click(ui_element.caption) self.ui.set_mode(mode=5) elif ui_element.ID == settings.BUTTON_ID_QUIT: console_echo_button_click(ui_element.caption) self.ui.set_mode(mode=8) # Start new game confirmation menu: elif self.ui.active_mode == 4: if ui_element.ID == settings.BUTTON_ID_YES: console_echo_button_click(ui_element.caption) self.ui.set_mode(mode=7) self.stop_game() elif ui_element.ID == settings.BUTTON_ID_NO: console_echo_button_click(ui_element.caption) self.ui.set_mode(mode=3) # End current game confirmation menu: elif self.ui.active_mode == 5: if ui_element.ID == settings.BUTTON_ID_YES: console_echo_button_click(ui_element.caption) self.ui.set_mode(mode=7) self.stop_game() elif ui_element.ID == settings.BUTTON_ID_NO: console_echo_button_click(ui_element.caption) self.ui.set_mode(mode=3) # Game results (Game won): elif self.ui.active_mode == 6: if ui_element.ID == settings.BUTTON_ID_CONTINUE: console_echo_button_click(ui_element.caption) self.ui.clockface.stopwatch.stop() self.ui.clockface.stopwatch.reset() self.ui.hide_clockface() self.display_checkers = False self.ui.set_mode(mode=0) elif ui_element.ID == settings.BUTTON_ID_QUIT: console_echo_button_click(ui_element.caption) self.ui.set_mode(mode=8) # Game results (Game lost/force end): elif self.ui.active_mode == 7: if ui_element.ID == settings.BUTTON_ID_CONTINUE: console_echo_button_click(ui_element.caption) self.ui.clockface.stopwatch.stop() self.ui.clockface.stopwatch.reset() self.ui.hide_clockface() self.display_checkers = False self.ui.set_mode(mode=0) elif ui_element.ID == settings.BUTTON_ID_QUIT: console_echo_button_click(ui_element.caption) self.ui.set_mode(mode=8) # Quit confirmation menu: elif self.ui.active_mode == 8: if ui_element.ID == settings.BUTTON_ID_YES: console_echo_button_click(ui_element.caption) quit() elif ui_element.ID == settings.BUTTON_ID_NO: console_echo_button_click(ui_element.caption) prev_mode = self.ui.previous_mode self.ui.set_mode(mode=prev_mode) # Game results (Game draw): elif self.ui.active_mode == 9: if ui_element.ID == settings.BUTTON_ID_CONTINUE: console_echo_button_click(ui_element.caption) self.ui.clockface.stopwatch.stop() self.ui.clockface.stopwatch.reset() self.ui.hide_clockface() self.display_checkers = False self.ui.set_mode(mode=0) elif ui_element.ID == settings.BUTTON_ID_QUIT: console_echo_button_click(ui_element.caption) self.ui.set_mode(mode=8) click_coordinates = [x, y] console.echo( message='Registered {button} click at {coordinates}'.format( button='LMB' if button == arcade.MOUSE_BUTTON_LEFT else \ 'RMB' if button == arcade.MOUSE_BUTTON_RIGHT else \ 'MMB' if button == arcade.MOUSE_BUTTON_MIDDLE else \ 'unregistered mouse button', coordinates=f'{x}:{y}'), level=1) if button == arcade.MOUSE_BUTTON_LEFT: if test.coordinates_in_board_boundaries(click_coordinates): if self.game_running and not self.game_paused: handle_board_click(click_coordinates) else: handle_panel_click(click_coordinates) else: if session.DEV_MODE: handle_board_click_dev(click_coordinates)
def set_mode(self, mode: int): self.__prev = self.__mode self.__mode = mode console.echo(message='Switching to {mode}...'.format( mode=mapping.PRESET_NAMES[mode]), level=3)