15
2024
11

python编程学习-黑白棋

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

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

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

from xdf import *

N = 8
CW = 64
OX = (768 - CW * N) / 2
OY = (1024 - CW * N) / 2
R = CW / 2 - 8
circles = []
data = []
curData = []
isOver = False
player = 1
total = 64
neighbour = [
    [-1, -1],[-1, 0],[-1, 1],
    [0, -1],[0, 1],
    [1, -1],[1, 0],[1, 1]
]
curPutdown = []

def xy2ij(x, y):
    return [int((y - OY) / CW), int((x - OX) / CW)]

def ij2xy(i, j):
    return [j * CW + OX, i * CW + OY]

for i in range(9):
    xy = ij2xy(i, 0)
    line(xy[0], xy[1], xy[0] + CW * N, xy[1], 1)
    xy = ij2xy(0, i)
    line(xy[0], xy[1], xy[0], xy[1] + CW * N, 1)

for i in range(8):
    a = []
    b = []
    for j in range(8):
        xy = ij2xy(i, j)
        a.append([
            circle(xy[0] + CW / 2, xy[1] + CW / 2, R, 'white', 'black'),
            circle(xy[0] + CW / 2, xy[1] + CW / 2, R, 'black', 'black'),
            circle(xy[0] + CW / 2, xy[1] + CW / 2, R, 'transparent', 'red'),
        ])
        b.append(0)
    circles.append(a)
    data.append(b)
    curData = data
    curPutdown = []

overTxt1 = text('你赢了', 768/2, 1024/2-100, 50, 'red', 'center')
overTxt2 = text('点击任意位置重新开始', 50, 'red', 'center')

def refresh():
    global circles, data, curPutdown
    for i in range(8):
        for j in range(8):
            a = circles[i][j]
            a[0].hide()
            a[1].hide()
            a[2].hide()
            tp = data[i][j]
            if tp == 1:
                a[0].show()
            elif tp == 2:
                a[1].show()
    if len(curPutdown):
        a = circles[curPutdown[0]][curPutdown[1]]
        a[2].show()

def setState(i, j, tp):
    global curData
    curData[i][j] = tp

def reset():
    global isOver, player, total, overTxt1, overTxt2, data, curData
    curData = data
    for i in range(8):
        for j in range(8):
            setState(i, j, 0)
    setState(3, 3, 1)
    setState(3, 4, 2)
    setState(4, 3, 2)
    setState(4, 4, 1)
    isOver = False
    player = 1
    total = 60
    overTxt1.hide()
    overTxt2.hide()
    refresh()

def tap():
    global isOver, player, data, curData
    if isOver:
        reset()
        return
    if player == 1:
        curData = data
        ij = xy2ij(x, y)
        i = ij[0]
        j = ij[1]
        if canPut(i, j, 1):
            putDown(i, j, 1)
            player = 2
            checkOver()
            if not isOver:
                aiTurn()

def canPut(i, j, tp):
    if isOut(i, j):
        return False
    if not isEmpty(i, j):
        return False
    return canChangeBy(i, j, tp)

def cloneCurData():
    global curData
    a = []
    for i in range(8):
        b = []
        for j in range(8):
            b.append(curData[i][j])
        a.append(b)
    return a

def putDown(i, j, tp):
    global total, curPutdown
    curPutdown = [i, j]
    setState(i, j, tp)
    total = total - 1
    changeBy(i, j, tp)
    refresh()

def canChangeBy(i, j, tp):
    global neighbour
    for ii in range(len(neighbour)):
        d = neighbour[ii]
        if canChangeByDir(i, j, d[0], d[1], tp):
            return True
    return False

def canChangeByDir(i, j, di, dj, tp):
    a = getChangeByDir(i, j, di, dj, tp)
    return len(a) > 1

def changeBy(i, j, tp):
    global neighbour
    for ii in range(len(neighbour)):
        d = neighbour[ii]
        changeByDir(i, j, d[0], d[1], tp)

def changeByDir(i, j, di, dj, tp):
    global curData
    a = getChangeByDir(i, j, di, dj, tp)
    if len(a) > 1:
        for i in range(len(a)):
            b = a[i]
            curData[b[0]][b[1]] = tp

def isOut(i, j):
    return i < 0 or i > 7 or j < 0 or j > 7

def getChangeByDir(i, j, di, dj, tp):
    global curData
    a = [[i,j]]
    while True:
        i = i + di
        j = j + dj
        if isOut(i, j):
            return []
        n = curData[i][j]
        if n == 0:
            return []
        if n == tp:
            break;
        a.append([i, j])
    return a

def checkOver():
    global total, isOver, overTxt1, overTxt2
    if checkIsOver():
        isOver = True
        nums = getNum()
        if nums[0] > nums[1]:
            overTxt1.change("你赢了")
        elif nums[0] < nums[1]:
            overTxt1.change("我赢了")
        else:
            overTxt1.change("打平了")
        overTxt1.show()
        overTxt2.show()

def checkIsOver():
    global total, isOver
    if total == 0:
        return True
    if hasLegalPos(player):
        return False
    return True

def hasLegalPos(tp):
    for i in range(8):
        for j in range(8):
            if canPut(i, j, tp):
                return True
    return False

def isEmpty(i, j):
    global curData
    return curData[i][j] == 0
    
def getNum():
    global circles, curData
    num1 = 0
    num2 = 0
    for i in range(8):
        for j in range(8):
            b = curData[i][j]
            if b == 1:
                num1 = num1 + 1
            elif b == 2:
                num2 = num2 + 1
    return [num1, num2]

def aiTurn():
    delay(aiplay, 200)

def getAiPos(poss):
    a = random(len(poss)) - 1
    p = poss[a]
    return p

def getScore(p):
    global curData
    curData = cloneCurData()
    i = p[0]
    j = p[1]
    changeBy(i, j, 2)
    nums = getNum()
    sc = nums[1] - nums[0]
    
    if i == 0 or i == 7:
        sc = sc + 10
    if j == 0 or j == 7:
        sc = sc + 10
    return sc

def getMaxScore(poss):
    i0 = 0
    maxScore = -64
    global curData
    dat = curData
    for i in range(len(poss)):
        curData = dat
        p = poss[i]
        sc = getScore(p)
        if sc > maxScore:
            maxScore = sc
            i0 = i
    return [i0, maxScore]

def getAiPos2(poss):
    a = getMaxScore(poss)
    p = poss[a[0]]
    return p

def aiplay():
    global curData, data
    curData = data
    poss = getLegalPos(2)
    p = getAiPos2(poss)
    curData = data
    putDown(p[0], p[1], 2)
    global player
    player = 1
    checkOver()

def getLegalPos(tp):
    poss = []
    for i in range(8):
        for j in range(8):
            if canPut(i, j, tp):
                poss.append([i, j])
    return poss

reset()

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



« 上一篇下一篇 »

相关文章:

python编程学习-迷宫04  (2024-11-15 11:43:7)

python编程学习-迷宫03  (2024-11-15 11:42:42)

python编程学习-迷宫02  (2024-11-15 11:42:16)

python编程学习-迷宫01  (2024-11-15 11:41:55)

python编程学习-连连看  (2024-11-15 11:41:16)

python编程学习-进入大圈  (2024-11-15 11:40:57)

python编程学习-跳伞  (2024-11-15 11:40:27)

python编程学习-跑酷01  (2024-11-15 11:40:3)

python编程学习-赛车  (2024-11-15 11:39:38)

python编程学习-贪食蛇  (2024-11-15 11:38:41)

发表评论:

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