@@ -75,7 +75,6 @@ def chance_node(state, action):
7575 for val in dice_rolls :
7676 game .dice_roll = val
7777 sum_chances += min_value (res_state ) * (1 / 36 if val [0 ] == val [1 ] else 1 / 18 )
78-
7978 return sum_chances / num_chances
8079
8180 # Body of expectiminimax:
@@ -396,7 +395,7 @@ class Backgammon(Game):
396395
397396 def __init__ (self ):
398397 self .dice_roll = (- random .randint (1 , 6 ), - random .randint (1 , 6 ))
399- board = Board ()
398+ board = BackgammonBoard ()
400399 self .initial = GameState (to_move = 'W' ,
401400 utility = 0 , board = board , moves = self .get_all_moves (board , 'W' ))
402401
@@ -437,35 +436,35 @@ def get_all_moves(self, board, player):
437436 at a given state."""
438437 all_points = board .points
439438 taken_points = [index for index , point in enumerate (all_points )
440- if point . checkers [player ] > 0 ]
439+ if point [player ] > 0 ]
441440 moves = list (itertools .permutations (taken_points , 2 ))
442441 moves = moves + [(index , index ) for index , point in enumerate (all_points )
443- if point . checkers [player ] >= 2 ]
442+ if point [player ] >= 2 ]
444443 return moves
445444
446445 def display (self , state ):
447446 """Display state of the game."""
448447 board = state .board
449448 player = state .to_move
450449 for index , point in enumerate (board .points ):
451- if point . checkers ['W' ] != 0 or point . checkers ['B' ] != 0 :
452- print ("Point : " , index , " W : " , point . checkers ['W' ], " B : " , point . checkers ['B' ])
450+ if point ['W' ] != 0 or point ['B' ] != 0 :
451+ print ("Point : " , index , " W : " , point ['W' ], " B : " , point ['B' ])
453452 print ("player : " , player )
454453
455454
456455 def compute_utility (self , board , move , player ):
457456 """If 'W' wins with this move, return 1; if 'B' wins return -1; else return 0."""
458457 count = 0
459458 for idx in range (0 , 24 ):
460- count = count + board .points [idx ]. checkers [player ]
459+ count = count + board .points [idx ][player ]
461460 if player == 'W' and count == 0 :
462461 return 1
463462 if player == 'B' and count == 0 :
464463 return - 1
465464 return 0
466465
467466
468- class Board :
467+ class BackgammonBoard :
469468 """The board consists of 24 points. Each player('W' and 'B') initially
470469 has 15 checkers on board. Player 'W' moves from point 23 to point 0
471470 and player 'B' moves from point 0 to 23. Points 0-7 are
@@ -474,19 +473,20 @@ class Board:
474473 def __init__ (self ):
475474 """Initial state of the game"""
476475 # TODO : Add bar to Board class where a blot is placed when it is hit.
477- self .points = [Point () for index in range (24 )]
478- self .points [0 ].checkers ['B' ] = self .points [23 ].checkers ['W' ] = 2
479- self .points [5 ].checkers ['W' ] = self .points [18 ].checkers ['B' ] = 5
480- self .points [7 ].checkers ['W' ] = self .points [16 ].checkers ['B' ] = 3
481- self .points [11 ].checkers ['B' ] = self .points [12 ].checkers ['W' ] = 5
476+ point = {'W' :0 , 'B' :0 }
477+ self .points = [point .copy () for index in range (24 )]
478+ self .points [0 ]['B' ] = self .points [23 ]['W' ] = 2
479+ self .points [5 ]['W' ] = self .points [18 ]['B' ] = 5
480+ self .points [7 ]['W' ] = self .points [16 ]['B' ] = 3
481+ self .points [11 ]['B' ] = self .points [12 ]['W' ] = 5
482482 self .allow_bear_off = {'W' : False , 'B' : False }
483483
484484 def checkers_at_home (self , player ):
485485 """Returns the no. of checkers at home for a player."""
486486 sum_range = range (0 , 7 ) if player == 'W' else range (17 , 24 )
487487 count = 0
488488 for idx in sum_range :
489- count = count + self .points [idx ]. checkers [player ]
489+ count = count + self .points [idx ][player ]
490490 return count
491491
492492 def is_legal_move (self , start , steps , player ):
@@ -498,7 +498,7 @@ def is_legal_move(self, start, steps, player):
498498 dest_range = range (0 , 24 )
499499 move1_legal = move2_legal = False
500500 if dest1 in dest_range :
501- if self .points [dest1 ]. is_open_for ( player ):
501+ if self .is_point_open ( player , self . points [dest1 ]):
502502 self .move_checker (start [0 ], steps [0 ], player )
503503 move1_legal = True
504504 else :
@@ -508,7 +508,7 @@ def is_legal_move(self, start, steps, player):
508508 if not move1_legal :
509509 return False
510510 if dest2 in dest_range :
511- if self .points [dest2 ]. is_open_for ( player ):
511+ if self .is_point_open ( player , self . points [dest2 ]):
512512 move2_legal = True
513513 else :
514514 if self .allow_bear_off [player ]:
@@ -519,30 +519,15 @@ def move_checker(self, start, steps, player):
519519 """Moves a checker from starting point by a given number of steps"""
520520 dest = start + steps
521521 dest_range = range (0 , 24 )
522- self .points [start ]. remove_checker ( player )
522+ self .points [start ][ player ] -= 1
523523 if dest in dest_range :
524- self .points [dest ]. add_checker ( player )
524+ self .points [dest ][ player ] += 1
525525 if self .checkers_at_home (player ) == 15 :
526526 self .allow_bear_off [player ] = True
527527
528- class Point :
529- """A point is one of the 24 triangles on the board where
530- the players' checkers are placed."""
531-
532- def __init__ (self ):
533- self .checkers = {'W' :0 , 'B' :0 }
534-
535- def is_open_for (self , player ):
528+ def is_point_open (self , player , point ):
536529 """A point is open for a player if the no. of opponent's
537530 checkers already present on it is 0 or 1. A player can
538531 move a checker to a point only if it is open."""
539532 opponent = 'B' if player == 'W' else 'W'
540- return self .checkers [opponent ] <= 1
541-
542- def add_checker (self , player ):
543- """Place a player's checker on a point."""
544- self .checkers [player ] += 1
545-
546- def remove_checker (self , player ):
547- """Remove a player's checker from a point."""
548- self .checkers [player ] -= 1
533+ return point [opponent ] <= 1
0 commit comments