小猿圈Python游戏之socket实现单机五子棋到双人对战

前段时间发的飞机大战的游戏很多小伙伴都私聊让再做个游戏,今天小猿圈Python讲师为大家分享的是socket实现单机五子棋到双人对战,想玩的小伙伴记得自己运行一下呦。

本次实验使用python语言。通过socket进行不同机器见的通信,具体可以分为以下四步:1.创建ServerSocket和Socket;2.打开链接到Socket的输入/输出流;3.按照协议对Socket进行读/写操作;4.关闭输入输出流、关闭Socket。

由于是双人对战,服务器必须应对多人及以上的客户端的连接,因此本实验还引入了python的threading多线程模块,通过监听实时监控网络状态,同时利用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):

        #判断是否结束

        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):

        #判断是否结束

        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):

        #判断是否结束

        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):

        #判断是否结束

        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):

        #判断是否结束

        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):

        # 判断是否结束

        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循环实现的单机版五子棋

# -*- 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函数

  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)

———————分割线———————

由于要实现双人对战,所以服务器端必须要用多线程使其服务多个客户端,因此使用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

# 创建 socket 对象

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

# 获取本地主机名

host = socket.gethostname()

port = 9999

# 绑定端口号

s.bind((host, port))

address=(host, port)

# 设置最大连接数,超过后排队

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

# 创建 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转成str,再encode编码

使用方法:先更改客户端host为自己地址,然后先打开服务端,然后打开多个客户端(大于2个开始排队),然后开始输入X,Y坐标开始游戏。

以上就是本文的全部内容,希望对大家的学习有所帮助,希望大家能灵活掌握本文中提到的方法,想要了解更多关于Python开发方面内容的小伙伴可以关注小猿圈官网Python交流群:874680195,如果有什么问题可以留言给小猿圈讲师,遇到的问题可以直接私聊或者提问,看到会尽快帮大家解决的。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,293评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,604评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,958评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,729评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,719评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,630评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,000评论 3 397
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,665评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,909评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,646评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,726评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,400评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,986评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,959评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,197评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,996评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,481评论 2 342

推荐阅读更多精彩内容