国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

讓電腦變得更聰明——用python實(shí)現(xiàn)五子棋游戲

這篇具有很好參考價(jià)值的文章主要介紹了讓電腦變得更聰明——用python實(shí)現(xiàn)五子棋游戲。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

作為經(jīng)典的棋類游戲,五子棋深受大眾喜愛,但如果僅實(shí)現(xiàn)人與人的博弈,那程序很簡(jiǎn)單,如果要實(shí)現(xiàn)人機(jī)對(duì)戰(zhàn),教會(huì)計(jì)算機(jī)如何戰(zhàn)勝人類,那就不是十分容易的事了。本文我們先從簡(jiǎn)單入手,完成五子棋游戲的基本操作,然后再嘗試引入一些實(shí)現(xiàn)人工智能的編程方法和技巧,從而實(shí)現(xiàn)人機(jī)博弈。

1.創(chuàng)建棋盤和棋子

對(duì)于棋類游戲來說,游戲的場(chǎng)景就是下棋的棋盤,而游戲的主要角色就是棋子。接下來我們開始創(chuàng)建棋盤和棋子。

1.1繪制棋盤

五子棋的棋盤可以看成是一個(gè)1818的網(wǎng)格,他由19條豎線和19條橫線(包含邊界)構(gòu)成,直線的交叉處就下棋子的位置。這里,我們用1818個(gè)棕色格子來填滿棋盤,每個(gè)格子的間距就是棋盤的縱橫交錯(cuò)的線條,python可以實(shí)現(xiàn)該功能的庫有pgzero、tkinter。這里我們用pygame


    # 創(chuàng)建窗口,背景為棕色
 screen = pygame.display.set_mode((615, 615))
 pygame.display.set_caption('五子棋')
 screen.fill("#DD954F")
#創(chuàng)建外邊框

 a = pygame.Surface((603, 603), flags=pygame.HWSURFACE)
 a.fill(color='#121010')
 b = pygame.Surface((585, 585), flags=pygame.HWSURFACE)
 b.fill(color="#DD954F")
 c = pygame.Surface((579, 579), flags=pygame.HWSURFACE)
 c.fill(color='#121010')

 #
 # d = pygame.Surface((576, 576), flags=pygame.HWSURFACE)
 # d.fill(color="#DD954F")
 #棋盤格子
 e = pygame.Surface((31, 31), flags=pygame.HWSURFACE)
 e.fill(color="#DD954F")
 screen.blit(a, (6.5, 6.5))
 screen.blit(b, (15, 15))
 screen.blit(c, (18, 18))
 for j in range(18):
     for i in range(18):
         #起點(diǎn)是20,間隔是32,每個(gè)格子大小31,所以格子間距1
         screen.blit(e, (20 + 32 * i, 20 + 32 * j))
 #存儲(chǔ)棋盤狀態(tài)
 alist  = np.zeros((19, 19))
 #星位
 pygame.draw.circle(screen, '#121010', [307.5, 307.5], 5)
 pygame.draw.circle(screen, '#121010', [115.5, 307.5], 5)
 pygame.draw.circle(screen, '#121010', [499.5, 307.5], 5)
 pygame.draw.circle(screen, '#121010', [115.5, 499.5], 5)
 pygame.draw.circle(screen, '#121010', [499.5, 499.5], 5)
 pygame.draw.circle(screen, '#121010', [115.5, 115.5], 5)
 pygame.draw.circle(screen, '#121010', [499.5, 115.5], 5)
 pygame.draw.circle(screen, '#121010', [307.5, 499.5], 5)
 pygame.draw.circle(screen, '#121010', [307.5, 115.5], 5)
#刷新窗口
 pygame.display.flip()

1.2創(chuàng)建棋子

本來打算直接上圖片,后來參考了別的博主的做法,其實(shí)可以通過多個(gè)半徑顏色不同的同心圓疊加來繪制圓滑的棋子

    def black(x, y):
        a = 20
        b =20
        c =20
        d = 0.01
        #循環(huán)50次,每次繪制50個(gè)半徑顏色不同的同心圓
        for i in range(50):
            pygame.draw.circle(screen, (a, b, c), [19.5 + 32 * x, 19.5 + 32 * y], (16/(d-5)+16))
            a += 1
            b += 1
            c += 1
            d += 0.08
        pygame.display.update()

    def white(x, y):
        a = 170
        b = 170
        c = 170
        d = 0.02
        for i in range(50):
            pygame.draw.circle(screen, (a, b, c), [19.5 + 32 * x, 19.5 + 32 * y],(16/(d-5)+16))
            a += 1
            b += 1
            c += 1
            d += 0.08
        pygame.display.update()

python五子棋,pygame,python,游戲,學(xué)習(xí),娛樂

2.完成走棋操作

棋盤和棋子都準(zhǔn)備好了,下面來實(shí)現(xiàn)下棋的功能,看看如何把棋子擺放在棋盤上。

五子棋的規(guī)則如下

1.對(duì)局雙方各執(zhí)一色棋子。 空棋盤開局。 黑先、白后,交替下子,每次只能下一子。
2.棋子下在棋盤的空白點(diǎn)上,棋子下定后,不得向其它點(diǎn)移動(dòng),不得從棋盤上拿掉或拿起另落別處。
3.五顆連續(xù)的同色棋子先連城一條線的那方贏。

