You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
SafariChess/SafariChess_Gamev1.0.py

388 lines
15 KiB

3 years ago
"""
Course: Programming practice
Students: Qu Qian /Tan Zhengyuan
"""
"""
Safafi Chess Game/SFF Chess Game
(Animal Chess Game)
Main code for run the game
it handle user input and GUI
"""
import colorsys
3 years ago
import json
3 years ago
import pygame as pg
import sys
3 years ago
import socket
3 years ago
import SafariChess_backend as backend
from SafariChess_Classes import Button
3 years ago
from threading import Thread, Lock
3 years ago
#设置棋盘的参数
WIDTH = 1000
HEIGHT = 800
BOARD_WIDTH = 800
BOARD_HEIGHT = 600
SCREEN_WIDTH = 800
SCREEN_HEIGHT = 600
3 years ago
MOVE_LOG_PANEL_WIDTH = 0
MOVE_LOG_PANEL_HEIGHT = BOARD_HEIGHT
DIMENSION = 8
DIMENSION_ROWS = 7
DIMENSION_COLUMNS = 9
SIZE = 64
IMAGES = {}
bias_top = 100 #棋盘的上边距
bias_left = 100 #棋盘的左边距
3 years ago
#multithreading?
3 years ago
def startNewThread(target):
thread = Thread(target=target)
thread.daemon = True
thread.start()
#网络版更新需要注意多线程的问题?
#尝试写一个函数分配一个新线程供监听
3 years ago
3 years ago
#等待敌人移动
def updateForEnemy(network: backend.Network,game_state: backend.GameState):
print("waiting for the other player to move...")
otherMove = game_state.dnldmv_server()
if otherMove is not None:
game_state.makeMove(otherMove)
3 years ago
def loadImages():#加载图片,a,b双方分别有象狮豹狼狐鹰鼠七个角色
pieces = ["r7", "r6", "r5", "r4", "r3", "r2", "r1",
"b7", "b6", "b5", "b4", "b3", "b2", "b1",
]
3 years ago
for piece in pieces:#字典的形式存储图片
3 years ago
IMAGES[piece] = pg.transform.scale(pg.image.load("./Image/pieces/pieces_rb/" + piece + ".png"), (SIZE - 10, SIZE - 10))
tools = ["trap", "home1","home2"]
3 years ago
for tool in tools:
IMAGES[tool] = pg.transform.scale(pg.image.load("./Image/tools/" + tool + ".jpg"), (SIZE-10, SIZE-10))
#screen = pg.display.set_mode((BOARD_WIDTH + MOVE_LOG_PANEL_WIDTH, BOARD_HEIGHT))#设置窗口大小
#screen.fill(pg.Color("white"))
3 years ago
3 years ago
def drawBoard(screen):#绘制棋盘:格子,河流,陷阱,巢穴
3 years ago
#colors = [(255, 255, 255), (0, 0, 0)]
3 years ago
for row in range(DIMENSION_ROWS):
for column in range(DIMENSION_COLUMNS):
pg.draw.rect(screen, pg.Color(199,237,204), pg.Rect(bias_left+column * SIZE, bias_top+row * SIZE, SIZE, SIZE))
pg.draw.rect(screen, pg.Color(90,150,75), pg.Rect((column * SIZE) + bias_left+3, (row * SIZE) + 3+bias_top, SIZE - 4, SIZE - 4))
#画河流
for row in [1,2,4,5]:
for column in [3,4,5]:
pg.draw.rect(screen, pg.Color(67,142,219),pg.Rect((column * SIZE) +bias_left+2, (row * SIZE) +bias_top +3, SIZE-2,SIZE-2))
#画陷阱
for row in [2,4]:
for column in [0,8]:
screen.blit(IMAGES["trap"], pg.Rect((column * SIZE) +bias_left+6, (row * SIZE) +bias_top +6, SIZE ,SIZE ))
for column in [1,7]:
screen.blit(IMAGES["trap"], pg.Rect((column * SIZE) +bias_left+6, (3 * SIZE) +bias_top +6, SIZE ,SIZE ))
#画巢穴
screen.blit(IMAGES["home1"], pg.Rect((bias_left+6, (3 * SIZE) +bias_top +6, SIZE ,SIZE )))
screen.blit(IMAGES["home2"], pg.Rect( 8*SIZE+bias_left+6, (3 * SIZE) +bias_top +6, SIZE ,SIZE ))
3 years ago
def drawPieces(screen,board):
#画棋子的位置
3 years ago
for row in range(DIMENSION_ROWS):
for column in range(DIMENSION_COLUMNS):
3 years ago
piece = board[row][column]
if piece != "00":
3 years ago
screen.blit(IMAGES[piece], pg.Rect((column * SIZE) + bias_left + 5, (row * SIZE) + bias_top + 5, SIZE - 10, SIZE - 10))
3 years ago
3 years ago
# square_selected 是当前选中的可以移动的棋子的位置
def protrudeSquares(screen,game_state,square_selected,valid_moves):
#高亮选中的棋子接下来可行的位置
if square_selected != ():
row = square_selected[0]
column = square_selected[1]
if game_state.board[row][column][0] == ('r' if game_state.red_to_move else 'b'):
# highlight selected square
s = pg.Surface((SIZE, SIZE))
s.set_alpha(100)
s.fill(pg.Color('blue'))
screen.blit(s, (column *SIZE + bias_left, row * SIZE + bias_top))
# highlight moves from that square
s.fill(pg.Color('yellow'))
for move in valid_moves:
if move.start_row == row and move.start_col == column:
screen.blit(s, (move.end_col * SIZE + bias_left, move.end_row * SIZE + bias_top))
3 years ago
def ShowGameState(screen,game_state,valid_moves,square_selected):#游戏状态
drawBoard(screen)
protrudeSquares(screen,game_state,square_selected,valid_moves)
drawPieces(screen,game_state.board)
3 years ago
3 years ago
#待开发
3 years ago
def drawMovelog(screen):#绘制移动日志
pass
def startGamePage(mode = 1):#开始游戏界面Human/AI
startpage = ('''
3 years ago
WELCOME TO
3 years ago
____ ____________ _____ _
/ __/ ___/ __ | / __ \ |
|__| |___| |__| | | / / |___ ___ ___ ___
\__ | ___| _ / | | | _ \/ _ \/ __/ __|
__| | | | | \ \ | \__/\ | | | __/\__ \__ |
|____/_| |_| \__| \_____/_| |_|\___||___/___/
3 years ago
################################################################
Please type one of the numbers below to choose a playing mode:
( 1 ) - 单机游戏
( 2 ) - 网络对战
( 3 ) - 人机对战
( 4 ) - 退出游戏
3 years ago
################################################################
Current Mode is: %s
'''%['单机游戏','网络对战','人机对战','退出游戏'][mode-1])
3 years ago
print(startpage)
# 选择游戏模式
3 years ago
not_selected = True
p1 , p2 = 0, 0
while not_selected:
try:
#mode = int(input())
#mode = 1
3 years ago
if mode in [1,2,3,4]:
if mode == 1:
p1 = 1
p2 = 1
##其余版本还未写
not_selected = False
else:
print("Please type one of the numbers below to choose a playing mode:")
print(" ( 1 ) - 单机游戏")
print(" ( 2 ) - 网络对战")
print(" ( 3 ) - 人机对战")
print(" ( 4 ) - 退出游戏")
3 years ago
except ValueError:
print("Wrong Input")
return p1, p2, mode
3 years ago
3 years ago
def showGameOverText(screen, text):
#游戏结束,出现的文字 text是字符串“Left Win”或“Right Win”
font = pg.font.SysFont("comicsansms", 32)
text_object = font.render(text, True, pg.Color("grey"))
3 years ago
text_location = pg.Rect(0, 0, BOARD_WIDTH, BOARD_HEIGHT).move(BOARD_WIDTH / 2 - text_object.get_width() / 2,
BOARD_HEIGHT / 2 - text_object.get_height() / 2)
screen.blit(text_object, text_location)
text_object = font.render(text, False, pg.Color('red'))
screen.blit(text_object, text_location.move(-2 , -2))
3 years ago
def MainMenu():
#显示主菜单
pg.init()
mainClock = pg.time.Clock()
#ui
3 years ago
screen = pg.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
pg.display.set_caption("SafariChess by ZY&&DQ")
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))
3 years ago
#按钮设置
#主菜单包含如下按钮:
#单机游戏,双人游戏,人机对战,退出游戏
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
3 years ago
3 years ago
3 years ago
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")
clock = pg.time.Clock()
screen.fill(pg.Color("white"))
loadImages()
3 years ago
drawBoard(screen)
3 years ago
isOnline = bool(network != None)
3 years ago
game_state=backend.GameState(isNet=isOnline,MySide=True if not isOnline else bool(NewPlayerMessage['side']),game_id=NewPlayerMessage['game_id'],client=network)
valid_moves=game_state.getAllMoves()
running = True
mademove = False
game_over = False
square_selected = ()#刚开始没有选择任何一个棋子
click_queue = []#点击队列,记录第一次点击和第二次点击位置,方便移动棋子
pg.display.update()
3 years ago
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
3 years ago
if mademove:
3 years ago
valid_moves = game_state.getAllMoves()
mademove = False
3 years ago
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:
3 years ago
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
3 years ago
if mademove:
3 years ago
valid_moves = game_state.getAllMoves()
#mademove = False
#* 网络对战局面更新
if network is not None:
startNewThread(updateForEnemy(network,game_state))
ShowGameState(screen,game_state,valid_moves,square_selected)
3 years ago
3 years ago
if game_state.conquer():
showGameOverText(screen,"player "+game_state.win_person+" wins")
game_over = True
clock.tick(60)
pg.display.flip()
3 years ago
if __name__ == '__main__':
print("Loading...")
print("Initialing game...")
mode = MainMenu()
3 years ago
player1='player1'
network = None #前后端通信接口
player2='player2'
main(mode,player1,player2,network)
3 years ago