first total function

master
tzzzzzzzx 2 years ago
parent 636deddbf1
commit 8deec0d443

8
.idea/.gitignore vendored

@ -0,0 +1,8 @@
# 默认忽略的文件
/shelf/
/workspace.xml
# 基于编辑器的 HTTP 客户端请求
/httpRequests/
# Datasource local storage ignored files
/dataSources/
/dataSources.local.xml

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="PYTHON_MODULE" version="4">
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$" />
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

@ -0,0 +1,6 @@
<component name="InspectionProjectProfileManager">
<settings>
<option name="USE_PROJECT_PROFILE" value="false" />
<version value="1.0" />
</settings>
</component>

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.9" project-jdk-type="Python SDK" />
</project>

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/SafariChess.iml" filepath="$PROJECT_DIR$/.idea/SafariChess.iml" />
</modules>
</component>
</project>

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>

@ -0,0 +1,294 @@
'''
Notice that we are using 2 unique moving functions for:
fox_moves and eagle_moves
varies on the two genres
'''
import random
from math import inf
import collections
piece_score = {"7": 120, "1": 100, "6": 120, "5": 80, "4": 60,"3": 70,"2": 100}
mouse_score = [[13, 13, 13, 13, 12, 11, 10, 9, 8],
[25, 20, 15, 13, 12, 12, 10, 9, 8],
[50, 25, 20, 12, 11, 11, 10, 9, 8],
[100000, 50, 20, 11, 9, 9, 9, 9, 0],
[50, 25, 20, 9, 8, 8, 8, 8, 8],
[25, 20, 15, 9, 8, 8, 8, 8, 8],
[11, 11, 10, 8, 8, 8, 8, 8, 8]]
# eagle_score = [[ 11, 12, 14, 13, 12, 11, 10, 8,
# 8],
# [ 15, 15, 14, 14, 0, 0, 0, 8,
# 8],
# [ 50, 20, 20, 0, 0, 0, 0, 8,
# 8],
# [100000, 50, 20, 13, 12, 11, 10, 8,
# 0],
# [ 50, 20, 20, 14, 0, 0, 0, 8,
# 8],
# [ 15, 12, 15, 14, 0, 0, 0, 8,
# 8],
# [ 11, 12, 14, 13, 12, 11, 10, 8,
# 8]]
eagle_score = [[14,13,10,12,14,13,10,8,7],
[15,15,14,0,0,0,9,8,6],
[50,20,20,0,0,0,7,5,4],
[100000,50,20,13,12,11,10,8,0],
[50,20,20,0,0,0,7,5,4],
[15,12,15,0,0,0,9,8,6],
[14,12,10,13,14,13,10,8,7]]
fox_score = [[ 11, 12, 14, 13, 12, 11, 10, 8,
8],
[ 15, 15, 14, 0, 0, 0, 10, 8,
8],
[ 50, 20, 20, 0, 0, 0, 10, 9,
10],
[100000, 50, 20, 13, 12, 11, 11, 10,
0],
[ 50, 20, 20, 0, 0, 0, 10, 9,
10],
[ 15, 12, 15, 0, 0, 0, 10, 8,
8],
[ 11, 12, 14, 13, 12, 11, 10, 8,
8]]
wolf_score = [[ 11, 12, 14, 13, 12, 11, 10, 8,
8],
[ 15, 15, 14, 0, 0, 0, 10, 8,
8],
[ 50, 20, 20, 0, 0, 0, 10, 9,
10],
[100000, 50, 20, 13, 12, 11, 11, 10,
0],
[ 50, 20, 20, 0, 0, 0, 10, 9,
10],
[ 15, 12, 15, 0, 0, 0, 10, 8,
8],
[ 11, 12, 14, 13, 12, 11, 10, 8,
8]]
leopard_score = [[ 11, 12, 14, 13, 12, 11, 10, 8,
8],
[ 15, 15, 14, 0, 0, 0, 10, 8,
8],
[ 50, 20, 20, 0, 0, 0, 10, 9,
10],
[100000, 50, 20, 13, 12, 11, 11, 10,
0],
[ 50, 20, 20, 0, 0, 0, 10, 9,
10],
[ 15, 12, 15, 0, 0, 0, 10, 8,
8],
[ 11, 12, 14, 13, 12, 11, 10, 8,
8]]
tiger_score = [[ 20, 20, 18, 15, 12, 11, 14, 12,
5],
[ 40, 25, 30, 0, 0, 0, 16, 12,
12],
[ 150, 40, 30, 0, 0, 0, 16, 12,
12],
[100000, 150, 20, 15, 15, 15, 9, 12,
0],
[ 150, 40, 30, 0, 0, 0, 16, 12,
12],
[ 40, 25, 30, 0, 0, 0, 16, 12,
12],
[ 20, 20, 18, 15, 12, 11, 14, 12,
5]]
# tiger_score is not used in the game...
lion_score = [[ 20, 20, 18, 15, 12, 11, 14, 12,
5],
[ 40, 25, 30, 0, 0, 0, 16, 12,
12],
[ 50, 40, 30, 0, 0, 0, 16, 12,
12],
[100000, 50, 20, 15, 15, 15, 9, 12,
0],
[ 50, 40, 30, 0, 0, 0, 16, 12,
12],
[ 40, 25, 30, 0, 0, 0, 16, 12,
12],
[ 20, 20, 18, 15, 12, 11, 14, 12,
5]]
elephant_score = [[ 20, 20, 18, 15, 12, 11, 14, 12,
5],
[ 40, 25, 30, 0, 0, 0, 16, 12,
12],
[ 50, 40, 30, 0, 0, 0, 16, 12,
12],
[100000, 50, 20, 15, 15, 15, 9, 12,
0],
[ 50, 40, 30, 0, 0, 0, 16, 12,
12],
[ 40, 25, 30, 0, 0, 0, 16, 12,
12],
[ 20, 20, 18, 15, 12, 11, 14, 12,
5]]
piece_position_scores = {"r1": mouse_score,
"b1": [line[::-1] for line in mouse_score[::-1]],
"r2": eagle_score,
"b2": [line[::-1] for line in eagle_score[::-1]],
"r3": fox_score,
"b3": [line[::-1] for line in fox_score[::-1]],
"r4": wolf_score,
"b4": [line[::-1] for line in wolf_score[::-1]],
"r5": leopard_score,
"b5": [line[::-1] for line in leopard_score[::-1]],
"r6": lion_score,
"b6": [line[::-1] for line in lion_score[::-1]],
"r7": elephant_score,
"b7": [line[::-1] for line in elephant_score[::-1]],
}
DEN_CONQUESTED=10000
DRAW=0
global DEPTH #=4
def findRandomMove(valid_moves):
return valid_moves[random.randint(0,len(valid_moves)-1)]
#is greedy_move function used here?
def find_GreadyMove(game_state, valid_moves):
turnMultiplier = 1 if game_state.red_to_move else -1
maxScore = -DEN_CONQUESTED
bestMove = None
for playerMove in valid_moves:
game_state.makeMove(playerMove)
score = turnMultiplier * scoreMaterial(game_state)
if score > maxScore:
maxScore = score
bestMove = playerMove
game_state.undoMove()
return bestMove
def scoreMaterial(game_state): # get the score
score = 0
penalty_for_rep = 0
for row in range(len(game_state.board)):
for col in range(len(game_state.board[row])):
piece = game_state.board[row][col]
if piece != "00":
piece_position_score = 0
piece_position_score = piece_position_scores[piece][row][col]
if piece_position_scores[piece][row][col] in last_moves:
penalty_for_rep += 70
if piece[0] == 'r':
score += piece_position_score + piece_score[piece[1]] - penalty_for_rep
elif piece[0] == 'b':
score -= piece_position_score + piece_score[piece[1]] - penalty_for_rep
return score
def findMove_NegaMaxAlphaBeta(game_state, valid_moves, depth,DEPTH, alpha, beta, turn_multiplier):
global next_move
if depth == 0:
return turn_multiplier * scoreMaterial(game_state)
max_score = -inf
for move in valid_moves:
game_state.makeMove(move)
next_moves = game_state.getAllMoves()
score = -findMove_NegaMaxAlphaBeta(game_state, next_moves, depth - 1,DEPTH, -beta, -alpha, -turn_multiplier)
if score > max_score: # > or >= ??
max_score = score
if depth == DEPTH:
next_move = move
game_state.undoMove()
if max_score > alpha:
alpha = max_score
if alpha >= beta:
break
return max_score
def findMove_MiniMaxAlphaBeta(game_state, valid_moves, depth, alpha, beta, turn_multiplier):
global next_move
def max_value(game_state,next_moves, alpha, beta,depth):
if depth == 0:
return turn_multiplier * scoreMaterial(game_state)
v = -inf
for move in valid_moves:
next_moves = game_state.getAllMoves()
v = max(v, min_value(game_state,next_moves, alpha, beta,depth - 1))
game_state.undoMove()
if v >= beta:
return v
alpha = max(alpha, v)
return v
def min_value(game_state,next_moves, alpha, beta,depth):
if depth == 0:
return turn_multiplier * scoreMaterial(game_state)
v = -inf
for move in valid_moves:
next_moves = game_state.getAllMoves()
v = min(v, max_value(game_state,next_moves, alpha, beta,depth - 1))
game_state.undoMove()
if v <= alpha:
return v
beta = min(beta, v)
return v
# Body of alpha_beta_search:
best_score = -inf
beta = inf
best_action = None
for move in valid_moves:
v = min_value(game_state,valid_moves, best_score, beta,depth)
if v > best_score:
best_score = v
best_action = move
return best_action
def find_BestMove(game_state, valid_moves,depth_p):
global next_move
DEPTH= depth_p
next_move = None
global last_moves
last_moves = collections.deque(maxlen=12)
random.shuffle(valid_moves)
ordered_valid_moves=orderby_GreadyMove(game_state, valid_moves)
# for i in valid_moves:
# print(f"Possible: {i}")
# for i in ordered_valid_moves:
# print(f"New possible: {i}")
findMove_NegaMaxAlphaBeta(game_state, ordered_valid_moves,depth_p,DEPTH, -DEN_CONQUESTED, DEN_CONQUESTED,1 if game_state.red_to_move else -1)
last_moves.append(next_move)
return next_move
def orderby_GreadyMove(game_state, valid_moves):
turnMultiplier = 1 if game_state.red_to_move else -1
maxScore = -DEN_CONQUESTED
de = collections.deque([])
for playerMove in valid_moves:
game_state.makeMove(playerMove)
score = turnMultiplier * scoreMaterial(game_state)
if score > maxScore:
maxScore = score
de.appendleft(playerMove)
else:
de.append(playerMove)
game_state.undoMove()
return de