人可以通過眼睛來判斷那個(gè)位置能下棋和何時(shí)輸贏,那計(jì)算機(jī)怎么判斷這些呢。計(jì)算不像人那樣有聰明的大腦,想要讓計(jì)算機(jī)能做出這些判斷,就必須把這些操作轉(zhuǎn)換成計(jì)算機(jī)能理解的數(shù)據(jù)。

怎么讓計(jì)算機(jī)知道棋盤的情況呢?我們用一個(gè)二維數(shù)組來模擬棋盤,棋盤上每個(gè)位置都有三種狀態(tài)(無子、黑子、白子)那我們就用(0、1、2)來表示這三種情況。用wb來表示當(dāng)前棋子,如果該位置為0則,更新該位置的值和wb的值,然后調(diào)用對(duì)用繪畫函數(shù)來更新窗口

    #存儲(chǔ)棋盤狀態(tài)
    alist  = np.zeros((19, 19))
    if event.type == pygame.MOUSEBUTTONDOWN:
               x, y = pygame.mouse.get_pos()
               # 棋盤邊界線的中點(diǎn)是19.5, 通過計(jì)算得到當(dāng)前坐標(biāo)在棋盤的行號(hào)和列號(hào)(x,y)
               x = round((x - 19.5) / 32)
               y = round((y - 19.5) / 32)
               if x < 0:
                   x = 0
               if x > 18:
                   x = 18
               if y < 0:
                   y = 0
               if y > 18:
                   y = 18
               z = False
               if alist[x][y] == 0:
               #這步相當(dāng)于black(x,y)或者是white(x,y)取決于wb
                   eval(wb + "({},{})".format(x, y))

3.判斷輸贏

怎么判斷贏了沒?我們通過鼠標(biāo)左機(jī)屏幕來下棋子,pygame也給我們提供了獲取鼠標(biāo)坐標(biāo)的函數(shù),每次鼠標(biāo)點(diǎn)擊后就進(jìn)行check()操做
分別檢查四個(gè)方向上是否有連子的情況,先找到該方向的第一個(gè)棋子然后向后統(tǒng)計(jì)同色數(shù)量,判斷輸贏。


def check(x,y):
        xx = x
        yy = y
        while True:
            #從最上邊的棋子開始檢查,記錄顏色相同得棋子數(shù)量

            #先找到最同一條線上最上邊的同色棋子
            if xx == 0:
                break
            elif alist[xx][yy] != alist[x][y]:
                xx += 1
                break
            else:
                xx -= 1
        num = 0
        while True:
            if xx == 18:
                break
            elif alist[xx][yy] != alist[x][y]:
                break
            else:
                xx += 1
                num += 1
        if num >= 5:

            win(wb1)

        # 從最邊的棋子開始檢查,記錄顏色相同得棋子數(shù)量

        # 先找到最同一條線上最左邊的同色棋子
        xx = x
        yy = y
        while True:
            if yy == 0:
                break
            elif alist[xx][yy] != alist[x][y]:
                yy += 1
                break
            else:
                yy -= 1
        num = 0
        while True:
            if yy == 18:
                break
            elif alist[xx][yy] != alist[x][y]:
                break
            else:
                yy += 1
                num += 1
        if num >= 5:
         win(wb1)
        
        # 從左上方的棋子開始檢查,記錄顏色相同得棋子數(shù)量

         # 先找到最同一條線上左上方的同色棋子
        xx = x
        yy = y
        while True:
            if xx == 0:
                break
            elif yy == 0:
                break
            elif alist[xx][yy] != alist[x][y]:
                xx += 1
                yy += 1
                break
            else:
                xx -= 1
                yy -= 1
        num = 0
        while True:
            if xx == 18:
                break
            elif yy == 18:
                break
            elif alist[xx][yy] != alist[x][y]:
                break
            else:
                xx += 1
                yy += 1
                num += 1
        if num >= 5:
            win(wb1)


        # 從右上方的棋子開始檢查,記錄顏色相同得棋子數(shù)量

        # 先找到最同一條線上右上方的同色棋子
        xx = x
        yy = y
        while True:
            if xx == 0:
                break
            elif yy == 18:
                break
            elif alist[xx][yy] != alist[x][y]:
                xx += 1
                yy -= 1
                break
            else:
                xx -= 1
                yy += 1
        num = 0
        while True:
            if xx == 18:
                break
            elif yy == 0:
                break
            elif alist[xx][yy] != alist[x][y]:
                break
            else:
                xx += 1
                yy -= 1
                num += 1
        if num >= 5:
            pygame.font.init()
            win(wb1)
     


def win(wb1):
    font = pygame.font.Font(None, 36)
    text = font.render("{}贏了".format(wb1), True, (255, 255, 255))
    screen.blit(text, ((665 - text.get_width()) / 2, (665 - text.get_height()) / 2))
    pygame.display.update()
    while True:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                sys.exit()
            if event.type == pygame.MOUSEBUTTONDOWN:
                do()

完成了這些步驟后,五子棋的基本規(guī)則已經(jīng)實(shí)現(xiàn),敲了幾十行代碼,終于能得到點(diǎn)反饋了。
下面是初級(jí)版的完整代碼


import random
import sys
import pygame

import numpy as np

