欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 教育 > 幼教 > python+pygame实现五子棋网络对战之二

python+pygame实现五子棋网络对战之二

2024/10/23 23:29:53 来源:https://blog.csdn.net/cxhold/article/details/140261033  浏览:    关键词:python+pygame实现五子棋网络对战之二

上篇我们对python的Socket编程有了一个基本的认识,接下来就可以完成五子棋的网络对战的实现。步骤如下:

1、服务端开始侦听

2、客户端通过tcp连接上服务端,开局

3、判断输赢后,一方提出是否开新局

4、对方同意后,开新局。

接下来就简单了,只要把Socket编程的通信部分弄到以前的代码就可以了。

五子棋人机对战版:(

https://blog.csdn.net/cxhold/article/details/140126002

https://blog.csdn.net/cxhold/article/details/140133224

https://blog.csdn.net/cxhold/article/details/140136176

https://blog.csdn.net/cxhold/article/details/140142940

https://blog.csdn.net/cxhold/article/details/140159258)

五子棋人机代码

三、

代码结构:

服务端和客户端的代码区别就在main.py中

3.1 服务端main.py

# encoding:utf-8
import pygame
from pygame.locals import *
import sys
import os
from socket import *
import selectimport  piece
from tkinter import *
from params import Params
from utils import *pygame.init()
pygame.mixer.init()WHITE = (255, 255, 255)
BLACK = (0, 0, 0)rows = int(Params.get('ROWS'))
blocksize = int(Params.get('blockSize'))
width = int(Params.get('WIDTH'))
height = int(Params.get('HEIGHT'))game_bgsize = width, height
# 棋盘
x = []    #x轴
y = []    #y轴for i in range(0, rows):   #棋盘的所有交叉点坐标(x,y)x.append(28 + i * blocksize)y.append(28 + i * blocksize)# 记录棋盘每个坐标的属性,没有棋子为0,白棋为1,黑棋为2
chess_map = {}    #结构是chess_map[28,28] = 0   ...# 字体
fontpath = os.path.join(Params.get('resourcePath'), Params.get('fontFolder'), 'simkai.ttf')
myfont = pygame.font.Font(fontpath, 38)# 起始选项
txtplayerandplayer = myfont.render("玩家与玩家", True, WHITE)
txtplayerandplayer_rect = txtplayerandplayer.get_rect()
txtplayerandplayer_rect.left, txtplayerandplayer_rect.top = (game_bgsize[0] - txtplayerandplayer_rect.width) // 2, \(game_bgsize[1] - txtplayerandplayer_rect.height) // 2 - 100txtplayerandcomputer = myfont.render('玩家与电脑', True, WHITE)
txtplayerandcomputer_rect = txtplayerandcomputer.get_rect()
txtplayerandcomputer_rect.left, txtplayerandcomputer_rect.top = (game_bgsize[0] - txtplayerandplayer_rect.width) // 2, \(game_bgsize[1] - txtplayerandplayer_rect.height) // 2txtplaysound = myfont.render('音效:  开', True, WHITE)
txtplaysound_rect = txtplaysound.get_rect()
txtplaysound_rect.left, txtplaysound_rect.top = (game_bgsize[0] - txtplaysound_rect.width) // 2, \(game_bgsize[1] - txtplaysound_rect.height) // 2 + 100txtclosesound = myfont.render('音效:  关', True, WHITE)
txtclosesound_rect = txtclosesound.get_rect()
txtclosesound_rect.left, txtclosesound_rect.top = (game_bgsize[0] - txtclosesound_rect.width) // 2, \(game_bgsize[1] - txtclosesound_rect.height) // 2 + 100# 输赢
successtext = myfont.render("你有点屌哦!!!", True, WHITE)
successtext_rect = successtext.get_rect()
successtext_rect.left, successtext_rect.top = (game_bgsize[0] - successtext_rect.width) // 2, \(game_bgsize[1] - successtext_rect.height) // 2
failuretext = myfont.render("小趴菜...", True, WHITE)
failuretext_rect = failuretext.get_rect()
failuretext_rect.left, failuretext_rect.top = (game_bgsize[0] - failuretext_rect.width) // 2, \(game_bgsize[1] - failuretext_rect.height) // 2
playagaintext = myfont.render("再玩一局", True, WHITE)
menutext = myfont.render('主菜单', True, WHITE)#连接
txtwatting = myfont.render('等待连接', True, WHITE)
txtwatting_rect = txtclosesound.get_rect()
txtwatting_rect.left, txtwatting_rect.top = (game_bgsize[0] - txtwatting_rect.width) // 2, \(game_bgsize[1] - txtwatting_rect.height) // 2
txtclosed = myfont.render('对方不愿和你玩并断开了连接', True, WHITE)
txtclosed_rect = txtclosed.get_rect()
txtclosed_rect.left, txtclosed_rect.top = (game_bgsize[0] - txtclosed_rect.width) // 2, \(game_bgsize[1] - txtclosed_rect.height) // 2
txtchallenge = myfont.render('对方再次向你发起挑战', True, WHITE)
txtchallenge_rect = txtchallenge.get_rect()
txtchallenge_rect.left, txtchallenge_rect.top = (game_bgsize[0] - txtchallenge_rect.width) // 2, \(game_bgsize[1] - txtchallenge_rect.height) // 2
txtrecive = myfont.render('接受挑战         不接受挑战', True, WHITE)
txtrecive_rect = txtrecive.get_rect()
txtrecive_rect.left, txtrecive_rect.top = (game_bgsize[0] - txtrecive_rect.width) // 2, \(game_bgsize[1] - txtrecive_rect.height) // 2 + 100# TCP服务
HOST = ''  # 地址
POST = 23338  # 端口
BUFSIZE = 2048    #缓冲区
HOSTADDR = (HOST, POST)
tcpserversocket = socket(AF_INET, SOCK_STREAM)   #创建套接字
tcpserversocket.bind(HOSTADDR)
tcpserversocket.listen(1)   #listen(n)的n值表示socket的“排队个数”,表示的是服务器拒绝(超过限制数量的)连接之前,操作系统可以挂起的最大连接数量。
#一般情况下,一个进程只有一个主线程(也就是单线程),那么socket允许的最大连接数为: n + 1 \
# 如果服务器是多线程,比如开了2个线程,那么socket允许的最大连接数就是: n + 2 \
# 换句话说:排队的人数(就是那个n) + 正在就餐的人数(服务器正在处理的socket连接数) = 允许接待的总人数(socket允许的最大连接数)\
# 因此listen(1),最大连接数是2,就是1个处理,1个“排队”inputs = [tcpserversocket]# 判断棋盘某位置上是否有棋子
def isempty(theposition):global chess_mapexistpiece = Falseif chess_map[str(theposition[0]) + ',' + str(theposition[1])]:existpiece = Truereturn existpiece# 电脑选取落子的位置
def computerdecision():value = max1 = max2 = 0pos1 = pos2 = ()# 进攻for i in range(0, rows):row = 28 + i * blocksizefor j in range(0, rows):col = 28 + j * blocksizepos = (row, col)if isempty(pos):continuevalue = pointvalue(chess_map,pos, 1, 2)   if value > max1:max1 = valuepos1 = (row, col)# 防守for i in range(0, rows):for j in range(0, rows):row = 28 + i * blocksizecol = 28 + j * blocksizeif isempty((row, col)):continuevalue = pointvalue(chess_map,(row, col), 2, 1)  if value > max2:max2 = valuepos2 = (row, col)if max1 > max2:return pos1else:return pos2# 初始化棋盘
def init():global chess_mapfor i in x:for j in y:chess_map[str(i) + ',' + str(j)] = 0    #清空def main():os.environ['SDL_VIDEO_CENTERED'] = '1'    #居中screen = pygame.display.set_mode(game_bgsize)pygame.display.set_caption('五子棋服务端')bgimagepath = os.path.join(Params.get('resourcePath'), Params.get('imgFolder'), 'bg.png')bg_image = pygame.image.load(bgimagepath).convert_alpha()  # 背景图片加载zzimagepath = os.path.join(Params.get('resourcePath'), Params.get('imgFolder'), 'zz.png') #遮罩图片zz_image = pygame.image.load(zzimagepath).convert_alpha()# 背景音乐bgsoundpath = os.path.join(Params.get('resourcePath'), Params.get('soundFolder'), '齐豫 - 莲花处处开.mp3')bg_sound = pygame.mixer.music.load(bgsoundpath)   # 背景音乐加载pygame.mixer.music.set_volume(0.08)pygame.mixer.music.play(-1)clicksoundpath = os.path.join(Params.get('resourcePath'), Params.get('soundFolder'), 'drop.wav')piece_sound = pygame.mixer.Sound(clicksoundpath) clock = pygame.time.Clock()# 棋子white_chesses = []   #白棋子对象black_chesses = []   #黑棋子对象white_positions = [] #白棋子位置集合black_positions = [] #黑棋子位置集合chesses = []         #所有棋子集合,主要是显示用is_player = False   # 轮到哪方下棋, is_finish = False     # 是否结束游戏# 赢方black_win = Falsewhite_win = Falsepeople2people = False   # 人与人,网络版  people2computer = False  # 人与电脑is_choise = False  # 是否做出选择对战方式,是people2people 还是 people2computer , 通过菜单选择对战方式is_play_sound = True   # 是否播放声音is_playagain = False    # 是否再来一局# 是否连接is_link = False# 对方是否发来重新开始的消息is_againmsg = False# 对面拒绝了重新开始is_reject = False# 初始化is_playagain = Falserunning = Trueinit()while running:screen.blit(bg_image, (0, 0))# 绘制游戏菜单if not is_choise:screen.blit(zz_image, (0, 0))  #遮罩层screen.blit(txtplayerandplayer, txtplayerandplayer_rect)screen.blit(txtplayerandcomputer, txtplayerandcomputer_rect)if not is_play_sound:screen.blit(txtclosesound, txtclosesound_rect)else:screen.blit(txtplaysound, txtplaysound_rect)else:  #if people2people:if not is_link and not is_reject:screen.blit(txtwatting, txtwatting_rect)# 绘制棋盘if is_choise:if chesses:for i in chesses:screen.blit(i.image, i.image_rect())for event in pygame.event.get():if event.type == QUIT:if is_link:tcpclientsocket.close()if people2people:tcpserversocket.close()pygame.quit()sys.exit()if event.type == MOUSEBUTTONDOWN:   #server下棋if event.button == 1 :if is_finish :if not is_againmsg and not is_reject:pos = event.posif successtext_rect.left < pos[0] < successtext_rect.right  and \successtext_rect.top < pos[1] < successtext_rect.top + 30:if people2people:tcpclientsocket.send('again'.encode('utf8'))if people2computer:is_playagain = Trueis_player = Trueis_finish = Falseinit()if successtext_rect.left < pos[0] < successtext_rect.right - 50 and \successtext_rect.top + 50 < pos[1] < successtext_rect.top + 120:people2people = Falseis_choise = Falseif is_link:is_link = Falsetcpclientsocket.send('no'.encode('utf8'))main()if is_reject:pos = event.posif txtclosed_rect.left + 150 < pos[0] < txtclosed_rect.left + 250 and \txtclosed_rect.top + 70 < pos[1] < txtclosed_rect.top + 190:main()is_choise = Falseif is_againmsg:pos = event.posif txtrecive_rect.left < pos[0] < txtrecive_rect.left + 150 and \txtrecive_rect.top < pos[1] < txtrecive_rect.top + 120:tcpclientsocket.send('yes'.encode('utf8'))is_againmsg = Falseis_playagain = Trueis_player = Falseis_finish = Falseif txtrecive_rect.left + 330 < pos[0] < txtrecive_rect.left + 480 and \txtrecive_rect.top < pos[1] < txtrecive_rect.top + 120:tcpclientsocket.send('no'.encode('utf8'))main()if is_choise:# 判断是否轮到server下棋if is_player  and not is_finish  and not is_againmsg:pos = event.pospblack = piece.Piece(pos,'pieces_black.png') if not isempty(pblack.pointtrans()):black_chesses.append(pblack)black_positions.append(pblack.pointtrans())chesses.append(pblack)chess_map[str(pblack.pointtrans()[0]) + ',' + str(pblack.pointtrans()[1])] = 2if people2people:   #tcpclientsocket.send(str(pos).encode('utf8'))is_player = Falsepiece_sound.play()# 判断输赢if len(black_chesses)>=5 and not is_finish and checkwin(black_positions,pblack.pointtrans()[0],pblack.pointtrans()[1]) :is_finish = Trueblack_win = Trueelse:del (pblack)else:pos = event.posif txtplayerandplayer_rect.left <= pos[0] <= txtplayerandplayer_rect.left + 170 and \txtplayerandplayer_rect.top  <= pos[1] <= txtplayerandplayer_rect.top + 30:is_choise = Truepeople2people = Trueif txtplayerandplayer_rect.left <= pos[0] <= txtplayerandplayer_rect.left + 170 and \txtplayerandplayer_rect.top + 100 <= pos[1] <= txtplayerandplayer_rect.top + 130:is_choise = Truepeople2computer = Trueis_player = Trueif txtplayerandplayer_rect.left <= pos[0] <= txtplayerandplayer_rect.left + 160 and \txtplayerandplayer_rect.top + 200 <= pos[1] <= txtplayerandplayer_rect.top + 230:is_play_sound = not is_play_soundif not is_play_sound:pygame.mixer.stop()pygame.mixer.music.stop()else:pygame.mixer.music.play()          '''select 模块在 Python 中不是标准库的一部分,而是一个提供底层 socket 接口的系统级模块。它通常用于编写跨平台的非阻塞 socket 服务器。select 模块中最常用的函数是 select(),它接受三个参数:读取标准输入的文件描述符集合  inputs写入标准输出的文件描述符集合  outputs异常处理的文件描述符集合      '''if people2people:readable, writable, exceptional = select.select(inputs, [], [], 0)   # 使用 select 模块的 select 函数进行非阻塞地等待连接,标准写法for readline in readable:if readline is tcpserversocket:    # 处理新的连接tcpclientsocket, HOSTADDR = tcpserversocket.accept()inputs.append(tcpclientsocket)is_link = True# print('connenct')else:try:         # 处理已连接的套接字数据data = readline.recv(BUFSIZE)    #获取数据# print(data.decode('utf8'))if data.decode('utf8') == 'again':is_againmsg = Trueif data.decode('utf8') == 'yes':is_playagain = Trueis_player = Falseif data.decode('utf8') == 'no':is_reject = Trueis_link = Falsedisconnected = not data    #如果没有数据,则关闭连接,disconnected为Trueexcept error:      #异常或错误时,则关闭连接,disconnected为True,is_link为Falsedisconnected = True   is_link = Falseif disconnected:     #断开后,移除接收的消息inputs.remove(readline)else:if not is_player and not is_finish:pwhite = piece.Piece(eval(data),'pieces_white.png')  #接收客户端的下棋位置,画白棋white_chesses.append(pwhite)white_positions.append(pwhite.pointtrans())chesses.append(pwhite)is_player = True# 判断输赢if len(white_chesses)>=5 and not is_finish and checkwin(white_positions,pwhite.pointtrans()[0],pwhite.pointtrans()[1]) :is_finish = Truewhite_win = True# 电脑落子if people2computer and not is_player:pwhite = piece.Piece(computerdecision(),'pieces_white.png')white_chesses.append(pwhite)white_positions.append(pwhite.pointtrans())chesses.append(pwhite)chess_map[str(pwhite.pointtrans()[0]) + ',' + str(pwhite.pointtrans()[1])] = 1is_player = Truepiece_sound.play()if len(white_chesses)>=5 and not is_finish and checkwin(white_positions,pwhite.pointtrans()[0],pwhite.pointtrans()[1]) :is_finish = Truewhite_win = Trueif black_win and is_finish and not is_againmsg and not is_reject:screen.blit(zz_image, (0, 0))  #遮罩层screen.blit(successtext, (successtext_rect.left, successtext_rect.top - 80))screen.blit(playagaintext, successtext_rect)screen.blit(menutext, (successtext_rect.left, successtext_rect.top + 80))if white_win and is_finish and not is_againmsg and not is_reject:screen.blit(zz_image, (0, 0))  #遮罩层screen.blit(failuretext, (successtext_rect.left, successtext_rect.top - 80))screen.blit(playagaintext, successtext_rect)screen.blit(menutext, (successtext_rect.left, successtext_rect.top + 80))if is_againmsg:screen.blit(txtchallenge, txtchallenge_rect)screen.blit(txtrecive, txtrecive_rect)if is_reject:screen.blit(txtclosed, txtclosed_rect)screen.blit(menutext, (txtclosed_rect.left + 150, txtwatting_rect.top + 70))if is_playagain:init()white_chesses.clear()black_chesses.clear()white_positions.clear()black_positions.clear()chesses.clear()is_finish = Falseblack_win = Falsewhite_win = Falseis_playagain = Falsepygame.display.flip()clock.tick(60)if __name__ == '__main__':main()

3.2 客户端main.py

# encoding:utf-8
import pygame
from pygame.locals import *
import sys
import os
from socket import *
import selectimport  piece
from tkinter import *
from params import Params
from utils import *pygame.init()
pygame.mixer.init()WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
rows = int(Params.get('ROWS'))
blocksize = int(Params.get('blockSize'))
width = int(Params.get('WIDTH'))
height = int(Params.get('HEIGHT'))# 棋盘
x = []    #x轴
y = []    #y轴for i in range(0, rows):   #棋盘的所有交叉点坐标(x,y)x.append(28 + i * blocksize)y.append(28 + i * blocksize)# 记录棋盘每个坐标的属性,没有棋子为0,白棋为1,黑棋为2
chess_map = {}    #结构是chess_map[28,28] = 0   ...# 判断棋盘某位置上是否有棋子
def isempty(theposition):global chess_mapexistpiece = Falseif chess_map[str(theposition[0]) + ',' + str(theposition[1])]:existpiece = Truereturn existpiece# 电脑选取落子的位置
def computerdecision():value = max1 = max2 = 0pos1 = pos2 = ()# 进攻for i in range(0, rows):row = 28 + i * blocksizefor j in range(0, rows):col = 28 + j * blocksizepos = (row, col)if isempty(pos):continuevalue = pointvalue(chess_map,pos, 1, 2)   if value > max1:max1 = valuepos1 = (row, col)# 防守for i in range(0, rows):for j in range(0, rows):row = 28 + i * blocksizecol = 28 + j * blocksizeif isempty((row, col)):continuevalue = pointvalue(chess_map,(row, col), 2, 1)  if value > max2:max2 = valuepos2 = (row, col)if max1 > max2:return pos1else:return pos2# 初始化棋盘
def init():global chess_mapfor i in x:for j in y:chess_map[str(i) + ',' + str(j)] = 0   #清空def main():# TCP服务BUFSIZE = 2048tcpclientsocket = socket(AF_INET, SOCK_STREAM)# 输入IP地址def screenConnect():top = Tk()top.title('服务器IP')top.geometry('%dx%d+%d+%d' % (300, 200, 418, 338))HOST = ''POST = 23338nonlocal tcpclientsocketdef fun():nonlocal HOSTnonlocal POSTnonlocal tcpclientsocketHOST = txtIP.get()HOSTADDR = (HOST, POST)try:tcpclientsocket.connect(HOSTADDR)lbl_msg = Label(top, text='')lbl_msg = Label(top, text='已连接')lbl_msg.grid(row=2, column=1)except error:lbl_msg = Label(top, text='连接失败')lbl_msg.grid(row=2, column=1)lblIP = Label(top, text='    IP 地址:',  padx=5, pady=30)lblIP.grid(row=1, column=0)txtIP = Entry(top)txtIP.grid(row=1, column=1)btnConn = Button(top, text='连接',  padx=1, command=fun)btnConn.grid(row=2, column=0)mainloop()game_bgsize = width, heightos.environ['SDL_VIDEO_CENTERED'] = '1' screen = pygame.display.set_mode(game_bgsize)pygame.display.set_caption('五子棋客户端')bgimagepath = os.path.join(Params.get('resourcePath'), Params.get('imgFolder'), 'bg.png')bg_image = pygame.image.load(bgimagepath).convert_alpha()  # 背景图片加载zzimagepath = os.path.join(Params.get('resourcePath'), Params.get('imgFolder'), 'zz.png') #遮罩图片zz_image = pygame.image.load(zzimagepath).convert_alpha()# 背景音乐bgsoundpath = os.path.join(Params.get('resourcePath'), Params.get('soundFolder'), '齐豫 - 莲花处处开.mp3')bg_sound = pygame.mixer.music.load(bgsoundpath)   # 背景音乐加载pygame.mixer.music.set_volume(0.08)pygame.mixer.music.play(-1)clicksoundpath = os.path.join(Params.get('resourcePath'), Params.get('soundFolder'), 'drop.wav')piece_sound = pygame.mixer.Sound(clicksoundpath) running = Trueclock = pygame.time.Clock()inputs = [tcpclientsocket]# 棋子white_chesses = []   #白棋子对象black_chesses = []   #黑棋子对象white_positions = [] #白棋子位置集合black_positions = [] #黑棋子位置集合chesses = []         #所有棋子集合,主要是显示用is_player = True    # 轮到哪方下棋is_finish = False   # 是否结束游戏# 赢方black_win = Falsewhite_win = Falsepeople2people = False    # 人人对战,网络版 people2computer = False   # 人与电脑对战 is_choise = False   # 是否做出选择对战方式,是people2people 还是 people2computer , 通过菜单选择对战方式is_play_sound = True   # 是否播放声音 is_playagain = False   # 是否再来一局# 是否连接is_link = False# 对方是否发来重新开始的消息is_againmsg = False# 对面拒绝了重新开始is_reject = False# 字体fontpath = os.path.join(Params.get('resourcePath'), Params.get('fontFolder'), 'simkai.ttf')myfont = pygame.font.Font(fontpath, 38)# 起始选项txtplayerandplayer = myfont.render("玩家与玩家", True, WHITE)txtplayerandplayer_rect = txtplayerandplayer.get_rect()txtplayerandplayer_rect.left, txtplayerandplayer_rect.top = (game_bgsize[0] - txtplayerandplayer_rect.width) // 2, \(game_bgsize[1] - txtplayerandplayer_rect.height) // 2 - 100txtplayerandcomputer = myfont.render('玩家与电脑', True, WHITE)txtplayerandcomputer_rect = txtplayerandcomputer.get_rect()txtplayerandcomputer_rect.left, txtplayerandcomputer_rect.top = (game_bgsize[0] - txtplayerandplayer_rect.width) // 2, \(game_bgsize[1] - txtplayerandplayer_rect.height) // 2txtplaysound = myfont.render('音效:  开', True, WHITE)txtplaysound_rect = txtplaysound.get_rect()txtplaysound_rect.left, txtplaysound_rect.top = (game_bgsize[0] - txtplaysound_rect.width) // 2, \(game_bgsize[1] - txtplaysound_rect.height) // 2 + 100txtclosesound = myfont.render('音效:  关', True, WHITE)txtclosesound_rect = txtclosesound.get_rect()txtclosesound_rect.left, txtclosesound_rect.top = (game_bgsize[0] - txtclosesound_rect.width) // 2, \(game_bgsize[1] - txtclosesound_rect.height) // 2 + 100# 输赢successtext = myfont.render("你有点屌哦!!!", True, WHITE)successtext_rect = successtext.get_rect()successtext_rect.left, successtext_rect.top = (game_bgsize[0] - successtext_rect.width) // 2, \(game_bgsize[1] - successtext_rect.height) // 2failuretext = myfont.render("小趴菜...", True, WHITE)failuretext_rect = failuretext.get_rect()failuretext_rect.left, failuretext_rect.top = (game_bgsize[0] - failuretext_rect.width) // 2, \(game_bgsize[1] - failuretext_rect.height) // 2playagaintext = myfont.render("再玩一局", True, WHITE)menutext = myfont.render('主菜单', True, WHITE)#连接txtclosed = myfont.render("对方不愿和你玩并断开了连接", True, WHITE)txtclosed_rect = txtclosed.get_rect()txtclosed_rect.left, txtclosed_rect.top = (game_bgsize[0] - txtclosed_rect.width) // 2, \(game_bgsize[1] - txtclosed_rect.height) // 2txtchallenge = myfont.render('对方再次向你发起挑战', True, WHITE)txtchallenge_rect = txtchallenge.get_rect()txtchallenge_rect.left, txtchallenge_rect.top = (game_bgsize[0] - txtchallenge_rect.width) // 2, \(game_bgsize[1] - txtchallenge_rect.height) // 2txtrecive = myfont.render('接受挑战         返回主菜单', True, WHITE)txtrecive_rect = txtrecive.get_rect()txtrecive_rect.left, txtrecive_rect.top = (game_bgsize[0] - txtrecive_rect.width) // 2, \(game_bgsize[1] - txtrecive_rect.height) // 2 + 100# 初始化init()while running:screen.blit(bg_image, (0, 0))# 绘制游戏菜单if not is_choise:screen.blit(zz_image, (0, 0))  #遮罩层screen.blit(txtplayerandplayer, txtplayerandplayer_rect)screen.blit(txtplayerandcomputer, txtplayerandcomputer_rect)if not is_play_sound:screen.blit(txtclosesound, txtclosesound_rect)else:screen.blit(txtplaysound, txtplaysound_rect)# 绘制棋盘if is_choise:if chesses:for i in chesses:screen.blit(i.image, i.image_rect())for event in pygame.event.get():if event.type == QUIT:if people2people:tcpclientsocket.close()pygame.quit()sys.exit()if event.type == MOUSEBUTTONDOWN:   #client下棋if event.button == 1: if is_finish : if not is_againmsg and not is_reject:pos = event.posif successtext_rect.left < pos[0] < successtext_rect.right - 50 and \successtext_rect.top < pos[1] < successtext_rect.top + 30:if people2people:tcpclientsocket.send('again'.encode('utf8'))if people2computer:is_playagain = Trueis_player = Trueis_finish = Falseinit()if successtext_rect.left < pos[0] < successtext_rect.right - 50 and \successtext_rect.top + 50 < pos[1] < successtext_rect.top + 120:people2people = Falseif is_link:is_link = Falsetcpclientsocket.send('no'.encode('utf8'))tcpclientsocket.close()main()if is_reject :pos = event.posif txtclosed_rect.left + 150 < pos[0] < txtclosed_rect.left + 250 and \txtclosed_rect.top + 70 < pos[1] < txtclosed_rect.top + 190:main()if is_againmsg :pos = event.posif txtrecive_rect.left < pos[0] < txtrecive_rect.left + 150 and \txtrecive_rect.top < pos[1] < txtrecive_rect.top + 120:tcpclientsocket.send('yes'.encode('utf8'))is_againmsg = Falseis_playagain = Trueis_player = Trueis_finish = Falsewhite_win = Falseblack_win = Falseif txtrecive_rect.left + 330 < pos[0] < txtrecive_rect.left + 480 and \txtrecive_rect.top < pos[1] < txtrecive_rect.top + 120:tcpclientsocket.send('no'.encode('utf8'))main()if is_choise:pos = event.pos# 判断是否是client下棋时间if is_player  and not is_finish and  not is_againmsg:pwhite = piece.Piece(pos,'pieces_white.png') if not isempty(pwhite.pointtrans()):white_chesses.append(pwhite)white_positions.append(pwhite.pointtrans())chesses.append(pwhite)chess_map[str(pwhite.pointtrans()[0]) + ',' + str(pwhite.pointtrans()[1])] = 1if people2people:tcpclientsocket.send(str(pos).encode('utf8'))is_player = Falsepiece_sound.play()if len(white_chesses)>=5 and not is_finish and checkwin(white_positions,pwhite.pointtrans()[0],pwhite.pointtrans()[1]) :is_finish = Truewhite_win = Trueelse:del (pwhite)else:pos = event.posif txtplayerandplayer_rect.left <= pos[0] <= txtplayerandplayer_rect.left + 170 and \txtplayerandplayer_rect.top  <= pos[1] <= txtplayerandplayer_rect.top + 30:is_choise = Truepeople2people = TruescreenConnect()if txtplayerandplayer_rect.left <= pos[0] <= txtplayerandplayer_rect.left + 170 and \txtplayerandplayer_rect.top + 100 <= pos[1] <= txtplayerandplayer_rect.top + 130:is_choise = Truepeople2computer = Trueif txtplayerandplayer_rect.left <= pos[0] <= txtplayerandplayer_rect.left + 160 and \txtplayerandplayer_rect.top + 200 <= pos[1] <= txtplayerandplayer_rect.top + 230:is_play_sound = not is_play_soundif not is_play_sound:pygame.mixer.stop()pygame.mixer.music.stop()else:pygame.mixer.music.play()# 电脑落子if people2computer and not is_player:pblack = piece.Piece(computerdecision(),'pieces_black.png')black_chesses.append(pblack)black_positions.append(pblack.pointtrans())chesses.append(pblack)chess_map[str(pblack.pointtrans()[0]) + ',' + str(pblack.pointtrans()[1])] = 2is_player = Truepiece_sound.play()# 判断输赢if len(black_chesses)>=5 and not is_finish and checkwin(black_positions,pblack.pointtrans()[0],pblack.pointtrans()[1]) :is_finish = Trueblack_win = True#网络消息,注释略,见gobang_serverif people2people:readable, writable, exceptional = select.select(inputs, [], [], 0)for readline in readable:if readline is tcpclientsocket:try:data = readline.recv(BUFSIZE)# print(data.decode('utf8'))is_link = Truedisconnected = not dataif data.decode('utf8') == 'again':is_againmsg = Trueif data.decode('utf8') == 'yes':is_playagain = Trueis_player = Trueif data.decode('utf8') == 'no':is_reject = Trueis_link = Falseif not is_player and not is_finish:pblack = piece.Piece(eval(data),'pieces_black.png')black_chesses.append(pblack)black_positions.append(pblack.pointtrans())chesses.append(pblack)is_player = Trueexcept error:disconnected = Trueis_link = False# 判断输赢if len(black_chesses)>=5 and not is_finish and checkwin(black_positions,pblack.pointtrans()[0],pblack.pointtrans()[1]) :is_finish = Trueblack_win = Trueif black_win and is_finish and not is_againmsg and not is_reject:screen.blit(zz_image, (0, 0))  #遮罩层screen.blit(failuretext, (successtext_rect.left, successtext_rect.top - 80))screen.blit(playagaintext, successtext_rect)screen.blit(menutext, (successtext_rect.left, successtext_rect.top + 80))if white_win and is_finish and not is_againmsg and not is_reject:screen.blit(zz_image, (0, 0))  #遮罩层screen.blit(successtext, (successtext_rect.left, successtext_rect.top - 80))screen.blit(playagaintext, successtext_rect)screen.blit(menutext, (successtext_rect.left, successtext_rect.top + 80))if is_againmsg:screen.blit(txtchallenge, txtchallenge_rect)screen.blit(txtrecive, txtrecive_rect)if is_reject:screen.blit(txtclosed, txtclosed_rect)screen.blit(menutext, (txtclosed_rect.left + 150, txtclosed_rect.top + 70))if is_playagain:init()white_chesses.clear()black_chesses.clear()white_positions.clear()black_positions.clear()chesses.clear()is_finish = Falseblack_win = Falsewhite_win = Falseis_playagain = Falsepygame.display.flip()clock.tick(60)if __name__ == '__main__':main()

3.3 先执行server的main.py,再执行client端的main.py

执行效果如下:

20240708_142557

五子棋Socket人人对战源码

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com