目录
前言
这学期的数据结构课设是计算机博弈,写程序去下亚马逊棋。
老师规定的平台是botzone,作为一个组长为了提高小组的上限决定分析一下亚马逊棋的上限。实际上没搞出来什么,因为历年棋谱大家的bot实在是参差不齐,那么为了找到比较厉害的bot,我写了以下程序来分析。(虽然下棋的主体代码要求使用c/c++来编写,但是跑个数据集还是python来得方便)
并附上我对于这些数据的分析供各位参考,全篇代码没有什么思维难度,纯是给各位节省时间。
有一些对于开局库建立的代码,大家也可以看看。
全篇代码非常易懂,耐心一点几分钟就可以看懂,代码逻辑真的非常简单!!!
(使用正则表达式来匹配,历年数据有坏掉的数据而且正则表达式确实很方便。反正在自己电脑上来跑也不算时间,实际上和直接识别json文件相比也没差多少时间。所以暴力把json变成txt,其实python直接读json也是可以的,可以在我的基础上略加修改。记得改文件名和文件路径)
经统计历年数据发现黑白双方胜率接近50%,但是黑方胜率在每个月的棋谱中都是53%左右,而白棋是47%左右。(在统计了结束时双方剩余棋子数据之后,发现白方在获胜的同时有1/6左右的棋局和黑方都无子可下,在轮到黑方下棋时白方自动胜利。)
终局以及局势
import re
# 文件路径
path = './data/2019-4/'
limit = 75200
last = 45
#基于正则表达式匹配识别json文件
# 打开文件,r是读取的意思,encoding是指定编码格式
left = 1
right = 100
ans = 0
# ans1 = 0
arr = [0, 0, 0, 0, 0, 0, 0, 0, 0]
def col( x ):
# x为黑方剩余走法减去白方剩余走法
if x < -30:
arr[0] += 1
elif x <= -20:
arr[1] += 1
elif x <= -10:
arr[2] += 1
elif x < 0:
arr[3] += 1
elif x == 0:
arr[8] += 1
elif x <= 10:
arr[4] += 1
elif x <= 20:
arr[5] += 1
elif x <= 30:
arr[6] += 1
else:
arr[7] += 1
while right < limit:
with open(path + format(left) + '-' + format(right) + '.matches', 'r', encoding='utf-8') as fp:
data = fp.read()
pattern3 = re.compile("blackCount\":\d+,\"whiteCount\":\d+,\"winner\":\d") # 查找终局局势
pattern2 = re.compile(r'\d+') # 查找数字
result0 = pattern3.findall(data)
for match in result0:
result = pattern2.findall(match)
# print(match)
col(int(result[0]) - int(result[1]))
fp.close()
left += 100
right += 100
# sum1 = 0 to debug
# 查找剩余的不足100个的棋谱文件
with open(path + format(left+100) + '-' + format(right+last) + '.matches', 'r', encoding='utf-8') as fp:
data = fp.read()
pattern3 = re.compile("blackCount\":\d+,\"whiteCount\":\d+,\"winner\":\d") # 查找终局局势
# print(result1)
pattern2 = re.compile(r'\d+') # 查找数字
result0 = pattern3.findall(data)
for match in result0:
result = pattern2.findall(match)
col(int(result[0]) - int(result[1]))
fp.close()
for match in arr:
ans += match
print("白方胜率为:{}%".format(round(100*(arr[0]+arr[1]+arr[2]+arr[3])/ans, 2)))
print("平局概率为:{}%".format(round(100*arr[8]/ans, 2)))
print("黑方胜率为:{}%".format(round(100*(arr[4]+arr[5]+arr[6]+arr[7])/ans, 2)))
#print(sum)
#print(result1[0])
#26322 33195 10030
for match in range(0, 4):
print('终局时黑方剩余格数 <' + format(-30+match*10) + ' : ' + format(arr[match]))
for match in range(4, 8):
print('终局时黑方剩余格数 <' + format(-30+match*10) + ' : ' + format(arr[match]))
print('终局时双方都无剩余选择情况 : ' + format(arr[8]))
#print(sum1)
#"blackCount":0,"whiteCount":14,"winner":1,
胜率较高的bot
把各个bot的对局总数、对局胜利总数分别装入两个字典里,以bot编号为key,对局数为value。
(实际上遇到了未预见的bug,在一半的数据之中bot可以正常找出来,