zoukankan      html  css  js  c++  java
  • python 五子棋

    参考http://www.skywind.me/blog/archives/1029

    http://blog.csdn.net/skywind/article/details/8164713

    https://github.com/skywind3000/gobang

    gobang

    Gobang game with artificial intelligence in 900 Lines !!

    How to play

    Download:

    git clone https://github.com/skywind3000/gobang.git gobang

    play in normal mode:

    python gobang/gobang.py

    play in hard mode:

    python gobang/gobang.py hard

    Game Rule

    Make five or more stones in a in to win. You will make your move by enter the coordinate value (row + column) of the chess-board to defeat the AI competitor.

    Play it in the console:

    Character 'O' - black stone (you) Character 'X' - white stone (computer)

    if you want to make a new move below the white stone 'X', just enter 'JI' (row is 'J', and column is 'I'):

    After entering 'JI' the computer will think for a few seconds and makes its move too. Then another turn begins, you can input new row-col values to continue playing until someone wins.

    #! /usr/bin/env python
    # -*- coding: utf-8 -*-
    import sys, time
    
    
    #----------------------------------------------------------------------
    # chessboard: 棋盘类,简单从字符串加载棋局或者导出字符串,判断输赢等
    #----------------------------------------------------------------------
    class chessboard (object):
    
    	def __init__ (self, forbidden = 0):
    		self.__board = [ [ 0 for n in xrange(15) ] for m in xrange(15) ]
    		self.__forbidden = forbidden
    		self.__dirs = ( (-1, 0), (-1, 1), (0, 1), (1, 1), (1, 0), 
    			(1, -1), (0, -1), (-1, -1) )
    		self.DIRS = self.__dirs
    		self.won = {}
    	
    	# 清空棋盘
    	def reset (self):
    		for j in xrange(15):
    			for i in xrange(15):
    				self.__board[i][j] = 0
    		return 0
    	
    	# 索引器
    	def __getitem__ (self, row):
    		return self.__board[row]
    
    	# 将棋盘转换成字符串
    	def __str__ (self):
    		text = '  A B C D E F G H I J K L M N O
    '
    		mark = ('. ', 'O ', 'X ')
    		nrow = 0
    		for row in self.__board:
    			line = ''.join([ mark[n] for n in row ])
    			text += chr(ord('A') + nrow) + ' ' + line
    			nrow += 1
    			if nrow < 15: text += '
    '
    		return text
    	
    	# 转成字符串
    	def __repr__ (self):
    		return self.__str__()
    
    	def get (self, row, col):
    		if row < 0 or row >= 15 or col < 0 or col >= 15:
    			return 0
    		return self.__board[row][col]
    
    	def put (self, row, col, x):
    		if row >= 0 and row < 15 and col >= 0 and col < 15:
    			self.__board[row][col] = x
    		return 0
    	
    	# 判断输赢,返回0(无输赢),1(白棋赢),2(黑棋赢)
    	def check (self):
    		board = self.__board
    		dirs = ((1, -1), (1, 0), (1, 1), (0, 1))
    		for i in xrange(15):
    			for j in xrange(15):
    				if board[i][j] == 0: continue
    				id = board[i][j]
    				for d in dirs:
    					x, y = j, i
    					count = 0
    					for k in xrange(5):
    						if self.get(y, x) != id: break
    						y += d[0]
    						x += d[1]
    						count += 1
    					if count == 5:
    						self.won = {}
    						r, c = i, j
    						for z in xrange(5):
    							self.won[(r, c)] = 1
    							r += d[0]
    							c += d[1]
    						return id
    		return 0
    	
    	# 返回数组对象
    	def board (self):
    		return self.__board
    	
    	# 导出棋局到字符串
    	def dumps (self):
    		import StringIO
    		sio = StringIO.StringIO()
    		board = self.__board
    		for i in xrange(15):
    			for j in xrange(15):
    				stone = board[i][j]
    				if stone != 0:
    					ti = chr(ord('A') + i)
    					tj = chr(ord('A') + j)
    					sio.write('%d:%s%s '%(stone, ti, tj))
    		return sio.getvalue()
    	
    	# 从字符串加载棋局
    	def loads (self, text):
    		self.reset()
    		board = self.__board
    		for item in text.strip('
    	 ').replace(',', ' ').split(' '):
    			n = item.strip('
    	 ')
    			if not n: continue
    			n = n.split(':')
    			stone = int(n[0])
    			i = ord(n[1][0].upper()) - ord('A')
    			j = ord(n[1][1].upper()) - ord('A')
    			board[i][j] = stone
    		return 0
    
    	# 设置终端颜色
    	def console (self, color):
    		if sys.platform[:3] == 'win':
    			try: import ctypes
    			except: return 0
    			kernel32 = ctypes.windll.LoadLibrary('kernel32.dll')
    			GetStdHandle = kernel32.GetStdHandle
    			SetConsoleTextAttribute = kernel32.SetConsoleTextAttribute
    			GetStdHandle.argtypes = [ ctypes.c_uint32 ]
    			GetStdHandle.restype = ctypes.c_size_t
    			SetConsoleTextAttribute.argtypes = [ ctypes.c_size_t, ctypes.c_uint16 ]
    			SetConsoleTextAttribute.restype = ctypes.c_long
    			handle = GetStdHandle(0xfffffff5)
    			if color < 0: color = 7
    			result = 0
    			if (color & 1): result |= 4
    			if (color & 2): result |= 2
    			if (color & 4): result |= 1
    			if (color & 8): result |= 8
    			if (color & 16): result |= 64
    			if (color & 32): result |= 32
    			if (color & 64): result |= 16
    			if (color & 128): result |= 128
    			SetConsoleTextAttribute(handle, result)
    		else:
    			if color >= 0:
    				foreground = color & 7
    				background = (color >> 4) & 7
    				bold = color & 8
    				sys.stdout.write(" 33[%s3%d;4%dm"%(bold and "01;" or "", foreground, background))
    				sys.stdout.flush()
    			else:
    				sys.stdout.write(" 33[0m")
    				sys.stdout.flush()
    		return 0
    	
    	# 彩色输出
    	def show (self):
    		print '  A B C D E F G H I J K L M N O'
    		mark = ('. ', 'O ', 'X ')
    		nrow = 0
    		self.check()
    		color1 = 10
    		color2 = 13
    		for row in xrange(15):
    			print chr(ord('A') + row),
    			for col in xrange(15):
    				ch = self.__board[row][col]
    				if ch == 0: 
    					self.console(-1)
    					print '.',
    				elif ch == 1:
    					if (row, col) in self.won:
    						self.console(9)
    					else:
    						self.console(10)
    					print 'O',
    					#self.console(-1)
    				elif ch == 2:
    					if (row, col) in self.won:
    						self.console(9)
    					else:
    						self.console(13)
    					print 'X',
    					#self.console(-1)
    			self.console(-1)
    			print ''
    		return 0
    
    
    #----------------------------------------------------------------------
    # evaluation: 棋盘评估类,给当前棋盘打分用
    #----------------------------------------------------------------------
    class evaluation (object):
    
    	def __init__ (self):
    		self.POS = []
    		for i in xrange(15):
    			row = [ (7 - max(abs(i - 7), abs(j - 7))) for j in xrange(15) ]
    			self.POS.append(tuple(row))
    		self.POS = tuple(self.POS)
    		self.STWO = 1		# 冲二
    		self.STHREE = 2		# 冲三
    		self.SFOUR = 3		# 冲四
    		self.TWO = 4		# 活二
    		self.THREE = 5		# 活三
    		self.FOUR = 6		# 活四
    		self.FIVE = 7		# 活五
    		self.DFOUR = 8		# 双四
    		self.FOURT = 9		# 四三
    		self.DTHREE = 10	# 双三
    		self.NOTYPE = 11	
    		self.ANALYSED = 255		# 已经分析过
    		self.TODO = 0			# 没有分析过
    		self.result = [ 0 for i in xrange(30) ]		# 保存当前直线分析值
    		self.line = [ 0 for i in xrange(30) ]		# 当前直线数据
    		self.record = []			# 全盘分析结果 [row][col][方向]
    		for i in xrange(15):
    			self.record.append([])
    			self.record[i] = []
    			for j in xrange(15):
    				self.record[i].append([ 0, 0, 0, 0])
    		self.count = []				# 每种棋局的个数:count[黑棋/白棋][模式]
    		for i in xrange(3):
    			data = [ 0 for i in xrange(20) ]
    			self.count.append(data)
    		self.reset()
    
    	# 复位数据
    	def reset (self):
    		TODO = self.TODO
    		count = self.count
    		for i in xrange(15):
    			line = self.record[i]
    			for j in xrange(15):
    				line[j][0] = TODO
    				line[j][1] = TODO
    				line[j][2] = TODO
    				line[j][3] = TODO
    		for i in xrange(20):
    			count[0][i] = 0
    			count[1][i] = 0
    			count[2][i] = 0
    		return 0
    
    	# 四个方向(水平,垂直,左斜,右斜)分析评估棋盘,然后根据分析结果打分
    	def evaluate (self, board, turn):
    		score = self.__evaluate(board, turn)
    		count = self.count
    		if score < -9000:
    			stone = turn == 1 and 2 or 1
    			for i in xrange(20):
    				if count[stone][i] > 0:
    					score -= i
    		elif score > 9000:
    			stone = turn == 1 and 2 or 1
    			for i in xrange(20):
    				if count[turn][i] > 0:
    					score += i
    		return score
    	
    	# 四个方向(水平,垂直,左斜,右斜)分析评估棋盘,然后根据分析结果打分
    	def __evaluate (self, board, turn):
    		record, count = self.record, self.count
    		TODO, ANALYSED = self.TODO, self.ANALYSED
    		self.reset()
    		# 四个方向分析
    		for i in xrange(15):
    			boardrow = board[i]
    			recordrow = record[i]
    			for j in xrange(15):
    				if boardrow[j] != 0:
    					if recordrow[j][0] == TODO:		# 水平没有分析过?
    						self.__analysis_horizon(board, i, j)
    					if recordrow[j][1] == TODO:		# 垂直没有分析过?
    						self.__analysis_vertical(board, i, j)
    					if recordrow[j][2] == TODO:		# 左斜没有分析过?
    						self.__analysis_left(board, i, j)
    					if recordrow[j][3] == TODO:		# 右斜没有分析过
    						self.__analysis_right(board, i, j)
    
    		FIVE, FOUR, THREE, TWO = self.FIVE, self.FOUR, self.THREE, self.TWO
    		SFOUR, STHREE, STWO = self.SFOUR, self.STHREE, self.STWO
    		check = {}
    
    		# 分别对白棋黑棋计算:FIVE, FOUR, THREE, TWO等出现的次数
    		for c in (FIVE, FOUR, SFOUR, THREE, STHREE, TWO, STWO):
    			check[c] = 1
    		for i in xrange(15):
    			for j in xrange(15):
    				stone = board[i][j]
    				if stone != 0:
    					for k in xrange(4):
    						ch = record[i][j][k]
    						if ch in check:
    							count[stone][ch] += 1
    		
    		# 如果有五连则马上返回分数
    		BLACK, WHITE = 1, 2
    		if turn == WHITE:			# 当前是白棋
    			if count[BLACK][FIVE]:
    				return -9999
    			if count[WHITE][FIVE]:
    				return 9999
    		else:						# 当前是黑棋
    			if count[WHITE][FIVE]:
    				return -9999
    			if count[BLACK][FIVE]:
    				return 9999
    		
    		# 如果存在两个冲四,则相当于有一个活四
    		if count[WHITE][SFOUR] >= 2:
    			count[WHITE][FOUR] += 1
    		if count[BLACK][SFOUR] >= 2:
    			count[BLACK][FOUR] += 1
    
    		# 具体打分
    		wvalue, bvalue, win = 0, 0, 0
    		if turn == WHITE:
    			if count[WHITE][FOUR] > 0: return 9990
    			if count[WHITE][SFOUR] > 0: return 9980
    			if count[BLACK][FOUR] > 0: return -9970
    			if count[BLACK][SFOUR] and count[BLACK][THREE]: 
    				return -9960
    			if count[WHITE][THREE] and count[BLACK][SFOUR] == 0:
    				return 9950
    			if	count[BLACK][THREE] > 1 and 
    				count[WHITE][SFOUR] == 0 and 
    				count[WHITE][THREE] == 0 and 
    				count[WHITE][STHREE] == 0:
    					return -9940
    			if count[WHITE][THREE] > 1:
    				wvalue += 2000
    			elif count[WHITE][THREE]:
    				wvalue += 200
    			if count[BLACK][THREE] > 1:
    				bvalue += 500
    			elif count[BLACK][THREE]:
    				bvalue += 100
    			if count[WHITE][STHREE]:
    				wvalue += count[WHITE][STHREE] * 10
    			if count[BLACK][STHREE]:
    				bvalue += count[BLACK][STHREE] * 10
    			if count[WHITE][TWO]:
    				wvalue += count[WHITE][TWO] * 4
    			if count[BLACK][TWO]:
    				bvalue += count[BLACK][TWO] * 4
    			if count[WHITE][STWO]:
    				wvalue += count[WHITE][STWO]
    			if count[BLACK][STWO]:
    				bvalue += count[BLACK][STWO]
    		else:
    			if count[BLACK][FOUR] > 0: return 9990
    			if count[BLACK][SFOUR] > 0: return 9980
    			if count[WHITE][FOUR] > 0: return -9970
    			if count[WHITE][SFOUR] and count[WHITE][THREE]:
    				return -9960
    			if count[BLACK][THREE] and count[WHITE][SFOUR] == 0:
    				return 9950
    			if	count[WHITE][THREE] > 1 and 
    				count[BLACK][SFOUR] == 0 and 
    				count[BLACK][THREE] == 0 and 
    				count[BLACK][STHREE] == 0:
    					return -9940
    			if count[BLACK][THREE] > 1:
    				bvalue += 2000
    			elif count[BLACK][THREE]:
    				bvalue += 200
    			if count[WHITE][THREE] > 1:
    				wvalue += 500
    			elif count[WHITE][THREE]:
    				wvalue += 100
    			if count[BLACK][STHREE]:
    				bvalue += count[BLACK][STHREE] * 10
    			if count[WHITE][STHREE]:
    				wvalue += count[WHITE][STHREE] * 10
    			if count[BLACK][TWO]:
    				bvalue += count[BLACK][TWO] * 4
    			if count[WHITE][TWO]:
    				wvalue += count[WHITE][TWO] * 4
    			if count[BLACK][STWO]:
    				bvalue += count[BLACK][STWO]
    			if count[WHITE][STWO]:
    				wvalue += count[WHITE][STWO]
    		
    		# 加上位置权值,棋盘最中心点权值是7,往外一格-1,最外圈是0
    		wc, bc = 0, 0
    		for i in xrange(15):
    			for j in xrange(15):
    				stone = board[i][j]
    				if stone != 0:
    					if stone == WHITE:
    						wc += self.POS[i][j]
    					else:
    						bc += self.POS[i][j]
    		wvalue += wc
    		bvalue += bc
    		
    		if turn == WHITE:
    			return wvalue - bvalue
    
    		return bvalue - wvalue
    	
    	# 分析横向
    	def __analysis_horizon (self, board, i, j):
    		line, result, record = self.line, self.result, self.record
    		TODO = self.TODO
    		for x in xrange(15):
    			line[x] = board[i][x]
    		self.analysis_line(line, result, 15, j)
    		for x in xrange(15):
    			if result[x] != TODO:
    				record[i][x][0] = result[x]
    		return record[i][j][0]
    	
    	# 分析横向
    	def __analysis_vertical (self, board, i, j):
    		line, result, record = self.line, self.result, self.record
    		TODO = self.TODO
    		for x in xrange(15):
    			line[x] = board[x][j]
    		self.analysis_line(line, result, 15, i)
    		for x in xrange(15):
    			if result[x] != TODO:
    				record[x][j][1] = result[x]
    		return record[i][j][1]
    	
    	# 分析左斜
    	def __analysis_left (self, board, i, j):
    		line, result, record = self.line, self.result, self.record
    		TODO = self.TODO
    		if i < j: x, y = j - i, 0
    		else: x, y = 0, i - j
    		k = 0
    		while k < 15:
    			if x + k > 14 or y + k > 14:
    				break
    			line[k] = board[y + k][x + k]
    			k += 1
    		self.analysis_line(line, result, k, j - x)
    		for s in xrange(k):
    			if result[s] != TODO:
    				record[y + s][x + s][2] = result[s]
    		return record[i][j][2]
    
    	# 分析右斜
    	def __analysis_right (self, board, i, j):
    		line, result, record = self.line, self.result, self.record
    		TODO = self.TODO
    		if 14 - i < j: x, y, realnum = j - 14 + i, 14, 14 - i
    		else: x, y, realnum = 0, i + j, j
    		k = 0
    		while k < 15:
    			if x + k > 14 or y - k < 0:
    				break
    			line[k] = board[y - k][x + k]
    			k += 1
    		self.analysis_line(line, result, k, j - x)
    		for s in xrange(k):
    			if result[s] != TODO:
    				record[y - s][x + s][3] = result[s]
    		return record[i][j][3]
    	
    	def test (self, board):
    		self.reset()
    		record = self.record
    		TODO = self.TODO
    		for i in xrange(15):
    			for j in xrange(15):
    				if board[i][j] != 0 and 1:
    					if self.record[i][j][0] == TODO:
    						self.__analysis_horizon(board, i, j)
    						pass
    					if self.record[i][j][1] == TODO:
    						self.__analysis_vertical(board, i, j)
    						pass
    					if self.record[i][j][2] == TODO:
    						self.__analysis_left(board, i, j)
    						pass
    					if self.record[i][j][3] == TODO:
    						self.__analysis_right(board, i, j)
    						pass
    		return 0
    	
    	# 分析一条线:五四三二等棋型
    	def analysis_line (self, line, record, num, pos):
    		TODO, ANALYSED = self.TODO, self.ANALYSED
    		THREE, STHREE = self.THREE, self.STHREE
    		FOUR, SFOUR = self.FOUR, self.SFOUR
    		while len(line) < 30: line.append(0xf)
    		while len(record) < 30: record.append(TODO)
    		for i in xrange(num, 30):
    			line[i] = 0xf
    		for i in xrange(num):
    			record[i] = TODO
    		if num < 5:
    			for i in xrange(num): 
    				record[i] = ANALYSED
    			return 0
    		stone = line[pos]
    		inverse = (0, 2, 1)[stone]
    		num -= 1
    		xl = pos
    		xr = pos
    		while xl > 0:		# 探索左边界
    			if line[xl - 1] != stone: break
    			xl -= 1
    		while xr < num:		# 探索右边界
    			if line[xr + 1] != stone: break
    			xr += 1
    		left_range = xl
    		right_range = xr
    		while left_range > 0:		# 探索左边范围(非对方棋子的格子坐标)
    			if line[left_range - 1] == inverse: break
    			left_range -= 1
    		while right_range < num:	# 探索右边范围(非对方棋子的格子坐标)
    			if line[right_range + 1] == inverse: break
    			right_range += 1
    		
    		# 如果该直线范围小于 5,则直接返回
    		if right_range - left_range < 4:
    			for k in xrange(left_range, right_range + 1):
    				record[k] = ANALYSED
    			return 0
    		
    		# 设置已经分析过
    		for k in xrange(xl, xr + 1):
    			record[k] = ANALYSED
    		
    		srange = xr - xl
    
    		# 如果是 5连
    		if srange >= 4:	
    			record[pos] = self.FIVE
    			return self.FIVE
    		
    		# 如果是 4连
    		if srange == 3:	
    			leftfour = False	# 是否左边是空格
    			if xl > 0:
    				if line[xl - 1] == 0:		# 活四
    					leftfour = True
    			if xr < num:
    				if line[xr + 1] == 0:
    					if leftfour:
    						record[pos] = self.FOUR		# 活四
    					else:
    						record[pos] = self.SFOUR	# 冲四
    				else:
    					if leftfour:
    						record[pos] = self.SFOUR	# 冲四
    			else:
    				if leftfour:
    					record[pos] = self.SFOUR		# 冲四
    			return record[pos]
    		
    		# 如果是 3连
    		if srange == 2:		# 三连
    			left3 = False	# 是否左边是空格
    			if xl > 0:
    				if line[xl - 1] == 0:	# 左边有气
    					if xl > 1 and line[xl - 2] == stone:
    						record[xl] = SFOUR
    						record[xl - 2] = ANALYSED
    					else:
    						left3 = True
    				elif xr == num or line[xr + 1] != 0:
    					return 0
    			if xr < num:
    				if line[xr + 1] == 0:	# 右边有气
    					if xr < num - 1 and line[xr + 2] == stone:
    						record[xr] = SFOUR	# XXX-X 相当于冲四
    						record[xr + 2] = ANALYSED
    					elif left3:
    						record[xr] = THREE
    					else:
    						record[xr] = STHREE
    				elif record[xl] == SFOUR:
    					return record[xl]
    				elif left3:
    					record[pos] = STHREE
    			else:
    				if record[xl] == SFOUR:
    					return record[xl]
    				if left3:
    					record[pos] = STHREE
    			return record[pos]
    		
    		# 如果是 2连
    		if srange == 1:		# 两连
    			left2 = False
    			if xl > 2:
    				if line[xl - 1] == 0:		# 左边有气
    					if line[xl - 2] == stone:
    						if line[xl - 3] == stone:
    							record[xl - 3] = ANALYSED
    							record[xl - 2] = ANALYSED
    							record[xl] = SFOUR
    						elif line[xl - 3] == 0:
    							record[xl - 2] = ANALYSED
    							record[xl] = STHREE
    					else:
    						left2 = True
    			if xr < num:
    				if line[xr + 1] == 0:	# 左边有气
    					if xr < num - 2 and line[xr + 2] == stone:
    						if line[xr + 3] == stone:
    							record[xr + 3] = ANALYSED
    							record[xr + 2] = ANALYSED
    							record[xr] = SFOUR
    						elif line[xr + 3] == 0:
    							record[xr + 2] = ANALYSED
    							record[xr] = left2 and THREE or STHREE
    					else:
    						if record[xl] == SFOUR:
    							return record[xl]
    						if record[xl] == STHREE:
    							record[xl] = THREE
    							return record[xl]
    						if left2:
    							record[pos] = self.TWO
    						else:
    							record[pos] = self.STWO
    				else:
    					if record[xl] == SFOUR:
    						return record[xl]
    					if left2:
    						record[pos] = self.STWO
    			return record[pos]
    		return 0
    	def textrec (self, direction = 0):
    		text = []
    		for i in xrange(15):
    			line = ''
    			for j in xrange(15):
    				line += '%x '%(self.record[i][j][direction] & 0xf)
    			text.append(line)
    		return '
    '.join(text)
    
    
    #----------------------------------------------------------------------
    # DFS: 博弈树搜索
    #----------------------------------------------------------------------
    class searcher (object):
    
    	# 初始化
    	def __init__ (self):
    		self.evaluator = evaluation()
    		self.board = [ [ 0 for n in xrange(15) ] for i in xrange(15) ]
    		self.gameover = 0
    		self.overvalue = 0
    		self.maxdepth = 3
    
    	# 产生当前棋局的走法
    	def genmove (self, turn):
    		moves = []
    		board = self.board
    		POSES = self.evaluator.POS
    		for i in xrange(15):
    			for j in xrange(15):
    				if board[i][j] == 0:
    					score = POSES[i][j]
    					moves.append((score, i, j))
    		moves.sort()
    		moves.reverse()
    		return moves
    	
    	# 递归搜索:返回最佳分数
    	def __search (self, turn, depth, alpha = -0x7fffffff, beta = 0x7fffffff):
    
    		# 深度为零则评估棋盘并返回
    		if depth <= 0:
    			score = self.evaluator.evaluate(self.board, turn)
    			return score
    
    		# 如果游戏结束则立马返回
    		score = self.evaluator.evaluate(self.board, turn)
    		if abs(score) >= 9999 and depth < self.maxdepth: 
    			return score
    
    		# 产生新的走法
    		moves = self.genmove(turn)
    		bestmove = None
    
    		# 枚举当前所有走法
    		for score, row, col in moves:
    
    			# 标记当前走法到棋盘
    			self.board[row][col] = turn
    			
    			# 计算下一回合该谁走
    			nturn = turn == 1 and 2 or 1
    
    			# 深度优先搜索,返回评分,走的行和走的列
    			score = - self.__search(nturn, depth - 1, -beta, -alpha)
    
    			# 棋盘上清除当前走法
    			self.board[row][col] = 0
    
    			# 计算最好分值的走法
    			# alpha/beta 剪枝
    			if score > alpha:
    				alpha = score
    				bestmove = (row, col)
    				if alpha >= beta:
    					break
    		
    		# 如果是第一层则记录最好的走法
    		if depth == self.maxdepth and bestmove:
    			self.bestmove = bestmove
    
    		# 返回当前最好的分数,和该分数的对应走法
    		return alpha
    
    	# 具体搜索:传入当前是该谁走(turn=1/2),以及搜索深度(depth)
    	def search (self, turn, depth = 3):
    		self.maxdepth = depth
    		self.bestmove = None
    		score = self.__search(turn, depth)
    		if abs(score) > 8000:
    			self.maxdepth = depth
    			score = self.__search(turn, 1)
    		row, col = self.bestmove
    		return score, row, col
    
    
    #----------------------------------------------------------------------
    # psyco speedup
    #----------------------------------------------------------------------
    def psyco_speedup ():
    	try:
    		import psyco
    		psyco.bind(chessboard)
    		psyco.bind(evaluation)
    	except:
    		pass
    	return 0
    
    psyco_speedup()
    
    
    #----------------------------------------------------------------------
    # main game
    #----------------------------------------------------------------------
    def gamemain():
    	b = chessboard()
    	s = searcher()
    	s.board = b.board()
    
    	opening = [
    		'1:HH 2:II',
    		#'2:IG 2:GI 1:HH',
    		'1:IH 2:GI',
    		'1:HG 2:HI',
    		#'2:HG 2:HI 1:HH',
    		#'1:HH 2:IH 2:GI',
    		#'1:HH 2:IH 2:HI',
    		#'1:HH 2:IH 2:HJ',
    		#'1:HG 2:HH 2:HI',
    		#'1:GH 2:HH 2:HI',
    	]
    
    	import random
    	openid = random.randint(0, len(opening) - 1)
    	b.loads(opening[openid])
    	turn = 2
    	history = []
    	undo = False
    
    	# 设置难度
    	DEPTH = 1
    
    	if len(sys.argv) > 1:
    		if sys.argv[1].lower() == 'hard':
    			DEPTH = 2
    
    	while 1:
    		print ''
    		while 1:
    			print '<ROUND %d>'%(len(history) + 1)
    			b.show()
    			print 'Your move (u:undo, q:quit):',
    			text = raw_input().strip('
    	 ')
    			if len(text) == 2:
    				tr = ord(text[0].upper()) - ord('A')
    				tc = ord(text[1].upper()) - ord('A')
    				if tr >= 0 and tc >= 0 and tr < 15 and tc < 15:
    					if b[tr][tc] == 0:
    						row, col = tr, tc
    						break
    					else:
    						print 'can not move there'
    				else:
    					print 'bad position'
    			elif text.upper() == 'U':
    				undo = True
    				break
    			elif text.upper() == 'Q':
    				print b.dumps()
    				return 0
    		
    		if undo == True:
    			undo = False
    			if len(history) == 0:
    				print 'no history to undo'
    			else:
    				print 'rollback from history ...'
    				move = history.pop()
    				b.loads(move)
    		else:
    			history.append(b.dumps())
    			b[row][col] = 1
    
    			if b.check() == 1:
    				b.show()
    				print b.dumps()
    				print ''
    				print 'YOU WIN !!'
    				return 0
    
    			print 'robot is thinking now ...'
    			score, row, col = s.search(2, DEPTH)
    			cord = '%s%s'%(chr(ord('A') + row), chr(ord('A') + col))
    			print 'robot move to %s (%d)'%(cord, score)
    			b[row][col] = 2
    
    			if b.check() == 2:
    				b.show()
    				print b.dumps()
    				print ''
    				print 'YOU LOSE.'
    				return 0
    
    	return 0
    
    
    #----------------------------------------------------------------------
    # testing case
    #----------------------------------------------------------------------
    if __name__ == '__main__':
    	def test1():
    		b = chessboard()
    		b[10][10] = 1
    		b[11][11] = 2
    		for i in xrange(4):
    			b[5 + i][2 + i] = 2
    		for i in xrange(4):
    			b[7 - 0][3 + i] = 2
    		print b
    		print 'check', b.check()
    		return 0
    	def test2():
    		b = chessboard()
    		b[7][7] = 1
    		b[8][8] = 2
    		b[7][9] = 1
    		eva = evaluation()
    		for l in eva.POS: print l
    		return 0
    	def test3():
    		e = evaluation()
    		line = [ 0, 0, 1, 0, 1, 1, 1, 0, 0, 0]
    		record = []
    		e.analysis_line(line, record, len(line), 6)
    		print record[:10]
    		return 0
    	def test4():
    		b = chessboard()
    		b.loads('2:DF 1:EG 2:FG 1:FH 2:FJ 2:GG 1:GH 1:GI 2:HG 1:HH 1:IG 2:IH 1:JF 2:JI 1:KE')
    		b.loads('2:CE 2:CK 1:DF 1:DK 2:DL 1:EG 1:EI 1:EK 2:FG 1:FH 1:FI 1:FJ 1:FK 2:FL 1:GD 2:GE 2:GF 2:GG 2:GH 1:GI 1:GK 2:HG 1:HH 2:HJ 2:HK 2:IG 1:JG 2:AA')
    		eva = evaluation()
    		print b
    		score = 0
    		t = time.time()
    		for i in xrange(10000):
    			score = eva.evaluate(b.board(), 2)
    		#eva.test(b.board())
    		t = time.time() - t
    		print score, t
    		print eva.textrec(3)
    		return 0
    	def test5():
    		import profile
    		profile.run("test4()", "prof.txt")
    		import pstats
    		p = pstats.Stats("prof.txt")
    		p.sort_stats("time").print_stats()
    	def test6():
    		b = chessboard()
    		b.loads('1:CJ 2:DJ 1:dk 1:DL 1:EH 1:EI 2:EJ 2:EK 2:FH 2:FI 2:FJ 1:FK 2:FL 1:FM 2:GF 1:GG 2:GH 2:GI 2:GJ 1:GK 1:GL 2:GM 1:HE 2:HF 2:HG 2:HH 2:HI 1:HJ 2:HK 2:HL 1:IF 1:IG 1:IH 2:II 1:IJ 2:IL 2:JG 1:JH 1:JI 1:JJ 1:JK 2:JL 1:JM 1:KI 2:KJ 1:KL 1:LJ 2:MK')
    		#b.loads('1:HH,1:HI,1:HJ,1:HK')
    		s = searcher()
    		s.board = b.board()
    		t = time.time()
    		score, row, col = s.search(2, 3)
    		t = time.time() - t
    		b[row][col] = 2
    		print b
    		print score, t
    		print chr(ord('A') + row) + chr(ord('A') + col)
    	def test7():
    		b = chessboard()
    		s = searcher()
    		s.board = b.board()
    		b.loads('2:HH 1:JF')
    		turn = 2
    		while 1:
    			score, row, col = s.search(2, 2)
    			print 'robot move %s%s (%d)'%(chr(ord('A') + row), chr(ord('A') + col), score)
    			b[row][col] = 2
    			if b.check() == 2:
    				print b
    				print b.dumps()
    				print 'you lose !!'
    				return 0
    			while 1:
    				print b
    				print 'your move (pos):',
    				text = raw_input().strip('
    	 ')
    				if len(text) == 2:
    					tr = ord(text[0].upper()) - ord('A')
    					tc = ord(text[1].upper()) - ord('A')
    					if tr >= 0 and tc >= 0 and tr < 15 and tc < 15:
    						if b[tr][tc] == 0:
    							row, col = tr, tc
    							break
    						else:
    							print 'can not move there'
    					else:
    						print 'bad position'
    				elif text.upper() == 'Q':
    					print b.dumps()
    					return 0
    			b[row][col] = 1
    			if b.check() == 1:
    				print b
    				print b.dumps()
    				print 'you win !!'
    				return 0
    		return 0
    	#test6()
    	gamemain()
    

    https://study.163.com/provider/400000000398149/index.htm?share=2&shareId=400000000398149(博主视频教学主页)

     

  • 相关阅读:
    在Myeclipse中移除项目对Hibernate的支持
    使用MyEclipse可视化开发Hibernate实例
    利用MyEclipse自动创建PO类、hbm文件(映射文件)、DAO
    Mtk Camera
    Linux问题,磁盘分区打不开了
    Android SDK在线更新镜像服务器大全
    TeamTalk——ubuntu服务端部署
    Nginx
    VCC/AVCC/VDD/AVDD区别
    android studio and sdk mirror for China
  • 原文地址:https://www.cnblogs.com/webRobot/p/5817740.html
Copyright © 2011-2022 走看看