Beispiel #1
0
def gui():
    display = pygame.display.set_mode((300, 200))

    sb = SlideBar(print, (150, 100), (200, 30), 0, 160, 1, interval=4)

    def func_b():
        sb.color = RED

    red = Button(func_b, (300, 200), (60, 40), 'RED', anchor=BOTTOMRIGHT)

    def func_sb(value):
        red.topright = 300, value

    sb.func = func_sb
    sb.set(0)

    run = True
    while run:
        mouse = pygame.mouse.get_pos()
        for event in pygame.event.get():

            red.update(event)

            if event.type == pygame.QUIT:
                run = False

            elif event.type == pygame.MOUSEBUTTONDOWN:
                if mouse in sb:
                    sb.focus()

            elif event.type == pygame.MOUSEBUTTONUP:
                sb.unfocus()

        display.fill(WHITE)
        sb.render(display)
        red.render(display)
        pygame.display.flip()
Beispiel #2
0
class Game:
    def __init__(self, network, color):
        self.screen = None
        self.scale = START_SCALE
        self.base_x, self.base_y = None, None
        self.paused = False
        self.running = False
        self.clock = None
        self.network = network
        self.color_id = color
        self.colors = COLORS

        self.color = COLORS[self.color_id]
        self.c = 0

        self.placing_cells_mode = True
        self.showing_info_mode = False
        self.eating_mode = False

        self.w, self.h = None, None
        self.alive = None
        self.new_round_info = Note(15, 15, WIDTH - 30, HEIGHT - 30)
        self.scores = None

        self.caption = "Life game"
        self.captions = {
            "eat": "Eating time",
            "place_cells": "Placing cells time",
            "show_info": ""
        }

        self.watching_settings = False

        self.color_picker = ColorPicker(20,
                                        20,
                                        WIDTH - 40,
                                        HEIGHT - 40,
                                        job_on_set=self.set_color)
        close_btn_icon = "x.png"
        self.close_color_picker_btn = Button(
            WIDTH - 70,
            30,
            job_on_click=self.close_color_picker,
            icon_path_1=close_btn_icon,
            icon_path_2=close_btn_icon)
        self.settings_button = Button(20,
                                      20,
                                      job_on_click=self.open_settings,
                                      icon_path_1="settings44px.png",
                                      icon_path_2="settings44px.png")

    def set_color(self):
        r = int(self.color_picker.r)
        g = int(self.color_picker.g)
        b = int(self.color_picker.b)
        self.network.send(
            f"(set_color int:{self.color_id} int:{r} int:{g} int:{b})")
        self.watching_settings = False

    def close_color_picker(self):
        self.watching_settings = False

    def open_settings(self):
        self.watching_settings = True

    def center(self):
        cell_count_h = HEIGHT // self.scale
        cell_count_w = WIDTH // self.scale
        received = self.network.send("(bounding_box )", res=True)
        min_x, min_y, max_x, max_y = pickle.loads(received)

        self.base_x = min_x - (cell_count_w - (max_x - min_x + 1)) // 2
        self.base_y = min_y - (cell_count_h - (max_y - min_y + 1)) // 2

    def start_game(self):
        pygame.init()
        self.screen = SCREEN
        pygame.display.set_caption(f'Game of Life')
        self.center()
        self.clock = pygame.time.Clock()
        self.main()

    def on_key_down(self, event):
        if not self.watching_settings:
            key = event.key
            if key == K_ESCAPE:
                self.running = False
            elif key == K_LEFT:
                self.base_x -= SCROLL_DELTA
            elif key == K_RIGHT:
                self.base_x += SCROLL_DELTA
            elif key == K_UP:
                self.base_y -= SCROLL_DELTA
            elif key == K_DOWN:
                self.base_y += SCROLL_DELTA
            elif event.key == K_EQUALS:
                if self.scale < MAX_SCALE:
                    self.scale += SCALE_DELTA
            elif event.key == K_MINUS:
                if self.scale > MIN_SCALE:
                    self.scale -= SCALE_DELTA
            elif event.unicode == 'c':
                self.center()

    def on_mouse_buttondown(self):
        self.settings_button.update()
        if self.placing_cells_mode and not self.watching_settings:
            mouse_x, mouse_y = pygame.mouse.get_pos()
            x = mouse_x // self.scale + self.base_x
            y = mouse_y // self.scale + self.base_y
            data = f"(toggle int:{x} int:{y} int:{self.color_id})"
            self.network.send(data)

        if self.watching_settings:
            self.close_color_picker_btn.update()

    def set_caption(self, cmd):
        if self.caption != self.captions[cmd]:
            self.caption = self.captions[cmd]
            pygame.display.set_caption(self.caption)

    def change_mode(self, cmd):
        if cmd == "show_info":
            self.showing_info_mode = True
            self.placing_cells_mode = False
            self.eating_mode = False
        elif cmd == "eat":
            pygame.display.set_caption("eating")
            self.eating_mode = True
            self.placing_cells_mode = False
            self.showing_info_mode = False
        elif cmd == "place_cells":
            pygame.display.set_caption("placing")
            self.placing_cells_mode = True
            self.showing_info_mode = False
            self.eating_mode = False

    def update(self):
        if not self.watching_settings:
            self.colors = pickle.loads(
                self.network.send("(get_colors )", res=True))
            cmd = self.network.send(f"(what_now? int:{self.color_id})",
                                    res=True).decode()
            self.set_caption(cmd)
            self.change_mode(cmd)

            if self.placing_cells_mode:
                received = self.network.send("(get_alive )", res=True)
                self.alive = pickle.loads(received)
            elif self.eating_mode:
                received = self.network.send("(advance )", res=True)
                self.alive = pickle.loads(received)
            elif self.showing_info_mode:
                received = self.network.send(f"(get_scores )", res=True)
                # print(received)
                self.scores = pickle.loads(received)

        pygame_events = pygame.event.get(EVENT_TYPES)
        for event in pygame_events:
            if self.watching_settings:
                print("heeeeere")
                self.color_picker.update(event.type)
            pygame_event_type = event.type
            if pygame_event_type == QUIT:
                pygame.quit()
                sys.exit()
            elif pygame_event_type == MOUSEBUTTONDOWN:
                print("here")
                self.on_mouse_buttondown()
            elif pygame_event_type == KEYDOWN:
                self.on_key_down(event)

    def draw(self):
        if self.showing_info_mode:
            self.draw_cells()
            self.draw_new_round()
        elif self.watching_settings:
            self.color_picker.display(self.screen)
            self.close_color_picker_btn.display(self.screen)
        else:
            self.draw_cells()
        self.settings_button.display(self.screen)
        pygame.display.flip()

    def draw_cells(self):
        self.screen.fill(WHITE)
        for x in range(0, WIDTH, self.scale):  # draw vertical lines
            pygame.draw.line(self.screen, BLACK, (x, 0), (x, HEIGHT))
        for y in range(0, HEIGHT, self.scale):  # draw horizontal lines
            pygame.draw.line(self.screen, BLACK, (0, y), (WIDTH, y))
        for x, y in self.alive:  # draw live cells
            pygame.draw.rect(
                self.screen, self.colors[self.alive.getitem((y, x))],
                ((x - self.base_x) * self.scale + GRID_LINE_WIDTH +
                 CELL_MARGIN,
                 (y - self.base_y) * self.scale + GRID_LINE_WIDTH +
                 CELL_MARGIN, self.scale - GRID_LINE_WIDTH - 2 * CELL_MARGIN,
                 self.scale - GRID_LINE_WIDTH - 2 * CELL_MARGIN))

    def draw_new_round(self):
        # print(scores)
        scoreboard = list(sorted(list(self.scores.items()),
                                 key=lambda x: x[1]))
        lines = [
            ("Round ended.", None),
        ]
        for color_id, score in scoreboard:
            lines.append((f" - {score}", color_id))
        self.new_round_info.display(self.screen, lines, self.colors)

    def main(self):
        while True:
            self.clock.tick(FPS)
            self.update()
            self.draw()
