小猿圈Python游戲之socket實現(xiàn)單機五子棋到雙人對戰(zhàn)

前段時間發(fā)的飛機大戰(zhàn)的游戲很多小伙伴都私聊讓再做個游戲,今天小猿圈Python講師為大家分享的是socket實現(xiàn)單機五子棋到雙人對戰(zhàn),想玩的小伙伴記得自己運行一下呦脖卖。

本次實驗使用python語言乒省。通過socket進行不同機器見的通信,具體可以分為以下四步:1.創(chuàng)建ServerSocket和Socket畦木;2.打開鏈接到Socket的輸入/輸出流袖扛;3.按照協(xié)議對Socket進行讀/寫操作;4.關(guān)閉輸入輸出流十籍、關(guān)閉Socket蛆封。

由于是雙人對戰(zhàn),服務器必須應對多人及以上的客戶端的連接勾栗,因此本實驗還引入了python的threading多線程模塊娶吞,通過監(jiān)聽實時監(jiān)控網(wǎng)絡狀態(tài),同時利用socket.listen(2)引入排隊等待機制械姻。

chess類

#五子棋類

import os

class chessboard(object):

? def __init__(self):

? ? self.size = 16

? ? #初始化棋盤

? ? self.__board=[[' ' for n in range(self.size)] for m in range(self.size)]

? ? n = 0

? ? #添加桌面標簽

? ? while n < self.size:

? ? ? ntr=str(n)

? ? ? self.__board[0][n] = ntr.zfill(2)

? ? ? self.__board[n][0] = ntr.zfill(2)

? ? ? n=n+1

? ? self.id=0

? #勝利條件

? def is_end(self):

? ? ch_stack=[]

? ? #行檢查

? ? for i in range(self.size):

? ? ? for j in range(self.size):

? ? ? ? #判斷是否結(jié)束

? ? ? ? chess=self.__board[i][j]

? ? ? ? if len(ch_stack)==5 and ch_stack[-1]=='* ':

? ? ? ? ? print('winner=id 1')

? ? ? ? ? return 1

? ? ? ? elif len(ch_stack) == 5 and ch_stack[-1] == '@ ':

? ? ? ? ? print('winner=id 2')

? ? ? ? ? return 2

? ? ? ? if chess==' ':

? ? ? ? ? ch_stack.clear()

? ? ? ? else:

? ? ? ? ? if (not ch_stack) or ch_stack[-1] == chess:

? ? ? ? ? ? ch_stack.append(chess)

? ? ? ? ? else:

? ? ? ? ? ? ch_stack.clear()

? ? ? ? ? ? ch_stack.append(chess)

? ? ? ch_stack.clear()

? ? ch_stack.clear()

? ? #列檢查

? ? for j in range(self.size):

? ? ? for i in range(self.size):

? ? ? ? #判斷是否結(jié)束

? ? ? ? if len(ch_stack)==5 and ch_stack[-1]=='* ':

? ? ? ? ? print('winner=id 1')

? ? ? ? ? return 1

? ? ? ? elif len(ch_stack) == 5 and ch_stack[-1] == '@ ':

? ? ? ? ? print('winner=id 2')

? ? ? ? ? return 2

? ? ? ? chess=self.__board[i][j]

? ? ? ? if chess==' ':

? ? ? ? ? ch_stack.clear()

? ? ? ? else:

? ? ? ? ? if (not ch_stack) or ch_stack[-1] == chess:

? ? ? ? ? ? ch_stack.append(chess)

? ? ? ? ? else:

? ? ? ? ? ? ch_stack.clear()

? ? ? ? ? ? ch_stack.append(chess)

? ? ? ch_stack.clear()

? ? ch_stack.clear()

? ? #左斜檢查

? ? #下三角

? ? for i in range(self.size):

? ? ? for j in range(1,self.size):

? ? ? ? #判斷是否結(jié)束

? ? ? ? if len(ch_stack)==5 and ch_stack[-1]=='* ':

? ? ? ? ? print('winner=id 1')

? ? ? ? ? return 1

? ? ? ? elif len(ch_stack) == 5 and ch_stack[-1] == '@ ':

? ? ? ? ? print('winner=id 2')

