After Width: | Height: | Size: 32 KiB |
@ -0,0 +1,5 @@
|
|||||||
|
1.使用方法
|
||||||
|
|
||||||
|
在cmd进入该文件夹下
|
||||||
|
|
||||||
|
键入命令: `python .\chess_main.py` 开始游戏
|
After Width: | Height: | Size: 4.6 KiB |
After Width: | Height: | Size: 4.6 KiB |
After Width: | Height: | Size: 8.8 KiB |
After Width: | Height: | Size: 4.8 KiB |
After Width: | Height: | Size: 8.7 KiB |
After Width: | Height: | Size: 5.9 KiB |
@ -0,0 +1,440 @@
|
|||||||
|
import collections
|
||||||
|
import pygame
|
||||||
|
import pygame.font
|
||||||
|
import sys
|
||||||
|
import copy
|
||||||
|
from math import sqrt
|
||||||
|
from pygame.locals import *
|
||||||
|
import main
|
||||||
|
from client import *
|
||||||
|
import traceback
|
||||||
|
import json
|
||||||
|
import wx
|
||||||
|
import re
|
||||||
|
|
||||||
|
|
||||||
|
WHITE = (255, 255, 255)
|
||||||
|
BLACK = (0, 0, 0)
|
||||||
|
GREEN = (0, 255, 0)
|
||||||
|
RED = (255, 0, 0)
|
||||||
|
BLUE = (0, 0, 255)
|
||||||
|
def transfer(x, y):
|
||||||
|
|
||||||
|
"""
|
||||||
|
将像素坐标转换为棋盘坐标
|
||||||
|
"""
|
||||||
|
|
||||||
|
chess_x = (x-25) / 100
|
||||||
|
chess_y = (y-25) / 50
|
||||||
|
|
||||||
|
return [chess_x, chess_y]
|
||||||
|
|
||||||
|
def retransfer(chess_x, chess_y):
|
||||||
|
|
||||||
|
"""
|
||||||
|
将棋盘坐标转换为像素坐标
|
||||||
|
"""
|
||||||
|
|
||||||
|
x = (int)(100*(chess_x )+25)
|
||||||
|
y = (int)(50*(chess_y )+25)
|
||||||
|
|
||||||
|
return [x, y]
|
||||||
|
|
||||||
|
|
||||||
|
def getxy(client, s):
|
||||||
|
print("lan_rec")
|
||||||
|
"""
|
||||||
|
接收对方消息
|
||||||
|
"""
|
||||||
|
print("--------------")
|
||||||
|
if client.inQueue.empty() == False: # to process the rival's message
|
||||||
|
rival_move = client.inQueue.get()
|
||||||
|
if "src" in rival_move:
|
||||||
|
s.srcx = rival_move["src"]["x"]
|
||||||
|
s.srcy = rival_move["src"]["y"]
|
||||||
|
s.dstx = rival_move["dst"]["x"]
|
||||||
|
s.dsty = rival_move["dst"]["y"]
|
||||||
|
s.sum = rival_move["num"]
|
||||||
|
[s.srcx, s.srcy] = retransfer(s.srcx, s.srcy)
|
||||||
|
[s.dstx, s.dsty] = retransfer(s.dstx, s.dsty)
|
||||||
|
#置收到消息信号为1
|
||||||
|
s.get = 1
|
||||||
|
|
||||||
|
print("收集到的坐标是", s.srcx, s.srcy, s.dstx, s.dsty)
|
||||||
|
|
||||||
|
def sendxy(client, s):
|
||||||
|
"""
|
||||||
|
发送己方消息
|
||||||
|
"""
|
||||||
|
print("lan_rec")
|
||||||
|
[s.ssrcx, s.ssrcy] = transfer(s.ssrcx, s.ssrcy)
|
||||||
|
[s.sdstx, s.sdsty] = transfer(s.sdstx, s.sdsty)
|
||||||
|
if (s.side == 0 and s.order == True ):
|
||||||
|
client.outQueue.put({
|
||||||
|
"type": 1,
|
||||||
|
"msg": {
|
||||||
|
"game_id": client.game_id,
|
||||||
|
"side": client.side,
|
||||||
|
"num":s.num,
|
||||||
|
"src": {
|
||||||
|
"x": s.ssrcx,
|
||||||
|
"y": s.ssrcy
|
||||||
|
},
|
||||||
|
"dst": {
|
||||||
|
"x": s.sdstx,
|
||||||
|
"y": s.sdsty
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
if (s.side == 1 and s.order == False):
|
||||||
|
print("发送到的坐标是", s.ssrcx, s.ssrcy, s.sdstx, s.sdsty)
|
||||||
|
client.outQueue.put({
|
||||||
|
"type": 1,
|
||||||
|
"msg": {
|
||||||
|
"game_id": client.game_id,
|
||||||
|
"side": client.side,
|
||||||
|
"num": s.num,
|
||||||
|
"src": {
|
||||||
|
"x": s.ssrcx,
|
||||||
|
"y": s.ssrcy
|
||||||
|
},
|
||||||
|
"dst": {
|
||||||
|
"x": s.sdstx,
|
||||||
|
"y": s.sdsty
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
def check_events(s, screen, client):
|
||||||
|
for event in pygame.event.get():
|
||||||
|
if event.type == pygame.QUIT:
|
||||||
|
client.quit()
|
||||||
|
exit()
|
||||||
|
pygame.quit()
|
||||||
|
sys.exit()
|
||||||
|
elif event.type == MOUSEBUTTONDOWN:
|
||||||
|
x=event.pos[0]
|
||||||
|
y=event.pos[1]
|
||||||
|
#getstop(client,s)
|
||||||
|
if s.over == False:
|
||||||
|
#print(s.order)
|
||||||
|
rival_chessman_move(client, s)
|
||||||
|
chessman_move(event, s, screen, client)
|
||||||
|
#认输游戏
|
||||||
|
if 25< x <225 and 600 <y<700:
|
||||||
|
s.request = 'quit'
|
||||||
|
#叫停
|
||||||
|
elif 25< x <225 and 100<y<200:
|
||||||
|
s.request = 'stop'
|
||||||
|
|
||||||
|
|
||||||
|
def victory(s, screen,text):
|
||||||
|
"""
|
||||||
|
胜利图片
|
||||||
|
"""
|
||||||
|
s.over = True
|
||||||
|
victory = pygame.image.load('images/result.png')
|
||||||
|
pic_rect = victory.get_rect()
|
||||||
|
pic_rect.centerx = 730
|
||||||
|
pic_rect.centery = 350
|
||||||
|
screen.blit(victory, pic_rect)
|
||||||
|
font = pygame.font.Font('font.ttf', 50)
|
||||||
|
rv = font.render(text, True, [255, 0, 0])
|
||||||
|
screen.blit(rv, (550, 310))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def whowin(s):
|
||||||
|
for key in s.hongqi.keys():
|
||||||
|
if tuple(s.hongqi[key]['now_weizhi']) not in HeiPoint:
|
||||||
|
return False
|
||||||
|
for key in s.lanqi.keys():
|
||||||
|
if tuple(s.lanqi[key]['now_weizhi']) not in HongPoint:
|
||||||
|
return False
|
||||||
|
return True
|
||||||
|
def find_fenshu(x, y):
|
||||||
|
if (x == 325 and y == 525) or (x == 1125 and y == 225):
|
||||||
|
return 1
|
||||||
|
elif (x == 325 and y == 325) or (x == 1125 and y == 425):
|
||||||
|
return 2
|
||||||
|
elif (x == 325 and y == 425) or (x == 1125 and y == 325):
|
||||||
|
return 3
|
||||||
|
elif (x == 325 and y == 225) or (x == 1125 and y == 525):
|
||||||
|
return 4
|
||||||
|
elif (x == 225 and y == 275) or (x == 1225 and y == 475):
|
||||||
|
return 5
|
||||||
|
elif (x == 225 and y == 375) or (x == 1225 and y == 375):
|
||||||
|
return 6
|
||||||
|
elif (x == 225 and y == 475) or (x == 1225 and y == 275):
|
||||||
|
return 7
|
||||||
|
elif (x == 125 and y == 425) or (x == 1325 and y == 325):
|
||||||
|
return 8
|
||||||
|
elif (x == 125 and y == 325) or (x == 1325 and y == 425):
|
||||||
|
return 9
|
||||||
|
else:
|
||||||
|
return 0
|
||||||
|
|
||||||
|
|
||||||
|
# 计分板
|
||||||
|
def fenshu(s):
|
||||||
|
red_fen = 0
|
||||||
|
hei_fen = 0
|
||||||
|
for key in s.hongqi.keys():
|
||||||
|
if tuple(s.hongqi[key]['now_weizhi']) in s.HeiPoint:
|
||||||
|
red_fen += (key) * find_fenshu(s.hongqi[key]['now_weizhi'][0], s.hongqi[key]['now_weizhi'][1])
|
||||||
|
for key in s.lanqi.keys():
|
||||||
|
if tuple(s.lanqi[key]['now_weizhi']) in s.HongPoint:
|
||||||
|
hei_fen += (key) * find_fenshu(s.lanqi[key]['now_weizhi'][0], s.lanqi[key]['now_weizhi'][1])
|
||||||
|
return red_fen, hei_fen
|
||||||
|
|
||||||
|
|
||||||
|
# 绘制红蓝提示器
|
||||||
|
def tishitext(s, screen):
|
||||||
|
s_font = pygame.font.Font('pz.ttf', 50)
|
||||||
|
s_text = s_font.render('红方得分: %s' % str(fenshu(s)[0]), True, (255, 0, 0))
|
||||||
|
screen.blit(s_text, (1100, 650))
|
||||||
|
s_text = s_font.render('蓝方得分: %s' % str(fenshu(s)[1]), True, (0, 0, 0))
|
||||||
|
screen.blit(s_text, (1100, 700))
|
||||||
|
|
||||||
|
def red_order(s, screen):
|
||||||
|
|
||||||
|
"""
|
||||||
|
红棋落子
|
||||||
|
"""
|
||||||
|
font = pygame.font.Font('pz.ttf', 60)
|
||||||
|
ro = font.render("红棋落子", True, [255, 0, 0])
|
||||||
|
screen.blit(ro, (1100, 580))
|
||||||
|
|
||||||
|
def black_order(s, screen):
|
||||||
|
|
||||||
|
"""
|
||||||
|
黑棋落子
|
||||||
|
"""
|
||||||
|
font = pygame.font.Font('pz.ttf', 60)
|
||||||
|
bo = font.render("黑棋落子", True, [0, 0, 0])
|
||||||
|
screen.blit(bo, (1100, 580))
|
||||||
|
|
||||||
|
#判断该位置有无棋子
|
||||||
|
def weizhi_panduan(s,x,y):
|
||||||
|
for key in s.hongqi.keys():
|
||||||
|
if [x,y] == s.hongqi[key]['now_weizhi']:
|
||||||
|
return True
|
||||||
|
for key in s.lanqi.keys():
|
||||||
|
if [x,y]==s.lanqi[key]['now_weizhi']:
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
# 移 规则
|
||||||
|
def yi_rule(chess_x,chess_y,x,y):
|
||||||
|
print("hong_yi")
|
||||||
|
if abs(chess_x-x) <= 100 and abs(chess_y-y) <= 100 :
|
||||||
|
if not(chess_x == x and chess_y == y):
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
#邻 规则
|
||||||
|
def lin_rule(s,chess_x,chess_y,x,y):
|
||||||
|
print("hong_lin")
|
||||||
|
if weizhi_panduan(s,(chess_x+x)/2 ,(chess_y+y)/2) and abs(x-chess_x)<=200:
|
||||||
|
if not(chess_x == x and chess_y == y):
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
#弹框规则
|
||||||
|
def tankuang(content, wx_type):
|
||||||
|
app=wx.App()
|
||||||
|
dlg = wx.MessageDialog(None,content,"提示",wx_type)
|
||||||
|
if dlg.ShowModal() == wx.ID_NO:
|
||||||
|
return False
|
||||||
|
else:
|
||||||
|
return True
|
||||||
|
|
||||||
|
#输入框获取值
|
||||||
|
def getInput():
|
||||||
|
try:
|
||||||
|
tmp1=['1' , '2' ,'3','4','5', '6' , '7' ,'8' , '9','0']
|
||||||
|
tmp2=[')','(']
|
||||||
|
tmp3=['+','-','/','*']
|
||||||
|
app = wx.App()
|
||||||
|
box = wx.TextEntryDialog(None,'请输入表达式:/n1.数字','运算方法','error')
|
||||||
|
if box.ShowModal() == wx.ID_OK:
|
||||||
|
answer = box.GetValue()
|
||||||
|
lena=len(answer)-1
|
||||||
|
a=0
|
||||||
|
for i in range(lena):
|
||||||
|
if answer[i] == '(':
|
||||||
|
a=a+1
|
||||||
|
if answer[i] ==')':
|
||||||
|
a=a-1
|
||||||
|
if i== lena:
|
||||||
|
if answer[i] not in tmp1 or answer[i] != ')':
|
||||||
|
print(1)
|
||||||
|
return 'error'
|
||||||
|
else:
|
||||||
|
if answer[i] not in (tmp1 + tmp2 + tmp3):
|
||||||
|
print(2)
|
||||||
|
return 'error'
|
||||||
|
else:
|
||||||
|
if answer[i] in tmp3 and answer[i+1] in tmp3:
|
||||||
|
print(3)
|
||||||
|
return 'error'
|
||||||
|
if a!=0:
|
||||||
|
return 'error'
|
||||||
|
return answer
|
||||||
|
|
||||||
|
except:
|
||||||
|
return 'error'
|
||||||
|
def find (s,x,y):
|
||||||
|
for key in s.hongqi.keys():
|
||||||
|
if s.hongqi[key]['now_weizhi'][0] - x == 0 and s.hongqi[key]['now_weizhi'][1]-y ==0:
|
||||||
|
return (key)
|
||||||
|
for key in s.lanqi.keys():
|
||||||
|
if s.lanqi[key]['now_weizhi'][0] - x == 0 and s.lanqi[key]['now_weizhi'][1]-y ==0:
|
||||||
|
return (key)
|
||||||
|
return -1
|
||||||
|
#单跨 规则
|
||||||
|
def dankua_rule(s,value,chess_x, chess_y, x, y):
|
||||||
|
print("hong_dankua")
|
||||||
|
|
||||||
|
if y == chess_y:
|
||||||
|
return False
|
||||||
|
elif x==chess_x:
|
||||||
|
y1 = (y - chess_y)/abs(y-chess_y)
|
||||||
|
if weizhi_panduan(s,x , y-y1*100):
|
||||||
|
a = (getInput())
|
||||||
|
if a!='error'and a!=None:
|
||||||
|
VALUE=eval(a)
|
||||||
|
v = []
|
||||||
|
r =re.split(r"[+-/*()]",a)
|
||||||
|
while '' in r:
|
||||||
|
r.remove('')
|
||||||
|
r = list(map(int,r))
|
||||||
|
for i in range(abs(int((y-chess_y)/100))-1):
|
||||||
|
v.append(find(s,x,chess_y+(i+1)*100*y1))
|
||||||
|
while -1 in v:
|
||||||
|
v.remove(-1)
|
||||||
|
r.sort()
|
||||||
|
v.sort()
|
||||||
|
return r==v and value == VALUE
|
||||||
|
else:
|
||||||
|
y1 = (y - chess_y)/abs(y-chess_y)
|
||||||
|
x1 = (x - chess_x)/abs(x-chess_x)
|
||||||
|
if weizhi_panduan(s,x-x1*100,y-y1*50) and abs(y-chess_y)/50 == abs(x-chess_x)/100:
|
||||||
|
a = (getInput())
|
||||||
|
if a != 'error'and a!=None :
|
||||||
|
print(1)
|
||||||
|
VALUE = eval(a)
|
||||||
|
v = []
|
||||||
|
r =re.split(r"[+-/*()]",a)
|
||||||
|
while '' in r:
|
||||||
|
r.remove('')
|
||||||
|
r = list(map(int,r))
|
||||||
|
print(r)
|
||||||
|
for i in range(abs(int((x-chess_x)/100))-1):
|
||||||
|
v.append(find(s,chess_x+(i+1)*100*x1,chess_y+(i+1)*50*y1))
|
||||||
|
while -1 in v:
|
||||||
|
v.remove(-1)
|
||||||
|
r.sort()
|
||||||
|
v.sort()
|
||||||
|
return r==v and VALUE == value
|
||||||
|
return False
|
||||||
|
|
||||||
|
HeiPoint = [(1125, 225), (1125, 325), (1125, 425), (1125, 525),(1225, 275), (1225, 375),
|
||||||
|
(1225, 475), (1325, 325), (1325, 425), (1425, 375)]
|
||||||
|
HongPoint = [(25 , 375), (125, 325), (125, 425), (225, 275), (225, 375), (225, 475),
|
||||||
|
(325, 225), (325, 325), (325, 425), (325, 525)]
|
||||||
|
#判断是否可以结束
|
||||||
|
def whowin(s):
|
||||||
|
for key in s.hongqi.keys():
|
||||||
|
if tuple(s.hongqi[key]['now_weizhi']) not in s.HeiPoint:
|
||||||
|
return False
|
||||||
|
for key in s.lanqi.keys():
|
||||||
|
if tuple(s.lanqi[key]['now_weizhi']) not in s.HongPoint:
|
||||||
|
return False
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
POINTS = [(25 , 375), (125, 325), (125, 425), (225, 275), (225, 375), (225, 475),
|
||||||
|
(325, 225), (325, 325), (325, 425), (325, 525), (425, 175), (425, 275),
|
||||||
|
(425, 375), (425, 475), (425, 575), (525, 125), (525, 225), (525, 325),
|
||||||
|
(525, 425), (525, 525), (525, 625), (625, 75), (625, 175), (625, 275),
|
||||||
|
(625, 375), (625, 475), (625, 575), (625, 675), (725, 25), (725, 125),
|
||||||
|
(725, 225), (725, 325), (725, 425), (725, 525), (725, 625), (725, 725),
|
||||||
|
(825, 75), (825, 175), (825, 275), (825, 375), (825, 475), (825, 575),
|
||||||
|
(825, 675), (925, 125), (925, 225), (925, 325), (925, 425), (925, 525),
|
||||||
|
(925, 625), (1025, 175), (1025, 275), (1025, 375), (1025, 475), (1025, 575),
|
||||||
|
(1125, 225), (1125, 325), (1125, 425), (1125, 525),(1225, 275), (1225, 375),
|
||||||
|
(1225, 475), (1325, 325), (1325, 425), (1425, 375)]
|
||||||
|
|
||||||
|
|
||||||
|
#己方棋子移动
|
||||||
|
def chessman_move(event, s, screen, client):
|
||||||
|
if event.button == 1:
|
||||||
|
x,y = event.pos[0],event.pos[1]
|
||||||
|
if s.running:#鼠标第一次按下选择棋子
|
||||||
|
if s.order == True:
|
||||||
|
for key in s.hongqi.keys():
|
||||||
|
if sqrt((s.hongqi[key]['now_weizhi'][0] - x)**2+(s.hongqi[key]['now_weizhi'][1]-y)**2) < s.r:
|
||||||
|
s.red_backups = [key,s.hongqi[key]]
|
||||||
|
s.num = int(key)
|
||||||
|
#backups3 = copy.deepcopy(s.red_backups)
|
||||||
|
#s.hongqi.pop(s.red_backups[0])
|
||||||
|
s.ssrcx = (event.pos[0])//50*50+25
|
||||||
|
s.ssrcy = (event.pos[1])//50*50+25
|
||||||
|
if s.red_backups:
|
||||||
|
s.running = False
|
||||||
|
#鼠标再次按下,落下棋子
|
||||||
|
else:
|
||||||
|
x = (event.pos[0])//50*50+25
|
||||||
|
y = (event.pos[1])//50*50+25
|
||||||
|
#if (x,y) in POINTS:
|
||||||
|
if s.red_backups :#红棋
|
||||||
|
#判断所走位置是否有棋子
|
||||||
|
if not weizhi_panduan(s,x,y) and (x,y)in POINTS:
|
||||||
|
s.sdstx = x
|
||||||
|
s.sdsty = y
|
||||||
|
#移 和 临近 规则
|
||||||
|
if (yi_rule(s.red_backups[1]['now_weizhi'][0],s.red_backups[1]['now_weizhi'][1],x,y) \
|
||||||
|
or lin_rule(s,s.red_backups[1]['now_weizhi'][0],s.red_backups[1]['now_weizhi'][1],x,y))\
|
||||||
|
and (s.order == True):
|
||||||
|
s.hongqi[s.red_backups[0]] = s.red_backups[1]
|
||||||
|
s.hongqi[s.red_backups[0]]['now_weizhi'] = [x,y]
|
||||||
|
s.restract_num= 1
|
||||||
|
sendxy(client, s)
|
||||||
|
s.order = False
|
||||||
|
# huiqinumber = 1
|
||||||
|
#单跨 规则
|
||||||
|
elif (s.order == True)and(dankua_rule(s,(s.red_backups[0]),s.red_backups[1]['now_weizhi'][0],s.red_backups[1]['now_weizhi'][1], x, y)):
|
||||||
|
s.hongqi[s.red_backups[0]] = s.red_backups[1]
|
||||||
|
s.hongqi[s.red_backups[0]]['now_weizhi'] = [x,y]
|
||||||
|
s.restract_num = 1
|
||||||
|
sendxy(client, s)
|
||||||
|
s.order = False
|
||||||
|
s.red_backups = []
|
||||||
|
s.running = True
|
||||||
|
|
||||||
|
|
||||||
|
def rival_chessman_move(client, s):
|
||||||
|
"""
|
||||||
|
对方棋子移动
|
||||||
|
"""
|
||||||
|
getxy(client, s)
|
||||||
|
|
||||||
|
#暂存对方选中的黑棋
|
||||||
|
if s.order == False and s.get == 1:
|
||||||
|
for key in s.lanqi.keys():
|
||||||
|
if s.srcx == s.lanqi[key]['now_weizhi'][0] and s.srcy == s.lanqi[key]['now_weizhi'][1]:
|
||||||
|
s.black_backups = [key, s.lanqi[key]]
|
||||||
|
print("get here")
|
||||||
|
if s.black_backups:
|
||||||
|
s.running = False
|
||||||
|
#更改黑棋位置
|
||||||
|
if s.black_backups and s.get == 1:
|
||||||
|
s.lanqi[s.black_backups[0]] = s.black_backups[1]
|
||||||
|
s.lanqi[s.black_backups[0]]['now_weizhi'] = [s.dstx, s.dsty]
|
||||||
|
|
||||||
|
#改为红棋落子
|
||||||
|
s.order = True
|
||||||
|
s.black_backups = []
|
||||||
|
#改为选子状态
|
||||||
|
s.running = True
|
After Width: | Height: | Size: 232 KiB |
@ -0,0 +1,5 @@
|
|||||||
|
SOCKET_HOST=127.0.0.1
|
||||||
|
SOCKET_PORT=50005
|
||||||
|
MAX_WAITING_TIME=450
|
||||||
|
MAX_THNIKING_TIME=30
|
||||||
|
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 = 2
|
||||||
|
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_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()
|
||||||
|
|