diff --git a/.vscode/launch.json b/.vscode/launch.json index 7e5da93..a42fab7 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -21,6 +21,15 @@ "cwd": "${fileDirname}", "console": "integratedTerminal", "justMyCode": true + }, + { + "name": "current file", + "type": "python", + "request": "launch", + "program": "${file}", + "cwd": "${fileDirname}", + "console": "integratedTerminal", + "justMyCode": true } ] } \ No newline at end of file diff --git a/SafariChess_Gamev1.0.py b/SafariChess_Gamev1.0.py index f35b54c..dc64986 100644 --- a/SafariChess_Gamev1.0.py +++ b/SafariChess_Gamev1.0.py @@ -10,13 +10,13 @@ it handle user input and GUI """ import colorsys -from json import load +import json import pygame as pg import sys -from time import process_time +import socket import SafariChess_backend as backend from SafariChess_Classes import Button -import network.server as Server +from threading import Thread, Lock #设置棋盘的参数 WIDTH = 1000 @@ -34,6 +34,9 @@ SIZE = 64 IMAGES = {} bias_top = 100 #棋盘的上边距 bias_left = 100 #棋盘的左边距 +#multithreading? +mutex = Lock() +mutex_playing = Lock() def loadImages():#加载图片,a,b双方分别有象狮豹狼狐鹰鼠七个角色 pieces = ["r7", "r6", "r5", "r4", "r3", "r2", "r1", @@ -80,8 +83,7 @@ def drawPieces(screen,board): if piece != "00": screen.blit(IMAGES[piece], pg.Rect((column * SIZE) + bias_left + 5, (row * SIZE) + bias_top + 5, SIZE - 10, SIZE - 10)) -def uploadtoServer(move : backend.Move): - pass + # square_selected 是当前选中的可以移动的棋子的位置 def protrudeSquares(screen,game_state,square_selected,valid_moves): @@ -234,7 +236,22 @@ def MainMenu(): -def main(mode,p1,p2): +def main(mode,p1,p2,network = None): + NewPlayerMessage = '' #来自对手的信息 + if mode == 2: + network=backend.Network() + player1 = input("Enter your name: ") + myPlayerData = { + 'type': 0, # game state type ? + 'msg': { + 'name': player1 + } + } + network.send(myPlayerData) + print("Waiting for other player...") + NewPlayerMessage = network.receive() + print() + player2 = NewPlayerMessage['counterpart_name'] pg.init() screen = pg.display.set_mode((BOARD_WIDTH + MOVE_LOG_PANEL_WIDTH, BOARD_HEIGHT)) pg.display.set_caption("Safafi Chess Game") @@ -242,7 +259,8 @@ def main(mode,p1,p2): screen.fill(pg.Color("white")) loadImages() drawBoard(screen) - game_state=backend.GameState() + isOnline = bool(network != None) + game_state=backend.GameState(isNet=isOnline,MySide=True if not isOnline else bool(NewPlayerMessage['side'])) valid_moves=game_state.getAllMoves() running = True mademove = False @@ -250,57 +268,105 @@ def main(mode,p1,p2): square_selected = ()#刚开始没有选择任何一个棋子 click_queue = []#点击队列,记录第一次点击和第二次点击位置,方便移动棋子 pg.display.update() - startGamePage() - while running: - for e in pg.event.get(): - #接下来处理游戏中的事件 - if e.type == pg.QUIT: - pg.quit() - sys.exit() + startGamePage(mode) + + if mode == 1: + while running: + for e in pg.event.get(): + #接下来处理游戏中的事件 + if e.type == pg.QUIT: + pg.quit() + sys.exit() + + elif e.type == pg.MOUSEBUTTONDOWN: + #鼠标点击事件:用于选择棋子,移动棋子 + if not game_over: + mouse_loc = pg.mouse.get_pos() + row = int((mouse_loc[1] - bias_top) / SIZE) + col = int((mouse_loc[0] - bias_left) / SIZE) #* get position of mouse click + if square_selected == (row,col) or col >=DIMENSION_COLUMNS or row >= DIMENSION_ROWS: + square_selected = () + click_queue = [] + else: + square_selected = (row,col) + click_queue.append(square_selected) + if(len(click_queue) == 2): + cur_piece_loc = click_queue[0] + nxt_piece_loc = click_queue[1] + move = backend.Move(cur_piece_loc,nxt_piece_loc,game_state.board) + if move in valid_moves: + game_state.makeMove(move) + mademove = True + square_selected = () + click_queue = [] + else: + click_queue = [square_selected] + + elif e.type == pg.KEYDOWN: + #设置某些按键用于悔棋,重新开始游戏,机器提示,退出游戏等功能 + pass - elif e.type == pg.MOUSEBUTTONDOWN: - #鼠标点击事件:用于选择棋子,移动棋子 - if not game_over: - mouse_loc = pg.mouse.get_pos() - row = int((mouse_loc[1] - bias_top) / SIZE) - col = int((mouse_loc[0] - bias_left) / SIZE) #* get position of mouse click - if square_selected == (row,col) or col >=DIMENSION_COLUMNS or row >= DIMENSION_ROWS: - square_selected = () - click_queue = [] - else: - square_selected = (row,col) - click_queue.append(square_selected) - if(len(click_queue) == 2): - cur_piece_loc = click_queue[0] - nxt_piece_loc = click_queue[1] - move = backend.Move(cur_piece_loc,nxt_piece_loc,game_state.board) - if move in valid_moves: - game_state.makeMove(move) - mademove = True + if mademove: + valid_moves = game_state.getAllMoves() + 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) + pg.display.flip() + elif mode == 2: + while running: + + for e in pg.event.get(): + #接下来处理游戏中的事件 + if e.type == pg.QUIT: + pg.quit() + sys.exit() + elif e.type == pg.MOUSEBUTTONDOWN: + #鼠标点击事件:用于选择棋子,移动棋子 + if not game_over: + mouse_loc = pg.mouse.get_pos() + row = int((mouse_loc[1] - bias_top) / SIZE) + col = int((mouse_loc[0] - bias_left) / SIZE) #* get position of mouse click + if square_selected == (row,col) or col >=DIMENSION_COLUMNS or row >= DIMENSION_ROWS: square_selected = () click_queue = [] else: - click_queue = [square_selected] + square_selected = (row,col) + click_queue.append(square_selected) + if(len(click_queue) == 2): + cur_piece_loc = click_queue[0] + nxt_piece_loc = click_queue[1] + move = backend.Move(cur_piece_loc,nxt_piece_loc,game_state.board) + if move in valid_moves: + game_state.makeMove(move) + mademove = True + square_selected = () + click_queue = [] + else: + click_queue = [square_selected] + + elif e.type == pg.KEYDOWN: + #设置某些按键用于悔棋,重新开始游戏,机器提示,退出游戏等功能 + pass - elif e.type == pg.KEYDOWN: - #设置某些按键用于悔棋,重新开始游戏,机器提示,退出游戏等功能 - pass - - if mademove: - valid_moves = game_state.getAllMoves() - 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) - pg.display.flip() - + if mademove: + valid_moves = game_state.getAllMoves() + 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) + pg.display.flip() if __name__ == '__main__': print("Loading...") print("Initialing game...") mode = MainMenu() - main() + player1='player1' + network = None #前后端通信接口 + player2='player2' + main(mode,player1,player2,network) \ No newline at end of file diff --git a/SafariChess_backend.py b/SafariChess_backend.py index 34a1259..4ca1318 100644 --- a/SafariChess_backend.py +++ b/SafariChess_backend.py @@ -1,11 +1,46 @@ +import socket +import requests +import sys +import json class GameState: - def __init__(self): + + ''' + def uploadtoServer(self,move): + #将move转换为json格式 + + #将json格式的move上传到服务器 + + pass + + def getEnemyMove(self): + #从服务器获取json信息 + + #将json信息转化成move + + #返回move + pass + + def updatefromServer(self,move): + move=getEnemyMove() + self.makeMove(move) + pass + + def getLoginInfo(self): + #从服务器获取登录信息 + + #返回登录信息 + pass + ''' + + def __init__(self, isNet = False, MySide = True): ''' 有关信息: 1. 棋盘尺寸为7*9(横向) 2. 按照以下命名格式对棋盘中的棋子进行标注: (b|r)(1|2|3|4|5|6|7) - 3. + 3. 左方为蓝方,对应的网络服务器中的side项目编号为0 + 右方为红方,对应的网络服务器中的side项目编号为1 + 4. 网络版需要额外的类变量:type, game_id, side, chessman(piece), src, dst ''' self.board = [ ['00','00','b7','00','00','00','r1','00','00'], @@ -32,15 +67,18 @@ class GameState: self.red_home=(3,8) self.blue_pieces=[7,6,5,4,3,2,1] self.red_pieces=[7,6,5,4,3,2,1] - #蓝方(左)先行 - self.red_to_move=False + #红方(右)先行 + self.isNet = isNet + self.red_to_move=MySide self.conquered=False self.win_person='' self.MASSACRE=False def color(self): return 'r' if self.red_to_move else 'b' - + #网络版相关组件 + def upld2server(self,move): + pass # 判断特殊位置 def inHome(self,row,col,color): @@ -247,7 +285,52 @@ class GameState: self.blue_pieces.remove(int(nxt_piece[1])) self.board[move.end_row][move.end_col] = self.board[move.start_row][move.start_col] self.board[move.start_row][move.start_col] = '00' - self.red_to_move = not self.red_to_move + if not self.isNet: self.red_to_move = not self.red_to_move + else: + + +class Network: + def __init__(self): + 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() + + def getPos(self): + return self.pos + + def connect(self): + try: + self.client.connect(self.addr) + #return self.client.recv(2048).decode() + except: + pass + + def send(self, msg): + try: + packet = json.dumps(msg) + if (sys.version[:1] == '3'): + packet = packet.encode('utf-8') + #return self.client.recv(2048).encode() + self.client.send(packet) + except socket.error as e: + print(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): + try: + msg = json.loads(self.client.recv(2048)) + print(msg) + return msg + except socket.error as e: + print(e) + return e class Move: def __init__(self,start_loc,end_loc,board): diff --git a/__pycache__/SafariChess_backend.cpython-39.pyc b/__pycache__/SafariChess_backend.cpython-39.pyc index 3f19128..91388e3 100644 Binary files a/__pycache__/SafariChess_backend.cpython-39.pyc and b/__pycache__/SafariChess_backend.cpython-39.pyc differ diff --git a/network/server.py b/network/server.py index 9770956..596f819 100644 --- a/network/server.py +++ b/network/server.py @@ -233,7 +233,7 @@ def main(): #now keep talking with the client start_new_thread(timer_thread, ()) - while True: + while True: #! 监听本体 #wait to accept a connection - blocking call conn, addr = server.accept() print ('Connected with ' + addr[0] + ':' + str(addr[1])) diff --git a/network/transfer.py b/network/transfer.py index fa66b15..e69de29 100644 --- a/network/transfer.py +++ b/network/transfer.py @@ -1,26 +0,0 @@ -def uploadtoServer(move,game_state): - #将move转换为json格式 - - #将json格式的move上传到服务器 - - pass - -def getEnemyMove(): - #从服务器获取json信息 - - #将json信息转化成move - - #返回move - pass - -def updatefromServer(game_state): - move=getEnemyMove() - game_state.makeMove(move) - pass - -def getLoginInfo(): - #从服务器获取登录信息 - - #返回登录信息 - pass -