猫史档案馆


【Python作品分享】翻转战喵 - win版【作品秀】

用户:焰魄流云焰魄流云查看:0 回复:0 评论:0 创建时间:2023-05-05T18:37:51


【作品展示】

center_image

 

【作品介绍】

努力吃对方棋子,要占掉最后一个格子,有三个NPC,加油吧少年

 

【作品源代码】

'''翻转战喵-NPC策略探索'''
import turtle as t
import random
from copy import deepcopy
import time

# 初始棋局状态
l=[
    [0, 0, 0, 0, 0, 0, 0, 0],
    [0, 0, 0, 0, 0, 0, 0, 0],
    [0, 0, 0, 0, 0, 0, 0, 0],
    [0, 0, 0, 1, 2, 0, 0, 0],
    [0, 0, 0, 2, 1, 0, 0, 0],
    [0, 0, 0, 0, 0, 0, 0, 0],
    [0, 0, 0, 0, 0, 0, 0, 0],
    [0, 0, 0, 0, 0, 0, 0, 0],
]
# AI权重识别
l_ai = [
    [  0,  0,  0,  0,  0,  0,  0,  0],
    [  0,  0,  0,  0,  0,  0,  0,  0],
    [  0,  0,  0,  0,  0,  0,  0,  0],
    [  0,  0,  0,  0,  0,  0,  0,  0],
    [  0,  0,  0,  0,  0,  0,  0,  0],
    [  0,  0,  0,  0,  0,  0,  0,  0],
    [  0,  0,  0,  0,  0,  0,  0,  0],
    [  0,  0,  0,  0,  0,  0,  0,  0],
]
# 默认玩家先手
turn = 1
# npc落子延迟
time_now = 0
time_npc = 0
# 空过判断
npc_pass = 0
player_pass = 0
# 判断是否在选择界面
first_choice = 1
# 判断选择的npc
npc_choice = 0

def try_next():
    '''判断是否可以继续落子'''
    pass

def try_left(x, y, l, l_change):
    '''左侧变动'''
    number = 0 # 改变数量
    if x == 0: # 最左边,不改变
        return number, l_change
    _l = []
    for i in range(x-1, -1, -1):
        if l[y][i] == 0:
            break
        _l.append(l[y][i])
        if l[y][i] == 2:
            break
    if len(_l) > 1 and 2 in _l:
        _x = x - 1
        while True: # 把所有1变成2,直到遇到2
            if l[y][_x] == 1:
                l_change[y][_x] = 2
                _x -= 1
                number += 1
            else:
                break
        return number, l_change
    else:
        return number, l_change

def try_right(x, y, l, l_change):
    '''右侧变动'''
    number = 0 # 改变数量
    if x == 7: # 最右边,不改变
        return number, l_change
    _l = []
    for i in range(x+1, 8):
        if l[y][i] == 0:
            break
        _l.append(l[y][i])
        if l[y][i] == 2:
            break
    if len(_l) > 1 and 2 in _l:
        _x = x + 1
        while True: # 把所有1变成2,直到遇到2
            if l[y][_x] == 1:
                l_change[y][_x] = 2
                _x += 1
                number += 1
            else:
                break
        return number, l_change
    else:
        return number, l_change

def try_up(x, y, l, l_change):
    '''上方变动'''
    number = 0 # 改变数量
    if y == 0:
        return number, l_change
    _l = []
    for i in range(y-1, -1, -1):
        if l[i][x] == 0:
            break
        _l.append(l[i][x])
        if l[i][x] == 2:
            break
    if len(_l) > 1 and 2 in _l:
        _y = y - 1
        while True: # 把所有1变成2,直到遇到2
            if l[_y][x] == 1:
                l_change[_y][x] = 2
                _y -= 1
                number += 1
            else:
                break
        return number, l_change
    else:
        return number, l_change

def try_down(x, y, l, l_change):
    '''下方变动'''
    number = 0  # 改变数量
    if y == 7:
        return number, l_change
    _l = []
    for i in range(y+1, 8):
        if l[i][x] == 0:
            break
        _l.append(l[i][x])
        if l[i][x] == 2:
            break
    if len(_l) > 1 and 2 in _l:
        _y = y + 1
        while True: # 把所有1变成2,直到遇到2
            if l[_y][x] == 1:
                l_change[_y][x] = 2
                _y += 1
                number += 1
            else:
                break
        return number, l_change
    else:
        return number, l_change

