Example #1
0
def main():
    """the main gameplay loop"""
    game = XiangqiGame()  # initializes game
    while True:
        clear_screen()  # start by clearing screen
        print("Type 'q' at any time to forfeit")
        print()
        game.show_board()
        print()
        print('Game state:', game.get_game_state())
        print('Turn:', game.get_turn(), end='')
        if game.is_in_check(game.get_turn().lower()):
            print(' (in check)')
        print()
        print()

        move_from = input('Move from: ')
        if move_from == 'q':
            if game.get_turn() == 'RED':
                print('BLACK_WON')
            if game.get_turn() == 'BLACK':
                print('RED_WON')
            time.sleep(1)
            break

        move_to = input('Move to: ')
        if move_to == 'q':
            break

        if not game.make_move(move_from, move_to):
            print("Invalid move. Try again.")
            time.sleep(1)
        else:
            game.make_move(move_from, move_to)
 def test_check(self):
     game = XiangqiGame()
     game.make_move("e4", "e5")
     game.make_move("e7", "e6")
     game.make_move("i4", "i5")
     game.make_move("a10", "a9")
     game.make_move("g4", "g5")
     game.make_move("h8", "c8")
     game.make_move("e5", "e6")
     game.make_move("a9", "e9")
     self.assertEqual(game.make_move("e6", "g6"),
                      False)  # will put general in check
     game.make_move("e6", "e7")
     game.make_move("e9", "e7")
     self.assertEqual(game.is_in_check('red'),
                      True)  # puts red general in check
     self.assertEqual(game.make_move("a4", "a5"),
                      False)  # will not save general
     self.assertEqual(game.make_move("f1", "e2"),
                      True)  # move saves the general
     self.assertEqual(game.is_in_check('red'),
                      False)  # previous move saved the general out of check