? ? ? ? ? return 2

? ? ? ? if i+j<self.size:

? ? ? ? ? chess=self.__board[i+j][j]

? ? ? ? ? if chess==' ':

? ? ? ? ? ? ch_stack.clear()

? ? ? ? ? else:

? ? ? ? ? ? if (not ch_stack) or ch_stack[-1] == chess:

? ? ? ? ? ? ? ch_stack.append(chess)

? ? ? ? ? ? else:

? ? ? ? ? ? ? ch_stack.clear()

? ? ? ? ? ? ? ch_stack.append(chess)

? ? ? ? else:

? ? ? ? ? break

? ? ? ch_stack.clear()

? ? ch_stack.clear()

? ? #上三角

? ? for i in range(self.size):

? ? ? for j in range(1,self.size):

? ? ? ? #判斷是否結(jié)束

? ? ? ? if len(ch_stack)==5 and ch_stack[-1]=='* ':

? ? ? ? ? print('winner=id 1')

? ? ? ? ? return 1

? ? ? ? elif len(ch_stack) == 5 and ch_stack[-1] == '@ ':

? ? ? ? ? print('winner=id 2')

? ? ? ? ? return 2

? ? ? ? if i+j<self.size:

? ? ? ? ? chess=self.__board[j][j+i]

? ? ? ? ? if chess==' ':

? ? ? ? ? ? ch_stack.clear()

? ? ? ? ? else:

? ? ? ? ? ? if (not ch_stack) or ch_stack[-1] == chess:

? ? ? ? ? ? ? ch_stack.append(chess)

? ? ? ? ? ? else:

? ? ? ? ? ? ? ch_stack.clear()

? ? ? ? ? ? ? ch_stack.append(chess)

? ? ? ? else:

? ? ? ? ? break

? ? ? ch_stack.clear()

? ? ch_stack.clear()

? ? #右斜檢查

? ? #上三角

? ? for i in range(self.size):

? ? ? for j in range(1,self.size):

? ? ? ? #判斷是否結(jié)束

? ? ? ? if len(ch_stack)==5 and ch_stack[-1]=='* ':

? ? ? ? ? print('winner=id 1')

? ? ? ? ? return 1

? ? ? ? elif len(ch_stack) == 5 and ch_stack[-1] == '@ ':

? ? ? ? ? print('winner=id 2')

? ? ? ? ? return 2

? ? ? ? if self.size-i-j+1>0:

? ? ? ? ? chess=self.__board[self.size-i-j][j]

? ? ? ? ? if chess==' ':

? ? ? ? ? ? ch_stack.clear()

? ? ? ? ? elif not chess:

? ? ? ? ? ? break

? ? ? ? ? else:

? ? ? ? ? ? if (not ch_stack) or ch_stack[-1] == chess:

? ? ? ? ? ? ? ch_stack.append(chess)

? ? ? ? ? ? else:

? ? ? ? ? ? ? ch_stack.clear()

? ? ? ? ? ? ? ch_stack.append(chess)

? ? ? ? else:

? ? ? ? ? break

? ? ? ch_stack.clear()

? ? ch_stack.clear()

? ? #下三角

? ? for i in range(self.size):

? ? ? for j in range(1,self.size):

? ? ? ? # 判斷是否結(jié)束

? ? ? ? if len(ch_stack) == 5 and ch_stack[-1] == '* ':

? ? ? ? ? print('winner=id 1')

? ? ? ? ? return 1

? ? ? ? elif len(ch_stack) == 5 and ch_stack[-1] == '@ ':

? ? ? ? ? print('winner=id 2')

? ? ? ? ? return 2

? ? ? ? if self.size-i-j> 0:

? ? ? ? ? chess = self.__board[j][self.size-i-j]

? ? ? ? ? if chess == ' ':

? ? ? ? ? ? ch_stack.clear()

? ? ? ? ? elif not chess:

? ? ? ? ? ? break

? ? ? ? ? else:

? ? ? ? ? ? if (not ch_stack) or ch_stack[-1] == chess:

? ? ? ? ? ? ? ch_stack.append(chess)

? ? ? ? ? ? else:

? ? ? ? ? ? ? ch_stack.clear()

