parent
34f1d261ae
commit
898c7c02e1
@ -0,0 +1,185 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
|
||||
"""
|
||||
import pygame
|
||||
import sys
|
||||
from pygame import gfxdraw
|
||||
import random
|
||||
|
||||
pygame.init()
|
||||
screen = pygame.display.set_mode((800, 700))
|
||||
pygame.display.set_caption('五子棋-Educoder')
|
||||
BOARD_COLOR = (204, 153, 102)
|
||||
GRID_COLOR = (0, 0, 0)
|
||||
BLACK_COLOR = (0, 0, 0)
|
||||
WHITE_COLOR = (255, 255, 255)
|
||||
TEXT_COLOR = (255, 255, 255)
|
||||
RESULT_COLOR = (255, 0, 0)
|
||||
BTN_COLOR = (100, 100, 200)
|
||||
BTN_HOVER_COLOR = (120, 120, 220)
|
||||
space = 30
|
||||
cell_size = 38
|
||||
cell_num = 15
|
||||
board_size = cell_size * (cell_num - 1) + space * 2
|
||||
right_panel_width = 250
|
||||
chess_arr = []
|
||||
current_player = 1
|
||||
game_state = 1
|
||||
black_wins = 0
|
||||
white_wins = 0
|
||||
restart_btn = pygame.Rect(580, 100, 180, 50)
|
||||
reset_btn = pygame.Rect(580, 180, 180, 50)
|
||||
exit_btn = pygame.Rect(580, 260, 180, 50)
|
||||
pygame.font.init()
|
||||
font = pygame.font.SysFont(["SimHei", "Microsoft YaHei"], 36)
|
||||
small_font = pygame.font.SysFont(["SimHei", "Microsoft YaHei"], 28)
|
||||
|
||||
def draw_board():
|
||||
screen.fill(BOARD_COLOR)
|
||||
for i in range(cell_num):
|
||||
pygame.draw.line(screen, GRID_COLOR,
|
||||
(space, space + i * cell_size),
|
||||
(space + (cell_num - 1) * cell_size, space + i * cell_size), 2)
|
||||
pygame.draw.line(screen, GRID_COLOR,
|
||||
(space + i * cell_size, space),
|
||||
(space + i * cell_size, space + (cell_num - 1) * cell_size), 2)
|
||||
star_points = [(3, 3), (11, 3), (3, 11), (11, 11), (7, 7)]
|
||||
for x, y in star_points:
|
||||
gfxdraw.filled_circle(screen, space + x * cell_size, space + y * cell_size, 6, GRID_COLOR)
|
||||
gfxdraw.aacircle(screen, space + x * cell_size, space + y * cell_size, 6, GRID_COLOR)
|
||||
pygame.draw.rect(screen, GRID_COLOR,
|
||||
(space - 5, space - 5, board_size - space * 2 + 10, board_size - space * 2 + 10), 5)
|
||||
|
||||
def draw_chess():
|
||||
for x, y, color in chess_arr:
|
||||
center_x = space + x * cell_size
|
||||
center_y = space + y * cell_size
|
||||
if color == 1:
|
||||
gfxdraw.filled_circle(screen, center_x, center_y, 18, (0, 0, 0))
|
||||
gfxdraw.aacircle(screen, center_x, center_y, 18, (0, 0, 0))
|
||||
gfxdraw.filled_circle(screen, center_x - 4, center_y - 4, 5, (80, 80, 80))
|
||||
gfxdraw.aacircle(screen, center_x - 4, center_y - 4, 5, (80, 80, 80))
|
||||
gfxdraw.aacircle(screen, center_x, center_y, 17, (50, 50, 50))
|
||||
else:
|
||||
gfxdraw.filled_circle(screen, center_x, center_y, 18, (255, 255, 255))
|
||||
gfxdraw.aacircle(screen, center_x, center_y, 18, (255, 255, 255))
|
||||
gfxdraw.filled_circle(screen, center_x - 4, center_y - 4, 5, (255, 255, 255))
|
||||
gfxdraw.aacircle(screen, center_x - 4, center_y - 4, 5, (255, 255, 255))
|
||||
gfxdraw.aacircle(screen, center_x, center_y, 17, (200, 200, 200))
|
||||
|
||||
def draw_status():
|
||||
title_text = "五子棋游戏"
|
||||
text_surface = font.render(title_text, True, BLACK_COLOR)
|
||||
screen.blit(text_surface, (580, 30))
|
||||
current_text = f"当前玩家: {'黑棋' if current_player == 1 else '白棋'}"
|
||||
text_surface = small_font.render(current_text, True, BLACK_COLOR)
|
||||
screen.blit(text_surface, (580, 400))
|
||||
stats_text = f"黑棋胜利: {black_wins} 局"
|
||||
text_surface = small_font.render(stats_text, True, (50, 50, 200))
|
||||
screen.blit(text_surface, (580, 450))
|
||||
stats_text = f"白棋胜利: {white_wins} 局"
|
||||
text_surface = small_font.render(stats_text, True, (200, 50, 50))
|
||||
screen.blit(text_surface, (580, 500))
|
||||
draw_button(restart_btn, "重新开始")
|
||||
draw_button(reset_btn, "重置统计")
|
||||
draw_button(exit_btn, "退出游戏")
|
||||
|
||||
def draw_button(rect, text):
|
||||
mouse_pos = pygame.mouse.get_pos()
|
||||
color = BTN_HOVER_COLOR if rect.collidepoint(mouse_pos) else BTN_COLOR
|
||||
pygame.draw.rect(screen, color, rect, border_radius=10)
|
||||
pygame.draw.rect(screen, GRID_COLOR, rect, 2, border_radius=10)
|
||||
text_surface = small_font.render(text, True, TEXT_COLOR)
|
||||
text_rect = text_surface.get_rect(center=rect.center)
|
||||
screen.blit(text_surface, text_rect)
|
||||
|
||||
def draw_result():
|
||||
s = pygame.Surface((board_size - space * 2 + 5, board_size - space * 2 + 5), pygame.SRCALPHA)
|
||||
s.fill((0, 0, 0, 180))
|
||||
screen.blit(s, (space, space))
|
||||
result_text = "黑棋获胜!" if game_state == 2 else "白棋获胜!"
|
||||
text_surface = font.render(result_text, True, RESULT_COLOR)
|
||||
text_rect = text_surface.get_rect(center=(board_size // 2, board_size // 2 - 20))
|
||||
screen.blit(text_surface, text_rect)
|
||||
hint_text = "点击任意位置继续"
|
||||
text_surface = small_font.render(hint_text, True, TEXT_COLOR)
|
||||
text_rect = text_surface.get_rect(center=(board_size // 2, board_size // 2 + 20))
|
||||
screen.blit(text_surface, text_rect)
|
||||
|
||||
def get_one_dire_num(lx, ly, dx, dy, matrix):
|
||||
tx, ty, count = lx, ly, 0
|
||||
while True:
|
||||
tx += dx
|
||||
ty += dy
|
||||
if tx < 0 or tx >= cell_num or ty < 0 or ty >= cell_num or matrix[ty][tx] == 0:
|
||||
return count
|
||||
count += 1
|
||||
|
||||
def check_win():
|
||||
if not chess_arr:
|
||||
return False
|
||||
matrix = [[0] * cell_num for _ in range(cell_num)]
|
||||
for x, y, c in chess_arr:
|
||||
if c == current_player:
|
||||
matrix[y][x] = 1
|
||||
lx, ly = chess_arr[-1][0], chess_arr[-1][1]
|
||||
directions = [[(-1, 0), (1, 0)], [(0, -1), (0, 1)], [(-1, -1), (1, 1)], [(-1, 1), (1, -1)]]
|
||||
for dire1, dire2 in directions:
|
||||
num1 = get_one_dire_num(lx, ly, dire1[0], dire1[1], matrix)
|
||||
num2 = get_one_dire_num(lx, ly, dire2[0], dire2[1], matrix)
|
||||
if num1 + num2 + 1 >= 5:
|
||||
return True
|
||||
return False
|
||||
|
||||
def reset_game():
|
||||
global chess_arr, current_player, game_state
|
||||
chess_arr = []
|
||||
game_state = 1
|
||||
current_player = random.choice([1, 2])
|
||||
|
||||
def main():
|
||||
global chess_arr, current_player, game_state, black_wins, white_wins
|
||||
clock = pygame.time.Clock()
|
||||
while True:
|
||||
screen.fill(BOARD_COLOR)
|
||||
for event in pygame.event.get():
|
||||
if event.type == pygame.QUIT:
|
||||
pygame.quit()
|
||||
sys.exit()
|
||||
if event.type == pygame.MOUSEBUTTONDOWN:
|
||||
mouse_x, mouse_y = event.pos
|
||||
if restart_btn.collidepoint(mouse_x, mouse_y):
|
||||
reset_game()
|
||||
elif reset_btn.collidepoint(mouse_x, mouse_y):
|
||||
black_wins = 0
|
||||
white_wins = 0
|
||||
reset_game()
|
||||
elif exit_btn.collidepoint(mouse_x, mouse_y):
|
||||
pygame.quit()
|
||||
sys.exit()
|
||||
if game_state == 1 and space <= mouse_x <= space + board_size - space * 2 and space <= mouse_y <= space + board_size - space * 2:
|
||||
xi = round((mouse_x - space) / cell_size)
|
||||
yi = round((mouse_y - space) / cell_size)
|
||||
if 0 <= xi < cell_num and 0 <= yi < cell_num and (xi, yi, 1) not in chess_arr and (xi, yi, 2) not in chess_arr:
|
||||
chess_arr.append((xi, yi, current_player))
|
||||
if check_win():
|
||||
game_state = 2 if current_player == 1 else 3
|
||||
if current_player == 1:
|
||||
black_wins += 1
|
||||
else:
|
||||
white_wins += 1
|
||||
else:
|
||||
current_player = 2 if current_player == 1 else 1
|
||||
elif game_state != 1:
|
||||
reset_game()
|
||||
draw_board()
|
||||
draw_chess()
|
||||
draw_status()
|
||||
if game_state != 1:
|
||||
draw_result()
|
||||
pygame.display.flip()
|
||||
clock.tick(60)
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
Loading…
Reference in new issue