网址可以访问了,继续
第八步
恭喜你到达第八步!
利用前一步得到的棋型分析结果,考察每一个可能落子的位置,给每一个可能的位置打分,将棋子落在分数最高的位置上。根据经验,我们可以总结出下面的落子规则:
1.致胜棋型
若在某处落子后我方获胜,采取这一落子位置。
我们将空位子记作.,本方棋子记作M(me),对方棋子记作O(opponent),考察点记作C(current),能够致胜的棋型必然包含:
"CMMMM"
"MCMMM"
"MMCMM"
"MMMCM"
"MMMMC"
为了保证其优先级,我们给这条规则分配一个大的分数10000。
2. 必须防守棋型
若我方棋子不落在某处,对方将出现致胜棋型,采取这一落子位置,不过优先级小于前者。
按照上面的记号,此时棋型应包含:
"OOOOC"
"COOOO"
我们给它分配一个较大的分数6000
3. 两步致胜棋型
若在某处落子后,出现致胜棋型,采取这一落子位置,不过优先级小于前者。
按照上面的记号,此时棋型应包含:
".CMMM."
".MCMM."
".MMCM."
".MMMC."
我们给它分配一个较大的分数5000
4. 两步防守棋型
若我方棋子不落在某处,对方将出现两步致胜棋型,采取这一落子位置,不过优先级小于前者。
"COOO."
".OOOC"
".OOCO."
".OCOO."
我们给它分配分数2500
5. 进攻棋型
若在某处落子后,出现一端被挡住的四个连续棋子,此时对方必需挡住另一端,采取这一落子位置,不过优先级小于前者。
按照上面的记号,此时棋型应包含:
"OCMMM."
"OMCMM."
"OMMCM."
"OMMMC."
".CMMMO"
".MCMMO"
".MMCMO"
".MMMCO"
我们给它分配分数2000
6. 两步进攻棋型
若在某处落子后,出现两端都不被挡住的三个连续棋子,此时对方必需挡住其中一端,采取这一落子位置,不过优先级小于前者。
".MMC."
".MCM."
".CMM."
我们给它分配分数400
7. 预防棋型
若我方棋子不落在某处,对方将出现两步进攻棋型或进攻棋型,采取这一落子位置。
".OOC"
"COO."
"MOOOC"
"COOOM"
我们给它分配分数400
8. 无效进攻防守棋型
若在某处落子后,出现一端被挡住的三个连续棋子,或者若我方棋子不落在某处,对方将出现一端被挡住的三个连续棋子,这一步进攻或者防守不会引起对方的立即反应。
".MMCO"
".MCMO"
".CMMO"
"OMMC."
"OMCM."
"OCMM."
"MOOC"
"COOM"
我们给它分配分数200
9. 布局棋型
若在某处落子后,出现两端都不被挡住的两个连续棋子。
".MC."
".CM."
我们给它分配分数50
10. 其他棋型
我们给它分配分数20
我们将计算每一个当前还是空着的位置的得分。
1.按照第六步的方法获得棋盘,此时需要根据当前落子是黑方还是白方,将黑棋和白棋表示为M或O
2.找到所有还空着的位置
3.对每一个空位子
a. 将这个位置设为C
b. 按照第七步的方法获得该位置的棋型字符串
c. 在所有的棋型字符串上按顺序寻找上述所有模式,每得到一个匹配,将对应的分数加上,最终所得即为该位置的分数
d. 将这个位置设为.
找出分数最大的位置,若分数最大的位置有多个,随意选择一个
任务 8
实现按照评分规则选择落子位置的算法,通过服务器的检验。
访问http://xxx/step_08服务器会给你几个棋局的坐标表示,保存到questions字段,以JSON数组表示。请给出分数最大的一个落子位置,写入到ans字段,按顺序给出坐标,坐标之间用逗号隔开。服务器不会告诉你,你是白棋还是黑棋,你需要根据规则自己确定。
正则表达式:https://www.runoob.com/python/python-reg-expressions.html
字符串匹配:https://www.cnblogs.com/huiAlex/p/7994606.html
list转字符串:https://www.cnblogs.com/who-care/p/9306800.html
权重计算:
import json
win_type = ["CMMMM", "MCMMM", "MMCMM", "MMMCM", "MMMMC"] #终-致胜
defense_type = ["OOOOC", "COOOO"] #御-必守
latent_win_type = [".CMMM.", ".MCMM.", ".MMCM.", ".MMMC."] #创-两步致胜
latent_defense_type = ["COOO.", ".OOOC", ".OOCO.", ".OCOO."] #忍-两步防守
kill_type = ["OCMMM.", "OMCMM.", "OMMCM.", "OMMMC.", ".CMMMO", ".MCMMO", ".MMCMO", ".MMMCO"] #攻-进攻
latent_kill_type = [".MMC.", ".MCM.", ".CMM."] #蓄-两步进攻
foresee_type = [".OOC", "COO.", "MOOOC", "COOOM"] #预-预防
invalid_type = [".MMCO", ".MCMO", ".CMMO", "OMMC.", "OMCM.", "OCMM.", "MOOC", "COOM"] #缓-无效进攻
layout_type = [".MC.", ".CM."] #势-布局
com = [win_type, defense_type, latent_win_type, latent_defense_type, kill_type, latent_kill_type, foresee_type, invalid_type, layout_type]
def calculate_score(str1): #计算分数
sum1 = 0
for i in range(9):
for j in com[i]:
if j in str1:
if i == 0:
sum1 = sum1 + 10000
elif i == 1:
sum1 = sum1 + 6000
elif i == 2:
sum1 = sum1 + 5000
elif i == 3:
sum1 = sum1 + 2500
elif i == 4:
sum1 = sum1 + 2000
elif i == 5:
sum1 = sum1 + 400
elif i == 6:
sum1 = sum1 + 400
elif i == 7:
sum1 = sum1 + 200
elif i == 8:
sum1 = sum1 + 50
else:
sum1 = sum1 + 20
return int(sum1)
def draw_board(): # 棋盘绘制
for i in range(15):
board.append([])
for j in range(15):
board[i].append(".")
def game_simulation(step): # 棋局模拟
flag = 1
for i in range(0, len(step), 2):
a = ord(step[i]) - 97
b = ord(step[i + 1]) - 97
if flag & 1 == 1: # 棋子判断,单数黑棋”x“
board[a][b] = "x"
else:
board[a][b] = "o"
flag = flag + 1
def game_transform(step): #棋子转换
if int(len(step) / 2) & 1 == 0: #该黑棋走
for i in range(0, len(step), 2):
a = ord(step[i]) - 97
b = ord(step[i + 1]) - 97
if board[a][b] == "x":
board[a][b] = "M"
elif board[a][b] == "o":
board[a][b] = "O"
else:
for i in range(0, len(step), 2):
a = ord(step[i]) - 97
b = ord(step[i + 1]) - 97
if board[a][b] == "x":
board[a][b] = "O"
elif board[a][b] == "o":
board[a][b] = "M"
def transverse_judge(a, b): # 横向判断
a = a
b = b
str1 = []
for j in range(-4, 5):
if 0 <= b + j <= 14:
str1.append(board[a][b + j])
else:
continue
str1 = "".join(str1)
return calculate_score(str1)
def portrait_judge(a, b): # 纵向判断
a = a
b = b
str1 = []
for j in range(-4, 5):
if 0 <= a + j <= 14:
str1.append(board[a + j][b])
else:
continue
str1 = "".join(str1)
return calculate_score(str1)
def left_leaning_judge(a, b): # 左倾判断(\)
a = a
b = b
str1 = []
for j in range(-4, 5):
if 0 <= a + j <= 14 and 0 <= b + j <= 14:
str1.append(board[a + j][b + j])
else:
continue
str1 = "".join(str1)
return calculate_score(str1)
def right_deviation_judge(a, b): # 右倾判断(/)
a = a
b = b
str1 = []
for j in range(-4, 5):
if 0 <= a - j <= 14 and 0 <= b + j <= 14:
str1.append(board[a - j][b + j])
else:
continue
str1 = "".join(str1)
return calculate_score(str1)
board = []
data = input()
py_data = json.loads(data) # 将 JSON 对象类型转换为 Python 字典
compositions = py_data['questions'] #将多个棋局转储
for composition in compositions:
board.clear() #清空棋盘
draw_board()
game_simulation(composition)
game_transform(composition)
sum_max = 0
site1 = 0
site2 = 0
for num1 in range(15):
for num2 in range(15):
max1 = 0
if board[num1][num2] == ".":
board[num1][num2] = "C"
max1 = max1 + transverse_judge(num1, num2) + portrait_judge(num1, num2) + left_leaning_judge(num1, num2) + right_deviation_judge(num1, num2)
board[num1][num2] = "."
if sum_max <= max1:
sum_max = max1
site1 = num1
site2 = num2
print(chr(site1 + 97), end="")
print(chr(site2 + 97), end=",")
print(sum_max)
棋型的储存形式和分数计算函数可以修改为:
win_type = {"CMMMM": 10000, "MCMMM": 10000, "MMCMM": 10000, "MMMCM": 10000, "MMMMC": 10000} #终-致胜
defense_type = {"OOOOC": 6000, "COOOO":6000} #御-必守
latent_win_type = {".CMMM.": 5000, ".MCMM.": 5000, ".MMCM.": 5000, ".MMMC.": 5000} #创-两步致胜
latent_defense_type = {"COOO.": 2500, ".OOOC": 2500, ".OOCO.": 2500, ".OCOO.": 2500} #忍-两步防守
kill_type = {"OCMMM.": 2000, "OMCMM.": 2000, "OMMCM.": 2000, "OMMMC.": 2000, ".CMMMO": 2000, ".MCMMO": 2000, ".MMCMO": 2000, ".MMMCO": 2000} #攻-进攻
latent_kill_type = {".MMC.": 400, ".MCM.": 400, ".CMM.": 400} #蓄-两步进攻
foresee_type = {".OOC": 400, "COO.": 400, "MOOOC": 400, "COOOM": 400} #预-预防
invalid_type = {".MMCO": 200, ".MCMO": 200, ".CMMO": 200, "OMMC.": 200, "OMCM.": 200, "OCMM.": 200, "MOOC": 200, "COOM": 200} #缓-无效进攻
layout_type = {".MC.": 50, ".CM.": 50} #势-布局
com = [win_type, defense_type, latent_win_type, latent_defense_type, kill_type, latent_kill_type, foresee_type, invalid_type, layout_type]
def calculate_score(str1): #计算分数
sum1 = 0
for i in com:
for item, value in i.items():
if item in str1:
sum1 = sum1 + value
return int(sum1)
测试发现,用字典储存且修改分数计算规则速度较快