def init():
    pygame.init()
    # 創(chuàng)建窗口,背景為棕色
    global screen
    screen = pygame.display.set_mode((615, 615))
    pygame.display.set_caption('五子棋')
    screen.fill("#DD954F")
    # 創(chuàng)建外邊框

    a = pygame.Surface((603, 603), flags=pygame.HWSURFACE)
    a.fill(color='#121010')
    b = pygame.Surface((585, 585), flags=pygame.HWSURFACE)
    b.fill(color="#DD954F")
    c = pygame.Surface((579, 579), flags=pygame.HWSURFACE)
    c.fill(color='#121010')

    e = pygame.Surface((31, 31), flags=pygame.HWSURFACE)
    e.fill(color="#DD954F")
    screen.blit(a, (6.5, 6.5))
    screen.blit(b, (15, 15))
    screen.blit(c, (18, 18))
    # 棋盤格子
    for j in range(18):
        for i in range(18):
            # 起點(diǎn)是20,間隔是32,每個(gè)格子大小31,所以格子間距1
            screen.blit(e, (20 + 32 * i, 20 + 32 * j))
    # 存儲(chǔ)棋盤狀態(tài)
    global alist
    alist = np.zeros((19, 19))
    # 星位
    pygame.draw.circle(screen, '#121010', [307.5, 307.5], 5)
    pygame.draw.circle(screen, '#121010', [115.5, 307.5], 5)
    pygame.draw.circle(screen, '#121010', [499.5, 307.5], 5)
    pygame.draw.circle(screen, '#121010', [115.5, 499.5], 5)
    pygame.draw.circle(screen, '#121010', [499.5, 499.5], 5)
    pygame.draw.circle(screen, '#121010', [115.5, 115.5], 5)
    pygame.draw.circle(screen, '#121010', [499.5, 115.5], 5)
    pygame.draw.circle(screen, '#121010', [307.5, 499.5], 5)
    pygame.draw.circle(screen, '#121010', [307.5, 115.5], 5)
    # 刷新窗口
    pygame.display.flip()


# 繪制棋子
def black(x, y):
    a = 20
    b = 20
    c = 20
    d = 0.01
    # 循環(huán)50次,每次繪制50個(gè)半徑顏色不同的同心圓
    for i in range(50):
        pygame.draw.circle(screen, (a, b, c), [19.5 + 32 * x, 19.5 + 32 * y], (16 / (d - 5) + 16))
        a += 1
        b += 1
        c += 1
        d += 0.08
    pygame.display.update()


def white(x, y):
    a = 170
    b = 170
    c = 170
    d = 0.02
    for i in range(50):
        pygame.draw.circle(screen, (a, b, c), [19.5 + 32 * x, 19.5 + 32 * y], (16 / (d - 5) + 16))
        a += 1
        b += 1
        c += 1
        d += 0.08
    pygame.display.update()


pygame.font.init()
font1 = pygame.font.Font(None, 250)


# 主要操作
def do(wb):
    while True:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                sys.exit()
            if event.type == pygame.MOUSEBUTTONDOWN:
                x, y = pygame.mouse.get_pos()
                # 棋盤邊界線的中點(diǎn)是19.5, 通過計(jì)算得到當(dāng)前坐標(biāo)在棋盤的行號(hào)和列號(hào)(x,y)
                x = round((x - 19.5) / 32)
                y = round((y - 19.5) / 32)
                if x < 0:
                    x = 0
                if x > 18:
                    x = 18
                if y < 0:
                    y = 0
                if y > 18:
                    y = 18
                if alist[x][y] == 0:
                    eval(wb + "({},{})".format(x, y))
                    if wb == "black":
                        alist[x][y] = 1
                        wb1 = "black"
                        wb = "white"
                    elif wb == "white":
                        alist[x][y] = 2
                        wb1 = "white"
                        wb = "black"
                    check(x, y, wb1)
def check(x, y, wb1):
    xx = x
    yy = y
    while True:
        # 從最上邊的棋子開始檢查,記錄顏色相同得棋子數(shù)量
        # 先找到最同一條線上最上邊的同色棋子
        if xx == 0:
            break
        elif alist[xx][yy] != alist[x][y]:
            xx += 1
            break
        else:
            xx -= 1
    num = 0
    while True:
        if xx == 18:
            break
        elif alist[xx][yy] != alist[x][y]:
            break
        else:
            xx += 1
            num += 1
    if num >= 5:
        win(wb1)
    # 從最邊的棋子開始檢查,記錄顏色相同得棋子數(shù)量
    # 先找到最同一條線上最左邊的同色棋子
    xx = x
    yy = y
    while True:
        if yy == 0:
            break
        elif alist[xx][yy] != alist[x][y]:
            yy += 1
            break
        else:
            yy -= 1
    num = 0
    while True:
        if yy == 18:
            break
        elif alist[xx][yy] != alist[x][y]:
            break
        else:
            yy += 1
            num += 1
    if num >= 5:
        win(wb1)

    # 從左上方的棋子開始檢查,記錄顏色相同得棋子數(shù)量

    # 先找到最同一條線上左上方的同色棋子
    xx = x
    yy = y
    while True:
        if xx == 0:
            break
        elif yy == 0:
            break
        elif alist[xx][yy] != alist[x][y]:
            xx += 1
            yy += 1
            break
        else:
            xx -= 1
            yy -= 1
    num = 0
    while True:
        if xx == 18:
            break
        elif yy == 18:
            break
        elif alist[xx][yy] != alist[x][y]:
            break
        else:
            xx += 1
            yy += 1
            num += 1
    if num >= 5:
        win(wb1)

    # 從右上方的棋子開始檢查,記錄顏色相同得棋子數(shù)量

    # 先找到最同一條線上右上方的同色棋子
    xx = x
    yy = y
    while True:
        if xx == 0:
            break
        elif yy == 18:
            break
        elif alist[xx][yy] != alist[x][y]:
            xx += 1
            yy -= 1
            break
        else:
            xx -= 1
            yy += 1
    num = 0
    while True:
        if xx == 18:
            break
        elif yy == 0:
            break
        elif alist[xx][yy] != alist[x][y]:
            break
        else:
            xx += 1
            yy -= 1
            num += 1
    if num >= 5:
        pygame.font.init()
        win(wb1)


