14
2024
11

python编程学习-井字棋

学习python编程,在新东方少儿编程官网的自由创作平台做的一些作品。

可以在线运行,效果如下(在新页面中打开链接):

代码如下(用到平台自定义的xdf库):

from xdf import *

bgColor = '#CCFF66'
box(80, 212, 600, 600, bgColor)
line(80, 212 + 200, 80 + 600, 212 + 200, 'black')
line(80, 212 + 400, 80 + 600, 212 + 400, 'black')
line(80 + 200, 212, 80 + 200, 212 + 600, 'black')
line(80 + 400, 212, 80 + 400, 212 + 600, 'black')

computerUrl = 'https://code-file.xdf.cn/files/dingdangweb/20230221/1676950106634_618443.png'
playerUrl = 'https://code-file.xdf.cn/files/dingdangweb/20230221/1676950106634_788910.png'
bubbleUrl = 'https://code-file.xdf.cn/files/dingdangweb/20230221/1676950106634_872903.png'
computer = stamp(computerUrl, 384, 150)
player = stamp(playerUrl, 384, 900)
computerBubble = stamp(bubbleUrl, 250, 120, 130)
playerBubble = stamp(bubbleUrl, 280, 900, 130)
computerTxt = text(' ', 250, 110, 20, 'black', 'center')
heroTxt = text(' ', 280, 890, 20, 'black', 'center')

qizi = []
mp = []
for i in range(9):
    mp.append(0)
    m = i // 3
    n = i % 3
    xi = 80 + 100 + n * 200
    yi = 212 + 100 + m * 200
    a = [
        circle(xi, yi, 60, 'blue'),
        circle(xi, yi, 50, bgColor),
        line(xi - 50, yi - 50, xi + 50, yi + 50, 'green'),
        line(xi + 50, yi - 50, xi - 50, yi + 50, 'green')
    ]
    qizi.append(a)
lines = [0, 1, 2,
        3, 4, 5,
        6, 7, 8,
        0, 3, 6,
        1, 4, 7,
        2, 5, 8,
        0, 4, 8,
        2, 4, 6];
isOver = False
difficult = 10 #难度0-10
total = 9 #当前棋盘上空位个数
turn = 1 #轮到谁下,1:player,2:computer
overTxt = text('点击任意位置重新开始', 0, 0, 50, 'red', 'center')
def computerSay(txt):
    computerTxt.change(txt)

def heroSay(txt):
    heroTxt.change(txt)

def xy2ij(x, y):
    return [int((y - 212) / 200), int((x - 80) / 200)]

def hideQizi(i):
    a = qizi[i]
    a[0].hide()
    a[1].hide()
    a[2].hide()
    a[3].hide()

def showQizi(i, tp):
    a = qizi[i]
    if tp == 1:
        a[0].show()
        a[1].show()
    elif tp == 2:
        a[2].show()
        a[3].show()

def reStart():
    global total, isOver, mp, turn, overTxt
    total = 9
    isOver = False
    computerSay(' ')
    heroSay(' ')
    overTxt.hide()
    for i in range(9):
        mp[i] = 0
        hideQizi(i)
    if random(10) < 5:
        turn = 1
        computerSay('你先走吧')
    else:
        turn = 2
        computerSay('这次我先来')
        aiTurn()

def checkWin():
    global total, mp, lines, turn, isOver, overTxt
    for i in range(8):
        n0 = i * 3
        a0 = mp[lines[n0]]
        a1 = mp[lines[n0 + 1]]
        a2 = mp[lines[n0 + 2]]
        if a0 != 0 and a0 == a1 and a1 == a2:
            if a0 == 1:
                computerSay('好吧,算你赢了')
                heroSay('哈哈,我赢了')
            else:
                computerSay('哈哈,我赢了')
                heroSay('好吧,算你赢了')
            isOver = True
            overTxt.show()
            return True
    if total == 0:
        isOver = True
        overTxt.show()
        computerSay('你还挺厉害的')
        heroSay('棋逢对手')
        return True
    return False

