Код этой статьи основан на python3.6 и pygame1.9.4.
Gobang намного сложнее, чем игры, которые я писал раньше. Если это битва между людьми, то компьютеру нужно только решить, победить или нет. Если это битва человека с машиной, то вы должны сообщить компьютеру, как играть.
Начнем с простых вопросов.
начало
рисовать шахматную доску
Первое, что нужно сделать, это нарисовать шахматную доску, используяpygameНарисовать шахматную доску 19×19 или 15×15 несложно, и она неоднократно использовалась в предыдущих статьях, поэтому повторяться не буду.
рисовать шахматные фигуры
Что нужно сказать, так это рисовать шахматные фигуры, потому что я не нашел подходящей картинки шахматных фигур, поэтому мне нужно просто рисовать шахматные фигуры самостоятельно.
мы используемpygame.draw.circle
Нарисованный круг выглядит так:
pygame.draw
Есть функция рисования сглаженных линийaaline
, но нетaacircle
Такая функция для рисования сглаженного круга.
Здесь нужно использоватьpygame.gfxdraw
Ла.pygame.gfxdraw
Пока это только экспериментальная версия, а это значит, что этоAPIможет быть позжеpygameизменяется или исчезает в версии.
Чтобы нарисовать фигуры со сглаживанием и заливкой, сначала используйте версию функции aa*, а затем версию с заливкой. Например:
col = (255, 0, 0)
surf.fill((255, 255, 255))
pygame.gfxdraw.aacircle(surf, x, y, 30, col)
pygame.gfxdraw.filled_circle(surf, x, y, 30, col)
Попробуем этим методом нарисовать фигуру на шахматной доске.
Видно, что эффект значительно улучшился.падать
Ход должен судить о событии мыши.При нажатии левой кнопки мыши определяется положение щелчка мыши, а затем в соответствии с положением шахматной доски рассчитывается положение, в котором шахматная фигура падает на шахматную доску. .
while True:
for event in pygame.event.get():
if event.type == QUIT:
sys.exit()
elif event.type == MOUSEBUTTONDOWN:
pressed_array = pygame.mouse.get_pressed()
if pressed_array[0]: # 鼠标左键点击
mouse_pos = pygame.mouse.get_pos()
click_point = _get_clickpoint(mouse_pos)
Победа
Когда сын падает, как судить, победа ли это?
Несомненно то, что когда определенная фигура падает, если есть 5-соединение, то выпавшая фигура должна быть на 5-соединенной линии. Тогда эту задачу можно упростить: нам не нужно сканировать всю доску, нам просто нужно сканировать ее по горизонтали и вертикали в позиции размещения, чтобы определить, есть ли 5 последовательных.
Мы определяем класс шахматной доски, в котором создается двумерный массив 19 × 19. Начальное значение равно 0, что означает пусто, 1 означает черную фигуру, а 2 означает белую фигуру. Этот класс предоставляет метод drop для внешнего мира.drop
, получает параметры квадрата хода и координаты хода, если ход выигрывает, возвращает победителя, иначе возвращает None.
Chessman = namedtuple('Chessman', 'Name Value Color')
Point = namedtuple('Point', 'X Y')
BLACK_CHESSMAN = Chessman('黑子', 1, (45, 45, 45))
WHITE_CHESSMAN = Chessman('白子', 2, (219, 219, 219))
offset = [(1, 0), (0, 1), (1, 1), (1, -1)]
class Checkerboard:
def __init__(self, line_points):
self._line_points = line_points
self._checkerboard = [[0] * line_points for _ in range(line_points)]
def _get_checkerboard(self):
return self._checkerboard
checkerboard = property(_get_checkerboard)
# 判断是否可落子
def can_drop(self, point):
return self._checkerboard[point.Y][point.X] == 0
def drop(self, chessman, point):
"""
落子
:param chessman: 黑子/白子
:param point:落子位置
:return:若该子落下之后即可获胜,则返回获胜方,否则返回 None
"""
print(f'{chessman.Name} ({point.X}, {point.Y})')
self._checkerboard[point.Y][point.X] = chessman.Value
if self._win(point):
print(f'{chessman.Name}获胜')
return chessman
# 判断是否赢了
def _win(self, point):
cur_value = self._checkerboard[point.Y][point.X]
for os in offset:
if self._get_count_on_direction(point, cur_value, os[0], os[1]):
return True
def _get_count_on_direction(self, point, value, x_offset, y_offset):
count = 1
for step in range(1, 5):
x = point.X + step * x_offset
y = point.Y + step * y_offset
if 0 <= x < self._line_points and 0 <= y < self._line_points and self._checkerboard[y][x] == value:
count += 1
else:
break
for step in range(1, 5):
x = point.X - step * x_offset
y = point.Y - step * y_offset
if 0 <= x < self._line_points and 0 <= y < self._line_points and self._checkerboard[y][x] == value:
count += 1
else:
break
return count >= 5
Здесь я определяю смещение, мы должны вычислить всего 4 линии по горизонтали и вертикали, и если какая-либо линия появится 5 раз подряд, она выиграет. Метод вычисления на самом деле тот же, но направление другое, поэтому определите массив смещений, и разные смещения представляют разные направления, так что вы можете использовать циклы для достижения, сохраняя много кода.
компьютер
Это изюминка всей статьи, как научить компьютер играть в гобанг. Во-первых, я использую относительно традиционный метод, а не глубокое обучение в полном смысле этого слова.
Gobang должен набрать 5 даже, поэтому в начале моя идея была такова: сохранить все ссылки в массиве, а при переходе выбирать самую длинную ссылку. Но есть неразрешимая проблема Как заставить компьютер распознавать "три три"?
Позже я увидел статью в Интернете, в которой использовался метод: пройтись по вакансиям на шахматной доске, посчитать, есть ли своя фигура в 8 направлениях по горизонтали и вертикали для каждой позиции, добавить 10 очков, если есть, и наконец, выберите позицию с наибольшим количеством очков.
Это не очень строго, и уровень компьютерной оценки написан очень хорошо, но идея верна.Смысл в том, чтобы найти самое стоящее место, поэтому мы просто делаем оценку для каждого места, которое можно разместить, и выбираем лучшее место развязать.
шахматный термин
Здесь нам нужно понять несколько основных шахматных форм игры в нарды: четные пять, живые четыре, быстрые четыре, живые три, спящие три, живые два, спящие два.
Лианву
Как следует из названия, пять фишек одного цвета соединяются вместе, чтобы выиграть.
жить вчетвером
Четыре фигуры одного цвета соединены вместе, и слева и справа нет фигур соперника, которые можно было бы заблокировать, и есть две фигуры с пятью очками.
спешить четыре
Четыре фигуры одного цвета соединены вместе, и одна сторона заблокирована фигурой соперника, или четыре фигуры не соединены, и имеется нейтральное положение, тогда только одна связана с пятью точками.
жить три, прыгать жить три
жить три: Три части одного цвета соединены вместе.
прыгать втроем: Живи втроем с промежутком между ними.спать три
Есть только две ситуации, которые могут образовать только мчащуюся четверку: одна — одна сторона заблокирована, а другая — два пробела посередине. (На самом деле я рассмотрел только первый случай в коде, и даже если он образует четверку, это не опасная ситуация.)
жить два и спать два
Живущие двое могут образовать двоих из трех, а спящие двое могут образовать двоих из спящих троих. Я не буду помещать здесь картинку, обратитесь к трем живу трем сплю троим.
Механизм подсчета очков
После понимания этих шахматных фигур, согласно нашему предыдущему мышлению, важно, как забивать.
- Во-первых, пятерки в ряду точно не бывает, а если есть пятерка в ряду, то победитель и проигравший делятся, так что пока идет шахматная партия, пятерки в ряду не будет. ряд. Итак, что имеет наивысший приоритет? Естественно, это четыре жизни.
- Вторая - "четверка" соперника.Если противник жив, вы проиграете, если не сможете защититься. Если противник устремится к четвертой, вы должны защищаться.
- Опять же, это живая тройка нашей стороны или раш-четверка, живая тройка и раш-четверка на самом деле одного уровня, и противник должен защищаться.
- Опять же, это живая тройка соперника или раш-четверка.
И так далее. Мы можем обобщить несколько правил:
- В той же шахматной форме наша сторона лучше, чем другая сторона.
- Чонг четыре — это один уровень с живыми тремя, а сон три — это один уровень с живыми двумя.
- Если в середине есть пробел, он должен быть немного ниже, чем без пробела, но он не будет деградировать.
Основная логика такая.Я не силен в написании кода этой штуки.Все суждение написано более 100 строк,поэтому код выкладывать не буду.Вы можете напрямую скачать исходники.
Гобанг Блэк гарантированно выиграет.В кодексе игрок первым играет черными, а компьютер белыми.Поэтому, если вы играете хорошо, вы можете полностью выиграть компьютер, но небольшая ошибка также может быть отменена компьютер.
Рекомендуемые записи в блоге
- Python: Игра: Змейка
- Python: игра: напишите тральщик точно так же, как на XP
- Python: Игра: Тетрис в 300 строках кода
- Python: Игра: Человеко-машинная битва за Гобанг
Отсканируйте код, чтобы подписаться на мою официальную учетную запись, ответьте на «Gobang» в фоновом режиме и получите исходный код.