def win(wb1):
    pygame.font.init()
    font = pygame.font.Font(None, 70)

    text = font.render(f"{wb1}  won", True, (255, 255, 255))
    screen.blit(text, ((655 - text.get_width()) / 2, (665 - text.get_height()) / 2))
    pygame.display.update()

    pygame.display.flip()
    while True:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                sys.exit()
            if event.type == pygame.MOUSEBUTTONDOWN:
                init()
                do("black")


if __name__ == "__main__":
    init()
    do('black')

4.實(shí)現(xiàn)人機(jī)對(duì)弈

現(xiàn)在五子棋的基本公能已經(jīng)實(shí)現(xiàn)了,但這種充滿策略與博弈的棋類游戲,猜測(cè)并應(yīng)對(duì)對(duì)手可能的布局,相互之間進(jìn)行激烈的智力對(duì)決才是游戲最好玩的部分,一個(gè)人玩也太無聊了,要是電腦能像人一樣可以思考該多好呀,就像近幾年的特別火的“阿爾法狗”一樣,我很期待被自己的程序打敗。那么怎樣實(shí)現(xiàn)人機(jī)對(duì)弈呢?

隨著人工智能的快速發(fā)展,其在許多領(lǐng)域都得到了廣泛應(yīng)用,其中就包括游戲人工智能。游戲人工智能分為兩大類,
一類叫做確定性人工智能,另一類叫做非確定性人工智能。
確定性人工智能,是指電腦按照確定的規(guī)則進(jìn)行判斷和抉擇。非確定性人工智能是指電腦根據(jù)已有的規(guī)則來學(xué)習(xí)新的規(guī)則,例如神經(jīng)網(wǎng)絡(luò)、遺傳算法、決策樹和概率方法等。
因?yàn)槲遄悠宓囊?guī)則是確定的,所以我們只用讓電腦記住規(guī)則,并按照規(guī)則來決策和判斷。在棋類游戲中,如果把棋子的每一種布局都當(dāng)作是一種狀態(tài),那對(duì)局中所有的可能局面的集合被稱為狀態(tài)空間,狀態(tài)空間搜素就是根據(jù)某種規(guī)則,在所有的局面中找到最有利的局面,并以此來決定下一步走法。由于五子棋的規(guī)則簡(jiǎn)單,不同狀態(tài)的最優(yōu)解比較少,不必采用耗費(fèi)空間的狀態(tài)空間搜素法,只用讓電腦記住所有的最優(yōu)解即可。

4.1列舉最優(yōu)解

回想一下自己下棋的思考過程,決策和判斷的依據(jù)無非就那幾種,進(jìn)過權(quán)衡后選擇最有利的走法。模仿人的思考過程,我們可以告訴電腦所有的走法,然后將這些走法按等級(jí)排序,電腦每次決策的時(shí)候就在這些走法集合中按照等級(jí)由高到低的順序依次搜素,沒有找到最優(yōu)解則隨機(jī)下子。

為了讓電腦能識(shí)別走法,首先要對(duì)棋局的各種走法進(jìn)行描述和儲(chǔ)存,這里我們用一個(gè)cdata列表實(shí)現(xiàn),0表示空棋、1表示黑棋、 2表示白棋、3表示將要下棋的位置。


# 0表示空棋
# 1表示黑棋
# 2表示白棋
# 3表示下棋的位置

cdata = [
    # 一顆棋子的情況

    [1, 3, 0, 0, 0], [0, 1, 3, 0, 0], [0, 0, 1, 3, 0], [0, 0, 0, 1, 3], [0, 0, 0, 3, 1],
    [2, 3, 0, 0, 0], [0, 2, 3, 0, 0], [0, 0, 2, 3, 0], [0, 0, 0, 2, 3], [0, 0, 0, 3, 2],
    # 二顆棋子的情況
    [0, 1, 3, 1, 0], [1, 1, 3, 0, 0], [0, 0, 3, 1, 1],
    [2, 2, 3, 0, 0], [0, 0, 3, 2, 2], [0, 2, 3, 2, 0],
    # 三顆棋子的情況
    [1, 1, 1, 3, 0], [0, 3, 1, 1, 1], [1, 1, 3, 1, 0], [1, 3, 1, 1, 0],
    [2, 2, 0, 3, 2], [2, 3, 0, 2, 2], [0, 3, 2, 2, 2], [2, 2, 3, 2, 0],
    [2, 3, 2, 2, 0], [0, 2, 3, 2, 2], [0, 2, 2, 3, 2], [2, 2, 2, 3, 0], [3, 2, 2, 2, 0],
    # 四顆棋子情況
    [1, 1, 1, 1, 3], [3, 1, 1, 1, 1], [1, 1, 1, 3, 1], [1, 3, 1, 1, 1], [1, 1, 3, 1, 1],
    [2, 2, 2, 2, 3], [3, 2, 2, 2, 2], [2, 2, 3, 2, 2], [2, 3, 2, 2, 2], [2, 2, 2, 3, 2]
]

4.2匹配最優(yōu)解

