master
tzzzzzzzx 3 years ago
parent f3f2f60df3
commit 15b3394ae5

@ -11,6 +11,7 @@ it handle user input and GUI
import colorsys
import json
from multiprocessing import connection
import pygame as pg
import sys
import socket
@ -34,10 +35,41 @@ SIZE = 64
IMAGES = {}
bias_top = 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双方分别有象狮豹狼狐鹰鼠七个角色
@ -200,7 +232,6 @@ def MainMenu():
button_3 = Button(bt3,(350,450))
button_4 = Button(bt4,(350,500))
mode = -1
p1,p2 = 0,0
run = True
while run:
mainClock.tick(60)
@ -238,38 +269,26 @@ def MainMenu():
def main(mode,p1,p2,network = None):
NewPlayerMessage = '' #来自对手的信息
if mode == 2:
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']
def main(mode):
global networkMsg
networkMsg = None
pg.init()
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()
screen.fill(pg.Color("white"))
loadImages()
drawBoard(screen)
isOnline = bool(network != None)
game_state=backend.GameState(isNet=isOnline,MySide=True if not isOnline else bool(NewPlayerMessage['side']),game_id=NewPlayerMessage['game_id'],client=network)
isOnline = bool(mode == 2)
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()
running = True
other_joined = False
mademove = False
game_over = False
square_selected = ()#刚开始没有选择任何一个棋子
click_queue = []#点击队列,记录第一次点击和第二次点击位置,方便移动棋子
square_selected = () #刚开始没有选择任何一个棋子
click_queue = [] #点击队列,记录第一次点击和第二次点击位置,方便移动棋子
pg.display.update()
startGamePage(mode)
@ -319,7 +338,36 @@ def main(mode,p1,p2,network = None):
clock.tick(60)
pg.display.flip()
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:
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():
#接下来处理游戏中的事件
if e.type == pg.QUIT:
@ -359,23 +407,22 @@ def main(mode,p1,p2,network = None):
#ShowGameState(screen,game_state,valid_moves,square_selected)
if mademove:
mademove = False
game_state.updateEnemy()#思路变成:定时对敌方进行扫描,若收到更新相关包则进行局面更新。
#思路变成:定时对敌方进行扫描,若收到更新相关包则进行局面更新。
ShowGameState(screen,game_state,valid_moves,square_selected)
if game_state.conquer():
showGameOverText(screen,"player "+game_state.win_person+" wins")
game_over = True
clock.tick(60)
clock.tick(10)
pg.display.flip()
if __name__ == '__main__':
print("Loading...")
print("Initialing game...")
mode = MainMenu()
player1='player1'
network = None #前后端通信接口
player2='player2'
main(mode,player1,player2,network)
#mode = MainMenu()
mode = 2
main(mode)

@ -4,20 +4,42 @@ import requests
import sys
import json
from threading import Thread
from queue import Queue
#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):
thread = Thread(target=target)
thread.daemon = True
thread.start()
class Network:
def __init__(self):
def __init__(self,isNet=False): #注意:这里是否在传引用?
self.client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.server = "127.0.0.1"
self.port = 50005
self.addr = (self.server, self.port)
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):
return self.pos
@ -34,44 +56,82 @@ class Network:
packet = json.dumps(msg)
if (sys.version[:1] == '3'):
packet = packet.encode('utf-8')
#return self.client.recv(2048).encode()
self.client.send(packet)
print("send complete")
return self.client.recv(2048).encode()
except socket.error as e:
print(e)
return e
def post(self, data): #using requests lib, data is json
headers = {'Content-Type': 'application/json'}
response = requests.post(url='http://localhost',data=data)
return response
def receive(self):
def receive(self): #写成持续监听模式
try:
while True:
recvMsg = self.client.recv(2048).decode('utf-8')
msg = json.loads(recvMsg)
print('receiver got: ', msg)
return msg
if len(recvMsg) != 0:
msg_from_serv = json.loads(recvMsg)
self.dataDealer(msg_from_serv)
except socket.error as e:
print(e)
return e
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 dataDealer(self, msg_json): #根据相关数据对棋盘状态进行更新
if 'status' in msg_json.keys():
#处理相关特殊情况
if msg_json['status'] == '1':
print('Waiting 4 the other player...')
elif 'src' and 'dst' in msg_json.keys(): #侦测到移动
theMove = Move([msg_json['src']['x'],msg_json['src']['y']],[msg_json['dst']['x'],msg_json['dst']['y']],self.game_state.board)
self.game_state.makeMove(theMove,toUpload = False)
self.game_state.exchange()
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:
def __init__(self, isNet = False, MySide = True,
game_id = None, client:Network = None ):
def __init__(self):
'''
有关信息
1. 棋盘尺寸为7*9横向
@ -107,51 +167,17 @@ class GameState:
self.blue_pieces=[7,6,5,4,3,2,1]
self.red_pieces=[7,6,5,4,3,2,1]
#红方(右)先行
self.isNet = isNet
self.game_id = game_id
self.red_to_move=MySide
self.MySide = MySide
self.client = client
self.red_to_move=True
self.conquered=False
self.win_person=''
self.MASSACRE=False
self.isStarted = False
def color(self):
return 'r' if self.red_to_move else 'b'
def exchange(self):
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):
if color=="b":
@ -347,7 +373,7 @@ class GameState:
return self.conquered
#移动操作
def makeMove(self,move,toUpload = True):#cur是当前位置nxt是下一个位置,参数传入为元组
def makeMove(self,move):#cur是当前位置nxt是下一个位置,参数传入为元组
# makeMove假设这个move一定是合法的
# 为什么添加toUpload防止使用makeMove更新己方棋盘时把敌方棋盘错误上传导致“棋子消失”。
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.red_to_move = not self.red_to_move
#由于使用多线程考虑让另一个线程去更新red_to_move
if self.isNet and toUpload:
#因为界面更新在main中考虑在main中执行相关指令。
self.upldmv_server(move)

Loading…
Cancel
Save