恭喜你到达第八步!
利用前一步得到的棋型分析结果,考察每一个可能落子的位置,给每一个可能的位置打分,将棋子落在分数最高的位置上。根据经验,我们可以总结出下面的落子规则:
若在某处落子后我方获胜,采取这一落子位置。
我们将空位子记作.,本方棋子记作M(me),对方棋子记作O(opponent),考察点记作C(current),能够致胜的棋型必然包含:
"CMMMM"
"MCMMM"
"MMCMM"
"MMMCM"
"MMMMC"
为了保证其优先级,我们给这条规则分配一个大的分数10000
。
若我方棋子不落在某处,对方将出现致胜棋型,采取这一落子位置,不过优先级小于前者。
按照上面的记号,此时棋型应包含:
"OOOOC"
"COOOO"
我们给它分配一个较大的分数6000
若在某处落子后,出现致胜棋型,采取这一落子位置,不过优先级小于前者。
按照上面的记号,此时棋型应包含:
".CMMM."
".MCMM."
".MMCM."
".MMMC."
我们给它分配一个较大的分数5000
若我方棋子不落在某处,对方将出现两步致胜棋型,采取这一落子位置,不过优先级小于前者。
"COOO."
".OOOC"
".OOCO."
".OCOO."
我们给它分配分数2500
若在某处落子后,出现一端被挡住的四个连续棋子,此时对方必需挡住另一端,采取这一落子位置,不过优先级小于前者。
按照上面的记号,此时棋型应包含:
"OCMMM."
"OMCMM."
"OMMCM."
"OMMMC."
".CMMMO"
".MCMMO"
".MMCMO"
".MMMCO"
我们给它分配分数2000
若在某处落子后,出现两端都不被挡住的三个连续棋子,此时对方必需挡住其中一端,采取这一落子位置,不过优先级小于前者。
".MMC."
".MCM."
".CMM."
我们给它分配分数400
若我方棋子不落在某处,对方将出现两步进攻棋型或进攻棋型,采取这一落子位置。
".OOC"
"COO."
"MOOOC"
"COOOM"
我们给它分配分数400
若在某处落子后,出现一端被挡住的三个连续棋子,或者若我方棋子不落在某处,对方将出现一端被挡住的三个连续棋子,这一步进攻或者防守不会引起对方的立即反应。
".MMCO"
".MCMO"
".CMMO"
"OMMC."
"OMCM."
"OCMM."
"MOOC"
"COOM"
我们给它分配分数200
若在某处落子后,出现两端都不被挡住的两个连续棋子。
".MC."
".CM."
我们给它分配分数50
20
再次说明,我们的方法并不是最好,但请你先实现这种方法,之后再尝试你的想法。
我们将计算每一个当前还是空着的位置的得分。
按照第六步的方法获得棋盘,此时需要根据当前落子是黑方还是白方,将黑棋和白棋表示为M
或O
找到所有还空着的位置
对每一个空位子
a. 将这个位置设为C
b. 按照第七步的方法获得该位置的棋型字符串
c. 在所有的棋型字符串上按顺序寻找上述所有模式,每得到一个匹配,将对应的分数加上,最终所得即为该位置的分数
d. 将这个位置设为.
找出分数最大的位置,若分数最大的位置有多个,随意选择一个
实现按照评分规则选择落子位置的算法,通过服务器的检验。
访问http://2**.207.12.156:9012/step_08
服务器会给你几个棋局的坐标表示,保存到questions字段,以JSON数组表示。请给出分数最大的一个落子位置,写入到ans字段,按顺序给出坐标,坐标之间用逗号隔开。服务器不会告诉你,你是白棋还是黑棋,你需要根据规则自己确定
{"is_success": true, "questions": ["hhifhjigkhjghghiihjhkjjijjij", "hhigjhihjgiiifhgjijfkhkeli", "hhjhiijjkijijkjgjfkhijiflihegdlh", "hhkhlhihkgjimijfnjoklgjhjgigmgnglfli", "hhjhihjiijjjjgjkjliihigjkgigkflehf", "edfefdgdeeefhcdffccfffdddegbgcecicjchb", "gheifhiihhihhiijighg", "hhjhiijgghjjjkjijfkjig", "ggffhggfhffgiefhfeheidehdidhgheg", "hhjhiijgghjjjkjijfkjiggiijih", "hhjhiijgghjjjkjijfkjiggi", "ghhihhhggiggihfhigfjiiifjh", "hhggfhghifgigfgjgkhfhkhiijfgjikh", "hhihgihijgiiigjffjekgghggjghijhjgkiffijekdkfgl", "hhjhihjiijjjjgjkjlii", "hhjhihjiijjjjgjkjliihigjkgigkflehfhgifjf", "ghhihhhggiggihfhigfjiiifjhkhjgjfhfgekfijkg"]}
import requests as re def getIndexNum(coords): """ 将字符下标转换为数字下标""" """coords y x""" # 0行 [0]='.'--- [14]='.'[15]='\n' # 1行 [16]='.'--- [30]='.'[31]='\n' # 2行 [32]='.'--- [46]='.'[47]='\n' # 15行 [240]='.'--- [254]='.'[255]='\n' return (ord(coords[0]) - ord('a'))*16 + ord(coords[1]) - ord('a') def allIndexStr(): """ 快速获取一个 以字符下标为值的列表 """ """ spot[0]='aa' spot[1]='ab' ....""" spot = [] for i in range(0,15): for j in range(0,16): spot.append(chr(i+97) + chr(j+97)) return spot def getLine(coord,board): """ 获得中心点的四周点情况 返回一个字符串列表 coord[0] y 纵坐标 coord[1] x 控制横坐标 board 棋局 """ line = ['', '' , '' , ''] i =0 """ 核心思想就是 将周围点两个坐标x,y的限制 转化为一个位置index的限制 """ while(i != 9): if ord(coord[1])-ord('a')- 4 + i in range(0, 15) : # line[0]是横线 只需保证 横坐标在棋盘里就好 line[0] +=board[(ord(coord[0])-ord('a'))*16 + ord(coord[1])-ord('a')- 4 + i] else: line[0] += ' ' if ord(coord[0])-ord('a') -4 + i in range(0, 15) : # line[2]是竖线 只需保证 纵坐标在棋盘里就好 line[2] +=board[(ord(coord[0])-ord('a')- 4 + i)*16 + ord(coord[1])-ord('a')] else: line[2] += ' ' # - 4 + i 是从最小值上升判断 + 4 - i 是从最大值下降判断 两者没有什么不同 根据index的求法而定 if ord(coord[1])-ord('a')- 4 + i in range(0, 15) and ord(coord[0])-ord('a') -4 + i in range(0, 15) : # line[1]是\线 保证 横纵坐标都在棋盘里就好 line[1] +=board[(ord(coord[0])-ord('a')- 4 + i)*16 + ord(coord[1])-ord('a')- 4 + i] else: line[1] += ' ' if ord(coord[1])-ord('a') + 4 - i in range(0, 15) and ord(coord[0])-ord('a') -4 + i in range(0, 15) : # line[3]是/线 保证 横纵坐标都在棋盘里就好 line[3] +=board[(ord(coord[0])-ord('a')- 4 + i)*16 + ord(coord[1])-ord('a')+ 4 - i] else: line[3] += ' ' i += 1 return line def judge(testOrder): """ 服务器并没有给我们我们是 M 还是 O""" """ 根据棋局的命令序列判断""" if (len(testOrder)//2) % 2 == 0: # 我是黑方 return 'MO' else: # 我是白方 return 'OM' def RuleWithPoints(): """ 返回一个 规则字典 对应规则和分值""" RWP = { ("CMMMM","MCMMM","MMCMM","MMMCM","MMMMC") : 10000, ("COOOO","OOOOC") : 6000, (".CMMM.",".MCMM.",".MMCM.",".MMMC.") : 5000, ("COOO.",".OOOC",".OOCO.",".OCOO.") :2500, ("OCMMM.","OMCMM.","OMMCM.","OMMMC.",".CMMMO",".MCMMO",".MMCMO",".MMMCO"):2000, (".MMC.",".MCM.",".CMM.") : 400, (".OOC","COO.","MOOOC","COOOM") : 400, (".MMCO",".MCMO",".CMMO","OMMC.","OMCM.","OCMM.","MOOC","COOM") : 200, (".MC.",".CM.") : 50, ('.') : 20 } return RWP def getMaxCoords(Order,RWP, indexSrc): """对于每一个当下的棋局 返回一个最成功的下点""" board = '' # 棋板 for i in range(0,15): board += '...............' + '\n' step = 0 # 步数 用于判断黑白 黑方先走 BW = judge(Order) for i in range(0, len(Order), 2): # i = 0 2 4 6 8 index = getIndexNum(Order[i:i+2]) # Python不允许直接修改字符串 只能用拼接的方法 if (step % 2) == 0: board = board[0: index] + BW[0] + board[index + 1:] else: board = board[0: index] + BW[1] + board[index + 1:] step += 1 #print(board) maxCoord = '' maxPoints = 0 for i in range(0,len(board)): if board[i] == '.': tempBoard = board[0: i] + 'C' + board[i + 1:] coord = indexSrc[i] lines4 = ','.join(getLine(coord,tempBoard)) points = 0 for rules,value in RWP.items(): for rul in range(0, len(rules)) : if rules[rul] in lines4: points += value * lines4.count(rules[rul]) if coord in ['kh','ke']: print(f"{coord} {points}") print(lines4) if points > maxPoints : maxPoints = points maxCoord = coord print(f"{maxCoord} {maxPoints}") return maxCoord def getNextStep(url,answer): """提交答案 获取下一题链接""" param = { 'ans' : answer[:-1] } getHtml = re.get(url, params=param) print(getHtml.text) url = "http://2**.207.12.156:9012/step_08/" getHtml = re.get(url) stepOrders = getHtml.json()['questions'] RWP = RuleWithPoints() indexSrc = allIndexStr() #answer = 'ki,he,ih,le,hg,ia,eh,gi,ci,hi,ke,kh,gl,gm,hi,kh,hj,' answer = '' for order in stepOrders: answer += getMaxCoords(order, RWP, indexSrc) + ',' getNextStep(url, answer)
注意规则的匹配次数!
文章会随时改动,注意到博客里去看。一些网站会爬取本文章,但是可能会有出入。
https://www.cnblogs.com/asmurmur/