master
tzzzzzzzx 3 years ago
parent f3f2f60df3
commit 15b3394ae5

@ -11,6 +11,7 @@ it handle user input and GUI
import colorsys import colorsys
import json import json
from multiprocessing import connection
import pygame as pg import pygame as pg
import sys import sys
import socket import socket
@ -34,10 +35,41 @@ SIZE = 64
IMAGES = {} IMAGES = {}
bias_top = 100 #棋盘的上边距 bias_top = 100 #棋盘的上边距
bias_left = 100 #棋盘的左边距 bias_left = 100 #棋盘的左边距
#网络道具
client = None
networkMsg = None
server = None
port = None
addr = None
connection = None
#网络版更新需要注意多线程的问题? #网络版更新需要注意多线程的问题?
#尝试写一个函数分配一个新线程供监听 #尝试写一个函数分配一个新线程供监听
def startNewThread(target):
thread = Thread(target=target)
thread.daemon =True
thread.start()
def listenFromServer():
global networkMsg
try:
while True:
recvMsg = client.recvfrom(1024).decode('utf-8')
if len(recvMsg) != 0:
networkMsg = json.loads(recvMsg)
except socket.error as e:
print(e)
return e
def startNetworkServices():
global client,server,port,addr,connection
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server = '127.0.0.1'
port = 50005
addr = (server,port)
connection = client.connect(addr)
startNewThread(target=listenFromServer)
def jsonAnalysis(networkMsg):
pass
#等待敌人移动 #等待敌人移动
def loadImages():#加载图片,a,b双方分别有象狮豹狼狐鹰鼠七个角色 def loadImages():#加载图片,a,b双方分别有象狮豹狼狐鹰鼠七个角色
@ -200,7 +232,6 @@ def MainMenu():
button_3 = Button(bt3,(350,450)) button_3 = Button(bt3,(350,450))
button_4 = Button(bt4,(350,500)) button_4 = Button(bt4,(350,500))
mode = -1 mode = -1
p1,p2 = 0,0
run = True run = True
while run: while run:
mainClock.tick(60) mainClock.tick(60)
@ -238,34 +269,22 @@ def MainMenu():
def main(mode,p1,p2,network = None): def main(mode):
NewPlayerMessage = '' #来自对手的信息 global networkMsg
if mode == 2: networkMsg = None
network=backend.Network()
#p1 = input("Enter your name: ")
p1 = 'player1'
myPlayerData = {
'type': 0, # game state type ?
'msg': {
'name': player1
}
}
network.send(myPlayerData)
print("Waiting for other player...")
NewPlayerMessage = network.receive()
print()
p2 = NewPlayerMessage['counterpart_name']
pg.init() pg.init()
screen = pg.display.set_mode((BOARD_WIDTH + MOVE_LOG_PANEL_WIDTH, BOARD_HEIGHT)) screen = pg.display.set_mode((BOARD_WIDTH + MOVE_LOG_PANEL_WIDTH, BOARD_HEIGHT))
pg.display.set_caption("Safafi Chess Game") pg.display.set_caption("Safari Chess Game")
clock = pg.time.Clock() clock = pg.time.Clock()
screen.fill(pg.Color("white")) screen.fill(pg.Color("white"))
loadImages() loadImages()
drawBoard(screen) drawBoard(screen)
isOnline = bool(network != None) isOnline = bool(mode == 2)
game_state=backend.GameState(isNet=isOnline,MySide=True if not isOnline else bool(NewPlayerMessage['side']),game_id=NewPlayerMessage['game_id'],client=network) game_state=backend.GameState()
#* cancelled args: MySide=True if not isOnline else bool(NewPlayerMessage['side']),game_id=NewPlayerMessage['game_id']
valid_moves=game_state.getAllMoves() valid_moves=game_state.getAllMoves()
running = True running = True
other_joined = False
mademove = False mademove = False
game_over = False game_over = False
square_selected = () #刚开始没有选择任何一个棋子 square_selected = () #刚开始没有选择任何一个棋子
@ -319,7 +338,36 @@ def main(mode,p1,p2,network = None):
clock.tick(60) clock.tick(60)
pg.display.flip() pg.display.flip()
elif mode == 2: elif mode == 2:
startNetworkServices()
myPlayerData = {
'type': 0, # game state type ?
'msg': {
'name': 'myName'
}
}
login_packet = json.dumps(myPlayerData)
if (sys.version[:1] == '3'):
login_packet = login_packet.encode('utf-8')
lastNetworkMsg = networkMsg
client.send(login_packet)
while running: while running:
if lastNetworkMsg != networkMsg:#handle
print('get new msg: ',networkMsg)
lastNetworkMsg = networkMsg #networkMsg中保存当前字典
if 'status' in networkMsg.keys():
if networkMsg['status'] == 1:
print('Waiting for another player to connect')
elif 'src' and 'dst' in networkMsg.keys():
if other_joined == False:
other_joined = True
print('Game start 2 play!')
else:
theMove = backend.Move([networkMsg['src']['x'],networkMsg['src']['y']],[networkMsg['dst']['x'],networkMsg['dst']['y']],game_state.board)
game_state.makeMove(theMove)
game_state.exchange()
for e in pg.event.get(): for e in pg.event.get():
#接下来处理游戏中的事件 #接下来处理游戏中的事件
if e.type == pg.QUIT: if e.type == pg.QUIT:
@ -359,23 +407,22 @@ def main(mode,p1,p2,network = None):
#ShowGameState(screen,game_state,valid_moves,square_selected) #ShowGameState(screen,game_state,valid_moves,square_selected)
if mademove: if mademove:
mademove = False mademove = False
game_state.updateEnemy()#思路变成:定时对敌方进行扫描,若收到更新相关包则进行局面更新。 #思路变成:定时对敌方进行扫描,若收到更新相关包则进行局面更新。
ShowGameState(screen,game_state,valid_moves,square_selected) ShowGameState(screen,game_state,valid_moves,square_selected)
if game_state.conquer(): if game_state.conquer():
showGameOverText(screen,"player "+game_state.win_person+" wins") showGameOverText(screen,"player "+game_state.win_person+" wins")
game_over = True game_over = True
clock.tick(60) clock.tick(10)
pg.display.flip() pg.display.flip()
if __name__ == '__main__': if __name__ == '__main__':
print("Loading...") print("Loading...")
print("Initialing game...") print("Initialing game...")
mode = MainMenu() #mode = MainMenu()
player1='player1' mode = 2
network = None #前后端通信接口 main(mode)
player2='player2'
main(mode,player1,player2,network)

