gomokuプログラムのPython実装

ほとんどの人がgobangゲームをプレイしたことがあると思いますが、今日はpythonを使用して一度実装します

特定のコードは私のGitHubアドレスから取得できます

ゴミボードを作る

from collections import namedtuple

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)]classCheckerboard:
 def __init__(self, line_points):
 self._line_points = line_points
 self._checkerboard =[[0]* line_points for _ inrange(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):"""
 Laozi
 : param chessman::param point:配置位置
 : return:子供が転んだ後に勝つことができる場合は勝者を返し、そうでない場合はなしを返します
    """
 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 =1for step inrange(1,5):
  x = point.X + step * x_offset
  y = point.Y + step * y_offset
  if0<= x < self._line_points and 0<= y < self._line_points and self._checkerboard[y][x]== value:
  count +=1else:breakfor step inrange(1,5):
  x = point.X - step * x_offset
  y = point.Y - step * y_offset
  if0<= x < self._line_points and 0<= y < self._line_points and self._checkerboard[y][x]== value:
  count +=1else:breakreturn count  =5

ゴバンマンマシンバトルを実現

import sys
import random
import pygame
from pygame.locals import*import pygame.gfxdraw
from checkerboard import Checkerboard, BLACK_CHESSMAN, WHITE_CHESSMAN, offset, Point
SIZE =30 #チェス盤の各ポイントの時間間隔
Line_Points =19 #ボードの各行/列あたりのポイント
Outer_Width =20 #チェス盤の外幅
Border_Width =4 #ボーダー幅
Inside_Width =4 #ボーダーと実際のチェスボードの間のスペース
Border_Length = SIZE *(Line_Points -1)+ Inside_Width *2+ Border_Width #境界線の長さ
Start_X = Start_Y = Outer_Width +int(Border_Width /2)+ Inside_Width #グリッド線の始点(左上隅)の座標
SCREEN_HEIGHT = SIZE *(Line_Points -1)+ Outer_Width *2+ Border_Width + Inside_Width *2 #ゲーム画面の高さ
SCREEN_WIDTH = SCREEN_HEIGHT +200 #ゲーム画面の幅
Stone_Radius = SIZE // 2 - 3 #チェスピースの半径
Stone_Radius2 = SIZE // 2 + 3
Checkerboard_Color =(0xE3,0x92,0x65) #チェッカーボードの色
BLACK_COLOR =(0,0,0)
WHITE_COLOR =(255,255,255)
RED_COLOR =(200,30,30)
BLUE_COLOR =(30,30,200)
RIGHT_INFO_POS_X = SCREEN_HEIGHT + Stone_Radius2 *2+10
def print_text(screen, font, x, y, text, fcolor=(255,255,255)):
imgText = font.render(text, True, fcolor)
screen.blit(imgText,(x, y))
def main():
pygame.init()
screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
pygame.display.set_caption('ゴバン')
font1 = pygame.font.SysFont('SimHei',32)
font2 = pygame.font.SysFont('SimHei',72)
fwidth, fheight = font2.size('黒が勝つ')
checkerboard =Checkerboard(Line_Points)
cur_runner = BLACK_CHESSMAN
winner = None
computer =AI(Line_Points, WHITE_CHESSMAN)
black_win_count =0
white_win_count =0while True:for event in pygame.event.get():if event.type == QUIT:
sys.exit()
elif event.type == KEYDOWN:if event.key == K_RETURN:if winner is not None:
winner = None
cur_runner = BLACK_CHESSMAN
checkerboard =Checkerboard(Line_Points)
computer =AI(Line_Points, WHITE_CHESSMAN)
elif event.type == MOUSEBUTTONDOWN:if winner is None:
pressed_array = pygame.mouse.get_pressed()if pressed_array[0]:
mouse_pos = pygame.mouse.get_pos()
click_point =_get_clickpoint(mouse_pos)if click_point is not None:if checkerboard.can_drop(click_point):
winner = checkerboard.drop(cur_runner, click_point)if winner is None:
cur_runner =_get_next(cur_runner)
computer.get_opponent_drop(click_point)
AI_point = computer.AI_drop()
winner = checkerboard.drop(cur_runner, AI_point)if winner is not None:
white_win_count +=1
cur_runner =_get_next(cur_runner)else:
black_win_count +=1else:print('ボードエリアを超えて')
# チェス盤を描く
_ draw_checkerboard(screen)
# ボード上に既存のピースを描画します
for i, row inenumerate(checkerboard.checkerboard):for j, cell inenumerate(row):if cell == BLACK_CHESSMAN.Value:_draw_chessman(screen,Point(j, i), BLACK_CHESSMAN.Color)
elif cell == WHITE_CHESSMAN.Value:_draw_chessman(screen,Point(j, i), WHITE_CHESSMAN.Color)_draw_left_info(screen, font1, cur_runner, black_win_count, white_win_count)if winner:print_text(screen, font2,(SCREEN_WIDTH - fwidth)//2, (SCREEN_HEIGHT - fheight)//2, winner.Name + '勝つ', RED_COLOR)
pygame.display.flip()
def _get_next(cur_runner):if cur_runner == BLACK_CHESSMAN:return WHITE_CHESSMAN
else:return BLACK_CHESSMAN
# チェス盤を描く
def _draw_checkerboard(screen):
# チェッカーボードの背景色を塗りつぶします
screen.fill(Checkerboard_Color)
# チェッカーボードのグリッド線の外側に境界線を描画します
pygame.draw.rect(screen, BLACK_COLOR,(Outer_Width, Outer_Width, Border_Length, Border_Length), Border_Width)
# グリッド線を引く
for i inrange(Line_Points):
pygame.draw.line(screen, BLACK_COLOR,(Start_Y, Start_Y + SIZE * i),(Start_Y + SIZE *(Line_Points -1), Start_Y + SIZE * i),1)for j inrange(Line_Points):
pygame.draw.line(screen, BLACK_COLOR,(Start_X + SIZE * j, Start_X),(Start_X + SIZE * j, Start_X + SIZE *(Line_Points -1)),1)
# 星と天元を描く
for i in(3,9,15):for j in(3,9,15):if i == j ==9:
radius =5else:
radius =3
# pygame.draw.circle(screen, BLACK,(Start_X + SIZE * i, Start_Y + SIZE * j), radius)
pygame.gfxdraw.aacircle(screen, Start_X + SIZE * i, Start_Y + SIZE * j, radius, BLACK_COLOR)
pygame.gfxdraw.filled_circle(screen, Start_X + SIZE * i, Start_Y + SIZE * j, radius, BLACK_COLOR)
# チェスのピースを描く
def _draw_chessman(screen, point, stone_color):
# pygame.draw.circle(screen, stone_color,(Start_X + SIZE * point.X, Start_Y + SIZE * point.Y), Stone_Radius)
pygame.gfxdraw.aacircle(screen, Start_X + SIZE * point.X, Start_Y + SIZE * point.Y, Stone_Radius, stone_color)
pygame.gfxdraw.filled_circle(screen, Start_X + SIZE * point.X, Start_Y + SIZE * point.Y, Stone_Radius, stone_color)
# 写真左情報表示
def _draw_left_info(screen, font, cur_runner, black_win_count, white_win_count):_draw_chessman_pos(screen,(SCREEN_HEIGHT + Stone_Radius2, Start_X + Stone_Radius2), BLACK_CHESSMAN.Color)_draw_chessman_pos(screen,(SCREEN_HEIGHT + Stone_Radius2, Start_X + Stone_Radius2 *4), WHITE_CHESSMAN.Color)print_text(screen, font, RIGHT_INFO_POS_X, Start_X +3,'プレーヤー', BLUE_COLOR)print_text(screen, font, RIGHT_INFO_POS_X, Start_X + Stone_Radius2 *3+3,'コンピューター', BLUE_COLOR)print_text(screen, font, SCREEN_HEIGHT, SCREEN_HEIGHT - Stone_Radius2 *8,'状況:', BLUE_COLOR)_draw_chessman_pos(screen,(SCREEN_HEIGHT + Stone_Radius2, SCREEN_HEIGHT -int(Stone_Radius2 *4.5)), BLACK_CHESSMAN.Color)_draw_chessman_pos(screen,(SCREEN_HEIGHT + Stone_Radius2, SCREEN_HEIGHT - Stone_Radius2 *2), WHITE_CHESSMAN.Color)print_text(screen, font, RIGHT_INFO_POS_X, SCREEN_HEIGHT -int(Stone_Radius2 *5.5)+3, f'{black_win_count}勝つ', BLUE_COLOR)print_text(screen, font, RIGHT_INFO_POS_X, SCREEN_HEIGHT - Stone_Radius2 *3+3, f'{white_win_count}勝つ', BLUE_COLOR)
def _draw_chessman_pos(screen, pos, stone_color):
pygame.gfxdraw.aacircle(screen, pos[0], pos[1], Stone_Radius2, stone_color)
pygame.gfxdraw.filled_circle(screen, pos[0], pos[1], Stone_Radius2, stone_color)
# マウスのクリック位置に応じて、ゲームエリアの座標に戻ります
def _get_clickpoint(click_pos):
pos_x = click_pos[0]- Start_X
pos_y = click_pos[1]- Start_Y
if pos_x <-Inside_Width or pos_y <-Inside_Width:return None
x = pos_x // SIZE
y = pos_y // SIZEif pos_x % SIZE   Stone_Radius:
x +=1if pos_y % SIZE   Stone_Radius:
y +=1if x  = Line_Points or y  = Line_Points:return None
returnPoint(x, y)classAI:
def __init__(self, line_points, chessman):
self._line_points = line_points
self._my = chessman
self._opponent = BLACK_CHESSMAN if chessman == WHITE_CHESSMAN else WHITE_CHESSMAN
self._checkerboard =[[0]* line_points for _ inrange(line_points)]
def get_opponent_drop(self, point):
self._checkerboard[point.Y][point.X]= self._opponent.Value
def AI_drop(self):
point = None
score =0for i inrange(self._line_points):for j inrange(self._line_points):if self._checkerboard[j][i]==0:
_ score = self._get_point_score(Point(i, j))if _score   score:
score = _score
point =Point(i, j)
elif _score == score and _score   0:
r = random.randint(0,100)if r %2==0:
point =Point(i, j)
self._checkerboard[point.Y][point.X]= self._my.Value
return point
def _get_point_score(self, point):
score =0for os in offset:
score += self._get_direction_score(point, os[0], os[1])return score
def _get_direction_score(self, point, x_offset, y_offset):
count =0  #私たちの場所での連続した息子の数
_ count =0 #対戦相手の連続した子供の数
space = None  #続きにスペースはありますか
_ space = None #対戦相手の続きにスペースはありますか
both =0  #連続体の両端に障害物はありますか?
_ both =0  #対戦相手の連続体が両端でブロックされているかどうか
# 1の場合、それは私たちが側にいることを意味し、2は敵です
flag = self._get_stone_color(point, x_offset, y_offset, True)if flag !=0:for step inrange(1,6):
x = point.X + step * x_offset
y = point.Y + step * y_offset
if0<= x < self._line_points and 0<= y < self._line_points:if flag ==1:if self._checkerboard[y][x]== self._my.Value:
count +=1if space is False:
space = True
elif self._checkerboard[y][x]== self._opponent.Value:
_ both +=1breakelse:if space is None:
space = False
else:break  #2番目のスペースに遭遇したら終了します
elif flag ==2:if self._checkerboard[y][x]== self._my.Value:
_ both +=1break
elif self._checkerboard[y][x]== self._opponent.Value:
_ count +=1if _space is False:
_ space = True
else:if _space is None:
_ space = False
else:breakelse:
# エッジに遭遇するとブロックされます
if flag ==1:
both +=1
elif flag ==2:
_ both +=1if space is False:
space = None
if _space is False:
_ space = None
_ flag = self._get_stone_color(point,-x_offset,-y_offset, True)if _flag !=0:for step inrange(1,6):
x = point.X - step * x_offset
y = point.Y - step * y_offset
if0<= x < self._line_points and 0<= y < self._line_points:if _flag ==1:if self._checkerboard[y][x]== self._my.Value:
count +=1if space is False:
space = True
elif self._checkerboard[y][x]== self._opponent.Value:
_ both +=1breakelse:if space is None:
space = False
else:break  #2番目のスペースに遭遇したら終了します
elif _flag ==2:if self._checkerboard[y][x]== self._my.Value:
_ both +=1break
elif self._checkerboard[y][x]== self._opponent.Value:
_ count +=1if _space is False:
_ space = True
else:if _space is None:
_ space = False
else:breakelse:
# エッジに遭遇するとブロックされます
if _flag ==1:
both +=1
elif _flag ==2:
_ both +=1
score =0if count ==4:
score =10000
elif _count ==4:
score =9000
elif count ==3:if both ==0:
score =1000
elif both ==1:
score =100else:
score =0
elif _count ==3:if _both ==0:
score =900
elif _both ==1:
score =90else:
score =0
elif count ==2:if both ==0:
score =100
elif both ==1:
score =10else:
score =0
elif _count ==2:if _both ==0:
score =90
elif _both ==1:
score =9else:
score =0
elif count ==1:
score =10
elif _count ==1:
score =9else:
score =0if space or _space:
score /=2return score
# 指定された位置が私たちの当事者、他の当事者、および指定された方向の空であるかどうかを判別します
def _get_stone_color(self, point, x_offset, y_offset, next):
x = point.X + x_offset
y = point.Y + y_offset
if0<= x < self._line_points and 0<= y < self._line_points:if self._checkerboard[y][x]== self._my.Value:return1
elif self._checkerboard[y][x]== self._opponent.Value:return2else:if next:return self._get_stone_color(Point(x, y), x_offset, y_offset, False)else:return0else:return0if __name__ =='__main__':main()

動作効果は以下のとおりです。

Pythonは誰にとってもバックギャモンを実現します

import sys
import pygame
from pygame.locals import*import pygame.gfxdraw
from checkerboard import Checkerboard, BLACK_CHESSMAN, WHITE_CHESSMAN, Point
SIZE =30 #チェス盤の各ポイントの時間間隔
Line_Points =19 #ボードの各行/列あたりのポイント
Outer_Width =20 #チェス盤の外幅
Border_Width =4 #ボーダー幅
Inside_Width =4 #ボーダーと実際のチェスボードの間のスペース
Border_Length = SIZE *(Line_Points -1)+ Inside_Width *2+ Border_Width #境界線の長さ
Start_X = Start_Y = Outer_Width +int(Border_Width /2)+ Inside_Width #グリッド線の始点(左上隅)の座標
SCREEN_HEIGHT = SIZE *(Line_Points -1)+ Outer_Width *2+ Border_Width + Inside_Width *2 #ゲーム画面の高さ
SCREEN_WIDTH = SCREEN_HEIGHT +200 #ゲーム画面の幅
Stone_Radius = SIZE // 2 - 3 #チェスピースの半径
Stone_Radius2 = SIZE // 2 + 3
Checkerboard_Color =(0xE3,0x92,0x65) #チェッカーボードの色
BLACK_COLOR =(0,0,0)
WHITE_COLOR =(255,255,255)
RED_COLOR =(200,30,30)
BLUE_COLOR =(30,30,200)
BLACK_STONE_COLOR =(45,45,45)
WHITE_STONE_COLOR =(219,219,219)
RIGHT_INFO_POS_X = SCREEN_HEIGHT + Stone_Radius2 *2+10
def print_text(screen, font, x, y, text, fcolor=(255,255,255)):
imgText = font.render(text, True, fcolor)
screen.blit(imgText,(x, y))
def main():
pygame.init()
screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
pygame.display.set_caption('ゴバン')
font1 = pygame.font.SysFont('SimHei',36)
font2 = pygame.font.SysFont('SimHei',72)
fwidth, fheight = font2.size('黒が勝つ')
checkerboard =Checkerboard(Line_Points)
cur_runner = BLACK_CHESSMAN
winner = None
while True:for event in pygame.event.get():if event.type == QUIT:
sys.exit()
elif event.type == KEYDOWN:if event.key == K_RETURN:if winner is not None:
winner = None
cur_runner = BLACK_CHESSMAN
checkerboard =Checkerboard(Line_Points)
elif event.type == MOUSEBUTTONDOWN:if winner is None:
pressed_array = pygame.mouse.get_pressed()if pressed_array[0]:
mouse_pos = pygame.mouse.get_pos()
click_point =_get_clickpoint(mouse_pos)if click_point is not None:if checkerboard.can_drop(click_point):
winner = checkerboard.drop(cur_runner, click_point)if cur_runner == BLACK_CHESSMAN:
cur_runner = WHITE_CHESSMAN
else:
cur_runner = BLACK_CHESSMAN
else:print('ボードエリアを超えて')
# チェス盤を描く
_ draw_checkerboard(screen)
# ボード上に既存のピースを描画します
for i, row inenumerate(checkerboard.checkerboard):for j, cell inenumerate(row):if cell == BLACK_CHESSMAN.Value:_draw_chessman(screen,Point(j, i), BLACK_CHESSMAN.Color)
elif cell == WHITE_CHESSMAN.Value:_draw_chessman(screen,Point(j, i), WHITE_CHESSMAN.Color)_draw_chessman_pos(screen,(SCREEN_HEIGHT + Stone_Radius2, Start_X +20), BLACK_STONE_COLOR)_draw_chessman_pos(screen,(SCREEN_HEIGHT + Stone_Radius2, Start_X +20+ Stone_Radius2 *3), WHITE_STONE_COLOR)if winner:print_text(screen, font2,(SCREEN_WIDTH - fwidth)//2, (SCREEN_HEIGHT - fheight)//2, winner.Name + '勝つ', RED_COLOR)if cur_runner == BLACK_CHESSMAN:print_text(screen, font1, RIGHT_INFO_POS_X, Start_X,'勝つ'if winner else'Laozizhong', BLUE_COLOR)else:print_text(screen, font1, RIGHT_INFO_POS_X, Start_X + Stone_Radius2 *3,'勝つ'if winner else'Laozizhong', BLUE_COLOR)
pygame.display.flip()
# チェス盤を描く
def _draw_checkerboard(screen):
# チェッカーボードの背景色を塗りつぶします
screen.fill(Checkerboard_Color)
# チェッカーボードのグリッド線の外側に境界線を描画します
pygame.draw.rect(screen, BLACK_COLOR,(Outer_Width, Outer_Width, Border_Length, Border_Length), Border_Width)
# グリッド線を引く
for i inrange(Line_Points):
pygame.draw.line(screen, BLACK_COLOR,(Start_Y, Start_Y + SIZE * i),(Start_Y + SIZE *(Line_Points -1), Start_Y + SIZE * i),1)for j inrange(Line_Points):
pygame.draw.line(screen, BLACK_COLOR,(Start_X + SIZE * j, Start_X),(Start_X + SIZE * j, Start_X + SIZE *(Line_Points -1)),1)
# 星と天元を描く
for i in(3,9,15):for j in(3,9,15):if i == j ==9:
radius =5else:
radius =3
# pygame.draw.circle(screen, BLACK,(Start_X + SIZE * i, Start_Y + SIZE * j), radius)
pygame.gfxdraw.aacircle(screen, Start_X + SIZE * i, Start_Y + SIZE * j, radius, BLACK_COLOR)
pygame.gfxdraw.filled_circle(screen, Start_X + SIZE * i, Start_Y + SIZE * j, radius, BLACK_COLOR)
# チェスのピースを描く
def _draw_chessman(screen, point, stone_color):
# pygame.draw.circle(screen, stone_color,(Start_X + SIZE * point.X, Start_Y + SIZE * point.Y), Stone_Radius)
pygame.gfxdraw.aacircle(screen, Start_X + SIZE * point.X, Start_Y + SIZE * point.Y, Stone_Radius, stone_color)
pygame.gfxdraw.filled_circle(screen, Start_X + SIZE * point.X, Start_Y + SIZE * point.Y, Stone_Radius, stone_color)
def _draw_chessman_pos(screen, pos, stone_color):
pygame.gfxdraw.aacircle(screen, pos[0], pos[1], Stone_Radius2, stone_color)
pygame.gfxdraw.filled_circle(screen, pos[0], pos[1], Stone_Radius2, stone_color)
# マウスのクリック位置に応じて、ゲームエリアの座標に戻ります
def _get_clickpoint(click_pos):
pos_x = click_pos[0]- Start_X
pos_y = click_pos[1]- Start_Y
if pos_x <-Inside_Width or pos_y <-Inside_Width:return None
x = pos_x // SIZE
y = pos_y // SIZEif pos_x % SIZE   Stone_Radius:
x +=1if pos_y % SIZE   Stone_Radius:
y +=1if x  = Line_Points or y  = Line_Points:return None
returnPoint(x, y)if __name__ =='__main__':main()

実行結果

より興味深い古典的なミニゲームの実装トピック、あなたと共有してください:

C ++クラシックゲームの概要

Pythonクラシックゲームの概要

pythontetrisゲームコレクション

JavaScriptクラシックゲームは常にプレイされています

古典的なJavaゲームの概要

JavaScriptクラシックゲームの概要

以上が本稿の内容ですので、皆様のご勉強に役立てていただければ幸いです。

Recommended Posts

gomokuプログラムのPython実装
Pythonプラグインメカニズムの詳細な実装
pythonリストの逆トラバーサルの実装
IOU計算ケースのPython実装
word2vec操作のPython予備実装
pythonselenium操作cookieの実装
python3登録グローバルホットキーの実装
python学生管理システムの実装
python勾配降下アルゴリズムの実装
pythonでのJWTユーザー認証の実装
交差点のPython実装とIOUチュートリアル
Python3.9の7つの機能
C言語プログラムを呼び出すPythonのメソッド分析
ファイルをダウンロードするためのPythonヘッドレスクローラーの実装
AI自動マットサンプル分析のPython実装
手描き効果の例の共有のPython実装
pythonによる名刺管理システムの実装
Pythonは釣りマスターのゲーム実装を書きます
Python構文の基本
Pythonの基本構文
Pythonの基礎知識(1)
pythonのPrettytableモジュール
09.Python3の共通モジュール
pythonに基づく名刺管理システムの実装
Pythonインターフェース開発の実装手順の詳細な説明
Pythonの基盤を統合する(4)
Python(7)の基盤を統合する
pythonリスト(LIST)の深い理解
Pythonのタプルの添え字
wavファイルのPython分析
Python(6)の基盤を統合する
Python描画ローズ実装コード
栄光のパイソンキング壁紙
Python(5)の基盤を統合する
Pythonサンドボックスエスケープの分析
Python3.10のいくつかの新機能
Pythonマルチスレッドの深い理解
Pythonオブジェクト指向プログラミングの分析
CentOS8.0ネットワーク構成の実装
python3はプログラムの実行時間を記録します
OpenCVインストールのPythonバージョン
PythonGUIシミュレーション実装計算機
Pythonの9つの機能エンジニアリング手法
python描画モジュールのmatplotlib
パラメータを渡すPythonメソッド
Pythonの基盤を統合する(3)
Python共通モジュールのコレクション
Pythontelnetログイン関数の実装コード
pythonでのwheelの使用法
Pythonの対数法の要約
Pythonセグメンテーションシーケンス図視覚化プログラム
pythonバックトラッキングテンプレートの詳細な説明
Pythonイールドの使用例の分析
Python開発でのパンダの使用
pythonシーケンスタイプの詳細な説明
Python変数スコープの詳細な理解
FMアルゴリズム分析とPython実装
情報エントロピーの例のPython計算
pythonプログラムを保存する方法
Python開発でのnumpyの使用
PythonATM関数の実装コード例