Скачиваний:
5
Добавлен:
03.06.2024
Размер:
806.07 Кб
Скачать

6 Вывод

В результате выполнения курсовой работы успешно разработано приложение для игры в шашки на одном компьютере с использованием языка программирования Python и библиотек pygame, numpy, sys, os. Приложение предоставляет возможность играть в шашки, взаимодействуя с другим игроком на одном компьютере и используя графический интерфейс, созданный с применением библиотеки pygame.

В ходе работы были использованы технологии, способствующие удобству и эффективности разработки игрового приложения. Библиотека pygame обеспечила не только визуализацию игрового поля и фигур, но и обработку пользовательского ввода для комфортного управления шашками. Библиотека numpy использована для эффективной обработки логики игры и хранения состояния игрового поля.

Преимущества выбранных технологий включают в себя удобство работы с графикой, простоту обработки событий пользовательского ввода и эффективность в хранении данных игрового процесса.

Результаты работы демонстрируют практическую применимость приложения в контексте игры в шашки и предоставляют основу для дальнейшего совершенствования.

Список используемой литературы

URL адрес

Библиографическая ссылка

https://urait.ru/bcode/496893

Чернышев, С. А. Основы программирования на Python : учебное пособие для вузов / С. А. Чернышев. — Москва: Издательство Юрайт, 2022. — 286 с.

https://urait.ru/bcode/497029

Чернышев, С. А. Принципы, паттерны и методологии разработки программного обеспечения: учебное пособие для вузов / С. А. Чернышев. — Москва: Издательство Юрайт, 2022. — 176 с.

https://znanium.com/catalog/product/1011120

Технология разработки программного обеспечения: учеб. пособие / Л.Г. Гагарина, Е.В. Кокорева, Б.Д. Сидорова-Виснадул ; под ред. Л.Г. Гагариной. —Москва: ИД «ФОРУМ» : ИНФРА-М, 2019. — 400 с.

https://urait.ru/bcode/452137

Лаврищева, Е. М. Программная инженерия и технологии программирования сложных систем: учебник для вузов /Е. М. Лаврищева. — 2-е изд., испр. и доп. — Москва: Издательство Юрайт, 2020. — 432 с

https://e.lanbook.com/book/106533

Технология программирования: учебник / Г. С. Иванова. — 3-е изд. — Москва: МГТУ им. Н.Э. Баумана, 2006. — 336 с

Приложение а

import 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)

Соседние файлы в папке Килимник Курсовая