代码
"""五子棋之人机对战""" import sys
import random
import pygame
from pygame. locals import *
import pygame. gfxdraw
from checkerboard import Checkerboard, BLACK_CHESSMAN, WHITE_CHESSMAN, offset, PointSIZE = 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_CHESSMANwinner = None computer = AI( Line_Points, WHITE_CHESSMAN) black_win_count = 0 white_win_count = 0 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_CHESSMANcheckerboard = 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 += 1 else : print ( '超出棋盘区域' ) _draw_checkerboard( screen) for i, row in enumerate ( checkerboard. checkerboard) : for j, cell in enumerate ( 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_CHESSMANelse : 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 in range ( 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 in range ( 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 = 5 else : radius = 3 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. 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_Xpos_y = click_pos[ 1 ] - Start_Yif pos_x < - Inside_Width or pos_y < - Inside_Width: return None x = pos_x // SIZEy = pos_y // SIZEif pos_x % SIZE > Stone_Radius: x += 1 if pos_y % SIZE > Stone_Radius: y += 1 if x >= Line_Points or y >= Line_Points: return None return Point( x, y) class AI : def __init__ ( self, line_points, chessman) : self. _line_points = line_pointsself. _my = chessmanself. _opponent = BLACK_CHESSMAN if chessman == WHITE_CHESSMAN else WHITE_CHESSMANself. _checkerboard = [ [ 0 ] * line_points for _ in range ( line_points) ] def get_opponent_drop ( self, point) : self. _checkerboard[ point. Y] [ point. X] = self. _opponent. Valuedef AI_drop ( self) : point = None score = 0 for i in range ( self. _line_points) : for j in range ( self. _line_points) : if self. _checkerboard[ j] [ i] == 0 : _score = self. _get_point_score( Point( i, j) ) if _score > score: score = _scorepoint = 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. Valuereturn pointdef _get_point_score ( self, point) : score = 0 for os in offset: score += self. _get_direction_score( point, os[ 0 ] , os[ 1 ] ) return scoredef _get_direction_score ( self, point, x_offset, y_offset) : count = 0 _count = 0 space = None _space = None both = 0 _both = 0 flag = self. _get_stone_color( point, x_offset, y_offset, True ) if flag != 0 : for step in range ( 1 , 6 ) : x = point. X + step * x_offsety = point. Y + step * y_offsetif 0 <= x < self. _line_points and 0 <= y < self. _line_points: if flag == 1 : if self. _checkerboard[ y] [ x] == self. _my. Value: count += 1 if space is False : space = True elif self. _checkerboard[ y] [ x] == self. _opponent. Value: _both += 1 break else : if space is None : space = False else : break elif flag == 2 : if self. _checkerboard[ y] [ x] == self. _my. Value: _both += 1 break elif self. _checkerboard[ y] [ x] == self. _opponent. Value: _count += 1 if _space is False : _space = True else : if _space is None : _space = False else : break else : if flag == 1 : both += 1 elif flag == 2 : _both += 1 if 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 in range ( 1 , 6 ) : x = point. X - step * x_offsety = point. Y - step * y_offsetif 0 <= x < self. _line_points and 0 <= y < self. _line_points: if _flag == 1 : if self. _checkerboard[ y] [ x] == self. _my. Value: count += 1 if space is False : space = True elif self. _checkerboard[ y] [ x] == self. _opponent. Value: _both += 1 break else : if space is None : space = False else : break elif _flag == 2 : if self. _checkerboard[ y] [ x] == self. _my. Value: _both += 1 break elif self. _checkerboard[ y] [ x] == self. _opponent. Value: _count += 1 if _space is False : _space = True else : if _space is None : _space = False else : break else : if _flag == 1 : both += 1 elif _flag == 2 : _both += 1 score = 0 if count == 4 : score = 10000 elif _count == 4 : score = 9000 elif count == 3 : if both == 0 : score = 1000 elif both == 1 : score = 100 else : score = 0 elif _count == 3 : if _both == 0 : score = 900 elif _both == 1 : score = 90 else : score = 0 elif count == 2 : if both == 0 : score = 100 elif both == 1 : score = 10 else : score = 0 elif _count == 2 : if _both == 0 : score = 90 elif _both == 1 : score = 9 else : score = 0 elif count == 1 : score = 10 elif _count == 1 : score = 9 else : score = 0 if space or _space: score /= 2 return scoredef _get_stone_color ( self, point, x_offset, y_offset, next ) : x = point. X + x_offsety = point. Y + y_offsetif 0 <= x < self. _line_points and 0 <= y < self. _line_points: if self. _checkerboard[ y] [ x] == self. _my. Value: return 1 elif self. _checkerboard[ y] [ x] == self. _opponent. Value: return 2 else : if next : return self. _get_stone_color( Point( x, y) , x_offset, y_offset, False ) else : return 0 else : return 0 if __name__ == '__main__' : main( )
效果