Beispiel #3
0
class GameTable():
    def __init__(self):

        self.screen = pygame.display.set_mode(SCREEN_SIZE, 0, 32)
        #pygame.display.set_caption(u'中国象棋')  #.encode('utf-8'))
        self.selected = None
        self.last_moved = None
        self.last_checked = False
        #self.done = None

        self.surface = load_image('board.png')
        self.select_surface = load_image_alpha('select.png')
        self.done_surface = load_image_alpha('done.png')
        self.over_surface = load_image_alpha('over.png')
        self.pieces_image = {}

        #self.back_btn = Button(self.back_btn_clicked, (WIDTH+100, 40), (180, 40), 'BACK') #, anchor=BOTTOMRIGHT)
        self.back_btn = Button(self.back_btn_clicked, (WIDTH + 100, 82),
                               (180, 40), 'GoBack')  #, anchor=BOTTOMRIGHT)
        self.next_btn = Button(self.next_btn_clicked, (WIDTH + 100, 124),
                               (180, 40), 'NextGame')  #, anchor=BOTTOMRIGHT)
        self.prev_btn = Button(self.prev_btn_clicked, (WIDTH + 100, 166),
                               (180, 40), 'PrevGame')  #, anchor=BOTTOMRIGHT)
        self.restart_btn = Button(self.restart_btn_clicked, (WIDTH + 100, 40),
                                  (180, 40),
                                  'RestartGame')  #, anchor=BOTTOMRIGHT)
        self.info_box = InLineTextBox((WIDTH + 10, 186),
                                      220,
                                      RED,
                                      anchor=TOPLEFT,
                                      default_text='')
        self.good_box = InLineTextBox((WIDTH + 10, 206),
                                      220,
                                      RED,
                                      anchor=TOPLEFT,
                                      default_text='')

        for name in ['r', 'n', 'c', 'k', 'a', 'b', 'p']:
            self.pieces_image[name] = load_image_alpha(name + '.png')

        #self.check_sound = load_sound('check.wav')
        #self.move_sound = load_sound('move.wav')
        #self.capture_sound = load_sound('capture.wav')

        self.clock = pygame.time.Clock()
        self.board = ChessBoard()

        self.engine = [None, None]

    def back_btn_clicked(self):
        #sb.color = RED
        print("back btn_clicked")

    def next_btn_clicked(self):
        #sb.color = RED
        print("next btn_clicked")

    def prev_btn_clicked(self):
        #sb.color = RED
        print("prev btn_clicked")

    def restart_btn_clicked(self):
        #sb.color = RED
        print("prev btn_clicked")

    def new_game(self, title, fen, best_moves):

        self.board.from_fen(fen)
        self.best_moves = best_moves.split(",")
        self.best_index = 0

        self.selected = None
        self.last_moved = None
        self.move_history = []
        self.dead_side = None
        self.kill_count = 0

        engine = self.engine[self.board.move_side]
        if engine:
            engine.go_from(self.board.to_fen())
        #pygame.display.set_caption(title.encode('utf-8'))
        pygame.display.set_caption(title)

    def attach_engine(self, engine, side):
        self.engine[side] = engine

    def try_move(self, move_from, move_to):

        if not self.board.is_valid_move(move_from, move_to):
            # print u"走法错误."
            return (False, None)

        check_count = self.board.is_checked_move(move_from, move_to)
        if check_count:
            if self.last_checked:
                print(u"必须应将。")
            else:
                print(u"不能送将。")
            return (False, None)

        self.show_move(move_from, move_to)
        move = self.board.move(move_from, move_to)
        print(move.to_chinese())

        self.last_moved = Pos(move_to.x, move_to.y)
        self.selected = None

        if self.best_index >= 0:
            if move.to_iccs() == self.best_moves[self.best_index]:
                self.good_box.text = "Good"
                print(u"GOOD")
                self.best_index += 1
            else:
                self.good_box.text = "Not Good"
                self.best_index = -1
        if self.best_index >= len(self.best_moves):
            self.best_index = -1

        engine = self.engine[self.board.move_side]
        if engine:
            engine.stop_thinking()
        self.board.next_turn()

        move.for_ucci(self.board.move_side, self.move_history)
        self.move_history.append(move)

        if self.board.is_checkmate():
            self.info_box.text = "Dead!"
            print(u"将死!")
            return (True, self.board.move_side)

        self.last_checked = self.board.is_checked()
        if self.last_checked:
            self.info_box.text = "Checked!"
            print(u"将军!")

        if move.is_king_killed():
            self.info_box.text = "Killed!"
            print(u"杀死!")
            return (True, self.board.move_side)

        engine = self.engine[self.board.move_side]
        if engine:
            #print move.to_ucci_fen()
            if self.best_index >= 0:
                engine.preset_best_move(self.best_moves[self.best_index])
            else:
                engine.go_from(move.to_ucci_fen())

        return (True, None)

    def draw(self):

        self.screen.fill((0, 0, 0))
        self.screen.blit(self.surface, (0, 0))

        for x in range(9):
            for y in range(10):
                key = Pos(x, y)
                piece = self.board.get_piece(key)
                if not piece:
                    continue

                image = self.pieces_image[piece.fench.lower()]
                board_pos = pos_to_screen(key)

                if piece.side == ChessSide.RED:
                    offset = (0, 0, 52, 52)
                else:
                    offset = (53, 0, 52, 52)

                self.screen.blit(image, board_pos(), offset)

                if self.selected and key == self.selected:
                    self.screen.blit(self.select_surface, board_pos(), offset)
                elif self.last_moved and key == self.last_moved:
                    self.screen.blit(self.done_surface, board_pos(), offset)

                # elif key == self.done:
                #    self.screen.blit(self.over_surface, board_pos(), offset)

    def make_move_steps(self, p_from, p_to):

        steps = []
        step_count = 7

        for i in range(step_count):
            x = p_from.x + (p_to.x - p_from.x) / step_count * (i + 1)
            y = p_from.y + (p_to.y - p_from.y) / step_count * (i + 1)
            steps.append(Pos(x, y))

        return steps

    def show_move(self, p_from, p_to):

        board_p_from = pos_to_screen(p_from)
        board_p_to = pos_to_screen(p_to)
        steps = self.make_move_steps(board_p_from, board_p_to)

        for step in steps:
            self.screen.blit(self.surface, (0, 0))

            for x in range(9):
                for y in range(10):
                    key = Pos(x, y)
                    piece = self.board.get_piece(key)
                    if piece is None:
                        continue

                    board_pos = pos_to_screen(piece)
                    image = self.pieces_image[piece.fench.lower()]
                    offset = (int(piece.side) * 53, 0, 52, 52)
                    if key == p_from:
                        self.screen.blit(image, step(), offset)
                    else:
                        self.screen.blit(image, board_pos(), offset)

            pygame.display.flip()
            pygame.event.pump()
            msElapsed = self.clock.tick(30)

    def run_once(self):

        if self.kill_count:
            self.kill_count += 1
            #print self.kill_count
            if self.kill_count > 60:
                return (False, self.dead_side)

        engine = self.engine[self.board.move_side]

        if engine:
            engine.handle_msg_once()
            if not engine.move_queue.empty():
                output = engine.move_queue.get()
                # print output
                if output[0] == 'best_move':
                    p_from, p_to = output[1]["move"]
                    has_moved, dead_side = self.try_move(p_from, p_to)
                    if dead_side is not None:
                        self.kill_count = 1
                        self.dead_side = self.board.move_side
                        #return (False, dead_side)
                    if not has_moved:
                        print("engine output error", p_from, p_to)

                elif output[0] == 'dead':
                    # print self.board.move_side
                    print(win_dict[self.board.move_side])
                    self.kill_count = 1
                    self.dead_side = self.board.move_side
                    #return (False, self.board.move_side)

        self.clock.tick(30)

        for event in pygame.event.get():
            if event.type == QUIT:
                return (True, None)

            self.back_btn.update(event)
            self.next_btn.update(event)
            self.prev_btn.update(event)
            self.restart_btn.update(event)

            if event.type == MOUSEBUTTONDOWN:
                #print(event.button)
                mouse_left_down, _, mouse_right_down = pygame.mouse.get_pressed(
                )

                #if mouse_right_down:
                #    return (False, -1)

                sx, sy = mouse = pygame.mouse.get_pos()

                if mouse in self.back_btn:
                    self.back_btn.click()
                elif mouse in self.next_btn:
                    self.next_btn.click()
                elif mouse in self.prev_btn:
                    self.prev_btn.click()
                elif mouse in self.restart_btn:
                    #self.restart_btn.click()
                    return (False, -1)

                if sx < BORDER or sx > (WIDTH - BORDER):
                    break
                if sy < BORDER or sy > (HEIGHT - BORDER):
                    break

                key = screen_to_pos(Pos(sx, sy))
                piece = self.board.get_piece(key)

                if piece and piece.side == self.board.move_side:
                    self.selected = key
                    self.last_moved = None
                else:
                    # move check
                    has_moved = False
                    if self.selected and (key != self.selected):
                        move_from = self.selected
                        move_to = key
                        has_moved, dead_side = self.try_move(
                            move_from, move_to)

                        if dead_side is not None:
                            self.kill_count = 1
                            self.dead_side = dead_side
                            #time.sleep(1)
                            #return (False, dead_side)

                        # pickup check
                        # if not has_moved:
                        #    piece = self.board.get_piece(key)
                        #    if piece and piece.side == self.board.move_side:
                        #        self.selected = key
                        #        self.last_moved = None
            elif event.type == MOUSEBUTTONUP:
                self.back_btn.release()
                self.next_btn.release()
                self.prev_btn.release()
                self.restart_btn.release()

        self.draw()
        self.back_btn.render(self.screen)
        self.next_btn.render(self.screen)
        self.prev_btn.render(self.screen)
        self.restart_btn.render(self.screen)
        self.info_box.render(self.screen)
        self.good_box.render(self.screen)
        pygame.display.flip()

        return (False, None)