Source code for game

# -*- coding: utf-8 -*-
import logging

from PyQt5.QtWidgets import QMessageBox

import game.game_logic
from tools import Color
from .board import Board
from .pieces import Pieces
from .ai_wrapper import ThreadAI


[docs]class Game: def __init__(self, screen, settings): logging.debug("game constructor") self.settings = settings self.screen = screen self.board = Board(screen) self.pieces = None self.whoseTurn = None self.possible_moves = list() self.multiplayer = False
[docs] def start_multiplayer_match(self, connection): if connection.networkThread.mode == "server": self.isHost = True else: self.isHost = False self.settings.ai = False # TO DO: sending settings over network self.multiplayer = True self.connection = connection self.connection.new_move.connect(self.mp_enemy_make_move) self.connection.special_action.connect(self.mp_enemy_special_action) self.pieces = Pieces(self) self.whoseTurn = Color.white self.screen.surrender_button.setDisabled(False) if self.isHost: self.compute_possible_moves_in_this_turn() self.screen.main_button.update() self.connection.connection_error.connect(self.connection_error) logging.debug("Starting Multiplayer match")
[docs] def start_match(self): self.pieces = Pieces(self) self.whoseTurn = self.settings.who_starts self.screen.surrender_button.setDisabled(False) if self.settings.ai and self.settings.who_starts: self.ai_start_turn() else: self.compute_possible_moves_in_this_turn() self.screen.main_button.update()
[docs] def end_match(self): self.possible_moves = list() self.pieces = None self.whoseTurn = None self.screen.main_button.update() self.multiplayer = False self.screen.surrender_button.setDisabled(True)
[docs] def try_to_make_a_move(self, piece, dest_cords): if piece.cords in self.possible_moves: if self.try_attack(piece, dest_cords): if self.settings.multiple_attack and game_logic.possible_attacks(piece.cords, *self.pieces.two_lists): self.possible_moves = [piece.cords] return self.end_turn() elif self.try_move(piece, dest_cords): self.end_turn()
[docs] def try_move(self, piece, dest_cords): possible_moves = game_logic.possible_moves(piece.cords, *self.pieces.two_lists) for possible_dest_cord, possible_destroyed_piece in possible_moves.items(): if possible_dest_cord == dest_cords: if self.multiplayer: self.connection.send_move(piece.cords, dest_cords) piece.cords = dest_cords return True return False
[docs] def try_attack(self, piece, dest_cords): possible_attacks = game_logic.possible_attacks(piece.cords, *self.pieces.two_lists) for possible_dest_cord, possible_destroyed_piece in possible_attacks.items(): if possible_dest_cord == dest_cords: if self.multiplayer: self.connection.send_move(piece.cords, dest_cords, possible_destroyed_piece) self.pieces.remove_piece(possible_destroyed_piece) piece.cords = dest_cords return True return False
[docs] def end_turn(self): self.whoseTurn = Color.opposite(self.whoseTurn) self.screen.main_button.update() if self.multiplayer and not (self.whoseTurn == self.isHost): self.possible_moves = list() self.connection.send_special_action("end_turn") return elif self.settings.ai and (self.whoseTurn == Color.white) and not self.multiplayer: self.ai_start_turn() else: self.compute_possible_moves_in_this_turn()
[docs] def mp_enemy_make_move(self, list_of_moves): piece_cord = list_of_moves[0] dest = list_of_moves[1] piece = self.pieces.get_piece(piece_cord) piece.cords = dest if len(list_of_moves) > 2: for destroyed_piece in list_of_moves[2:]: self.pieces.remove_piece(destroyed_piece)
[docs] def mp_enemy_special_action(self, command): if command == "end_turn": self.end_turn() elif command == "surrender": self.end_match() self.connection.close() QMessageBox.information(self.screen, 'Game Over', " You Won, network player surrenderd ") elif "[settings]" in command: self.settings.json_import_dump(command[10:])
[docs] def ai_start_turn(self): self.threadAI = ThreadAI(self.pieces, self.settings) self.threadAI.finished_calculation.connect(self.ai_end_turn) self.threadAI.start()
[docs] def ai_end_turn(self): if self.threadAI.best_move is None: self.end_match() self.threadAI = None QMessageBox.information(self.screen, 'Game Over', " You Won. ") return piece_cords, target_cords, beaten_cords = self.threadAI.best_move logging.debug("[AI]: AI chose to make a move %s -> %s", str(piece_cords), str(target_cords)) piece = self.pieces.get_piece(piece_cords) piece.cords = target_cords if beaten_cords != 0: for beaten_piece in beaten_cords: self.pieces.remove_piece(beaten_piece) self.whoseTurn = Color.opposite(self.whoseTurn) self.screen.main_button.update() self.threadAI = None self.compute_possible_moves_in_this_turn()
[docs] def list_of_pieces_which_can_attack(self) -> list: list_of_pieces_which_can_attack = list() for piece in self.pieces: if piece.color == self.whoseTurn: possible_attacks = game_logic.possible_attacks(piece.cords, *self.pieces.two_lists) if possible_attacks: list_of_pieces_which_can_attack.append(piece.cords) return list_of_pieces_which_can_attack
[docs] def list_of_pieces_which_can_move(self) -> list: list_of_pieces_which_can_move = list() for piece in self.pieces: if self.whoseTurn == piece.color: if game_logic.possible_moves(piece.cords, *self.pieces.two_lists).keys(): list_of_pieces_which_can_move.append(piece.cords) return list_of_pieces_which_can_move
[docs] def update_drawing(self): self.board.redraw()
[docs] def compute_possible_moves_in_this_turn(self): ret_list = list() list_of_pieces_which_can_attack = self.list_of_pieces_which_can_attack() list_of_pieces_which_can_move = self.list_of_pieces_which_can_move() for piece in self.pieces: if piece.color == self.whoseTurn and piece.cords in list_of_pieces_which_can_attack: ret_list.append(piece.cords) if ret_list and self.settings.force_attack: self.possible_moves = ret_list return for piece in self.pieces: if piece.color == self.whoseTurn and piece.cords in list_of_pieces_which_can_move: ret_list.append(piece.cords) self.possible_moves = ret_list if not self.possible_moves: self.end_match() if self.settings.ai: QMessageBox.information(self.screen, 'Game Over', "You Lost.") else: QMessageBox.information(self.screen, 'Game Over', "Player with "+Color.to_str(Color.opposite(self.whoseTurn))+" pieces won.")
[docs] def connection_error(self, err): logging.debug(err) if "10054" in err: QMessageBox.warning(self.screen, 'Connection Error', " Connection was suddenly closed. ") else: QMessageBox.warning(self.screen, 'Connection Error', " Connection Error. ") self.end_match()