def try_left_up(x, y, l, l_change):
    '''左上变动'''
    number = 0 # 改变数量
    if x == 0 or y == 0:
        return number, l_change
    _l = []
    _i = min(x, y)
    for i in range(1, _i+1):
        if l[y-i][x-i] == 0:
            break
        _l.append(l[y-i][x-i])
        if l[y-i][x-i] == 2:
            break
    if len(_l) >= 1 and 2 in _l:
        _x = x - 1
        _y = y - 1
        while True: # 把所有1变成2,直到遇到2
            if l[_y][_x] == 1:
                l_change[_y][_x] = 2
                _x -= 1
                _y -= 1
                number += 1
            else:
                break
        return number, l_change
    else:
        return number, l_change

def try_left_down(x, y, l, l_change):
    '''左下变动'''
    number = 0 # 改变数量
    if x == 0 or y == 7:
        return number, l_change
    _l = []
    _i = min(x, 7-y)
    for i in range(1, _i+1):
        if l[y+i][x-i] == 0:
            break
        _l.append(l[y+i][x-i])
        if l[y+i][x-i] == 2:
            break
    if len(_l) >= 1 and 2 in _l:
        _x = x - 1
        _y = y + 1
        while True: # 把所有1变成2,直到遇到2
            if l[_y][_x] == 1:
                l_change[_y][_x] = 2
                _x -= 1
                _y += 1
                number += 1
            else:
                break
        return number, l_change
    else:
        return number, l_change

def try_right_up(x, y, l, l_change):
    '''右上变动'''
    number = 0 # 改变数量
    if x == 7 or y == 0:
        return number, l_change
    _l = []
    _i = min(7-x, y)
    for i in range(1, _i+1):
        if l[y-i][x+i] == 0:
            break
        _l.append(l[y-i][x+i])
        if l[y-i][x+i] == 2:
            break
    if len(_l) >= 1 and 2 in _l:
        _x = x + 1
        _y = y - 1
        while True: # 把所有1变成2,直到遇到2
            if l[_y][_x] == 1:
                l_change[_y][_x] = 2
                _x += 1
                _y -= 1
                number += 1
            else:
                break
        return number, l_change
    else:
        return number, l_change

def try_right_down(x, y, l, l_change):
    '''右下变动'''
    number = 0 # 改变数量
    if x == 7 or y == 7:
        return number, l_change
    _l = []
    _i = min(7-x, 7-y)
    for i in range(1, _i+1):
        if l[y+i][x+i] == 0:
            break
        _l.append(l[y+i][x+i])
        if l[y+i][x+i] == 2:
            break
    if len(_l) >= 1 and 2 in _l:
        _x = x + 1
        _y = y + 1
        while True: # 把所有1变成2,直到遇到2
            if l[_y][_x] == 1:
                l_change[_y][_x] = 2
                _x += 1
                _y += 1
                number += 1
            else:
                break
        return number, l_change
    else:
        return number, l_change

def npc_will_go():
    '''npc落子判断'''
    l_go = [] # 可走的落子点坐标表
    l_changes = [] # 落子点对应的棋盘改变情况
    l_numbers = [] # 改变棋子数量表
    for x in range(0, 8):
        for y in range(0, 8):
            if l[y][x] != 0:
                continue
            number = 0 # 改变了的点数
            l_change = deepcopy(l)
            l_move = [
                try_left,
                try_right,
                try_up,
                try_down,
                try_left_up,
                try_left_down,
                try_right_up,
                try_right_down,
            ]
            for i in l_move:
                res = i(x, y, l, l_change)
                number += res[0]
                l_change = res[1]
            if number != 0:
                l_go.append((x, y))
                l_changes.append(l_change)
                l_numbers.append(number)
    return l_go, l_changes, l_numbers

def npc_go(l_ai):
    '''npc落子'''
    l_go, l_changes, l_numbers = npc_will_go()
    ai_choise = []
    for i in range(len(l_go)):
        ai_choise.append(l_ai[l_go[i][1]][l_go[i][0]]+l_numbers[i])
    if ai_choise:
        max_ai_choise = max(ai_choise)
        res_xy = []
        res_l = []
        for i in range(len(l_go)):
            if ai_choise[i] == max_ai_choise:
                res_xy.append(l_go[i])
                res_l.append(l_changes[i])
        r = random.randint(0, len(res_xy)-1)
        return res_xy[r], res_l[r]
    else:
        return None, None