? ? ? ? ? ? ? ch_stack.append(chess)

? ? ? ? else:

? ? ? ? ? break

? ? ? ch_stack.clear()

? ? ch_stack.clear()

? ? return 0

? def draw(self):

? ? #clear()

? ? for x in self.__board:

? ? ? print(x)

? ? return 0

? def drop_chess(self,x,y,id):

? ? if id==1 and self.__board[x][y]==' ':

? ? ? self.__board[x][y]='* '

? ? ? return 1

? ? elif id==2 and self.__board[x][y]==' ':

? ? ? self.__board[x][y]='@ '

? ? ? return 1

? ? else:

? ? ? return 0

然后是用while循環(huán)實現(xiàn)的單機版五子棋

# -*- coding: utf-8 -*-

#單機版五子棋

from chess import chessboard

def changeid(id):

? if id==1:

? ? return 2

? elif id==2:

? ? return 1

? else:

? ? return 0

t=chessboard()

id=1#初始化id

t.draw()

while (not t.is_end()):#end函數(shù)

? print('your id is %d,input your next drop(x,y)'% id)

? x=input()

? y=input()

? x=int(x)

? y=int(y)

? if t.drop_chess(x,y,id):

? ? t.draw()

? else:

? ? print('_________Illegal Input,Please Check Again_________')

? ? continue

? id=changeid(id)

———————分割線———————

由于要實現(xiàn)雙人對戰(zhàn)妒蛇,所以服務器端必須要用多線程使其服務多個客戶端,因此使用threading

服務器端

# -*- coding: utf-8 -*-

#服務器

import os

import socket

import json

import threading

import time

import sys

from chess import chessboard

t=chessboard()

id=1#初始化id

def handle():

? while (not t.is_end()):

? ? for c in socks:

? ? ? global id

? ? ? json_string0 = json.dumps(t._chessboard__board)

? ? ? c.sendto(json_string0.encode('utf-8'), address)

? ? ? msg1 = 'Your id is %d,input your next drop' % id + "\r\n"

? ? ? c.send(msg1.encode('utf-8'))

? ? ? msg2x = c.recv(1024)

? ? ? msg2y = c.recv(1024)

? ? ? x = int(msg2x.decode('utf-8'))

? ? ? y = int(msg2y.decode('utf-8'))

? ? ? print('processing......\n')

? ? ? if t.drop_chess(x, y, id):

? ? ? ? json_string = json.dumps(t._chessboard__board)

? ? ? ? c.sendto(json_string.encode('utf-8'), address)

? ? ? else:

? ? ? ? msg3 = '_________Illegal Input,Please Check Again_________'

? ? ? ? c.send(msg3.encode('utf-8'))

? ? ? ? continue

? ? ? id = changeid(id)

def clear():

? os.system('cls')

def changeid(id):

? if id==1:

? ? return 2

? elif id==2:

? ? return 1

? else:

? ? return 0

# 創(chuàng)建 socket 對象

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

# 獲取本地主機名

host = socket.gethostname()

port = 9999

# 綁定端口號

s.bind((host, port))

address=(host, port)

# 設置最大連接數(shù)楷拳,超過后排隊

s.listen(2)

socks=[]

th = threading.Thread(target=handle)

th.start()

while 1:

? c, addr = s.accept()

? print

? 'connected from:', addr

? socks.append(c)

s.close()

然后是客戶端

# -*- coding: utf-8 -*-

#客戶端

import socket

import time

# 創(chuàng)建 socket 對象

c = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

# 獲取本地主機名

#host = socket.gethostname()

host='10.41.114.198'

# 設置端口號

port = 9999

# 連接服務绣夺,指定主機和端口

c.connect((host, port))

address=(host, port)

while 1:

? #s=c.accept()

? print('')

? print('__________________wait__________________')

? msg0 = c.recv(2048).decode('utf-8') # 棋盤大于1024

? for x in msg0:

? ? if x == '[':

? ? ? print('')

? ? else:

? ? ? print(x, end='')

? print('')

? msg1 = c.recv(1024)#接收輸入提示

? print (msg1.decode('utf-8'))

? time.sleep(1)

? x = input('x=')

? y = input('y=')

