ほとんどの人が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