def red_circle(pic):
    '''npc落子'''
    t.pendown()
    t.shape(pic+'棋子.gif')
    t.stamp()
    t.penup()

def black_circle():
    '''玩家落子'''
    t.pendown()
    t.shape('玩家棋子.gif')
    t.stamp()
    t.penup()

def draw_line(pic, intro):
    '''棋盘场景绘制'''
    # 棋盘边框绘制
    # t.color('black')
    # t.goto(240, 240)
    # t.pendown()
    # t.goto(240, -240)
    # t.goto(-240, -240)
    # t.goto(-240, 240)
    # t.goto(240, 240)
    # t.penup()
    # npc棋手头像
    t.pensize(3)
    if turn != 1:
        t.color('orange')
    else:
        t.color('gray')
    t.goto(260, 250)
    t.pendown()
    t.goto(380, 250)
    t.goto(380, 130)
    t.goto(260, 130)
    t.goto(260, 250)
    t.penup()
    t.goto(320, 190)
    t.shape(pic+'.gif')
    t.stamp()
    if turn != 1:
        t.shape('NPC箭头2.gif')
    else:
        t.shape('NPC箭头1.gif')
    t.goto(320, 20)
    t.stamp()
    # 玩家头像
    t.pensize(3)
    if turn == 1:
        t.color('orange')
    else:
        t.color('gray')
    t.goto(-260, -250)
    t.pendown()
    t.goto(-380, -250)
    t.goto(-380, -130)
    t.goto(-260, -130)
    t.goto(-260, -250)
    t.penup()
    t.goto(-320, -190)
    t.shape('编程猫.gif')
    t.stamp()
    if turn == 1:
        t.shape('玩家箭头2.gif')
    else:
        t.shape('玩家箭头1.gif')
    t.goto(-320, -20)
    t.stamp()
    # npc棋手名字
    if turn != 1:
        t.color('orange')
    else:
        t.color('gray')
    if len(pic) % 2 == 1:
        pic = pic + ' '
    pic = int((24 - len(pic)) / 2) * ' ' + pic
    t.goto(260, 100)
    t.write(pic, font=('Arial', 12, 'bold'))

def npc_1():
    '''选择npc1'''
    global npc_choice, first_choice
    npc_choice = 1
    first_choice = 0

def npc_2():
    '''选择npc2'''
    global npc_choice, first_choice
    npc_choice = 2
    first_choice = 0


def npc_3():
    '''选择npc3'''
    global npc_choice, first_choice
    npc_choice = 3
    first_choice = 0