現(xiàn)在電腦已經(jīng)掌握各種走法了,決勝秘籍在手,電腦改怎么用呢?接下來我們定義三個(gè)全局變量,用來輔助匹配算法的執(zhí)行。 用ai_col 下棋位置列號(hào), ai_row下棋位置行號(hào),max_level走法等級(jí)

  global ai_col, ai_row, max_level
    ai_col = -1
    ai_row = -1
    max_level = -1

接著我們來定義auto_match()函數(shù)

def auto_mach(row, col, level, dx, dy):
    global ai_col, ai_row, max_level
    col_sel = -1  # 暫存棋子列號(hào)
    row_sel = -1  # 暫存棋子行號(hào)
    isfind = True  # 匹配成功的標(biāo)記

    for j in range(5):
        cs = alist[row + j * dx][col + j * dy]
        if cs == 0:
            if cdata[level][j] == 3:
                row_sel = row + j * dx
                col_sel = col + j * dy
            elif cdata[level][j] == 1:
                isfind = False
                break
            elif cdata[level][j] == 2:
                isfind = False
                break
        elif cs != cdata[level][j]:
            isfind = False
            break
    if isfind:
        ai_row = row_sel
        ai_col = col_sel
        max_level = level
        return True
    return False

函數(shù)需要4個(gè)參數(shù)row和col是棋子的位置,level是走法等級(jí),dx,dy是下一步方向,用row_sel,col_sel來存儲(chǔ)匹配過程中棋子的位值,棋子按照dx,dy的方向一次往后匹配,
如果棋盤布局和走法列表匹配成功則發(fā)揮True,反正返回False。

4.3自主操作

完成了匹配操作后,電腦就有了判斷的能力了,接下來我們來實(shí)現(xiàn)電腦的自主操作。下面定義ai_play()


def ai_play():
    global ai_col, ai_row, max_level
    ai_col = -1
    ai_row = -1
    max_level = -1
    # 搜素棋盤每個(gè)位置
    for i in range(19):
        for j in range(19):
            # 從高到低搜索
            for level in range(len(cdata) - 1, -1, -1):
                if level > max_level:
                    if i + 4 < 19:
                        if auto_mach(i, j, level, 1, 0):
                            break
                    if j + 4 < 19:
                        if auto_mach(i, j, level, 0, 1):
                            break

                    if i + 4 < 19 and j + 4 < 19:
                        if auto_mach(i, j, level, 1, 1):
                            break

                    if i + 4 < 19 and j - 4 > 0:
                        if auto_mach(i, j, level, 1, -1):
                            break
    if ai_row!=-1 and ai_row!=-1:
        alist[ai_row][ai_col]=2
        return True
    while True:
        col = random.randint(0,18)
        row = random.randint(0, 18)
        if alist[row][col]==0:
            alist[row][col]=2
            ai_row=row
            ai_col=col

            return True
    return False

該函數(shù)首先將全局變量max_level,ai_row,ai_col重置為-1,清除上次結(jié)果的影響,然后從棋盤第一個(gè)位置開始匹配,max_level記錄最高等級(jí),凡是等級(jí)比其低的走法直接不考慮,這樣能減少不必要的操作,加快程序運(yùn)行速率,匹配結(jié)束后,若找到最優(yōu)解了就更新ai_row,ai_col,沒找到就隨機(jī)選一個(gè)符合要求的位置。

完整代碼

至此程序全部編寫完成,現(xiàn)在運(yùn)行游戲玩一下,看看你和計(jì)算機(jī)誰更厲害,如果被打敗了這就是你肝了半天的代碼最好的反饋。


import random
import sys
import pygame

import numpy as np

# 0表示空棋
# 1表示黑棋
# 2表示白棋
# 3表示下棋的位置

cdata = [
    # 一顆棋子的情況

    [1, 3, 0, 0, 0], [0, 1, 3, 0, 0], [0, 0, 1, 3, 0], [0, 0, 0, 1, 3], [0, 0, 0, 3, 1],
    [2, 3, 0, 0, 0], [0, 2, 3, 0, 0], [0, 0, 2, 3, 0], [0, 0, 0, 2, 3], [0, 0, 0, 3, 2],
    # 二顆棋子的情況
    [0, 1, 3, 1, 0], [1, 1, 3, 0, 0], [0, 0, 3, 1, 1],
    [2, 2, 3, 0, 0], [0, 0, 3, 2, 2], [0, 2, 3, 2, 0],
    # 三顆棋子的情況
    [1, 1, 1, 3, 0], [0, 3, 1, 1, 1], [1, 1, 3, 1, 0], [1, 3, 1, 1, 0],
    [2, 2, 0, 3, 2], [2, 3, 0, 2, 2], [0, 3, 2, 2, 2], [2, 2, 3, 2, 0],
    [2, 3, 2, 2, 0], [0, 2, 3, 2, 2], [0, 2, 2, 3, 2], [2, 2, 2, 3, 0], [3, 2, 2, 2, 0],
    # 四顆棋子情況
    [1, 1, 1, 1, 3], [3, 1, 1, 1, 1], [1, 1, 1, 3, 1], [1, 3, 1, 1, 1], [1, 1, 3, 1, 1],
    [2, 2, 2, 2, 3], [3, 2, 2, 2, 2], [2, 2, 3, 2, 2], [2, 3, 2, 2, 2], [2, 2, 2, 3, 2]
]