@ -4,20 +4,42 @@ import requests
import sys import sys
import json import json
from threading import Thread from threading import Thread
from queue import Queue
#multithreading? #multithreading?
class Move:
def __init__(self,start_loc,end_loc,board):
self.start_row = start_loc[0]
self.start_col = start_loc[1]
self.end_row = end_loc[0]
self.end_col = end_loc[1]
self.nxt_piece = board[self.end_row][self.end_col]
self.cur_piece = board[self.start_row][self.start_col]
self.attack = self.nxt_piece != '00'
self.moveID = self.start_row + self.start_col*10 + self.end_row *100 +self.end_col * 1000 #Hash
def __eq__(self, __o: object) -> bool:
if isinstance(__o, Move):
return self.moveID == __o.moveID
return False
def startNewThread(target): def startNewThread(target):
thread = Thread(target=target) thread = Thread(target=target)
thread.daemon = True thread.daemon = True
thread.start() thread.start()
class Network: class Network:
def __init__(self): def __init__(self,isNet=False): #注意:这里是否在传引用?
self.client = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.server = "127.0.0.1" self.server = "127.0.0.1"
self.port = 50005 self.port = 50005
self.addr = (self.server, self.port) self.addr = (self.server, self.port)
self.msg = self.connect() self.msg = self.connect()
#self.game_state = game_state #考虑将game_state接入Network以方便修改
global msg_from_serv
thread = Thread(target = self.receive())#开线程始终监听
thread.setDaemon(True)
thread.start() #专用数据接收线程
def getPos(self): def getPos(self):
return self.pos return self.pos
@ -34,44 +56,82 @@ class Network:
packet = json.dumps(msg) packet = json.dumps(msg)
if (sys.version[:1] == '3'): if (sys.version[:1] == '3'):
packet = packet.encode('utf-8') packet = packet.encode('utf-8')
#return self.client.recv(2048).encode()
self.client.send(packet) self.client.send(packet)
print("send complete") print("send complete")
return self.client.recv(2048).encode()
except socket.error as e: except socket.error as e:
print(e) print(e)
return e
def post(self, data): #using requests lib, data is json def post(self, data): #using requests lib, data is json
headers = {'Content-Type': 'application/json'} headers = {'Content-Type': 'application/json'}
response = requests.post(url='http://localhost',data=data) response = requests.post(url='http://localhost',data=data)
return response return response
def receive(self): def receive(self): #写成持续监听模式
try: try:
while True:
recvMsg = self.client.recv(2048).decode('utf-8') recvMsg = self.client.recv(2048).decode('utf-8')
msg = json.loads(recvMsg) if len(recvMsg) != 0:
print('receiver got: ', msg) msg_from_serv = json.loads(recvMsg)
return msg self.dataDealer(msg_from_serv)
except socket.error as e: except socket.error as e:
print(e) print(e)
return e return e
class Move: def dataDealer(self, msg_json): #根据相关数据对棋盘状态进行更新
def __init__(self,start_loc,end_loc,board): if 'status' in msg_json.keys():
self.start_row = start_loc[0] #处理相关特殊情况
self.start_col = start_loc[1] if msg_json['status'] == '1':
self.end_row = end_loc[0] print('Waiting 4 the other player...')
self.end_col = end_loc[1]
self.nxt_piece = board[self.end_row][self.end_col]
self.cur_piece = board[self.start_row][self.start_col] elif 'src' and 'dst' in msg_json.keys(): #侦测到移动
self.attack = self.nxt_piece != '00' theMove = Move([msg_json['src']['x'],msg_json['src']['y']],[msg_json['dst']['x'],msg_json['dst']['y']],self.game_state.board)
self.moveID = self.start_row + self.start_col*10 + self.end_row *100 +self.end_col * 1000 #Hash self.game_state.makeMove(theMove,toUpload = False)
def __eq__(self, __o: object) -> bool: self.game_state.exchange()
if isinstance(__o, Move):
return self.moveID == __o.moveID
return False def dataReceiver(self):
try:
while True:
msg = self.client.recv(2048).decode('utf-8')
if len(msg) != 0: self.dataDealer(json.loads(msg))
except socket.error as e:
print(e)
return e
def tell_move(self, move: Move):
thisMove = {
'type': 1,
'msg':{
"game_id": self.game_id,
"side": int(self.red_to_move),
"chessman": move.cur_piece,
"src": {
"x": move.start_row,
"y": move.start_col
},
"dst": {
"x": move.end_row,
"y": move.end_col
}
}
}
self.client.send(thisMove)
def login(self,myName):
myPlayerData = {
'type': 0, # game state type ?
'msg': {
'name': myName
}
}
self.client.send(myPlayerData)
class GameState: class GameState:
def __init__(self, isNet = False, MySide = True,
game_id = None, client:Network = None ): def __init__(self):
''' '''
有关信息 有关信息
1. 棋盘尺寸为7*9横向 1. 棋盘尺寸为7*9横向
@ -107,51 +167,17 @@ class GameState:
self.blue_pieces=[7,6,5,4,3,2,1] self.blue_pieces=[7,6,5,4,3,2,1]
self.red_pieces=[7,6,5,4,3,2,1] self.red_pieces=[7,6,5,4,3,2,1]
#红方(右)先行 #红方(右)先行
self.isNet = isNet self.red_to_move=True
self.game_id = game_id
self.red_to_move=MySide
self.MySide = MySide
self.client = client
self.conquered=False self.conquered=False
self.win_person='' self.win_person=''
self.MASSACRE=False self.MASSACRE=False
self.isStarted = False
def color(self): def color(self):
return 'r' if self.red_to_move else 'b' return 'r' if self.red_to_move else 'b'
def exchange(self): def exchange(self):
self.red_to_move = not self.red_to_move self.red_to_move = not self.red_to_move
#网络版相关组件
def upldmv_server(self,move):
thisMove = {
'type': 1,
'msg':{
"game_id": self.game_id,
"side": int(self.red_to_move),
"chessman": move.cur_piece,
"src": {
"x": move.start_row,
"y": move.start_col
},
"dst": {
"x": move.end_row,
"y": move.end_col
}
}
}
self.client.send(thisMove)
def __updateOther__(self):#! 注意:考虑使用多线程执行该函数。
#print('waiting 4 other player 2 act...')
thisMovejson = self.client.receive()
if not thisMovejson or thisMovejson['side'] == int(self.MySide):
return
print('passing checkpoint')
if 'chessman' in thisMovejson.keys(): #正常移动过程
thisMove = Move([thisMovejson['src']['x'],thisMovejson['src']['y']],[thisMovejson['dst']['x'],thisMovejson['dst']['y']],self.board)
self.makeMove(thisMove,toUpload=False)
self.exchange()
def updateEnemy(self):
startNewThread(self.__updateOther__)#测试多线程更新……
# 判断特殊位置 # 判断特殊位置
def inHome(self,row,col,color): def inHome(self,row,col,color):
if color=="b": if color=="b":
@ -347,7 +373,7 @@ class GameState:
return self.conquered return self.conquered
#移动操作 #移动操作
def makeMove(self,move,toUpload = True):#cur是当前位置nxt是下一个位置,参数传入为元组 def makeMove(self,move):#cur是当前位置nxt是下一个位置,参数传入为元组
# makeMove假设这个move一定是合法的 # makeMove假设这个move一定是合法的
# 为什么添加toUpload防止使用makeMove更新己方棋盘时把敌方棋盘错误上传导致“棋子消失”。 # 为什么添加toUpload防止使用makeMove更新己方棋盘时把敌方棋盘错误上传导致“棋子消失”。
if self.board[move.end_row][move.end_col] != '00': if self.board[move.end_row][move.end_col] != '00':
@ -360,8 +386,5 @@ class GameState:
self.board[move.start_row][move.start_col] = '00' self.board[move.start_row][move.start_col] = '00'
self.red_to_move = not self.red_to_move self.red_to_move = not self.red_to_move
#由于使用多线程考虑让另一个线程去更新red_to_move #由于使用多线程考虑让另一个线程去更新red_to_move
if self.isNet and toUpload:
#因为界面更新在main中考虑在main中执行相关指令。
self.upldmv_server(move)

Loading…
Cancel
Save