def main():
    '''主函数'''
    global l, turn, time_now, time_npc, pass_time, npc_pass, first_choice

    # 监听事件
    t.onkey(npc_1, '1')
    t.onkey(npc_2, '2')
    t.onkey(npc_3, '3')
    t.listen()

    # turtle基础设置
    t.addshape('玩家获胜.gif')
    t.addshape('npc获胜.gif')
    t.addshape('和棋.gif')
    t.addshape('编程猫.gif')
    t.addshape('玩家棋子.gif')
    t.addshape('棋盘.gif')
    t.addshape('初始界面.gif')
    t.addshape('玩家箭头1.gif')
    t.addshape('玩家箭头2.gif')
    t.addshape('NPC箭头1.gif')
    t.addshape('NPC箭头2.gif')
    s = t.getscreen()
    t.setup(800, 600, 0, 0)
    t.hideturtle()
    t.tracer(False)
    t.penup()

    # 加载3个npc
    pic1, intro1, l_ai1 = load_aduan()
    pic2, intro2, l_ai2 = load_xiadi()
    pic3, intro3, l_ai3 = load_my_npc()

    # intro处理
    intro1_l = [pic1+'——按1与他对战!\n\n']
    for i in range(0, len(intro1), 26):
        intro1_l.append(intro1[i:i+26]+'\n')
    intro2_l = [pic2+'——按2与她对战!\n\n']
    for i in range(0, len(intro2), 26):
        intro2_l.append(intro2[i:i+26]+'\n')
    intro3_l = [pic3+'——按3与他对战!\n\n']
    for i in range(0, len(intro3), 26):
        intro3_l.append(intro3[i:i+26]+'\n')
    for i in range(6):
        if len(intro1_l) < 6:
            intro1_l.append('\n')
        if len(intro2_l) < 6:
            intro2_l.append('\n')
        if len(intro3_l) < 6:
            intro3_l.append('\n')
    intro = ''
    for i in intro1_l:
        intro += i
    intro += '\n'
    for i in intro2_l:
        intro += i
    intro += '\n'
    for i in intro3_l:
        intro += i

    # pic处理
    t.addshape(pic1+'.gif')
    t.addshape(pic1+'棋子.gif')
    t.addshape(pic2+'.gif')
    t.addshape(pic2+'棋子.gif')
    if pic3 != '':
        t.addshape(pic3+'.gif')
        t.addshape(pic3+'棋子.gif')

    # 第一幕
    while True:
        if first_choice == 0:
            break
        t.clear()
        # 绘制背景
        t.goto(0, 0)
        t.shape('初始界面.gif')
        t.stamp()
        # 绘制2/3个角色
        t.goto(-260, 120)
        t.shape(pic1+'.gif')
        t.stamp()
        t.goto(-260, -35)
        t.shape(pic2+'.gif')
        t.stamp()
        if pic3 != '':
            t.goto(-260, -190)
            t.shape(pic3+'.gif')
            t.stamp()
        t.goto(-160, -290)
        t.pendown()
        t.color(0.85, 0.95, 0.85)
        t.write(intro, font=('Arial', 13, 'bold'))
        t.penup()
        t.update()
    
    if npc_choice == 1:
        pic, intro, l_ai = load_aduan()
    elif npc_choice == 2:
        pic, intro, l_ai = load_xiadi()
    elif npc_choice == 3:
        pic, intro, l_ai = load_my_npc()

    def put_down(x, y):
        '''落子捕捉'''
        global l, turn, time_now, time_npc, pass_time, npc_pass
        t.goto(x, y)
        _x = int((x + 240) // 60)
        _y = 7 - int((y + 240) // 60)
        if l[_y][_x] == 0:
            number = 0
            _l = deepcopy(l)
            for i in range(0, 8):
                for j in range(0, 8):
                    if _l[j][i] == 1:
                        _l[j][i] = 2
                    elif _l[j][i] == 2:
                        _l[j][i] = 1
            l_change = deepcopy(_l)
            l_move = [
                try_left,
                try_right,
                try_up,
                try_down,
                try_left_up,
                try_left_down,
                try_right_up,
                try_right_down,
            ]
            for i in l_move:
                res = i(_x, _y, _l, l_change)
                number += res[0]
                l_change = res[1]
            for i in range(0, 8):
                for j in range(0, 8):
                    if l_change[j][i] == 1:
                        l_change[j][i] = 2
                    elif l_change[j][i] == 2:
                        l_change[j][i] = 1
            if number != 0 and turn == 1:
                l = l_change
                l[_y][_x] = 1
                turn = 0
                npc_pass = 0
                time_npc = time.time() + 1
        s.onclick(put_down)

    s.onclick(put_down)
    # 第二幕
    while True:
        # 胜负判断
        if npc_pass == 1 and player_pass == 1:
            player_numbers = 0
            npc_numbers = 0
            for x in range(0, 8):
                for y in range(0, 8):
                    if l[y][x] == 1:
                        player_numbers += 1
                    elif l[y][x] == 2:
                        npc_numbers += 1
            if player_numbers > npc_numbers:
                print(player_numbers, '玩家获胜')
                t.goto(0, 0)
                t.shape('玩家获胜.gif')
                t.stamp()
            elif player_numbers < npc_numbers:
                print(npc_numbers, 'npc获胜')
                t.goto(0, 0)
                t.shape('npc获胜.gif')
                t.stamp()
            else:
                print(npc_numbers, '和棋')
                t.goto(0, 0)
                t.shape('和棋.gif')
                t.stamp()
            break
        t.clear()
        # 绘制背景
        t.goto(0, 0)
        t.shape('棋盘.gif')
        t.stamp()
        if turn == 0 and time.time() >= time_npc: # 如果该npc落子的话
            r1, r2 = npc_go(l_ai)
            if r1 != None: # 判断npc是否需要空过
                l = r2
                l[r1[1]][r1[0]] = 2
                player_pass = 0
            else:
                npc_pass = 1
                print(npc_pass)
            turn = 1
        # 判断玩家是否需要空过
        number = 0
        _l = deepcopy(l)
        for i in range(0, 8):
            for j in range(0, 8):
                if _l[j][i] == 1:
                    _l[j][i] = 2
                elif _l[j][i] == 2:
                    _l[j][i] = 1
        l_go = [] # 可走的落子点坐标表
        for x in range(0, 8):
            for y in range(0, 8):
                if _l[y][x] != 0:
                    continue
                number = 0 # 改变了的点数
                l_change = deepcopy(_l)
                l_move = [
                    try_left,
                    try_right,
                    try_up,
                    try_down,
                    try_left_up,
                    try_left_down,
                    try_right_up,
                    try_right_down,
                ]
                for i in l_move:
                    res = i(x, y, _l, l_change)
                    number += res[0]
                    l_change = res[1]
                if number != 0:
                    l_go.append((x, y))
        if not l_go:
            player_pass = 1
            print(player_pass)
            turn = 0
            print(player_pass)
        for x in range(0, 8): # 刷新棋盘
            for y in range(0, 8):
                t.goto(x*60-210, -y*60+210)
                if l[y][x] == 1:
                    black_circle()
                elif l[y][x] == 2:
                    red_circle(pic)
        draw_line(pic, intro)
        s.update()
        t.update()
    t.done()

def load_aduan():
    '''加载npc棋手阿短'''
    pic = '阿短'
    intro = '充满自信的棋界莽夫,棋路飘忽不定,非常擅长吃掉对手的棋子,占领更多区域,但似乎也只在意这一点,没什么大局观。'
    l_ai = [
        [   0,   0,   0,   0,   0,   0,   0,   0],
        [   0,   0,   0,   0,   0,   0,   0,   0],
        [   0,   0,   0,   0,   0,   0,   0,   0],
        [   0,   0,   0,   0,   0,   0,   0,   0],
        [   0,   0,   0,   0,   0,   0,   0,   0],
        [   0,   0,   0,   0,   0,   0,   0,   0],
        [   0,   0,   0,   0,   0,   0,   0,   0],
        [   0,   0,   0,   0,   0,   0,   0,   0],
    ]
    return pic, intro, l_ai

def load_xiadi():
    '''加载npc棋手夏笛'''
    pic = '夏笛'
    intro = '沉着冷静,外表酷酷但内心温柔,棋力不凡,不过总喜欢在对手的左下方落子,据说是曾经下过围棋的缘故。'
    l_ai = [
        [   0,   0,   0,   0,   0,   0,   0,   0],
        [   0,   0,   0,   0,   0,   0,   0,   0],
        [   0,   0,   0,   0,   0,   0,   0,   0],
        [   0,   0,   0,   0,   0,   0,   0,   0],
        [   4,   9,   4,   7,   0,   0,   0,   0],
        [   7,   6,   9,   7,   0,   0,   0,   0],
        [   7,   10,   10,   9,   0,   0,   0,   0],
        [   10,   9,   11,   9,   0,   0,   0,   0],
    ]
    return pic, intro, l_ai

def load_my_npc():
    '''加载自创棋手'''
    pic = '黑客'
    intro = '自创棋手——黑客,极为神秘,是一位棋坛新星。棋法:未知。击败程度:未知。'
    l_ai = [
        [   10,   1,   8,   4,   1,   6,   2,   10],
        [   5,   9,   4,   0,   10,   0,   3,   6],
        [   5,   0,   0,   7,   0,   8,   0,   10],
        [   1,   3,   6,   2,   6,   0,   8,   9],
        [   8,   0,   2,   0,   10,   20,   0,   4],
        [   9,   0,   5,   3,   0,   0,   0,   9],
        [   6,   10,   0,   6,   0,   0,   8,   8],
        [   5,   2,   10,   6,   1,   7,   8,   10],
    ]
    return pic, intro, l_ai

if __name__ == '__main__':
    main()

 

【提示】

部分含有Python第三方库相关内容的作品,在海龟编辑器网页端无法运行哦!如遇到这种情况,可以打开下面的链接,下载海龟编辑器客户端:

https://python.codemao.cn


回复

上一页1 页 / 共 0下一页