围棋
2017-05-20
这几天心情不佳,耽搁了随笔记录。补上今天的作品,花了一天时间使用pygame制作了个围棋游戏,代码逻辑比较简单清晰,实现了基本的下棋、吃子功能、计算棋子的活,还有很多细节处理的不是很好,如重新开始游戏、游戏局势、悔棋、棋谱制作。
主要是想以后有机会试一试蒙特卡洛或者其他神经网络方法。
运行效果如下:

代码如下:
# coding:utf-8
import pygame
from pygame.locals import *
import sys
import copy
CLICK = USEREVENT + 1
BLACK = 100
WHITE = 101
RED = 102
GREY = 103
LIGHTGRAY = 104
GAME_START = 200
GAME_PAUSE = 201
GAME_END = 202
INVFONT = 301
FONT2 = 302
pygame.init()
fonts = {
FONT2: pygame.font.Font('./resources/mnjdy.ttf', 18)
}
colors = {
BLACK: (0, 0, 0),
RED: (255, 0, 0),
GREY: (190, 190, 190),
LIGHTGRAY:(211, 211, 211),
WHITE: (255, 255, 255)
}
blackChess = 1
whiteChess = 2
icon = 0
textures = {
blackChess: pygame.image.load('./resources/blackChess.png'),
whiteChess: pygame.image.load('./resources/whiteChess.png'),
icon: pygame.image.load('./resources/yscc.ico')
}
class Panel(object):
def __init__(self):
# 棋盘的边界距
self.posX = 40
self.posY = 40
# 棋盘格子数
self.width = 19
self.height = 19
# 每一个格子的大小
self.tileSize = 30
self.htileSize = self.tileSize / 2
# 棋盘
self.tiles = [[0 for _ in range(0, 19)] for _ in range(0, 19)]
# 棋盘大小
self.w = self.width * self.tileSize
self.h = self.height * self.tileSize
# 鼠标位置
self.mouseX = 0
self.mouseY = 0
# 黑白棋执手 黑棋为1 白棋为2
self.flag = 1
# 黑棋数目
self.blackChessCount = 0
# 白棋数目
self.whiteChessCount = 0
self.info1 = ''
self.info2 = ''
self.info3 = ''
def getPos(self, pos):
return (pos[0] - self.posX + self.htileSize,
pos[1] - self.posY +self.htileSize)
def update(self,screen):
for x in range(0, self.width):
for y in range(0, self.height):
#pygame.draw.aaline(screen, (0, 0, 0),
# (int(self.posX + x * self.tileSize), int(self.posY + y * self.tileSize)),
# (int(self.posX + x * self.tileSize), int(self.posY + y)),False)
#pygame.draw.aaline(screen, (0, 0, 0), False,
# (self.posX + x * self.tileSize, self.posY + y * self.tileSize),
# (self.posX + x, self.posY + y * self.tileSize))
pygame.draw.line(screen, colors[BLACK],
(self.posX + x * self.tileSize, self.posY + y * self.tileSize), (self.posX + x * self.tileSize, self.posY + y))
pygame.draw.line(screen, colors[BLACK],
(self.posX + x * self.tileSize, self.posY + y * self.tileSize), (self.posX + x, self.posY + y * self.tileSize))
for x in range(0, self.width):
for y in range(0, self.height):
if self.tiles[x][y] == 1:
#blackC = pygame.transform.scale(textures[blackChess], (self.tileSize, self.tileSize))
#screen.blit(blackC, (self.posX + x*self.tileSize - self.htileSize, self.posY + y*self.tileSize - self.htileSize))
pos = (int(self.posX + x*self.tileSize), int(self.posY + y*self.tileSize))
pygame.draw.circle(screen, colors[BLACK],
pos, int(self.htileSize))
if self.tiles[x][y] == 2:
#whiteC = pygame.transform.scale(textures[whiteChess], (self.tileSize, self.tileSize))
#screen.blit(whiteC, (self.posX + x * self.tileSize - self.htileSize, self.posY + y * self.tileSize - self.htileSize))
pos = (int(self.posX + x * self.tileSize), int(self.posY + y * self.tileSize))
pygame.draw.circle(screen, colors[GREY],
pos, int(self.htileSize))
self.drawRedCircle(screen)
def drawRedCircle(self, screen):
pos = (int(self.mouseX*self.tileSize)+self.posX, int(self.mouseY * self.tileSize)+self.posY)
pygame.draw.circle(screen, colors[RED],
pos, int(self.htileSize), 1)
def mouseEvent(self, event):
if event.type == MOUSEMOTION:
pos = self.getPos(event.dict['pos'])
if int(pos[0] / self.tileSize) < self.width:
self.mouseX = int(pos[0] / self.tileSize)
elif int(pos[0] / self.tileSize) > self.width:
self.mouseX = self.width - 1
if int(pos[1] / self.tileSize) < self.height:
self.mouseY = int(pos[1] / self.tileSize)
elif int(pos[1] / self.tileSize) > self.height:
self.mouseY = self.height - 1
tiles = copy.deepcopy(self.tiles)
flag = tiles[self.mouseX][self.mouseY]
if flag == 1:
self.info1 = '当前棋子颜色:黑'
self.info2 = '当前棋子坐标:('+str(self.mouseX)+','+str(self.mouseY)+')'
self.info3 = '当前棋子活:'+str(self.judgeOne(self.mouseX, self.mouseY, flag, tiles))
if flag == 2:
self.info1 = '当前棋子颜色:白'
self.info2 = '当前棋子坐标:('+str(self.mouseX)+','+str(self.mouseY)+')'
self.info3 = '当前棋子活:'+str(self.judgeOne(self.mouseX, self.mouseY, flag, tiles))
elif event.type == MOUSEBUTTONUP:
if event.button == 1:
pos = self.getPos(event.dict['pos'])
if 0 <= int(pos[0] / self.tileSize) < self.width and 0 <= int(pos[1] / self.tileSize) < self.height:
if self.tiles[self.mouseX][self.mouseY] == 0:
if self.flag == 1:
self.tiles[self.mouseX][self.mouseY] = 1
self.flag = 2
self.blackChessCount += 1
else:
self.tiles[self.mouseX][self.mouseY] =2
self.flag = 1
self.whiteChessCount += 1
tiles = copy.deepcopy(self.tiles)
X = [(0,1),(1,0),(0,-1),(-1,0)]
for x in X:
if 0 <= self.mouseX + x[0] < self.width and 0 <= self.mouseY + x[1] < self.height:
if self.tiles[self.mouseX + x[0]][self.mouseY + x[1]] == self.flag:
if self.judgeOne(self.mouseX + x[0], self.mouseY + x[1], self.flag, tiles) == 0:
self.removeArea(self.mouseX + x[0], self.mouseY + x[1], self.flag)
def judgeOne(self, x, y, flag, tiles):
tiles[x][y] = -1 * flag
i = 0
if x - 1 >= 0:
if tiles[x - 1][y] == 0:
i += 1
elif tiles[x - 1][y] == flag:
i += self.judgeOne(x - 1, y, flag, tiles)
if x + 1 < self.width:
if tiles[x + 1][y] == 0:
i += 1
elif tiles[x + 1][y] == flag:
i += self.judgeOne(x + 1, y, flag, tiles)
if y - 1 >= 0:
if tiles[x][y - 1] == 0:
i += 1
elif tiles[x][y - 1] == flag:
i += self.judgeOne(x, y - 1, flag, tiles)
if y + 1 < self.height:
if tiles[x][y + 1] == 0:
i += 1
elif tiles[x][y + 1] == flag:
i += self.judgeOne(x, y + 1, flag, tiles)
return i
def removeArea(self, x, y, flag):
if self.tiles[x][y] != flag:
return
self.tiles[x][y] = 0
if x - 1 >= 0:
if self.tiles[x - 1][y] == flag:
self.removeArea(x - 1, y, flag)
if x + 1 >= 0:
if self.tiles[x + 1][y] == flag:
self.removeArea(x + 1, y, flag)
if y - 1 >= 0:
if self.tiles[x][y - 1] == flag:
self.removeArea(x, y - 1, flag)
if y + 1 >= 0:
if self.tiles[x][y + 1] == flag:
self.removeArea(x, y + 1, flag)
class Surrender(object):
def __init__(self):
self.windowWidth = 900
self.windowHeight = 600
self.panel = Panel()
self.status = GAME_PAUSE
self.DISPLAYSURF = pygame.display.set_mode((900, 600))
self.fpsClock = pygame.time.Clock()
def drawText(self, screen, text, x, y):
textObj = fonts[FONT2].render(text, True, colors[BLACK], colors[GREY])
screen.blit(textObj, (x, y))
def update(self):
self.fpsClock.tick(24)
self.DISPLAYSURF.fill(colors[WHITE])
self.panel.update(self.DISPLAYSURF)
self.drawText(self.DISPLAYSURF, '黑子总数:'+str(self.panel.blackChessCount), 650, 40)
self.drawText(self.DISPLAYSURF, '白子总数:'+str(self.panel.whiteChessCount), 650, 80)
self.drawText(self.DISPLAYSURF, self.panel.info1, 650, 120)
self.drawText(self.DISPLAYSURF, self.panel.info2, 650, 160)
self.drawText(self.DISPLAYSURF, self.panel.info3, 650, 200)
pygame.draw.rect(self.DISPLAYSURF,
colors[RED],
(0, 0, self.windowWidth, self.windowHeight),2)
pygame.display.update()
def mouseEvent(self, event):
self.panel.mouseEvent(event)
def exit(self):
pygame.quit()
sys.exit()
if __name__ == "__main__":
game = Surrender()
pygame.display.set_caption("Yscc-Surrender")
pygame.display.set_icon(textures[icon])
pygame.time.set_timer(CLICK, 1000)
while True:
game.update()
for event in pygame.event.get():
print(event)
if event.type == QUIT:
game.exit()
if event.type == MOUSEMOTION or event.type == MOUSEBUTTONDOWN or event.type == MOUSEBUTTONUP:
game.mouseEvent(event)