def auto_mach(row, col, level, dx, dy):
    global ai_col, ai_row, max_level
    col_sel = -1  # 暫存棋子列號(hào)
    row_sel = -1  # 暫存棋子行號(hào)
    isfind = True  # 匹配成功的標(biāo)記

    for j in range(5):
        cs = alist[row + j * dx][col + j * dy]
        if cs == 0:
            if cdata[level][j] == 3:
                row_sel = row + j * dx
                col_sel = col + j * dy
            elif cdata[level][j] == 1:
                isfind = False
                break
            elif cdata[level][j] == 2:
                isfind = False
                break
        elif cs != cdata[level][j]:
            isfind = False
            break
    if isfind:
        ai_row = row_sel
        ai_col = col_sel
        max_level = level
        return True
    return False


def ai_play():
    global ai_col, ai_row, max_level
    ai_col = -1
    ai_row = -1
    max_level = -1
    # 搜素棋盤每個(gè)位置
    for i in range(19):
        for j in range(19):
            # 從高到低搜索
            for level in range(len(cdata) - 1, -1, -1):
                if level > max_level:
                    if i + 4 < 19:
                        if auto_mach(i, j, level, 1, 0):
                            break
                    if j + 4 < 19:
                        if auto_mach(i, j, level, 0, 1):
                            break

                    if i + 4 < 19 and j + 4 < 19:
                        if auto_mach(i, j, level, 1, 1):
                            break

                    if j + 4 < 19 and i - 4 > 0:
                        if auto_mach(i, j, level, -1, 1):
                            break
    if ai_row!=-1 and ai_row!=-1:
        alist[ai_row][ai_col]=2
        return True
    while True:
        col = random.randint(0,18)
        row = random.randint(0, 18)
        if alist[row][col]==0:
            alist[row][col]=2
            ai_row=row
            ai_col=col

            return True
    return False


def init():
    pygame.init()
    # 創(chuàng)建窗口,背景為棕色
    global screen
    screen = pygame.display.set_mode((615, 615))
    pygame.display.set_caption('五子棋')
    screen.fill("#DD954F")
    # 創(chuàng)建外邊框

    a = pygame.Surface((603, 603), flags=pygame.HWSURFACE)
    a.fill(color='#121010')
    b = pygame.Surface((585, 585), flags=pygame.HWSURFACE)
    b.fill(color="#DD954F")
    c = pygame.Surface((579, 579), flags=pygame.HWSURFACE)
    c.fill(color='#121010')

    e = pygame.Surface((31, 31), flags=pygame.HWSURFACE)
    e.fill(color="#DD954F")
    screen.blit(a, (6.5, 6.5))
    screen.blit(b, (15, 15))
    screen.blit(c, (18, 18))
    # 棋盤格子
    for j in range(18):
        for i in range(18):
            # 起點(diǎn)是20,間隔是32,每個(gè)格子大小31,所以格子間距1
            screen.blit(e, (20 + 32 * i, 20 + 32 * j))
    # 存儲(chǔ)棋盤狀態(tài)
    global alist
    alist = np.zeros((19, 19))
    # 星位
    pygame.draw.circle(screen, '#121010', [307.5, 307.5], 5)
    pygame.draw.circle(screen, '#121010', [115.5, 307.5], 5)
    pygame.draw.circle(screen, '#121010', [499.5, 307.5], 5)
    pygame.draw.circle(screen, '#121010', [115.5, 499.5], 5)
    pygame.draw.circle(screen, '#121010', [499.5, 499.5], 5)
    pygame.draw.circle(screen, '#121010', [115.5, 115.5], 5)
    pygame.draw.circle(screen, '#121010', [499.5, 115.5], 5)
    pygame.draw.circle(screen, '#121010', [307.5, 499.5], 5)
    pygame.draw.circle(screen, '#121010', [307.5, 115.5], 5)
    # 刷新窗口
    pygame.display.flip()


# 繪制棋子
def black(x, y):
    a = 20
    b = 20
    c = 20
    d = 0.01
    # 循環(huán)50次,每次繪制50個(gè)半徑顏色不同的同心圓
    for i in range(50):
        pygame.draw.circle(screen, (a, b, c), [19.5 + 32 * x, 19.5 + 32 * y], (16 / (d - 5) + 16))
        a += 1
        b += 1
        c += 1
        d += 0.08
    pygame.display.update()


def white(x, y):
    a = 170
    b = 170
    c = 170
    d = 0.02
    for i in range(50):
        pygame.draw.circle(screen, (a, b, c), [19.5 + 32 * x, 19.5 + 32 * y], (16 / (d - 5) + 16))
        a += 1
        b += 1
        c += 1
        d += 0.08
    pygame.display.update()


pygame.font.init()
font1 = pygame.font.Font(None, 250)


# 主要操作
def do(wb):
    while True:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                sys.exit()
            if event.type == pygame.MOUSEBUTTONDOWN:
                x, y = pygame.mouse.get_pos()
                # 棋盤邊界線的中點(diǎn)是19.5, 通過計(jì)算得到當(dāng)前坐標(biāo)在棋盤的行號(hào)和列號(hào)(x,y)
                x = round((x - 19.5) / 32)
                y = round((y - 19.5) / 32)
                if x < 0:
                    x = 0
                if x > 18:
                    x = 18
                if y < 0:
                    y = 0
                if y > 18:
                    y = 18
                if alist[x][y] == 0:
                    black(x, y)
                    alist[x][y] = 1
                    wb1 = "You"
                    wb = "white"
                    check(x, y, wb1)
                    pygame.time.wait(100)
                    if ai_play():
                        white(ai_row, ai_col)
                        wb1 = "AI"
                        wb = "black"
                        check(ai_row, ai_col, wb1)

