五子棋day-6

网址可以访问了,继续

第八步
恭喜你到达第八步!

利用前一步得到的棋型分析结果,考察每一个可能落子的位置,给每一个可能的位置打分,将棋子落在分数最高的位置上。根据经验,我们可以总结出下面的落子规则:

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)

测试发现,用字典储存且修改分数计算规则速度较快

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值