@ -16,10 +16,12 @@ import pygame as pg
import sys import sys
import socket import socket
import SafariChess_backend as backend import SafariChess_backend as backend
import SafariChess_AI as AI
from SafariChess_Classes import Button, DropDown from SafariChess_Classes import Button, DropDown
from threading import Thread, Lock from threading import Thread, Lock
from itertools import count, cycle from itertools import count, cycle
import time import time
import random
#设置棋盘的参数 #设置棋盘的参数
WIDTH = 1000 WIDTH = 1000
@ -38,12 +40,14 @@ IMAGES = {}
bias_top = 100 #棋盘的上边距 bias_top = 100 #棋盘的上边距
bias_left = 20 #棋盘的左边距 bias_left = 20 #棋盘的左边距
#网络道具 #网络道具
general_countdown = 10
client = None client = None
networkMsg = None networkMsg = None
server = None server = None
port = None port = None
addr = None addr = None
connection = None connection = None
DEPTH = 3
#网络版更新需要注意多线程的问题? #网络版更新需要注意多线程的问题?
server_died_message = 'fucking server died and quit' server_died_message = 'fucking server died and quit'
#尝试写一个函数分配一个新线程供监听 #尝试写一个函数分配一个新线程供监听
@ -66,7 +70,7 @@ def listenFromServer():
def startNetworkServices(): def startNetworkServices():
global client,server,port,addr,connection global client,server,port,addr,connection
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM) client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server = '192.168.64.246' server = '192.168.43.183'
port = 50005 port = 50005
addr = (server,port) addr = (server,port)
connection = client.connect(addr) connection = client.connect(addr)
@ -172,10 +176,10 @@ Please type one of the numbers below to choose a playing mode:
( 1 ) - 单机游戏 ( 1 ) - 单机游戏
( 2 ) - 网络对战 ( 2 ) - 网络对战
( 3 ) - 人机对战 ( 3 ) - 人机对战
( 4 ) - 退出游戏 ( 4 ) - AI代打
################################################################ ################################################################
Current Mode is: %s Current Mode is: %s
'''%['单机游戏','网络对战','人机对战','退出游戏'][mode-1]) '''%['单机游戏','网络对战','人机对战','AI代打'][mode-1])
print(startpage) print(startpage)
# 选择游戏模式 # 选择游戏模式
not_selected = True not_selected = True
@ -341,7 +345,7 @@ def main(mode):
screen.fill(pg.Color("white")) screen.fill(pg.Color("white"))
loadImages() loadImages()
drawBoard(screen) drawBoard(screen)
isOnline = bool(mode == 2) isOnline = bool(mode == 2 or mode == 4)
game_state=backend.GameState() game_state=backend.GameState()
#* cancelled args: MySide=True if not isOnline else bool(NewPlayerMessage['side']),game_id=NewPlayerMessage['game_id'] #* 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()
@ -361,7 +365,10 @@ def main(mode):
screen.blit(button_music.image, button_music.rect) screen.blit(button_music.image, button_music.rect)
pg.display.update() pg.display.update()
startGamePage(mode) #游戏进入前,可以进一步优化一些显示细节 startGamePage(mode) #游戏进入前,可以进一步优化一些显示细节
if mode == 1: if mode == 1 or mode == 3:
if mode == 3:
AI_side = random.randint(0,1)
print('AI side:{}'.format('b' if AI_side == 1 else 'r'))
while running: while running:
for e in pg.event.get(): for e in pg.event.get():
#接下来处理游戏中的事件 #接下来处理游戏中的事件
@ -390,17 +397,41 @@ def main(mode):
mademove = True mademove = True
square_selected = () square_selected = ()
click_queue = [] click_queue = []
valid_moves = game_state.getAllMoves()
else: else:
click_queue = [square_selected] click_queue = [square_selected]
elif e.type == pg.KEYDOWN: elif e.type == pg.KEYDOWN:
#设置某些按键用于悔棋,重新开始游戏,机器提示,退出游戏等功能 #设置某些按键用于悔棋,重新开始游戏,机器提示,退出游戏等功能
pass if e.key == pg.K_z: # undo when 'z' is pressed
game_state.undoMove()
mademove = True
game_over = False
if mademove: if mademove:
valid_moves = game_state.getAllMoves() valid_moves = game_state.getAllMoves()
mademove = False mademove = False
if not game_over and mode == 3:
if AI_side == 1 and not game_state.red_to_move:
ai_move = AI.find_BestMove(game_state,valid_moves,DEPTH)
if ai_move is not None:
game_state.makeMove(ai_move)
mademove = True
else:
ai_move = AI.find_GreadyMove(game_state,valid_moves)
game_state.makeMove(ai_move)
mademove = True
elif AI_side == 0 and game_state.red_to_move:
ai_move = AI.find_BestMove(game_state,valid_moves,DEPTH)
if ai_move is not None:
game_state.makeMove(ai_move)
mademove = True
else:
ai_move = AI.find_GreadyMove(game_state,valid_moves)
game_state.makeMove(ai_move)
mademove = True
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")
@ -408,8 +439,8 @@ def main(mode):
clock.tick(60) clock.tick(60)
pg.display.flip() pg.display.flip()
elif mode == 2: elif mode == 2 or mode == 4:
counts=20 #双方倒计时 counts=general_countdown #双方倒计时
startNetworkServices() startNetworkServices()
#! start login #! start login
myPlayerData = { myPlayerData = {
@ -510,12 +541,39 @@ def main(mode):
#Move handler #Move handler
elif 'src' and 'dst' in networkMsg.keys(): elif 'src' and 'dst' in networkMsg.keys():
theMove = backend.Move([networkMsg['src']['y'],networkMsg['src']['x']],[networkMsg['dst']['y'],networkMsg['dst']['x']],game_state.board) theMove = backend.Move([networkMsg['src']['y'],networkMsg['src']['x']],[networkMsg['dst']['y'],networkMsg['dst']['x']],game_state.board)
violate_175 = game_state.seventeen_five_violation(goal=theMove.get_goal(),color=theMove.get_turn(), showTrace= True)
violate_73 = game_state.seventy_three_violation(goal=theMove.get_goal(), color = theMove.get_turn(), showTrace= True)
if not type(violate_175) == bool:
print("player {} foul 17-5".format(theMove.get_turn()))
print("Recent 17 Move: {}".format(violate_175))
reportJson = {
"type": 2,
"msg": {
"request": "report",
"game_id": game_id,
"side": MySide
}
}
client.send(json.dumps(reportJson).encode('utf-8'))
if not type(violate_73) == bool:
print("player {} foul 7-3".format(theMove.get_turn()))
print("Recent 7 Move: {}".format(violate_73))
reportJson = {
"type": 2,
"msg": {
"request": "report",
"game_id": game_id,
"side": MySide
}
}
client.send(json.dumps(reportJson).encode('utf-8'))
game_state.makeMove(theMove) game_state.makeMove(theMove)
valid_moves = game_state.getAllMoves() valid_moves = game_state.getAllMoves()
other_stage = not other_stage other_stage = not other_stage
counts=20 counts=general_countdown
thisMove = None thisMove = None
for e in pg.event.get(): for e in pg.event.get():
#接下来处理游戏中的事件 #接下来处理游戏中的事件
if e.type == pg.QUIT: if e.type == pg.QUIT:
@ -619,14 +677,35 @@ def main(mode):
if not game_over and mode == 4:
#! 特别注意红方是0蓝方是1
if MySide == 1 and not game_state.red_to_move:
thisMove = AI.find_BestMove(game_state,valid_moves,DEPTH)
if thisMove is not None:
game_state.makeMove(thisMove)
mademove = True
else:
thisMove = AI.find_GreadyMove(game_state,valid_moves)
game_state.makeMove(thisMove)
mademove = True
elif MySide == 0 and game_state.red_to_move:
thisMove = AI.find_BestMove(game_state,valid_moves,DEPTH)
if thisMove is not None:
game_state.makeMove(thisMove)
mademove = True
else:
thisMove = AI.find_GreadyMove(game_state,valid_moves)
game_state.makeMove(thisMove)
mademove = True
square_selected = ()
click_queue = []
if mademove: if mademove:
#print(thisMove)
valid_moves = game_state.getAllMoves() valid_moves = game_state.getAllMoves()
mademove = False mademove = False
if isOnline: if isOnline:
print('waiting for the other player to move...') print('waiting for the other player to move...')
other_stage = not other_stage other_stage = not other_stage
thisMoveJson = { thisMoveJson = {
'type': 1, 'type': 1,
@ -678,11 +757,13 @@ def main(mode):
clock.tick(50) clock.tick(50)
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()
#mode = 2 #mode = 4
main(mode) main(mode)

@ -22,113 +22,24 @@ class Move:
if isinstance(__o, Move): if isinstance(__o, Move):
return self.moveID == __o.moveID return self.moveID == __o.moveID
return False return False
def __str__(self):
return f"{self.start_row=},"+f"{self.start_col=},"+f"{self.end_row=},"+f"{self.end_col=}"
def get_goal(self):
return (self.end_row, self.end_col)
def get_start(self):
return (self.start_row, self.start_col)
def get_goal_chess_comb(self):
return (self.end_row, self.end_col, self.cur_piece)
def get_turn(self):
return self.cur_piece[0]
def get_piece(self):
return self.cur_piece
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:
# 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
# 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')
# 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): #写成持续监听模式
# try:
# while True:
# recvMsg = self.client.recv(2048).decode('utf-8')
# if len(recvMsg) != 0:
# msg_from_serv = json.loads(recvMsg)
# self.dataDealer(msg_from_serv)
# except socket.error as e:
# print(e)
# return e
# 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: class GameState:
def __init__(self): def __init__(self):
@ -172,12 +83,89 @@ class GameState:
self.win_person='' self.win_person=''
self.MASSACRE=False self.MASSACRE=False
self.isStarted = False self.isStarted = False
self.move_log = []
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 seventy_three_violation(self, goal, color, showTrace = False):
#输入goal为三元组(格坐标x格坐标y棋子)
# color为颜色
# showTrace为是否查看轨迹
past7Moves = []
#寻找该动物的移动轨迹
for i in range(len(self.move_log)-1, -1, -1):
if self.move_log[i].get_turn() == color:
past7Moves.append(self.move_log[i])
if len(past7Moves) > 7:
break
# print("past7Moves= ",[move.get_goal_chess_comb() for move in past7Moves])
if len(past7Moves) > 7:
past7Moves = past7Moves[-7:]
visit_counts = dict()
for move in past7Moves:
if move.get_goal() in (self.blue_trap_loc + self.red_trap_loc):
return True
try:
visit_counts[move.get_goal_chess_comb()] += 1
except KeyError:
visit_counts[move.get_goal_chess_comb()] = 1
try:
if visit_counts[goal] >= 3:
if showTrace:
return goal
else:
return False
else:
return True
except:
return True
def seventeen_five_violation(self, goal, color, showTrace = False):
# 输入goal为三元组(格坐标x格坐标y棋子)
# color为颜色
# showTrace为是否查看轨迹
#获取近17步操作
past17Moves = []
for i in range(len(self.move_log) - 1, -1, -1):
if self.move_log[i].get_turn() == color:
past17Moves.append(self.move_log[i])
if len(past17Moves) > 17:
break
if len(past17Moves) >= 17:
past17Moves = past17Moves[-17:]
else:
return True
#判断是否为同一棋子的移动
piece = past17Moves[0].get_piece()
for i in range(len(past17Moves)):
if past17Moves[i].get_piece() != piece:
return True
#当为同一棋子时……
visit_locs = []
for move in past17Moves:
if move.get_goal() in (self.blue_trap_loc + self.red_trap_loc):
return True
try:
visit_locs.append(move.get_goal())
except KeyError:
visit_locs.append(move.get_goal())
try:
if showTrace and len(visit_locs) <= 5:
if goal in visit_locs:
return (goal,visit_locs)
else:
return True
elif len(visit_locs)<=5:
if goal in visit_locs:
return False
else:
return True
except:
return True
# 判断特殊位置 # 判断特殊位置
def inHome(self,row,col,color): def inHome(self,row,col,color):
if color=="b": if color=="b":
@ -223,7 +211,13 @@ class GameState:
if (player == 'r' and self.red_to_move or player == 'b' and not self.red_to_move): if (player == 'r' and self.red_to_move or player == 'b' and not self.red_to_move):
#print('what color is the valid move? ',player) #print('what color is the valid move? ',player)
self.moveFunctions[self.board[row][col][1]](row,col,moves) self.moveFunctions[self.board[row][col][1]](row,col,moves)
return moves valid_moves = []
for move in moves: # 己方躲避17-5和7-3
if self.seventy_three_violation(goal=move.get_goal_chess_comb(), color=self.color()) and self.seventeen_five_violation(goal=move.get_goal_chess_comb(), color=self.color()):
valid_moves.append(move)
if len(valid_moves) == 0:
print('warning: no available moves at side {}'.format('b' if not self.red_to_move else 'r'))
return valid_moves
def getStdMoves(self,row,col,moves):#输入当前的位置将可行路径输出给moves def getStdMoves(self,row,col,moves):#输入当前的位置将可行路径输出给moves
@ -267,7 +261,7 @@ class GameState:
if nxt_piece == '00' and not self.inTrap(new_row,col,enemy_color) and not self.inTrap(new_row,col,'r' if enemy_color == 'b' else 'b'): if nxt_piece == '00' and not self.inTrap(new_row,col,enemy_color) and not self.inTrap(new_row,col,'r' if enemy_color == 'b' else 'b'):
if not self.inHome(new_row,col,self.color()) and not self.inWater(new_row,col): moves.append(Move((row,col),(new_row,col),self.board)) if not self.inHome(new_row,col,self.color()) and not self.inWater(new_row,col): moves.append(Move((row,col),(new_row,col),self.board))
else: else:
if self.Eliminate(row,col,new_row,col): moves.append(Move((row,col),(new_row,col),self.board)) if self.Eliminate(row,col,new_row,col) and not self.inWater(new_row,col): moves.append(Move((row,col),(new_row,col),self.board))
if new_row != row: break if new_row != row: break
new_row -= 1 new_row -= 1
new_row = row new_row = row
@ -276,7 +270,7 @@ class GameState:
if nxt_piece == '00' and not self.inTrap(new_row,new_col,enemy_color) and not self.inTrap(new_row,col,'r' if enemy_color == 'b' else 'b'): if nxt_piece == '00' and not self.inTrap(new_row,new_col,enemy_color) and not self.inTrap(new_row,col,'r' if enemy_color == 'b' else 'b'):
if not self.inHome(new_row,col,self.color()) and not self.inWater(new_row,col): moves.append(Move((row,col),(new_row,col),self.board)) if not self.inHome(new_row,col,self.color()) and not self.inWater(new_row,col): moves.append(Move((row,col),(new_row,col),self.board))
else: else:
if self.Eliminate(row,col,new_row,col): moves.append(Move((row,col),(new_row,col),self.board)) if self.Eliminate(row,col,new_row,col) and not self.inWater(new_row,col): moves.append(Move((row,col),(new_row,col),self.board))
if new_row != row: break if new_row != row: break
new_row += 1 new_row += 1
#L&R Direction #L&R Direction
@ -285,7 +279,7 @@ class GameState:
if nxt_piece == '00' and not self.inTrap(row,new_col,enemy_color) and not self.inTrap(new_row,col,'r' if enemy_color == 'b' else 'b'): if nxt_piece == '00' and not self.inTrap(row,new_col,enemy_color) and not self.inTrap(new_row,col,'r' if enemy_color == 'b' else 'b'):
if not self.inHome(row,new_col,self.color()) and not self.inWater(row,new_col): moves.append(Move((row,col),(row,new_col),self.board)) if not self.inHome(row,new_col,self.color()) and not self.inWater(row,new_col): moves.append(Move((row,col),(row,new_col),self.board))
else: else:
if self.Eliminate(row,col,row,new_col): moves.append(Move((row,col),(row,new_col),self.board)) if self.Eliminate(row,col,row,new_col) and not self.inWater(row,new_col): moves.append(Move((row,col),(row,new_col),self.board))
if new_col != col: break if new_col != col: break
new_col -= 1 new_col -= 1
new_col = col new_col = col
@ -294,7 +288,7 @@ class GameState:
if nxt_piece == '00' and not self.inTrap(row,new_col,enemy_color) and not self.inTrap(new_row,col,'r' if enemy_color == 'b' else 'b'): if nxt_piece == '00' and not self.inTrap(row,new_col,enemy_color) and not self.inTrap(new_row,col,'r' if enemy_color == 'b' else 'b'):
if not self.inHome(row,new_col,self.color()) and not self.inWater(row,new_col): moves.append(Move((row,col),(row,new_col),self.board)) if not self.inHome(row,new_col,self.color()) and not self.inWater(row,new_col): moves.append(Move((row,col),(row,new_col),self.board))
else: else:
if self.Eliminate(row,col,row,new_col): moves.append(Move((row,col),(row,new_col),self.board)) if self.Eliminate(row,col,row,new_col) and not self.inWater(row,new_col): moves.append(Move((row,col),(row,new_col),self.board))
if new_col != col: break if new_col != col: break
new_col += 1 new_col += 1
return moves return moves
@ -386,6 +380,16 @@ class GameState:
self.board[move.end_row][move.end_col] = self.board[move.start_row][move.start_col] 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.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
self.move_log.append(move)
#由于使用多线程考虑让另一个线程去更新red_to_move #由于使用多线程考虑让另一个线程去更新red_to_move
def undoMove(self):
if len(self.move_log) != 0:
move = self.move_log.pop()
self.board[move.start_row][move.start_col] = move.cur_piece
self.board[move.end_row][move.end_col] = move.nxt_piece
if move.nxt_piece != '00' and move.nxt_piece not in (self.blue_pieces if move.nxt_piece[0]=='b' else self.red_pieces):
(self.blue_pieces if move.nxt_piece[0]=='b' else self.red_pieces).append(int(move.nxt_piece[1]))
self.red_to_move = not self.red_to_move

@ -1,5 +1,5 @@
SOCKET_HOST=127.0.0.1 SOCKET_HOST=192.168.43.183
SOCKET_PORT=50005 SOCKET_PORT=50005
MAX_WAITING_TIME=600 MAX_WAITING_TIME=600
MAX_THNIKING_TIME=200 MAX_THNIKING_TIME=10
MAX_TOTAL_TIME=1000 MAX_TOTAL_TIME=1000

Loading…
Cancel
Save