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()
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()
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)