def check(x, y, wb1):
    xx = x
    yy = y
    while True:
        # 從最上邊的棋子開始檢查,記錄顏色相同得棋子數(shù)量
        # 先找到最同一條線上最上邊的同色棋子
        if xx == 0:
            if alist[xx][yy] != alist[x][y]:
                xx += 1
            break
        elif alist[xx][yy] != alist[x][y]:
            xx += 1
            break
        else:
            xx -= 1
    num = 0
    while True:
        if xx == 18:
            if alist[xx][yy] == alist[x][y]:
                num += 1
            break
        elif alist[xx][yy] != alist[x][y]:
            break
        else:
            xx += 1
            num += 1
    if num >= 5:
        win(wb1)
    # 從最邊的棋子開始檢查,記錄顏色相同得棋子數(shù)量
    # 先找到最同一條線上最左邊的同色棋子
    xx = x
    yy = y
    while True:
        if yy == 0:
            if alist[xx][yy] != alist[x][y]:
                yy += 1

            break
        elif alist[xx][yy] != alist[x][y]:
            yy += 1
            break
        else:
            yy -= 1
    num = 0
    while True:
        if yy == 18:
            if alist[xx][yy] == alist[x][y]:
                num += 1
            break
        elif alist[xx][yy] != alist[x][y]:
            break
        else:
            yy += 1
            num += 1
    if num >= 5:
        win(wb1)

    # 從左上方的棋子開始檢查,記錄顏色相同得棋子數(shù)量

    # 先找到最同一條線上左上方的同色棋子
    xx = x
    yy = y
    while True:
        if xx == 0:
            if alist[xx][yy] != alist[x][y]:
                xx += 1
                yy += 1
            break
        elif yy == 0:
            if alist[xx][yy] != alist[x][y]:
                xx += 1
                yy += 1
            break
        elif alist[xx][yy] != alist[x][y]:
            xx += 1
            yy += 1
            break
        else:
            xx -= 1
            yy -= 1
    num = 0
    while True:
        if xx == 18:
            if alist[xx][yy] == alist[x][y]:
                num += 1

            break
        elif yy == 18:
            if alist[xx][yy] == alist[x][y]:
                num += 1
            break
        elif alist[xx][yy] != alist[x][y]:
            break
        else:
            xx += 1
            yy += 1
            num += 1
    if num >= 5:
        win(wb1)

    # 從右上方的棋子開始檢查,記錄顏色相同得棋子數(shù)量

    # 先找到最同一條線上右上方的同色棋子
    xx = x
    yy = y
    while True:
        if xx == 0:
            if alist[xx][yy] != alist[x][y]:
                xx += 1
                yy -= 1
            break
        elif yy == 18:
            if alist[xx][yy] != alist[x][y]:
                xx += 1
                yy -= 1
            break
        elif alist[xx][yy] != alist[x][y]:
            xx += 1
            yy -= 1
            break
        else:
            xx -= 1
            yy += 1
    num = 0
    while True:
        if xx == 18:
            if alist[xx][yy] == alist[x][y]:
                num += 1
            break
        elif yy == 0:
            if alist[xx][yy] == alist[x][y]:
                num += 1
            break
        elif alist[xx][yy] != alist[x][y]:
            break
        else:
            xx += 1
            yy -= 1
            num += 1
    if num >= 5:
        win(wb1)


def win(wb1):
    pygame.font.init()
    font = pygame.font.Font(None, 70)

    text = font.render(f"{wb1}  won", True, (255, 255, 255))
    screen.blit(text, ((655 - text.get_width()) / 2, (665 - text.get_height()) / 2))
    pygame.display.update()

    while True:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                sys.exit()
            if event.type == pygame.MOUSEBUTTONDOWN:
                init()
                text = font.render("Start the game", True, (255, 255, 255))
                screen.blit(text, ((655 - text.get_width()) / 2, (665 - text.get_height()) / 2))
                pygame.display.update()
                pygame.time.wait(500)
                init()
                do("black")


if __name__ == "__main__":
    init()
    do('black')



python五子棋,pygame,python,游戲,學(xué)習(xí),娛樂

參考資料《趣學(xué)python游戲編程》文章來源地址http://www.zghlxwxcb.cn/news/detail-751363.html