def tap():
    global turn, mp, isOver, total
    if isOver:
        reStart()
        return
    if turn == 1:
        ij = xy2ij(x, y)
        i = ij[0]
        j = ij[1]
        if i >= 0 and i < 3 and j >= 0 and j < 3:
            n = i * 3 + j
            if mp[n] == 0:
                mp[n] = 1
                showQizi(n, 1)
                turn = 2
                computerSay(' ')
                heroSay('该你了')
                total = total - 1
                if(not checkWin()):
                    aiTurn()

def aiGetPos():
    n = random(9) - 1
    while mp[n] != 0:
        n = random(9) - 1
    return n

def aiPlay():
    global turn,mp,total, difficult
    n = aiGetPos()
    if random(10) <= difficult:
        n = ai()
    mp[n] = 2
    showQizi(n, 2)
    turn = 1
    computerSay('我放好了')
    heroSay(' ')
    total = total - 1
    checkWin()
    
def aiTurn():
    delay(aiPlay, 1000 + random(1000))

#各种棋形的分数,这个关系到ai的能力
s0 = 0
s1 = 70      #000
s2 = 1000    #002
s3 = 100000  #022
s4 = 80      #001
s5 = 8000    #011
s6 = 1       #012
#每一行或列或斜都由3个位置组成,每个位置可能有3种状态(0:空,1:用户的子,2:ai的子),3个位置共有27种组合方式,下面是各种组合的得分表。                                    //    000 001    002    010    011    012    020    021    022
             #000 001 002 010 011 012 020 021 022
scoreTable = [s1, s4, s2, s4, s5, s6, s2, s6, s3,
            #100 101 102 110 111 112 120 121 122
            s4, s5, s6, s5, s0, s0, s6, s0, s0,
            #200 201 202 210 200 212 220 221 222
            s2, s6, s3, s6, s2, s0, s3, s0, s0
            ]
# ai策略实现
def ai():
    global mp, lines, scoreTable
    #创建评分表,初始得分全部为0
    scores = []
    for i in range(9):
        scores.append(0)
    #根据当前棋形更新评分表
    #总共有8条线,每一条线的棋形必然是scoreTable中的一种,根据所属棋形,为该行中所有非空位置加分。
    #比如第一行,坐标是【0,1,2】,如果该行的状态是【叉,圈,叉】(即【2,1,0】),对应scoreTable中的索引为2*9+1*3+0=21,对应的分数为scoreTable[21]=1,则scores[2]+=1(因为0,1位置已经有棋子,所以得分始终为0).
    for i in range(8):
        n0 = i * 3
        c = mp[lines[n0]] * 9 + mp[lines[n0 + 1]] * 3 + mp[lines[n0 + 2]]
        for j in range(3):
            a = lines[n0 + j]
            if mp[a] == 0:
                scores[a] = scores[a] + scoreTable[c]
    #从评分表里取出得分最高的位置,如果有并列最高,随机取
    m = 0
    s = 0
    for i in range(9):
        if scores[i] > m:
            s = i
            m = scores[i]
        elif scores[i] == m:
            if random(2) > 1:
                s = i
    return s

reStart()


也可以下载代码,本地python环境运行(用pygame封装了xdf库)。



« 上一篇下一篇 »

相关文章:

python编程学习-华容道  (2024-11-14 16:43:25)

python编程学习-动画  (2024-11-14 16:39:37)

python编程学习-别踩白块  (2024-11-14 16:38:59)

python编程学习-俄罗斯方块  (2024-11-14 16:38:19)

python编程学习-五子棋  (2024-11-14 16:33:23)

python编程学习-乒乓  (2024-11-14 16:32:46)

python编程学习-一笔画关卡生成  (2024-11-14 16:32:6)

python编程学习-一笔画  (2024-11-14 16:31:27)

python编程学习-woblox  (2024-11-14 16:30:47)

python编程学习-where-my-ice-cream  (2024-11-14 16:29:57)

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。