python跳棋pygame V3

#跳棋服务器.py
import socket
import sqlite3
import threading

client_sockets = []
client_sockets_lock = threading.Lock()  # 锁,用于线程安全的操作client_sockets
# 初始创建数据库表(只需要执行一次)
def init_db():
    conn = sqlite3.connect('equipment.db')
    cursor = conn.cursor()
    try:
        cursor.execute('CREATE TABLE IF NOT EXISTS user (id VARCHAR(20) PRIMARY KEY, password VARCHAR(20))')
        conn.commit()
    except Exception as e:
        print(e)
    finally:
        conn.close()
cnt=0
def handle_client(client_socket, client_address):
    # 在每个线程中创建独立的数据库连接和游标
    conn = sqlite3.connect('equipment.db')
    cursor = conn.cursor()
    global cnt
    try:
        print(f"处理来自 {client_address} 的连接")
        while True:
            try:
                message = client_socket.recv(1024).decode()
                if not message:
                    break
                print(f"收到来自 {client_address} 的消息: {message}")

                if message.startswith("register:"):
                    _, username, password = message.split(':')
                    cursor.execute('SELECT * FROM user WHERE id=?', (username,))
                    if cursor.fetchone():
                        response = "用户已存在"
                    else:
                        cursor.execute('INSERT INTO user (id, password) VALUES (?, ?)', (username, password))
                        conn.commit()
                        response = "注册成功"
                    client_socket.sendall(response.encode())

                elif message.startswith("user:"):
                    _, username, password = message.split(':')
                    cursor.execute('SELECT * FROM user WHERE id=? AND password=?', (username, password))
                    user = cursor.fetchone()
                    if user:
                        response = "登录成功:" + str(len(client_sockets))
                    else:
                        response = "登录失败"
                    client_socket.sendall(response.encode())

                elif message == "quit":
                    break
                else:
                    cnt += 1
                    print(cnt)
                    cnt %= len(client_sockets)
                    response = eval(message)
                    response.append(cnt+1)
                    print(response)
                    response=str(response)
                    with client_sockets_lock:
                        for i in client_sockets:
                            # if i != client_socket:  # 不要把消息发回给发送者
                            try:
                                i.sendall(response.encode())
                                print(response)
                            except OSError:
                                print("发送消息时出错,可能是套接字已关闭")
            except ConnectionResetError:
                print(f"与 {client_address} 的连接被远程主机重置")
                break
    finally:
        with client_sockets_lock:
            client_sockets.remove(client_socket)
        client_socket.close()
        conn.close()
        print(f"与 {client_address} 的连接已关闭")

def start_server():
    init_db()  # 初始化数据库
    server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    server_socket.bind(('10.171.131.51', 8888))
    server_socket.listen(5)

    print("服务器启动,等待连接...")

    while True:
        client_socket, client_address = server_socket.accept()
        with client_sockets_lock:
            client_sockets.append(client_socket)
        print(f"连接来自 {client_address}")
        client_handler = threading.Thread(target=handle_client, args=(client_socket, client_address))
        client_handler.start()

if __name__ == "__main__":
    start_server()
#CheckerPiece
import math

import pygame


class CheckerPiece:
    def __init__(self, center, color):
        self.center = center  # 棋子的中心位置
        self.color = [color, (0, 0, 0)]  # 棋子的颜色
        self.radius = 5  # 棋子的半径
        self.clicked = False  # 标记棋子是否被点击了
        self.index = 0

    def draw(self, screen):
        # 绘制棋子
        pygame.draw.circle(screen, (0, 0, 0), self.center, self.radius + 2)  # 绘制黑色的边框
        pygame.draw.circle(screen, self.color[self.index], self.center, self.radius)  # 绘制棋子

    def is_clicked(self, pos):
        # 判断点击位置是否在棋子范围内
        distance = math.sqrt((pos[0] - self.center[0]) ** 2 + (pos[1] - self.center[1]) ** 2)
        return distance < self.radius

    def handle_click(self):
        # 处理点击事件
        self.clicked = True

#CheckersBoard.py
import socket
import threading
import time
import pygame
import sys
import math

from CheckerPiece import CheckerPiece