? c.send(x.encode('utf-8'))

? c.send(y.encode('utf-8'))

? msg3 = c.recv(2048).decode('utf-8')#棋盤大于1024

? if msg3=='_________Illegal Input,Please Check Again_________':

? ? print(msg3)

? ? continue

? else:

? ? #print(msg3)

? ? for x in msg3:

? ? ? if x=='[':

? ? ? ? print('')

? ? ? else:

? ? ? ? print(x, end='')

? ? print('')

? ? print('__________________wait__________________')

? print('')

c.close()

注意socket傳輸時只能傳送bytes,因此list先用json轉(zhuǎn)成str欢揖,再encode編碼

使用方法:先更改客戶端host為自己地址陶耍,然后先打開服務端,然后打開多個客戶端(大于2個開始排隊)她混,然后開始輸入X,Y坐標開始游戲烈钞。

以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助坤按,希望大家能靈活掌握本文中提到的方法毯欣,想要了解更多關(guān)于Python開發(fā)方面內(nèi)容的小伙伴可以關(guān)注小猿圈官網(wǎng)Python交流群:874680195,如果有什么問題可以留言給小猿圈講師臭脓,遇到的問題可以直接私聊或者提問酗钞,看到會盡快幫大家解決的。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末来累,一起剝皮案震驚了整個濱河市砚作,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌嘹锁,老刑警劉巖葫录,帶你破解...
    沈念sama閱讀 211,376評論 6 491
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異领猾,居然都是意外死亡米同,警方通過查閱死者的電腦和手機骇扇,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,126評論 2 385
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來窍霞,“玉大人匠题,你說我怎么就攤上這事〉穑” “怎么了韭山?”我有些...
    開封第一講書人閱讀 156,966評論 0 347
  • 文/不壞的土叔 我叫張陵,是天一觀的道長冷溃。 經(jīng)常有香客問我杉允,道長犬金,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,432評論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮拦惋,結(jié)果婚禮上具壮,老公的妹妹穿的比我還像新娘呀癣。我一直安慰自己食磕,他們只是感情好,可當我...
    茶點故事閱讀 65,519評論 6 385
  • 文/花漫 我一把揭開白布答憔。 她就那樣靜靜地躺著味赃,像睡著了一般。 火紅的嫁衣襯著肌膚如雪虐拓。 梳的紋絲不亂的頭發(fā)上心俗,一...
    開封第一講書人閱讀 49,792評論 1 290
  • 那天,我揣著相機與錄音蓉驹,去河邊找鬼城榛。 笑死,一個胖子當著我的面吹牛态兴,可吹牛的內(nèi)容都是我干的狠持。 我是一名探鬼主播,決...
    沈念sama閱讀 38,933評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼诗茎,長吁一口氣:“原來是場噩夢啊……” “哼工坊!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起敢订,我...
    開封第一講書人閱讀 37,701評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎罢吃,沒想到半個月后楚午,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,143評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡尿招,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,488評論 2 327
  • 正文 我和宋清朗相戀三年矾柜,在試婚紗的時候發(fā)現(xiàn)自己被綠了阱驾。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,626評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡怪蔑,死狀恐怖里覆,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情缆瓣,我是刑警寧澤喧枷,帶...
    沈念sama閱讀 34,292評論 4 329
  • 正文 年R本政府宣布,位于F島的核電站弓坞,受9級特大地震影響隧甚,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜渡冻,卻給世界環(huán)境...
    茶點故事閱讀 39,896評論 3 313
  • 文/蒙蒙 一戚扳、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧族吻,春花似錦帽借、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,742評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至握础,卻和暖如春辐董,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背禀综。 一陣腳步聲響...
    開封第一講書人閱讀 31,977評論 1 265
  • 我被黑心中介騙來泰國打工简烘, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人定枷。 一個月前我還...
    沈念sama閱讀 46,324評論 2 360
  • 正文 我出身青樓孤澎,卻偏偏與公主長得像,于是被迫代替她去往敵國和親欠窒。 傳聞我的和親對象是個殘疾皇子覆旭,可洞房花燭夜當晚...
    茶點故事閱讀 43,494評論 2 348

推薦閱讀更多精彩內(nèi)容