from enum import IntEnum
import pygame
from pygame.locals import *
import copy
import time
version = 'FiveChessV2.0 author:ZeHao Cao most_recent_updated:2020/6/4 21:24'
# 基础参数设置
square_size = 40 # 单格的宽度(不是格数!是为了方便绘制棋盘用的变量
chess_size = square_size // 2 - 2 # 棋子大小
web_broad = 17 # 棋盘格数+1(nxn)
map_w = web_broad * square_size # 棋盘长度
map_h = web_broad * square_size # 棋盘高度
info_w = 60 # 按钮界面宽度
button_w = 140 # 按钮长宽
button_h = 50
screen_w = map_w # 总窗口长宽
screen_h = map_h + info_w
# 地图绘制模块
class MAP_ENUM(IntEnum): # 用数字表示当前格的情况
be_empty = 0, # 无人下
player1 = 1, # 玩家一,执白
player2 = 2, # 玩家二,执黑
out_of_range = 3, # 出界
class Map: # 地图类
def __init__(self, width, height): # 构造函数
self.width = width
self.height = height
self.map = [[0 for x in range(self.width)] for y in range(self.height)] # 存储棋盘的二维数组
self.steps = [] # 记录步骤先后
def get_init(self): # 重置棋盘
for y in range(self.height):
for x in range(self.width):
self.map[y][x] = 0
self.steps = []
def intoNextTurn(self, turn): # 进入下一回合,交换下棋人
if turn == MAP_ENUM.player1:
return MAP_ENUM.player2
else:
return MAP_ENUM.player1
def getLocate(self, x, y): # 输入下标,返回具体位置
map_x = x * square_size
map_y = y * square_size
return (map_x, map_y, square_size, square_size) # 返回位置信息
def getIndex(self, map_x, map_y): # 输入具体位置,返回下标
x = map_x // square_size
y = map_y // square_size
return (x, y)
def isInside(self, map_x, map_y): # 是否在有效范围内
if (map_x <= 0 or map_x >= map_w or
map_y <= 0 or map_y >= map_h):
return False
return True
def isEmpty(self, x, y): # 当前格子是否已经有棋子
return (self.map[y][x] == 0)
def click(self, x, y, type): # 点击的下棋动作
self.map[y][x] = type.value # 下棋
self.steps.append((x, y)) # 记录步骤信息
def printChessPiece(self, screen): # 绘制棋子
player_one = (255, 245, 238) # 象牙白
player_two = (41, 36, 33) # 烟灰
player_color = [player_one, player_two]
for i in range(len(self.steps)):
x, y = self.steps[i]
map_x, map_y, width, height = self.getLocate(x, y)
pos, radius = (map_x + width // 2, map_y + height // 2), chess_size
turn = self.map[y][x]
pygame.draw.circle(screen, player_color[turn - 1], pos, radius) # 画
def drawBoard(self, screen): # 画棋盘
color = (0, 0, 0) # 线色
for y in range(self.height):
# 画横着的棋盘线
start_pos, end_pos = (square_size // 2, square_size // 2 + square_size * y), (
map_w - square_size // 2, square_size // 2 + square_size * y)
pygame.draw.line(screen, color, start_pos, end_pos, 1)
for x in range(self.width):
# 画竖着的棋盘线
start_pos, end_pos = (square_size // 2 + square_size * x, square_size // 2), (
square_size // 2 + square_size * x, map_h - square_size // 2)
pygame.draw.line(screen, color, start_pos, end_pos, 1)
# 高级AI模块(参考文献)
class SITUATION(IntEnum): # 棋型
NONE = 0, # 无
SLEEP_TWO = 1, # 眠二
LIVE_TWO = 2, # 活二
SLEEP_THREE = 3, # 眠三
LIVE_THREE = 4, # 活三
CHONG_FOUR = 5, # 冲四
LIVE_FOUR = 6, # 活四
LIVE_FIVE = 7, # 活五
SITUATION_NUM = 8 # 长度
# 方便后续调用枚举内容
FIVE = SITUATION.LIVE_FIVE.value
FOUR, THREE, TWO = SITUATION.LIVE_FOUR.value, SITUATION.LIVE_THREE.value, SITUATION.LIVE_TWO.value
SFOUR, STHREE, STWO = SITUATION.CHONG_FOUR.value, SITUATION.SLEEP_THREE.value, SITUATION.SLEEP_TWO.value
class MyChessAI():
def __init__(self, chess_len): # 构造函数
self.len = chess_len # 当前棋盘大小
# 二维数组,每一格存的是:横评分,纵评分,左斜评分,右斜评分
self.record = [[[0, 0, 0, 0] for i in range(chess_len)] for j in range(chess_len)]
# 存储当前格具体棋型数量
self.count = [[0 for i in range(SITUATION_NUM)] for j in range(2)]
# 位置分(同条件下越靠近棋盘中央越高)
self.position_isgreat = [[(web_broad - max(abs(i - web_broad / 2 + 1), abs(j - web_broad / 2 + 1 ))) for i in range(chess_len)]
for j in ran