"""五子棋之人机对战""" 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( )