Example #3
0
class Board(Canvas):
    def __init__(self):
        super().__init__(width=board_size + offset, height=board_size + offset)
        self.initgame()
        self.pack()

    def initgame(self):
        self.board_status = XiangqiGame()
        self.selected = False
        self.last_position = ''
        # bind left click from mouse as user input
        self.bind_all('<Button-1>', self.click)
        # bind right click from mouse as move options
        self.bind_all('<Button-3>', self.rightclick)

        self.board_setup()
        self.load_images()
        self.draw_pieces()

    def resetgame(self):
        self.initgame()

    def quitgame(self):
        exit(0)

    def undoMove(self):
        self.board_status.sync_to_last_log()
        self.board_setup()
        self.draw_pieces()

    def board_setup(self):
        # draw board
        self.create_rectangle(0,
                              0,
                              board_size + offset,
                              board_size + offset,
                              fill='#be4d00')
        self.create_rectangle(offset / 2,
                              offset / 2,
                              board_size + offset / 2,
                              board_size + offset / 2,
                              fill='#ffbd33')
        # vertical lines on board
        for i in range(1, 8):
            self.create_line(i * board_size / 8 + offset / 2, offset / 2,
                             i * board_size / 8 + offset / 2,
                             4 * board_size / 9 + offset / 2)
            self.create_line(i * board_size / 8 + offset / 2,
                             5 * board_size / 9 + offset / 2,
                             i * board_size / 8 + offset / 2,
                             board_size + offset / 2)
        # horizontal lines on board
        for i in range(1, 9):
            self.create_line(offset / 2, i * board_size / 9 + offset / 2,
                             board_size + offset / 2,
                             i * board_size / 9 + offset / 2)
        # palace diagonals
        self.create_line(3 * board_size / 8 + offset / 2, offset / 2,
                         5 * board_size / 8 + offset / 2,
                         2 * board_size / 9 + offset / 2)
        self.create_line(5 * board_size / 8 + offset / 2, offset / 2,
                         3 * board_size / 8 + offset / 2,
                         2 * board_size / 9 + offset / 2)
        self.create_line(3 * board_size / 8 + offset / 2,
                         7 * board_size / 9 + offset / 2,
                         5 * board_size / 8 + offset / 2,
                         9 * board_size / 9 + offset / 2)
        self.create_line(3 * board_size / 8 + offset / 2,
                         9 * board_size / 9 + offset / 2,
                         5 * board_size / 8 + offset / 2,
                         7 * board_size / 9 + offset / 2)
        self.create_text(board_size + offset - 2,
                         board_size + offset - 2,
                         text='possible moves [right click]',
                         anchor=SE,
                         fill='#f6e198')
        active_player = self.board_status.get_active_player()
        check = self.board_status.is_in_check(active_player)
        if active_player == 'RED':
            player_text = '1st Player'
            color = player1_color
        else:
            player_text = '2nd Player'
            color = player2_color
        if check:
            player_text += ' (IN CHECK)'

        color_bx_size = 15
        self.create_rectangle(4,
                              board_size + offset - 4,
                              4 + color_bx_size,
                              board_size + offset - 4 - color_bx_size,
                              fill=color)
        self.create_text(4 + color_bx_size + 4,
                         board_size + offset - 4 - color_bx_size,
                         text=player_text,
                         anchor=NW,
                         fill='#f6e198')

    def load_images(self):
        piece_size = (board_size // 10, board_size // 10)
        try:
            # get horse image
            self.ihorse = Image.open('media/horse.png')
            horse = self.ihorse.resize(piece_size)
            self.horse = ImageTk.PhotoImage(horse)
            # get elephant image
            self.ielephant = Image.open('media/elephant.png')
            elephant = self.ielephant.resize(piece_size)
            self.elephant = ImageTk.PhotoImage(elephant)
            # get soldier image
            self.isoldier = Image.open('media/soldier.png')
            soldier = self.isoldier.resize(piece_size)
            self.soldier = ImageTk.PhotoImage(soldier)
            # get cannon image
            self.icannon = Image.open('media/cannon.png')
            cannon = self.icannon.resize(piece_size)
            self.cannon = ImageTk.PhotoImage(cannon)
            # get chariot image
            self.ichariot = Image.open('media/chariot.png')
            chariot = self.ichariot.resize(piece_size)
            self.chariot = ImageTk.PhotoImage(chariot)
            # get general image
            self.igeneral = Image.open('media/general.png')
            general = self.igeneral.resize(piece_size)
            self.general = ImageTk.PhotoImage(general)
            # get advisor image
            self.iadvisor = Image.open('media/advisor.png')
            advisor = self.iadvisor.resize(piece_size)
            self.advisor = ImageTk.PhotoImage(advisor)
        except IOError as e:
            print(e)
            sys.exit(1)

    def draw_pieces(self):
        pieces = self.board_status.get_board_dictionary()
        for location in pieces:
            pixel_location = (int(location[0] * board_size / 8) + offset / 4,
                              int(location[1] * board_size / 9) + offset / 4)
            piece = pieces[location]
            # create player background
            self.create_oval(pixel_location[0],
                             pixel_location[1],
                             pixel_location[0] + piece_size[0],
                             pixel_location[1] + piece_size[1],
                             fill='#8e8e8e')
            if piece.get_player().upper() == 'RED':
                self.create_oval(pixel_location[0] + 2,
                                 pixel_location[1] + 2,
                                 pixel_location[0] + piece_size[0] - 2,
                                 pixel_location[1] + piece_size[1] - 2,
                                 fill=player1_color)
            else:
                self.create_oval(pixel_location[0] + 2,
                                 pixel_location[1] + 2,
                                 pixel_location[0] + piece_size[0] - 2,
                                 pixel_location[1] + piece_size[1] - 2,
                                 fill=player2_color)

            # create piece icon
            if piece.get_pieceName() == 'horse':
                self.create_image(
                    int(location[0] * board_size / 8) + offset / 4,
                    int(location[1] * board_size / 9) + offset / 4,
                    image=self.horse,
                    anchor=NW,
                    tag="horse")
            elif piece.get_pieceName() == 'elephant':
                self.create_image(
                    int(location[0] * board_size / 8) + offset / 4,
                    int(location[1] * board_size / 9) + offset / 4,
                    image=self.elephant,
                    anchor=NW,
                    tag="elephant")
            elif piece.get_pieceName() == 'soldier':
                self.create_image(
                    int(location[0] * board_size / 8) + offset / 4,
                    int(location[1] * board_size / 9) + offset / 4,
                    image=self.soldier,
                    anchor=NW,
                    tag="soldier")
            elif piece.get_pieceName() == 'cannon':
                self.create_image(
                    int(location[0] * board_size / 8) + offset / 4,
                    int(location[1] * board_size / 9) + offset / 4,
                    image=self.cannon,
                    anchor=NW,
                    tag="cannon")
            elif piece.get_pieceName() == 'chariot':
                self.create_image(
                    int(location[0] * board_size / 8) + offset / 4,
                    int(location[1] * board_size / 9) + offset / 4,
                    image=self.chariot,
                    anchor=NW,
                    tag="chariot")
            elif piece.get_pieceName() == 'general':
                self.create_image(
                    int(location[0] * board_size / 8) + offset / 4,
                    int(location[1] * board_size / 9) + offset / 4,
                    image=self.general,
                    anchor=NW,
                    tag="general")
            elif piece.get_pieceName() == 'advisor':
                self.create_image(
                    int(location[0] * board_size / 8) + offset / 4,
                    int(location[1] * board_size / 9) + offset / 4,
                    image=self.advisor,
                    anchor=NW,
                    tag="advisor")
            else:
                print('no icon found')

    def click(self, event):
        print("click event")
        col = int((event.x - offset / 4) // (board_size / 8))
        row = int((event.y - offset / 4) // (board_size / 9)) + 1
        position = notation[col] + str(row)
        pixel_location = (int(col * board_size / 8) + offset / 4,
                          int((row - 1) * board_size / 9) + offset / 4)
        if self.selected:
            print(" from:" + self.last_position + "to:" + position)
            madeMove = self.board_status.make_move(self.last_position,
                                                   position)
            self.board_status.show_board()
            self.board_setup()
            self.draw_pieces()

            self.selected = False
        else:
            if self.board_status.piece_at_location(position) == None:
                return
            self.board_setup()
            self.draw_pieces()
            self.last_position = position
            self.selected = True
            print(pixel_location)
            self.create_oval(pixel_location[0],
                             pixel_location[1],
                             pixel_location[0] + piece_size[0],
                             pixel_location[1] + piece_size[1],
                             width=2,
                             outline='#32dee1')

    def rightclick(self, event):
        print("right click event")
        self.board_setup()
        self.draw_pieces()
        col = int((event.x - offset / 4) // (board_size / 8))
        row = int((event.y - offset / 4) // (board_size / 9)) + 1
        pixel_location = (int(col * board_size / 8) + offset / 4,
                          int((row - 1) * board_size / 9) + offset / 4)
        self.create_oval(pixel_location[0],
                         pixel_location[1],
                         pixel_location[0] + piece_size[0],
                         pixel_location[1] + piece_size[1],
                         width=2,
                         outline='#32dee1')
        position = notation[col] + str(row)
        piece = self.board_status.piece_at_location(position)
        if piece != None:
            print('show moves')
            moves = piece.allowed_move(self.board_status)
            for move in moves:

                pixel_location = (int(move[0] * board_size / 8) + offset / 4,
                                  int((move[1]) * board_size / 9) + offset / 4)
                self.create_oval(pixel_location[0],
                                 pixel_location[1],
                                 pixel_location[0] + piece_size[0],
                                 pixel_location[1] + piece_size[1],
                                 width=2,
                                 outline='#32dee1')

                if move in self.board_status.get_board_dictionary():
                    self.create_line(pixel_location[0],
                                     pixel_location[1],
                                     pixel_location[0] + piece_size[0],
                                     pixel_location[1] + piece_size[1],
                                     width=2,
                                     fill='#32dee1')
        else:
            print('no piece selected')