9.6下午5678节课

master
DoubleQ 3 years ago
parent c6980f6ef7
commit 4c4e4afc3b

@ -12,6 +12,15 @@
"cwd": "${workspaceFolder}",
"console": "integratedTerminal",
"justMyCode": true
},
{
"name": "run single server",
"type": "python",
"request": "launch",
"program": "${workspaceFolder}/network/server.py",
"cwd": "${fileDirname}",
"console": "integratedTerminal",
"justMyCode": true
}
]
}

@ -124,5 +124,12 @@ ex.大致图像
#### 二、开发流程
UI设计
-----增加相关按钮,增加提示,增加每一步的提示
(二)功能实现
-----与服务器数据交换

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 45 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 45 KiB

@ -4,18 +4,15 @@
"""
class Button:
def _init_(self, image, position, callback=None):
def __init__(self, image, position, callback=None):
self.image = image
self.rect = image.get_rect(topleft=position)
self.callback = callback
def on_click(self, mouse_pos):
if self.rect.collidepoint(mouse_pos):
if self.callback:
self.callback()
return True
return False
def on_click(self, event):
if event.button == 1:
if self.rect.collidepoint(event.pos):
self.callback(self)
#class DropDown():
#下拉选择框

@ -15,16 +15,16 @@ import pygame as pg
import sys
from time import process_time
import SafariChess_backend as backend
import SafariChess_Classes as classes
from SafariChess_Classes import Button
import network.server as Server
#设置棋盘的参数
WIDTH = 800
HEIGHT = 1000
BOARD_WIDTH = 600
BOARD_HEIGHT = 800
SCREEN_WIDTH = 600
SCREEN_HEIGHT = 800
WIDTH = 1000
HEIGHT = 800
BOARD_WIDTH = 800
BOARD_HEIGHT = 600
SCREEN_WIDTH = 800
SCREEN_HEIGHT = 600
MOVE_LOG_PANEL_WIDTH = 0
MOVE_LOG_PANEL_HEIGHT = BOARD_HEIGHT
DIMENSION = 8
@ -32,8 +32,8 @@ DIMENSION_ROWS = 7
DIMENSION_COLUMNS = 9
SIZE = 64
IMAGES = {}
bias_top = 200 #棋盘的上边距
bias_left = 10 #棋盘的左边距
bias_top = 100 #棋盘的上边距
bias_left = 100 #棋盘的左边距
def loadImages():#加载图片,a,b双方分别有象狮豹狼狐鹰鼠七个角色
pieces = ["r7", "r6", "r5", "r4", "r3", "r2", "r1",
@ -80,6 +80,8 @@ 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):
@ -112,8 +114,8 @@ def drawMovelog(screen):#绘制移动日志
pass
def startGamePage():#开始游戏界面Human/AI
startpage = '''
def startGamePage(mode = 1):#开始游戏界面Human/AI
startpage = ('''
WELCOME TO
@ -129,13 +131,13 @@ def startGamePage():#开始游戏界面Human/AI
################################################################
Please type one of the numbers below to choose a playing mode:
( 1 ) - Human vs Human
( 2 ) - Human vs AI
( 3 ) - AI vs AI
( 4 ) - Quit
( 1 ) - 单机游戏
( 2 ) - 网络对战
( 3 ) - 人机对战
( 4 ) - 退出游戏
################################################################
'''
Current Mode is: %s
'''%['单机游戏','网络对战','人机对战','退出游戏'][mode-1])
print(startpage)
# 选择游戏模式
not_selected = True
@ -143,7 +145,7 @@ Please type one of the numbers below to choose a playing mode:
while not_selected:
try:
#mode = int(input())
mode = 1
#mode = 1
if mode in [1,2,3,4]:
if mode == 1:
p1 = 1
@ -152,10 +154,10 @@ Please type one of the numbers below to choose a playing mode:
not_selected = False
else:
print("Please type one of the numbers below to choose a playing mode:")
print(" ( 1 ) - Human vs Human")
print(" ( 2 ) - Human vs AI")
print(" ( 3 ) - AI vs AI")
print(" ( 4 ) - Quit")
print(" ( 1 ) - 单机游戏")
print(" ( 2 ) - 网络对战")
print(" ( 3 ) - 人机对战")
print(" ( 4 ) - 退出游戏")
except ValueError:
print("Wrong Input")
return p1, p2, mode
@ -178,16 +180,61 @@ def MainMenu():
pg.init()
mainClock = pg.time.Clock()
#ui
screen = pg.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
pg.display.set_caption("SafariChess by ZY&&DQ")
bg = pg.image.load("images/MenuBg.jpg")
bg = pg.transform.scale(pg.image.load("Image/MenuBg.jpg"), (SCREEN_WIDTH, SCREEN_HEIGHT))
bt1 = pg.transform.scale(pg.image.load("Image/button1.jpg"),(150,40))
bt2 = pg.transform.scale(pg.image.load("Image/button2.jpg"),(150,40))
bt3 = pg.transform.scale(pg.image.load("Image/button3.jpg"),(150,40))
bt4 = pg.transform.scale(pg.image.load("Image/button4.jpg"),(150,40))
#按钮设置
return 1
#主菜单包含如下按钮:
#单机游戏,双人游戏,人机对战,退出游戏
button_1 = Button(bt1,(350,350))
button_2 = Button(bt2,(350,400))
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)
mode = 0
events = pg.event.get()
for event in events:
if event.type == pg.QUIT:
pg.quit()
sys.exit()
if event.type == pg.KEYDOWN:
if event.key == pg.K_ESCAPE:
pg.quit()
sys.exit()
if event.type == pg.MOUSEBUTTONDOWN:
if event.button == 1: #左键
if button_1.rect.collidepoint(event.pos):
mode = 1
run = False
if button_2.rect.collidepoint(event.pos):
mode = 2
run = False
if button_3.rect.collidepoint(event.pos):
mode = 3
run = False
if button_4.rect.collidepoint(event.pos):
pg.quit()
sys.exit()
screen.blit(bg, (0, 0))
screen.blit(button_1.image, button_1.rect)
screen.blit(button_2.image, button_2.rect)
screen.blit(button_3.image, button_3.rect)
screen.blit(button_4.image, button_4.rect)
pg.display.flip()
return mode
def main():
def main(mode,p1,p2):
pg.init()
screen = pg.display.set_mode((BOARD_WIDTH + MOVE_LOG_PANEL_WIDTH, BOARD_HEIGHT))
pg.display.set_caption("Safafi Chess Game")
@ -252,6 +299,7 @@ def main():
if __name__ == '__main__':
print("Loading...")
print("Initialing game...")
mode = MainMenu()
main()

@ -0,0 +1,5 @@
SOCKET_HOST=127.0.0.1
SOCKET_PORT=50005
MAX_WAITING_TIME=600
MAX_THNIKING_TIME=15
MAX_TOTAL_TIME=1000

@ -0,0 +1,247 @@
# coding:utf-8
import socket
import sys
import json
import uuid
import time
from threading import Thread, Lock
if(sys.version[:1] == "3"):
import queue as Queue
from _thread import *
else:
import Queue
from thread import *
class Config:
SOCKET_HOST = '127.0.0.1' # Symbolic name meaning all available interfaces
SOCKET_PORT = 50005 # Arbitrary non-privileged port
MAX_WAITING_TIME = 180
MAX_THNIKING_TIME = 60
MAX_TOTAL_TIME = 600
class Client:
def __init__(self, conn, addr, name, side, time, total):
self.conn = conn
self.addr = addr
self.name = name
self.side = side
self.time = time
self.total = total
mutex = Lock()
mutex_playing = Lock()
playing_ones = {}
waiting_players = Queue.Queue()
#init queues
#for games in range(1, 10):
# waiting_players[games] = Queue.Queue()
def load_config():
with open('config.txt', 'r') as f:
for line in f.readlines():
line = line.strip()
if line.find('SOCKET_HOST=') >= 0:
Config.SOCKET_HOST = line[line.index('=') + 1 : ]
elif line.find('SOCKET_PORT=') >= 0:
Config.SOCKET_PORT = int(line[line.index('=') + 1 : ])
elif line.find('MAX_WAITING_TIME=') >= 0:
Config.MAX_WAITING_TIME = int(line[line.index('=') + 1 : ])
elif line.find('MAX_THNIKING_TIME=') >= 0:
Config.MAX_THNIKING_TIME = int(line[line.index('=') + 1 : ])
elif line.find('MAX_TOTAL_TIME=') >= 0:
Config.MAX_TOTAL_TIME = int(line[line.index('=') + 1 : ])
else:
pass
def get_counterpart_from(waiting_ones):
counterpart = None
mutex.acquire()
if not waiting_ones.empty():
counterpart = waiting_ones.get()
mutex.release()
return counterpart
def to_wait_in_queue(client, the_queue):
mutex.acquire()
the_queue.put(client)
mutex.release()
def remove_one_from_queue(the_queue):
mutex.acquire()
if (the_queue.qsize() == 1):
the_queue.get()
mutex.release()
def send_msg_to(client, msg):
packet = json.dumps(msg)
if (sys.version[:1] == "3"):
packet = packet.encode('utf-8')
#print(client.addr[0] + ":" + str(client.addr[1]) + "\t" + str(msg))
client.conn.send(packet)
def __start_match_between(client0, client1):
match_uuid = str(uuid.uuid4())
mutex_playing.acquire()
playing_ones[match_uuid] = (client0, client1)
mutex_playing.release()
client0.side = 0
client0.time = Config.MAX_THNIKING_TIME
client0.total = Config.MAX_TOTAL_TIME
client1.side = 1
client1.time = -1
client1.total = Config.MAX_TOTAL_TIME
msg0 = {
"status": 1,
"counterpart_name": client1.name,
"game_id": match_uuid,
"side": client0.side,
"think_time": Config.MAX_THNIKING_TIME,
"total_time": Config.MAX_TOTAL_TIME,
}
send_msg_to(client0, msg0)
msg1 = {
"status": 1,
"counterpart_name": client0.name,
"game_id": match_uuid,
"side": client1.side,
"think_time": Config.MAX_THNIKING_TIME,
"total_time": Config.MAX_TOTAL_TIME,
}
send_msg_to(client1, msg1)
def join_game_handler(msg, addr, conn):
new_client = Client(conn, addr, msg['name'], -1, -1, -1)
#game_type = msg["id"]
#the_queue = waiting_players[game_type]
counterpart = get_counterpart_from(waiting_players)
if not counterpart: #wait
to_wait_in_queue(new_client, waiting_players)
return
else:
#counterpart=get_counterpart_from(waiting_players[game_type])
__start_match_between(new_client, counterpart)
def quit_game_handler(msg):
match_uuid = msg['game_id']
if match_uuid is None:
remove_one_from_queue(waiting_players)
return
pairs = None
mutex_playing.acquire()
if (match_uuid in playing_ones):
pairs = playing_ones[match_uuid]
del playing_ones[match_uuid]
mutex_playing.release()
if pairs is not None:
if(pairs[0].side == msg['side']):
to_notify = pairs[1]
else:
to_notify = pairs[0]
msg = {
"status": 2, #exit
"game_id": match_uuid,
"side": msg['side'],
"request": msg['request'],
}
send_msg_to(to_notify, msg)
def timer_thread():
while True:
time.sleep(1)
mutex_playing.acquire()
for game_id in list(playing_ones.keys()):
(client0, client1) = playing_ones[game_id]
#print("%d - %d" % (client0.time, client1.time))
if (client0.time < 0):
client = client1
else:
client = client0
if (client.time == 0 or client.total == 0):
msg = {
"status": 3, #timeout exit
"game_id": game_id,
"side": client.side,
}
send_msg_to(client0, msg)
send_msg_to(client1, msg)
del playing_ones[game_id]
else:
client.time -= 1
client.total -= 1
mutex_playing.release()
def transfer_message(msg):
match_uuid = msg['game_id']
pairs = playing_ones[match_uuid]
if(pairs[0].side == msg['side']):
to_notify = pairs[1]
pairs[0].time = -1
else:
to_notify = pairs[0]
pairs[1].time = -1
to_notify.time = Config.MAX_THNIKING_TIME
send_msg_to(to_notify, msg)
def client_thread(conn, addr):
while True:
data = conn.recv(1024)
if not data:
break
print(data)
data = json.loads(data)
if not 'type' in data:
transfer_message(data['msg'])
continue
if data['type'] == 0:
join_game_handler(data['msg'], addr, conn)
continue
elif data['type'] == 1:
transfer_message(data['msg'])
continue
elif data['type'] == 2:
quit_game_handler(data['msg'])
break
elif data['type'] == 3:
break
else:
#delivering message between the two clients
transfer_message(data['msg'])
continue
#came out of loop
conn.close()
def main():
load_config()
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
print('Socket server created')
#try:
server.bind((Config.SOCKET_HOST, Config.SOCKET_PORT))
#except (socket.error, msg):
# print ('Bind failed. Error Code : ' + str(msg[0]) + ' Message ' + msg[1])
# sys.exit()
print('Socket bind complete')
server.listen(10)
print('Socket now listening')
#now keep talking with the client
start_new_thread(timer_thread, ())
while True:
#wait to accept a connection - blocking call
conn, addr = server.accept()
print ('Connected with ' + addr[0] + ':' + str(addr[1]))
#start new thread takes 1st argument as a function name to be run, second is the tuple of arguments to the function.
start_new_thread(client_thread, (conn, addr))
server.close()
if __name__ == '__main__':
main()

@ -0,0 +1,26 @@
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
Loading…
Cancel
Save