到了這里,關(guān)于讓電腦變得更聰明——用python實(shí)現(xiàn)五子棋游戲的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • python項(xiàng)目分享 python五子棋小游戲

    python項(xiàng)目分享 python五子棋小游戲

    ?? Hi,各位同學(xué)好呀,這里是L學(xué)長(zhǎng)! ??今天向大家分享一個(gè)今年(2022)最新完成的畢業(yè)設(shè)計(jì)項(xiàng)目作品 python小游戲畢設(shè) 五子棋小游戲設(shè)計(jì)與實(shí)現(xiàn) (源碼) ?? 學(xué)長(zhǎng)根據(jù)實(shí)現(xiàn)的難度和等級(jí)對(duì)項(xiàng)目進(jìn)行評(píng)分(最低0分,滿分5分) 難度系數(shù):3分 工作量:3分 創(chuàng)新點(diǎn):4分 項(xiàng)目獲?。?htt

    2024年02月03日
    瀏覽(25)
  • python項(xiàng)目分享 - python五子棋小游戲

    python項(xiàng)目分享 - python五子棋小游戲

    ?? Hi,各位同學(xué)好呀,這里是L學(xué)長(zhǎng)! ??今天向大家分享一個(gè)今年(2022)最新完成的畢業(yè)設(shè)計(jì)項(xiàng)目作品 python小游戲畢設(shè) 五子棋小游戲設(shè)計(jì)與實(shí)現(xiàn) (源碼) ?? 學(xué)長(zhǎng)根據(jù)實(shí)現(xiàn)的難度和等級(jí)對(duì)項(xiàng)目進(jìn)行評(píng)分(最低0分,滿分5分) 難度系數(shù):3分 工作量:3分 創(chuàng)新點(diǎn):4分 項(xiàng)目獲?。?htt

    2024年02月03日
    瀏覽(27)
  • 用c++實(shí)現(xiàn)五子棋小游戲

    用c++實(shí)現(xiàn)五子棋小游戲

    五子棋是一款經(jīng)典小游戲,今天我們就用c++實(shí)現(xiàn)簡(jiǎn)單的五子棋小游戲 目錄 用到的算法: 思路分析 定義變量? 開始寫代碼 ? 完整代碼? 結(jié)果圖: 合法移動(dòng)的判斷: isValidMove 函數(shù)通過檢查指定位置是否在棋盤范圍內(nèi),并且該位置是否為空位來確定是否為合法的移動(dòng)。 獲勝條

    2024年02月07日
    瀏覽(24)
  • Java實(shí)現(xiàn)五子棋小游戲(附源碼)

    Java實(shí)現(xiàn)五子棋小游戲(附源碼)

    ??銅9鐵10已經(jīng)結(jié)束了,但還是有很多Java程序員沒有找到工作或者成功跳槽,跳槽成功的也只是從一個(gè)坑中,跳入另一個(gè)坑中…… ? 在LZ看來,真正有意義的就業(yè)與跳槽,是要進(jìn)入到一個(gè)有絕對(duì)潛力的行業(yè)或者薪資能實(shí)現(xiàn)爆炸式增長(zhǎng)的。這件事不容易,但也沒有想象的遙不可

    2024年02月08日
    瀏覽(24)
  • Android Studio實(shí)現(xiàn)五子棋小游戲

    Android Studio實(shí)現(xiàn)五子棋小游戲

    五子棋是一種兩人對(duì)弈的策略型棋類游戲,本次五子棋小游戲具有人機(jī)對(duì)戰(zhàn)和人人對(duì)戰(zhàn)兩種玩法。人機(jī)對(duì)戰(zhàn)可以單人挑戰(zhàn)AI,實(shí)時(shí)記錄比賽得分,AI是根據(jù)棋盤上每個(gè)點(diǎn)的得分進(jìn)行決策,人人對(duì)戰(zhàn)采用輪流下棋方式進(jìn)行對(duì)決,下棋過程中會(huì)記錄當(dāng)前棋子的顏色。可以在下棋過程

    2024年02月08日
    瀏覽(27)
  • 基于Java的五子棋游戲的設(shè)計(jì)與實(shí)現(xiàn)

    基于 Java 的五子棋游戲的設(shè)計(jì) 摘? 要 五子棋作為一個(gè)棋類競(jìng)技運(yùn)動(dòng),在民間十分流行,為了熟悉五子棋規(guī)則及技巧,以及研究簡(jiǎn)單的人工智能,決定用Java開發(fā)五子棋游戲。主要完成了人機(jī)對(duì)戰(zhàn)和玩家之間聯(lián)網(wǎng)對(duì)戰(zhàn)2個(gè)功能。網(wǎng)絡(luò)連接部分為Socket編程應(yīng)用,客戶端和服務(wù)器端的

    2023年04月23日
    瀏覽(23)
  • C語言實(shí)現(xiàn)五子棋小游戲(內(nèi)附源碼)

    C語言實(shí)現(xiàn)五子棋小游戲(內(nèi)附源碼)

    游戲中有人機(jī),雙人兩種模式。五子棋作為一個(gè)平面游戲,很明顯用二維數(shù)組來寫最合適不過。為了讓代碼看起來更有條理,我們用三個(gè).c文件,分別是:text.c 用來測(cè)試我們的游戲;game.c 游戲功能的實(shí)現(xiàn);is_win.c 判斷輸贏的版塊。另外,還有一個(gè)game.h 文件來放我們的函數(shù)聲

    2024年02月09日
    瀏覽(28)
  • C#實(shí)現(xiàn)五子棋小游戲:簡(jiǎn)單、有趣的編程項(xiàng)目
  • Java實(shí)現(xiàn)五子棋小游戲(附思路講解,全部代碼,游戲截圖)

    Java實(shí)現(xiàn)五子棋小游戲(附思路講解,全部代碼,游戲截圖)

    本文章是如何實(shí)現(xiàn)一個(gè)單機(jī)版雙人五子棋小游戲,通過Swing技術(shù)進(jìn)行可視操作. 個(gè)人簡(jiǎn)介: ???♂?個(gè)人主頁:碼云不禿頭. ??本人是一名大三學(xué)生,馬上就要變成考研狗啦,通過一學(xué)期對(duì)Java學(xué)習(xí),經(jīng)過老師的教學(xué),實(shí)現(xiàn)單機(jī)版的雙人五子棋小游戲,大家互相學(xué)習(xí),也同時(shí)為了完成我的實(shí)

    2024年02月07日
    瀏覽(23)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包