Pygame 做的中国象棋,一直以来喜欢下象棋,写了 python 就拿来做一个试试,水平有限,希望源码能帮助大家更好的学习 python。总共分为四个文件,chinachess.py 为主文件,constants.py 数据常量,pieces.py 棋子类,走法,computer.py 电脑走法计算。 源码:
chinachess.py 为主文件
import pygame
import time
import constants
import pieces
import computer
class MainGame():
window \= None
Start\_X \= constants.Start\_X
Start\_Y \= constants.Start\_Y
Line\_Span \= constants.Line\_Span
Max\_X \= Start\_X + 8 \* Line\_Span
Max\_Y \= Start\_Y + 9 \* Line\_Span
player1Color \= constants.player1Color
player2Color \= constants.player2Color
Putdownflag \= player1Color
piecesSelected \= None
button\_go \= None
piecesList \= \[\]
def start\_game(self):
MainGame.window \= pygame.display.set\_mode(\[constants.SCREEN\_WIDTH, constants.SCREEN\_HEIGHT\])
pygame.display.set\_caption("天青-中国象棋")
MainGame.button\_go \= Button(MainGame.window, "重新开始", constants.SCREEN\_WIDTH - 100, 300) # 创建开始按钮
self.piecesInit()
while True:
time.sleep(0.1)
# 获取事件
MainGame.window.fill(constants.BG\_COLOR)
self.drawChessboard()
#MainGame.button\_go.draw\_button()
self.piecesDisplay()
self.VictoryOrDefeat()
self.Computerplay()
self.getEvent()
pygame.display.update()
pygame.display.flip()
def drawChessboard(self):
mid\_end\_y \= MainGame.Start\_Y + 4 \* MainGame.Line\_Span
min\_start\_y \= MainGame.Start\_Y + 5 \* MainGame.Line\_Span
for i in range(0, 9):
x \= MainGame.Start\_X + i \* MainGame.Line\_Span
if i==0 or i ==8:
y \= MainGame.Start\_Y + i \* MainGame.Line\_Span
pygame.draw.line(MainGame.window, constants.BLACK, \[x, MainGame.Start\_Y\], \[x, MainGame.Max\_Y\], 1)
else:
pygame.draw.line(MainGame.window, constants.BLACK, \[x, MainGame.Start\_Y\], \[x, mid\_end\_y\], 1)
pygame.draw.line(MainGame.window, constants.BLACK, \[x, min\_start\_y\], \[x, MainGame.Max\_Y\], 1)
for i in range(0, 10):
x \= MainGame.Start\_X + i \* MainGame.Line\_Span
y \= MainGame.Start\_Y + i \* MainGame.Line\_Span
pygame.draw.line(MainGame.window, constants.BLACK, \[MainGame.Start\_X, y\], \[MainGame.Max\_X, y\], 1)
speed\_dial\_start\_x \= MainGame.Start\_X + 3 \* MainGame.Line\_Span
speed\_dial\_end\_x \= MainGame.Start\_X + 5 \* MainGame.Line\_Span
speed\_dial\_y1 \= MainGame.Start\_Y + 0 \* MainGame.Line\_Span
speed\_dial\_y2 \= MainGame.Start\_Y + 2 \* MainGame.Line\_Span
speed\_dial\_y3 \= MainGame.Start\_Y + 7 \* MainGame.Line\_Span
speed\_dial\_y4 \= MainGame.Start\_Y + 9 \* MainGame.Line\_Span
pygame.draw.line(MainGame.window, constants.BLACK, \[speed\_dial\_start\_x, speed\_dial\_y1\], \[speed\_dial\_end\_x, speed\_dial\_y2\], 1)
pygame.draw.line(MainGame.window, constants.BLACK, \[speed\_dial\_start\_x, speed\_dial\_y2\],
\[speed\_dial\_end\_x, speed\_dial\_y1\], 1)
pygame.draw.line(MainGame.window, constants.BLACK, \[speed\_dial\_start\_x, speed\_dial\_y3\],
\[speed\_dial\_end\_x, speed\_dial\_y4\], 1)
pygame.draw.line(MainGame.window, constants.BLACK, \[speed\_dial\_start\_x, speed\_dial\_y4\],
\[speed\_dial\_end\_x, speed\_dial\_y3\], 1)
def piecesInit(self):
MainGame.piecesList.append(pieces.Rooks(MainGame.player2Color, 0,0))
MainGame.piecesList.append(pieces.Rooks(MainGame.player2Color, 8, 0))
MainGame.piecesList.append(pieces.Elephants(MainGame.player2Color, 2, 0))
MainGame.piecesList.append(pieces.Elephants(MainGame.player2Color, 6, 0))
MainGame.piecesList.append(pieces.King(MainGame.player2Color, 4, 0))
MainGame.piecesList.append(pieces.Knighs(MainGame.player2Color, 1, 0))
MainGame.piecesList.append(pieces.Knighs(MainGame.player2Color, 7, 0))
MainGame.piecesList.append(pieces.Cannons(MainGame.player2Color, 1, 2))
MainGame.piecesList.append(pieces.Cannons(MainGame.player2Color, 7, 2))
MainGame.piecesList.append(pieces.Mandarins(MainGame.player2Color, 3, 0))
MainGame.piecesList.append(pieces.Mandarins(MainGame.player2Color, 5, 0))
MainGame.piecesList.append(pieces.Pawns(MainGame.player2Color, 0, 3))
MainGame.piecesList.append(pieces.Pawns(MainGame.player2Color, 2, 3))
MainGame.piecesList.append(pieces.Pawns(MainGame.player2Color, 4, 3))
MainGame.piecesList.append(pieces.Pawns(MainGame.player2Color, 6, 3))
MainGame.piecesList.append(pieces.Pawns(MainGame.player2Color, 8, 3))
MainGame.piecesList.append(pieces.Rooks(MainGame.player1Color, 0, 9))
MainGame.piecesList.append(pieces.Rooks(MainGame.player1Color, 8, 9))
MainGame.piecesList.append(pieces.Elephants(MainGame.player1Color, 2, 9))
MainGame.piecesList.append(pieces.Elephants(MainGame.player1Color, 6, 9))
MainGame.piecesList.append(pieces.King(MainGame.player1Color, 4, 9))
MainGame.piecesList.append(pieces.Knighs(MainGame.player1Color, 1, 9))
MainGame.piecesList.append(pieces.Knighs(MainGame.player1Color, 7, 9))
MainGame.piecesList.append(pieces.Cannons(MainGame.player1Color, 1, 7))
MainGame.piecesList.append(pieces.Cannons(MainGame.player1Color, 7, 7))
MainGame.piecesList.append(pieces.Mandarins(MainGame.player1Color, 3, 9))
MainGame.piecesList.append(pieces.Mandarins(MainGame.player1Color, 5, 9))
MainGame.piecesList.append(pieces.Pawns(MainGame.player1Color, 0, 6))
MainGame.piecesList.append(pieces.Pawns(MainGame.player1Color, 2, 6))
MainGame.piecesList.append(pieces.Pawns(MainGame.player1Color, 4, 6))
MainGame.piecesList.append(pieces.Pawns(MainGame.player1Color, 6, 6))
MainGame.piecesList.append(pieces.Pawns(MainGame.player1Color, 8, 6))
def piecesDisplay(self):
for item in MainGame.piecesList:
item.displaypieces(MainGame.window)
#MainGame.window.blit(item.image, item.rect)
def getEvent(self):
# 获取所有的事件
eventList \= pygame.event.get()
for event in eventList:
if event.type == pygame.QUIT:
self.endGame()
elif event.type == pygame.MOUSEBUTTONDOWN:
pos \= pygame.mouse.get\_pos()
mouse\_x \= pos\[0\]
mouse\_y \= pos\[1\]
if (
mouse\_x \> MainGame.Start\_X - MainGame.Line\_Span / 2 and mouse\_x < MainGame.Max\_X + MainGame.Line\_Span / 2) and (
mouse\_y \> MainGame.Start\_Y - MainGame.Line\_Span / 2 and mouse\_y < MainGame.Max\_Y + MainGame.Line\_Span / 2):
# print( str(mouse\_x) \+ "" + str(mouse\_y))
# print(str(MainGame.Putdownflag))
if MainGame.Putdownflag != MainGame.player1Color:
return
click\_x \= round((mouse\_x - MainGame.Start\_X) / MainGame.Line\_Span)
click\_y \= round((mouse\_y - MainGame.Start\_Y) / MainGame.Line\_Span)
click\_mod\_x \= (mouse\_x - MainGame.Start\_X) % MainGame.Line\_Span
click\_mod\_y \= (mouse\_y - MainGame.Start\_Y) % MainGame.Line\_Span
if abs(click\_mod\_x - MainGame.Line\_Span / 2) >= 5 and abs(
click\_mod\_y \- MainGame.Line\_Span / 2) >= 5:
# print("有效点:x="+str(click\_x)+" y="+str(click\_y))
# 有效点击点
self.PutdownPieces(MainGame.player1Color, click\_x, click\_y)
else:
print("out")
if MainGame.button\_go.is\_click():
#self.restart()
print("button\_go click")
else:
print("button\_go click out")
def PutdownPieces(self, t, x, y):
selectfilter\=list(filter(lambda cm: cm.x == x and cm.y == y and cm.player == MainGame.player1Color,MainGame.piecesList))
if len(selectfilter):
MainGame.piecesSelected \= selectfilter\[0\]
return
if MainGame.piecesSelected :
#print("1111")
arr \= pieces.listPiecestoArr(MainGame.piecesList)
if MainGame.piecesSelected.canmove(arr, x, y):
self.PiecesMove(MainGame.piecesSelected, x, y)
MainGame.Putdownflag \= MainGame.player2Color
else:
fi \= filter(lambda p: p.x == x and p.y == y, MainGame.piecesList)
listfi \= list(fi)
if len(listfi) != 0:
MainGame.piecesSelected \= listfi\[0\]
def PiecesMove(self,pieces, x , y):
for item in MainGame.piecesList:
if item.x ==x and item.y == y:
MainGame.piecesList.remove(item)
pieces.x \= x
pieces.y \= y
print("move to " +str(x) +" "+str(y))
return True
def Computerplay(self):
if MainGame.Putdownflag == MainGame.player2Color:
print("轮到电脑了")
computermove \= computer.getPlayInfo(MainGame.piecesList)
#if computer==None:
#return
piecemove \= None
for item in MainGame.piecesList:
if item.x == computermove\[0\] and item.y == computermove\[1\]:
piecemove\= item
self.PiecesMove(piecemove, computermove\[2\], computermove\[3\])
MainGame.Putdownflag \= MainGame.player1Color
#判断游戏胜利
def VictoryOrDefeat(self):
txt \=""
result \= \[MainGame.player1Color,MainGame.player2Color\]
for item in MainGame.piecesList:
if type(item) ==pieces.King:
if item.player == MainGame.player1Color:
result.remove(MainGame.player1Color)
if item.player == MainGame.player2Color:
result.remove(MainGame.player2Color)
if len(result)==0:
return
if result\[0\] == MainGame.player1Color :
txt \= "失败!"
else:
txt \= "胜利!"
MainGame.window.blit(self.getTextSuface("%s" % txt), (constants.SCREEN\_WIDTH - 100, 200))
MainGame.Putdownflag \= constants.overColor
def getTextSuface(self, text):
pygame.font.init()
# print(pygame.font.get\_fonts())
font \= pygame.font.SysFont('kaiti', 18)
txt \= font.render(text, True, constants.TEXT\_COLOR)
return txt
def endGame(self):
print("exit")
exit()
if \_\_name\_\_ == '\_\_main\_\_':
MainGame().start\_game()
constants.py 数据常量
import pygame
SCREEN\_WIDTH\=900
SCREEN\_HEIGHT\=650
Start\_X \= 50
Start\_Y \= 50
Line\_Span \= 60
player1Color \= 1
player2Color \= 2
overColor \= 3
BG\_COLOR\=pygame.Color(200, 200, 200)
Line\_COLOR\=pygame.Color(255, 255, 200)
TEXT\_COLOR\=pygame.Color(255, 0, 0)
# 定义颜色
BLACK \= ( 0, 0, 0)
WHITE \= (255, 255, 255)
RED \= (255, 0, 0)
GREEN \= ( 0, 255, 0)
BLUE \= ( 0, 0, 255)
repeat \= 0
pieces\_images \= {
'b\_rook': pygame.image.load("imgs/s2/b\_c.gif"),
'b\_elephant': pygame.image.load("imgs/s2/b\_x.gif"),
'b\_king': pygame.image.load("imgs/s2/b\_j.gif"),
'b\_knigh': pygame.image.load("imgs/s2/b\_m.gif"),
'b\_mandarin': pygame.image.load("imgs/s2/b\_s.gif"),
'b\_cannon': pygame.image.load("imgs/s2/b\_p.gif"),
'b\_pawn': pygame.image.load("imgs/s2/b\_z.gif"),
'r\_rook': pygame.image.load("imgs/s2/r\_c.gif"),
'r\_elephant': pygame.image.load("imgs/s2/r\_x.gif"),
'r\_king': pygame.image.load("imgs/s2/r\_j.gif"),
'r\_knigh': pygame.image.load("imgs/s2/r\_m.gif"),
'r\_mandarin': pygame.image.load("imgs/s2/r\_s.gif"),
'r\_cannon': pygame.image.load("imgs/s2/r\_p.gif"),
'r\_pawn': pygame.image.load("imgs/s2/r\_z.gif"),
}
pieces.py 棋子类,走法,
import pygame
import constants
class Pieces():
def \_\_init\_\_(self, player, x, y):
self.imagskey \= self.getImagekey()
self.image \= constants.pieces\_images\[self.imagskey\]
self.x \= x
self.y \= y
self.player \= player
self.rect \= self.image.get\_rect()
self.rect.left \= constants.Start\_X + x \* constants.Line\_Span - self.image.get\_rect().width / 2
self.rect.top \= constants.Start\_Y + y \* constants.Line\_Span - self.image.get\_rect().height / 2
def displaypieces(self,screen):
#print(str(self.rect.left))
self.rect.left \= constants.Start\_X + self.x \* constants.Line\_Span - self.image.get\_rect().width / 2
self.rect.top \= constants.Start\_Y + self.y \* constants.Line\_Span - self.image.get\_rect().height / 2
screen.blit(self.image,self.rect);
#self.image \= self.images
#MainGame.window.blit(self.image,self.rect)
def canmove(self, arr, moveto\_x, moveto\_y):
pass
def getImagekey(self):
return None
def getScoreWeight(self,listpieces):
return None
class Rooks(Pieces):
def \_\_init\_\_(self, player, x, y):
self.player \= player
super().\_\_init\_\_(player, x, y)
def getImagekey(self):
if self.player == constants.player1Color:
return "r\_rook"
else:
return "b\_rook"
def canmove(self, arr, moveto\_x, moveto\_y):
if self.x == moveto\_x and self.y == moveto\_y:
return False
if arr\[moveto\_x\]\[moveto\_y\] ==self.player :
return False
if self.x == moveto\_x:
step \= -1 if self.y > moveto\_y else 1
for i in range(self.y +step, moveto\_y, step):
if arr\[self.x\]\[i\] !=0 :
return False
#print(" move y")
return True
if self.y == moveto\_y:
step \= -1 if self.x > moveto\_x else 1
for i in range(self.x + step, moveto\_x, step):
if arr\[i\]\[self.y\] != 0:
return False
return True
def getScoreWeight(self, listpieces):
score \= 11
return score
class Knighs(Pieces):
def \_\_init\_\_(self, player, x, y):
self.player \= player
super().\_\_init\_\_(player, x, y)
def getImagekey(self):
if self.player == constants.player1Color:
return "r\_knigh"
else:
return "b\_knigh"
def canmove(self, arr, moveto\_x, moveto\_y):
if self.x == moveto\_x and self.y == moveto\_y:
return False
if arr\[moveto\_x\]\[moveto\_y\] == self.player:
return False
#print(str(self.x) +""+str(self.y))
move\_x \= moveto\_x-self.x
move\_y \= moveto\_y - self.y
if abs(move\_x) == 1 and abs(move\_y) == 2:
step \= 1 if move\_y > 0 else -1
if arr\[self.x\]\[self.y + step\] == 0:
return True
if abs(move\_x) == 2 and abs(move\_y) == 1:
step \= 1 if move\_x >0 else -1
if arr\[self.x +step\]\[self.y\] ==0 :
return True
def getScoreWeight(self, listpieces):
score \= 5
return score
class Elephants(Pieces):
def \_\_init\_\_(self, player, x, y):
self.player \= player
super().\_\_init\_\_(player, x, y)
def getImagekey(self):
if self.player == constants.player1Color:
return "r\_elephant"
else:
return "b\_elephant"
def canmove(self, arr, moveto\_x, moveto\_y):
if self.x == moveto\_x and self.y == moveto\_y:
return False
if arr\[moveto\_x\]\[moveto\_y\] == self.player:
return False
if self.y <=4 and moveto\_y >=5 or self.y >=5 and moveto\_y <=4:
return False
move\_x \= moveto\_x - self.x
move\_y \= moveto\_y - self.y
if abs(move\_x) == 2 and abs(move\_y) == 2:
step\_x \= 1 if move\_x > 0 else -1
step\_y \= 1 if move\_y > 0 else -1
if arr\[self.x + step\_x\]\[self.y + step\_y\] == 0:
return True
def getScoreWeight(self, listpieces):
score \= 2
return score
class Mandarins(Pieces):
def \_\_init\_\_(self, player, x, y):
self.player \= player
super().\_\_init\_\_(player, x, y)
def getImagekey(self):
if self.player == constants.player1Color:
return "r\_mandarin"
else:
return "b\_mandarin"
def canmove(self, arr, moveto\_x, moveto\_y):
if self.x == moveto\_x and self.y == moveto\_y:
return False
if arr\[moveto\_x\]\[moveto\_y\] == self.player:
return False
if moveto\_x <3 or moveto\_x >5:
return False
if moveto\_y > 2 and moveto\_y < 7:
return False
move\_x \= moveto\_x - self.x
move\_y \= moveto\_y - self.y
if abs(move\_x) == 1 and abs(move\_y) == 1:
return True
def getScoreWeight(self, listpieces):
score \= 2
return score
class King(Pieces):
def \_\_init\_\_(self, player, x, y):
self.player \= player
super().\_\_init\_\_(player, x, y)
def getImagekey(self):
if self.player == constants.player1Color:
return "r\_king"
else:
return "b\_king"
def canmove(self, arr, moveto\_x, moveto\_y):
if self.x == moveto\_x and self.y == moveto\_y:
return False
if arr\[moveto\_x\]\[moveto\_y\] == self.player:
return False
if moveto\_x < 3 or moveto\_x > 5:
return False
if moveto\_y > 2 and moveto\_y < 7:
return False
move\_x \= moveto\_x - self.x
move\_y \= moveto\_y - self.y
if abs(move\_x) + abs(move\_y) == 1:
return True
def getScoreWeight(self, listpieces):
score \= 150
return score
class Cannons(Pieces):
def \_\_init\_\_(self, player, x, y):
self.player \= player
super().\_\_init\_\_(player, x, y)
def getImagekey(self):
if self.player == constants.player1Color:
return "r\_cannon"
else:
return "b\_cannon"
def canmove(self, arr, moveto\_x, moveto\_y):
if self.x == moveto\_x and self.y == moveto\_y:
return False
if arr\[moveto\_x\]\[moveto\_y\] == self.player:
return False
overflag \= False
if self.x == moveto\_x:
step \= -1 if self.y > moveto\_y else 1
for i in range(self.y + step, moveto\_y, step):
if arr\[self.x\]\[i\] != 0:
if overflag:
return False
else:
overflag \= True
if overflag and arr\[moveto\_x\]\[moveto\_y\] == 0:
return False
if not overflag and arr\[self.x\]\[moveto\_y\] != 0:
return False
return True
if self.y == moveto\_y:
step \= -1 if self.x > moveto\_x else 1
for i in range(self.x + step, moveto\_x, step):
if arr\[i\]\[self.y\] != 0:
if overflag:
return False
else:
overflag \= True
if overflag and arr\[moveto\_x\]\[moveto\_y\] == 0:
return False
if not overflag and arr\[moveto\_x\]\[self.y\] != 0:
return False
return True
def getScoreWeight(self, listpieces):
score \= 6
return score
class Pawns(Pieces):
def \_\_init\_\_(self, player, x, y):
self.player \= player
super().\_\_init\_\_(player, x, y)
def getImagekey(self):
if self.player == constants.player1Color:
return "r\_pawn"
else:
return "b\_pawn"
def canmove(self, arr, moveto\_x, moveto\_y):
if self.x == moveto\_x and self.y == moveto\_y:
return False
if arr\[moveto\_x\]\[moveto\_y\] == self.player:
return False
move\_x \= moveto\_x - self.x
move\_y \= moveto\_y - self.y
if self.player == constants.player1Color:
if self.y > 4 and move\_x != 0 :
return False
if move\_y > 0:
return False
elif self.player \== constants.player2Color:
if self.y <= 4 and move\_x != 0 :
return False
if move\_y < 0:
return False
if abs(move\_x) + abs(move\_y) == 1:
return True
def getScoreWeight(self, listpieces):
score \= 2
return score
def listPiecestoArr(piecesList):
arr \= \[\[0 for i in range(10)\] for j in range(9)\]
for i in range(0, 9):
for j in range(0, 10):
if len(list(filter(lambda cm: cm.x == i and cm.y == j and cm.player == constants.player1Color,
piecesList))):
arr\[i\]\[j\] \= constants.player1Color
elif len(list(filter(lambda cm: cm.x \== i and cm.y == j and cm.player == constants.player2Color,
piecesList))):
arr\[i\]\[j\] \= constants.player2Color
return arr
computer.py 电脑走法计算
import constants
#import time
from pieces import listPiecestoArr
def getPlayInfo(listpieces):
pieces \= movedeep(listpieces ,1 ,constants.player2Color)
return \[pieces\[0\].x,pieces\[0\].y, pieces\[1\], pieces\[2\]\]
def movedeep(listpieces, deepstep, player):
arr \= listPiecestoArr(listpieces)
listMoveEnabel \= \[\]
for i in range(0, 9):
for j in range(0, 10):
for item in listpieces:
if item.player == player and item.canmove(arr, i, j):
#标记是否有子被吃 如果被吃 在下次循环时需要补会
piecesremove \= None
for itembefore in listpieces:
if itembefore.x == i and itembefore.y == j:
piecesremove\= itembefore
break
if piecesremove != None:
listpieces.remove(piecesremove)
#记录移动之前的位置
move\_x \= item.x
move\_y \= item.y
item.x \= i
item.y \= j
#print(str(move\_x) \+ "," + str(move\_y) + "," + str(item.x) + " , " + str(item.y))
scoreplayer1 \= 0
scoreplayer2 \= 0
for itemafter in listpieces:
if itemafter.player == constants.player1Color:
scoreplayer1 += itemafter.getScoreWeight(listpieces)
elif itemafter.player \== constants.player2Color:
scoreplayer2 += itemafter.getScoreWeight(listpieces)
#print("得分:"+item.imagskey +", "+str(len(moveAfterListpieces))+","+str(i)+","+str(j)+"," +str(scoreplayer1) +" , "+ str(scoreplayer2) )
#print(str(deepstep))
#如果得子 判断对面是否可以杀过来,如果又被杀,而且子力评分低,则不干
arrkill \= listPiecestoArr(listpieces)
if scoreplayer2 > scoreplayer1 :
for itemkill in listpieces:
if itemkill.player == constants.player1Color and itemkill.canmove(arrkill, i, j):
scoreplayer2\=scoreplayer1
if deepstep > 0 :
nextplayer \= constants.player1Color if player == constants.player2Color else constants.player2Color
nextpiecesbest\= movedeep(listpieces, deepstep -1, nextplayer)
listMoveEnabel.append(\[item, i, j, nextpiecesbest\[3\], nextpiecesbest\[4\], nextpiecesbest\[5\]\])
else:
#print(str(len(listpieces)))
#print("得分:" + item.imagskey + ", " + str(len(listpieces)) + "," + str(move\_x) + "," + str(move\_y) + "," + str(i) + " , " + str(j))
if player == constants.player2Color:
listMoveEnabel.append(\[item, i, j, scoreplayer1, scoreplayer2, scoreplayer1 \- scoreplayer2\])
else:
listMoveEnabel.append(\[item, i, j, scoreplayer1, scoreplayer2, scoreplayer2 \- scoreplayer1\])
#print("得分:"+str(scoreplayer1))
item.x \= move\_x
item.y \= move\_y
if piecesremove != None:
listpieces.append(piecesremove)
list\_scorepalyer1 \= sorted(listMoveEnabel, key=lambda tm: tm\[5\], reverse=True)
piecesbest \= list\_scorepalyer1\[0\]
if deepstep ==1 :
print(list\_scorepalyer1)
return piecesbest