
Добавил:
useruser123
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз:
Предмет:
Файл:Килимник Курсовая / шашки
.pyimport pygame
import sys, os
from numpy import sign
# Задание ширины окна и числа рядов
WIDTH = 800
ROWS = 8
def resource_path(relative_path):
try:
base_path = sys._MEIPASS
except Exception:
base_path = os.path.abspath(".")
return os.path.join(base_path, relative_path)
icon = pygame.image.load(resource_path('checkers.ico'))
# Задание изображений шашек
BLACK= pygame.image.load(resource_path('black.png'))
WHITE= pygame.image.load(resource_path('white.png'))
BLACKKING = pygame.image.load(resource_path('blackKing.png'))
WHITEKING = pygame.image.load(resource_path('whiteKing.png'))
DEFAULT_IMAGE_SIZE = (100,100)
BLACK= pygame.transform.scale(BLACK, DEFAULT_IMAGE_SIZE)
WHITE= pygame.transform.scale(WHITE, DEFAULT_IMAGE_SIZE)
BLACKKING = pygame.transform.scale(BLACKKING, DEFAULT_IMAGE_SIZE)
WHITEKING = pygame.transform.scale(WHITEKING, DEFAULT_IMAGE_SIZE)
# Задание цветов
Colour_WHITE = (255,255,255)
Colour_BLACK = (105, 105, 105)
Colour_BLUE = (52, 152, 219)
Colour_GREEN = (46, 204, 113)
# Инициализация игры и создание окна
pygame.init()
WIN = pygame.display.set_mode((WIDTH,WIDTH))
pygame.display.set_icon(icon)
pygame.display.set_caption('Шашки')
move_sound = pygame.mixer.Sound(resource_path("push.mp3"))
eat_sound = pygame.mixer.Sound(resource_path("roll.mp3"))
# Класс клетка
class Node:
def __init__(self, row, col, width):
self.row = row
self.col = col
self.x = int(row * width)
self.y = int(col * width)
self.colour = Colour_WHITE
self.piece = None
# Отрисовка клетки
def draw(self, WIN):
pygame.draw.rect(WIN, self.colour, (self.x, self.y, WIDTH / ROWS, WIDTH / ROWS))
if self.piece:
WIN.blit(self.piece.image, (self.x, self.y))
# Обновление отображения
def update_display(win, grid, rows, width):
for row in grid:
for spot in row:
spot.draw(win)
draw_grid(win, rows, width)
pygame.display.update()
# Создание поля
def make_grid(rows, width):
grid = []
gap = width// rows
count = 0
for i in range(rows):
grid.append([])
for j in range(rows):
node = Node(j,i, gap)
if abs(i-j) % 2 == 0:
node.colour=Colour_BLACK
if (abs(i+j)%2==0) and (i<3):
node.piece = Piece('B')
elif(abs(i+j)%2==0) and i>4:
node.piece=Piece('W')
count+=1
grid[i].append(node)
return grid
# Отрисовка поля
def draw_grid(win, rows, width):
gap = width // ROWS
for i in range(rows):
pygame.draw.line(win, Colour_BLACK, (0, i * gap), (width, i * gap))
for j in range(rows):
pygame.draw.line(win, Colour_BLACK, (j * gap, 0), (j * gap, width))
# Класс шашка
class Piece:
def __init__(self, team):
self.team=team
self.image= BLACK if self.team=='B' else WHITE
self.type=None
# Отрисовка шашки
def draw(self, x, y):
WIN.blit(self.image, (x,y))
# Получение клетки
def getNode(grid, rows, width):
# Ширина клетки (ширину окна разделить на количество рядов)
gap = width//rows
# Получение координат клика мыши
RowX,RowY = pygame.mouse.get_pos()
# Вычисление ряда и столбца (Целочисленное деление координаты клика на ширину клетки)
Row = RowX//gap
Col = RowY//gap
return (Col,Row)
# Обновить цвета
def resetColours(grid, node):
positions = generatePotentialMoves(node, grid)
positions.append(node)
# Закрашивание клеток
for colouredNodes in positions:
nodeX, nodeY = colouredNodes
grid[nodeX][nodeY].colour = Colour_BLACK if abs(nodeX - nodeY) % 2 == 0 else Colour_WHITE
# Подсветка возможных ходов
def HighlightpotentialMoves(piecePosition, grid):
positions = generatePotentialMoves(piecePosition, grid)
for position in positions:
Column,Row = position
grid[Column][Row].colour=Colour_GREEN
# Определение команды противника
def opposite(team):
return "B" if team=="W" else "W"
# Генерация возможных ходов
def generatePotentialMoves(nodePosition, grid):
checker = lambda x,y: x+y>=0 and x+y<8
positions = []
column, row = nodePosition
if grid[column][row].piece:
# Задаём дальность хода для обычной шашки и для дамки
vector_range=2
if grid[column][row].piece.type=='KING':
vector_range=8
# Векторы для ударных ходов
vectors = [[1, -1], [1, 1],[-1, -1], [-1, 1]]
# Ударные ходы
for vector in vectors:
count_obstacle=0
columnVector, rowVector = vector
for i in range (1, vector_range):
# Проверка, что шашка не окажется за границами поля
if checker(columnVector*i,column) and checker(rowVector*i,row):
# Проверка, что на пути встречено 0 шашек
if count_obstacle==0:
# Проверка, что на векторе стоит шашка
if grid[column + columnVector*i][row+rowVector*i].piece:
count_obstacle+=1
# Проверка, что на векторе стоит вражеская шашка
if grid[column + columnVector*i][row+rowVector*i].piece.team==opposite(grid[column][row].piece.team):
# Проверка, что шашка не окажется за границами поля после ударного хода
if checker((columnVector*(i + 1)), column) and checker((rowVector*(i + 1)), row):
# Проверка, что за вражеской шашкой пусто
if not grid[(columnVector*(i + 1)) + column][(rowVector*(i + 1)) + row].piece:
# Занесение хода в массив
positions.append((columnVector*(i + 1) + column, rowVector*(i + 1) + row ))
# Если за шашкой есть еще одна мы прибавляем к счетчику встреченных шашек
elif grid[(columnVector*(i + 1)) + column][(rowVector*(i + 1)) + row].piece:
count_obstacle+=1
# Если на векторе стоит дружественная шашка, переходим на следующий вектор
else:
break
# Если уже встречена шашка и активная шашка - дамка, проверям ходы за встреченной шашкой
elif grid[column][row].piece.type=='KING' and count_obstacle==1:
# Проверка, что на векторе пусто
if not grid[column + columnVector*i][row+rowVector*i].piece:
positions.append((column + columnVector*i,row+rowVector*i))
elif grid[column + columnVector*i][row+rowVector*i].piece:
count_obstacle+=1
# Выход из функции если есть ударный ход
if len(positions)!=0:
return positions
# Тихие ходы
else:
# Присвоение векторов для тихого хода, если шашка не является дамкой
if not grid[column][row].piece.type=='KING':
vectors = [[1, -1], [1, 1]] if grid[column][row].piece.team == "B" else [[-1, -1], [-1, 1]]
for vector in vectors:
columnVector, rowVector = vector
for i in range (1, vector_range):
# Проверка, что шашка не окажется за границами поля
if checker(columnVector*i,column) and checker(rowVector*i,row):
# Проверка, что на месте хода нет шашки
if not grid[(column+columnVector*i)][(row+rowVector*i)].piece:
positions.append((column + columnVector*i, row + rowVector*i))
# Если на пути вектора встречается шашка, происходит переход на следующий вектор
else:
break
# Выход из функции
return positions
# Управление подсветкой
def highlight(ClickedNode, Grid, OldHighlight):
Column,Row = ClickedNode
Grid[Column][Row].colour=Colour_BLUE
if OldHighlight:
resetColours(Grid, OldHighlight)
HighlightpotentialMoves(ClickedNode, Grid)
return (Column,Row)
# Управление ходами
def move(grid, piecePosition, newPosition):
resetColours(grid, piecePosition)
newColumn, newRow = newPosition
oldColumn, oldRow = piecePosition
# Перемещение шашки
piece = grid[oldColumn][oldRow].piece
grid[newColumn][newRow].piece=piece
grid[oldColumn][oldRow].piece = None
# Обнуление превращения и статуса "съел"
transform=False
ate=False
# Превращение в дамку
if not grid[newColumn][newRow].piece.type=='KING':
if newColumn==7 and grid[newColumn][newRow].piece.team=='B':
grid[newColumn][newRow].piece.type='KING'
grid[newColumn][newRow].piece.image=BLACKKING
# Передача хода
transform=True
if newColumn==0 and grid[newColumn][newRow].piece.team=='W':
grid[newColumn][newRow].piece.type='KING'
grid[newColumn][newRow].piece.image=WHITEKING
# Передача хода
transform=True
# Ударный ход
if abs(newColumn-oldColumn)>=2 or abs(newRow-oldRow)>=2:
# Удаление съеденной шашки
for i,j in zip(range(abs(newColumn-oldColumn)),range(abs(newRow-oldRow))):
if grid[oldColumn+i*(sign(newColumn-oldColumn))][oldRow+j*sign(newRow-oldRow)].piece:
grid[oldColumn+i*(sign(newColumn-oldColumn))][oldRow+j*sign(newRow-oldRow)].piece = None
ate=True
# Запуск звука ударного хода
pygame.mixer.Sound.play(eat_sound)
break
# Передача хода если было превращение в дамку
if transform:
return opposite(grid[newColumn][newRow].piece.team)
# Дальность повторного хода для обычной шашки и для дамки
eat_limit=2
if grid[newColumn][newRow].piece.type=='KING':
eat_limit=7
# Проверка на возможность еще одного ударного хода
if ate:
for i in range(1, eat_limit):
# Проверка что на возможном пути есть вражеская шашка и за ней пусто
# В случае возможности еще одного ударного хода, ход не передается
try:
if ((0<=newColumn+i+1<=7 and 0<=newRow+i+1<=7) and grid[newColumn+i][newRow+i].piece and grid[newColumn+i][newRow+i].piece.team==opposite(grid[newColumn][newRow].piece.team) and grid[newColumn+i+1][newRow+i+1].piece == None):
return grid[newColumn][newRow].piece.team
except:
pass
try:
if ((0<=newColumn-i-1<=7 and 0<=newRow+i+1<=7) and grid[newColumn-i][newRow+i].piece and grid[newColumn-i][newRow+i].piece.team==opposite(grid[newColumn][newRow].piece.team) and grid[newColumn-i-1][newRow+i+1].piece == None):
return grid[newColumn][newRow].piece.team
except:
pass
try:
if ((0<=newColumn-i-1<=7 and 0<=newRow-i-1<=7) and grid[newColumn-i][newRow-i].piece and grid[newColumn-i][newRow-i].piece.team==opposite(grid[newColumn][newRow].piece.team) and grid[newColumn-i-1][newRow-i-1].piece == None):
return grid[newColumn][newRow].piece.team
except:
pass
try:
if ((0<=newColumn+i+1<=7 and 0<=newRow-i-1<=7) and grid[newColumn+i][newRow-i].piece and grid[newColumn+i][newRow-i].piece.team==opposite(grid[newColumn][newRow].piece.team) and grid[newColumn+i+1][newRow-i-1].piece == None):
return grid[newColumn][newRow].piece.team
except:
pass
# Передача хода
return opposite(grid[newColumn][newRow].piece.team)
def main(WIDTH, ROWS):
grid = make_grid(ROWS, WIDTH)
highlightedPiece = None
currMove = 'W'
while True:
if currMove=='W':
pygame.display.set_caption('Шашки Ход Белых')
else:
pygame.display.set_caption('Шашки Ход Чёрных')
for event in pygame.event.get():
if event.type== pygame.QUIT:
print('EXIT SUCCESSFUL')
pygame.quit()
sys.exit()
if event.type == pygame.MOUSEBUTTONDOWN:
clickedNode = getNode(grid, ROWS, WIDTH)
ClickedPositionColumn, ClickedPositionRow = clickedNode
if grid[ClickedPositionColumn][ClickedPositionRow].colour == Colour_GREEN:
if highlightedPiece:
pieceColumn, pieceRow = highlightedPiece
if currMove == grid[pieceColumn][pieceRow].piece.team:
resetColours(grid, highlightedPiece)
currMove=move(grid, highlightedPiece, clickedNode)
# Запуск звука перемещения
pygame.mixer.Sound.play(move_sound)
elif highlightedPiece == clickedNode:
pass
else:
if grid[ClickedPositionColumn][ClickedPositionRow].piece:
if currMove == grid[ClickedPositionColumn][ClickedPositionRow].piece.team:
highlightedPiece = highlight(clickedNode, grid, highlightedPiece)
update_display(WIN, grid,ROWS,WIDTH)
main(WIDTH, ROWS)