class CheckersBoard:
    def __init__(self):
        pygame.init()
        self.client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.server_address = ('192.168.1.137', 8888)
        self.client_socket.connect(self.server_address)
        # 启动接收消息的线程
        self.receive_thread = threading.Thread(target=self.receive_messages)
        self.receive_thread.start()
        self.winner=-1
        self.is_clicked = -1
        self.BOARDSIZE = 600
        self.CEN = self.BOARDSIZE / 2
        self.EDGE = 30
        self.RADIUS = self.CEN - self.EDGE
        self.RATIO = 0.87
        self.HEIGHT = self.RADIUS / 2
        self.SIDE = self.HEIGHT / self.RATIO
        self.EACHHEIGHT = self.RADIUS / 8
        self.EACHWIDTH = self.SIDE / 8
        self.RA = 5
        self.gamestate=False
        self.WHITE = (255, 255, 255)
        self.BLACK = (0, 0, 0)
        self.YELLOW = (255, 255, 0)
        self.GREEN = (0, 255, 0)
        self.BLUE = (0, 0, 255)
        self.RED = (255, 0, 0)
        self.COLOR=[self.RED,self.GREEN,self.BLUE]
        self.id=""
        self.password=""
        self.playerid=0
        self.playernow=1
        self.POS1 = [
            (12, 0), (11, 1), (13, 1), (10, 2), (12, 2), (14, 2), (9, 3), (11, 3),
            (13, 3), (15, 3)
        ]
        self.POS2 = [
            (3, 7), (2, 6), (4, 6), (1, 5), (3, 5), (5, 5), (0, 4), (2, 4),
            (4, 4), (6, 4)
        ]
        self.POS3 = [
            (21, 7), (20, 6), (22, 6), (19, 5), (21, 5), (23, 5), (18, 4), (20, 4),
            (22, 4), (24, 4)
        ]
        self.victoy = [[(20,8),(19,9),(21,9),(18,10),(20,10),(22,10),(17,11),(19,11),(21,11),(23,11),(16,12),(18,12),(20,12),(22,12),(24,12)],
                       [(8,12),(10,12),(12,12),(14,12),(16,12),(9,13),(11,13),(13,13),(15,13),(10,14),(12,14),(14,14),(11,15),(13,15),(12,16)],
                       [(4,8),(3,9),(5,9),(2,10),(4,10),(6,10),(1,11),(3,11),(5,11),(7,11),(0,12),(2,12),(4,12),(6,12),(8,12)]]
        self.POS4 = self.POS1 + self.POS2 + self.POS3 + [(x, y) for y in range(4, 13) for x in
                                                         range(8 - y + 4, 16 + y - 4 + 2, 2)] + [(x, y) for y in
                                                                                                 range(13, 18) for x in
                                                                                                 range(8 + y - 12,
                                                                                                       16 - y + 13, 2)]

        # self.screen = pygame.display.set_mode((self.BOARDSIZE, self.BOARDSIZE))
        pygame.display.set_caption('Checkers Board')
        self.pieces = []
        for row, col in self.POS1:
            center_xy = self.rcToXy((row, col))
            self.pieces.append(CheckerPiece(center_xy, self.GREEN))
        for row, col in self.POS2:
            center_xy = self.rcToXy((row, col))
            self.pieces.append(CheckerPiece(center_xy, self.RED))
        for row, col in self.POS3:
            center_xy = self.rcToXy((row, col))
            self.pieces.append(CheckerPiece(center_xy, self.BLUE))

        # 字体初始化
        font_name = pygame.font.get_fonts()[0]
        self.font = pygame.font.SysFont(font_name, 18)

        # 定义状态
        self.state = "INITIAL"

    def is_clicked_empty(self, pos, center):
        center = self.rcToXy((center[0], center[1]))
        for i in self.pieces:
            if center == i.center:
                return False
        distance = math.sqrt((pos[0] - center[0]) ** 2 + (pos[1] - center[1]) ** 2)
        return distance < 5

    def rcToXy(self, rc):
        xy = [0, 0]
        xy[0] = (rc[0] - 12) * self.EACHWIDTH + self.CEN
        xy[1] = rc[1] * self.EACHHEIGHT + self.EDGE
        return xy

    def drawLine(self, start_rc, end_rc):
        start_xy = self.rcToXy(start_rc)
        end_xy = self.rcToXy(end_rc)
        pygame.draw.aaline(self.screen, self.BLACK, start_xy, end_xy, 1)

    def drawBoard(self):
        self.screen.fill(self.WHITE)

        tan = [
            [(self.CEN - self.SIDE / 2, self.EDGE + self.HEIGHT), (self.CEN + self.SIDE / 2, self.EDGE + self.HEIGHT),
             (self.CEN + self.SIDE, self.CEN),
             (self.CEN + self.SIDE / 2, self.BOARDSIZE - self.EDGE - self.HEIGHT),
             (self.CEN - self.SIDE / 2, self.BOARDSIZE - self.EDGE - self.HEIGHT), (self.CEN - self.SIDE, self.CEN)],
            [(self.CEN, self.EDGE), (self.CEN - self.SIDE / 2, self.EDGE + self.HEIGHT),
             (self.CEN + self.SIDE / 2, self.EDGE + self.HEIGHT)],
            [(self.CEN + self.SIDE * 3 / 2, self.EDGE + self.HEIGHT),
             (self.CEN + self.SIDE / 2, self.EDGE + self.HEIGHT), (self.CEN + self.SIDE, self.CEN)],
            [(self.CEN + self.SIDE * 3 / 2, self.BOARDSIZE - self.EDGE - self.HEIGHT), (self.CEN + self.SIDE, self.CEN),
             (self.CEN + self.SIDE / 2, self.BOARDSIZE - self.EDGE - self.HEIGHT)],
            [(self.CEN, self.BOARDSIZE - self.EDGE),
             (self.CEN + self.SIDE / 2, self.BOARDSIZE - self.EDGE - self.HEIGHT),
             (self.CEN - self.SIDE / 2, self.BOARDSIZE - self.EDGE - self.HEIGHT)],
            [(self.CEN - self.SIDE * 3 / 2, self.BOARDSIZE - self.EDGE - self.HEIGHT),
             (self.CEN - self.SIDE / 2, self.BOARDSIZE - self.EDGE - self.HEIGHT), (self.CEN - self.SIDE, self.CEN)],
            [(self.CEN - self.SIDE * 3 / 2, self.EDGE + self.HEIGHT), (self.CEN - self.SIDE, self.CEN),
             (self.CEN - self.SIDE / 2, self.EDGE + self.HEIGHT)]
        ]

        for i in range(0, 4):
            if i == 0:
                COLOR = self.YELLOW
                pygame.draw.polygon(self.screen, COLOR, tan[i], 0)
            else:
                if i == 1:
                    COLOR = self.GREEN
                elif i == 2:
                    COLOR = self.BLUE
                elif i == 3:
                    COLOR = self.RED
                pygame.draw.polygon(self.screen, COLOR, tan[i], 0)
                pygame.draw.polygon(self.screen, COLOR, tan[i + 3], 0)

        start_rc = [12, 0]
        end_rc = [12, 0]
        for each in range(0, 4):
            self.drawLine(start_rc, end_rc)
            start_rc[0] -= 1
            start_rc[1] += 1
            end_rc[0] += 1
            end_rc[1] += 1

        start_rc = [0, 4]
        end_rc = [24, 4]
        for each in range(0, 5):
            self.drawLine(start_rc, end_rc)
            start_rc[0] += 1
            start_rc[1] += 1
            end_rc[0] -= 1
            end_rc[1] += 1

        start_rc = [4, 8]
        end_rc = [20, 8]
        for each in range(0, 5):
            self.drawLine(start_rc, end_rc)
            start_rc[0] -= 1
            start_rc[1] += 1
            end_rc[0] += 1
            end_rc[1] += 1

        start_rc = [9, 13]
        end_rc = [15, 13]
        for each in range(0, 4):
            self.drawLine(start_rc, end_rc)
            start_rc[0] += 1
            start_rc[1] += 1
            end_rc[0] -= 1
            end_rc[1] += 1

        start_rc = [24, 4]
        end_rc = [24, 4]
        for each in range(0, 5):
            self.drawLine(start_rc, end_rc)
            start_rc[0] -= 2
            end_rc[0] -= 1
            end_rc[1] += 1

        start_rc = [12, 0]
        end_rc = [24, 12]
        for each in range(0, 5):
            self.drawLine(start_rc, end_rc)
            start_rc[0] -= 1
            start_rc[1] += 1
            end_rc[0] -= 2

        start_rc = [6, 4]
        end_rc = [15, 13]
        for each in range(0, 4):
            self.drawLine(start_rc, end_rc)
            start_rc[0] -= 2
            end_rc[0] -= 1
            end_rc[1] += 1

        start_rc = [3, 9]
        end_rc = [6, 12]
        for each in range(0, 4):
            self.drawLine(start_rc, end_rc)
            start_rc[0] -= 1
            start_rc[1] += 1
            end_rc[0] -= 2

        start_rc = [0, 4]
        end_rc = [0, 4]
        for each in range(0, 4):
            self.drawLine(start_rc, end_rc)
            start_rc[0] += 2
            end_rc[0] += 1
            end_rc[1] += 1

        start_rc = [0, 12]
        end_rc = [12, 0]
        for each in range(0, 4):
            self.drawLine(start_rc, end_rc)
            start_rc[0] += 2
            end_rc[0] += 1
            end_rc[1] += 1

        start_rc = [21, 7]
        end_rc = [18, 4]
        for each in range(0, 4):
            self.drawLine(start_rc, end_rc)
            start_rc[0] += 1
            start_rc[1] -= 1
            end_rc[0] += 2

        start_rc = [8, 12]
        end_rc = [16, 4]
        for each in range(0, 5):
            self.drawLine(start_rc, end_rc)
            start_rc[0] += 1
            start_rc[1] += 1
            end_rc[0] += 2

        start_rc = [21, 9]
        end_rc = [18, 12]
        for each in range(0, 4):
            self.drawLine(start_rc, end_rc)
            start_rc[0] += 1
            start_rc[1] += 1
            end_rc[0] += 2

        # 画棋子
        for piece in self.pieces:
            piece.draw(self.screen)

        # 显示状态提示
        self.display_status()

        pygame.display.flip()

    def display_status(self):
        if self.is_clicked == -1:
            status_text = "player"+str(self.playernow)+":Click on a piece to move"
        elif self.is_clicked == 114514:
            status_text = "winner:"+str(self.winner)
        else:
            status_text = "player"+str(self.playernow)+":Click on a destination to move the piece"
        status_surface = self.font.render(status_text, True, self.BLACK)
        self.screen.blit(status_surface, (10, 10))

        status_text = "your player id:"+str(self.playerid)
        status_surface = self.font.render(status_text, True, self.BLACK)
        self.screen.blit(status_surface, (500, 10))
    def receive_messages(self):
        while True:
            try:
                response = self.client_socket.recv(1024).decode()
                if response:
                    print(f"收到服务器的回复: {response}")
                    if response.startswith("登录成功"):
                        self.gamestate = True
                        self.playerid = int(response.split(':')[1])
                        print("你的playerid:",self.playerid)
                    elif response == "登录失败":
                        print("密码错误")
                    elif response == "注册成功":
                        print("注册成功")
                    else:
                        try:
                            numbers = eval(response)
                            if isinstance(numbers, list) and len(numbers) == 4:
                                print(f"提取到的4个数字: {numbers}")
                                self.pieces[numbers[0]].center = self.rcToXy((numbers[1], numbers[2]))
                                self.playernow = numbers[3]
                            else:
                                print("未能成功解析到三个数字列表")
                        except Exception as e:
                            print(f"解析出错: {e}")
                else:
                    break
            except ConnectionResetError:
                print("与服务器的连接断开")
                break

    def send_message(self, message):
        self.client_socket.sendall(message.encode())

    def close(self):
        self.client_socket.close()
    def checkVictory(self):
        cnt=[0,0,0]
        for piece in self.pieces:
            for i in range(3):
                for center in self.victoy[i]:
                    #print(self.COLOR[self.playerid - 1],piece.color[0],self.rcToXy((center[0], center[1])),piece.center)
                    if self.COLOR[self.playerid - 1] == piece.color[0] and self.rcToXy((center[0], center[1])) == piece.center:
                        cnt[i] += 1
                        break
        for i in range(3):
            if cnt[i] == 10:
                return i
        return -1

    def main(self):
        while self.gamestate == False:
            action = input("请选择操作 (1: 登录, 2: 注册): ")

            if action == "1":
                self.id = input("输入用户名:")
                self.password = input("输入密码:")
                self.send_message("user:" + str(self.id) + ":" + str(self.password))
            elif action == "2":
                self.id = input("输入注册用户名:")
                self.password = input("输入注册密码:")
                self.send_message("register:" + str(self.id) + ":" + str(self.password))
            else:
                print("无效的选项,请重新选择")

            time.sleep(1)
        self.screen = pygame.display.set_mode((self.BOARDSIZE, self.BOARDSIZE))
        while self.gamestate == True:
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    pygame.quit()
                    sys.exit()
                # 在事件处理函数中处理点击事件
                if event.type == pygame.MOUSEBUTTONDOWN:
                    if event.button == 1:  # 左键点击
                        if self.is_clicked != -1:
                            for center in self.POS4:
                                if self.is_clicked_empty(event.pos, center):
                                    self.pieces[self.is_clicked].center = self.rcToXy((center[0], center[1]))
                                    self.send_message("[%d, %d, %d]" % (self.is_clicked, center[0], center[1]))
                                    self.pieces[self.is_clicked].index = 0
                                    self.is_clicked = -1
                                    self.winner = self.checkVictory()

                                    if(self.winner != -1):
                                        print("winner:",self.winner)
                                        self.is_clicked = 114514
                                    break
                        else:
                            i = 0
                            for piece in self.pieces:
                                #print(self.COLOR[self.playerid-1]==piece.color[0],self.playerid == self.playernow)
                                if piece.is_clicked(event.pos) and self.COLOR[self.playerid-1]==piece.color[0]  and self.playerid == self.playernow:

                                    piece.handle_click()
                                    if self.is_clicked != -1:
                                        self.pieces[self.is_clicked].index = 0
                                    self.is_clicked = i
                                    self.pieces[self.is_clicked].index = 1

                                i += 1

            self.drawBoard()
            pygame.display.flip()

#main.py
import socket
import time
import pygame
import sys
import math
from CheckerPiece import CheckerPiece
from CheckersBoard import CheckersBoard

if __name__ == "__main__":
    checker_board = CheckersBoard()
    checker_board.main()

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值