盐水冲茶的个人小站 +

围棋

这几天心情不佳,耽搁了随笔记录。补上今天的作品,花了一天时间使用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)

Blog

Dump

Project