@@ -75,7 +75,6 @@ def chance_node(state, action):
75
75
for val in dice_rolls :
76
76
game .dice_roll = val
77
77
sum_chances += min_value (res_state ) * (1 / 36 if val [0 ] == val [1 ] else 1 / 18 )
78
-
79
78
return sum_chances / num_chances
80
79
81
80
# Body of expectiminimax:
@@ -396,7 +395,7 @@ class Backgammon(Game):
396
395
397
396
def __init__ (self ):
398
397
self .dice_roll = (- random .randint (1 , 6 ), - random .randint (1 , 6 ))
399
- board = Board ()
398
+ board = BackgammonBoard ()
400
399
self .initial = GameState (to_move = 'W' ,
401
400
utility = 0 , board = board , moves = self .get_all_moves (board , 'W' ))
402
401
@@ -437,35 +436,35 @@ def get_all_moves(self, board, player):
437
436
at a given state."""
438
437
all_points = board .points
439
438
taken_points = [index for index , point in enumerate (all_points )
440
- if point . checkers [player ] > 0 ]
439
+ if point [player ] > 0 ]
441
440
moves = list (itertools .permutations (taken_points , 2 ))
442
441
moves = moves + [(index , index ) for index , point in enumerate (all_points )
443
- if point . checkers [player ] >= 2 ]
442
+ if point [player ] >= 2 ]
444
443
return moves
445
444
446
445
def display (self , state ):
447
446
"""Display state of the game."""
448
447
board = state .board
449
448
player = state .to_move
450
449
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' ])
453
452
print ("player : " , player )
454
453
455
454
456
455
def compute_utility (self , board , move , player ):
457
456
"""If 'W' wins with this move, return 1; if 'B' wins return -1; else return 0."""
458
457
count = 0
459
458
for idx in range (0 , 24 ):
460
- count = count + board .points [idx ]. checkers [player ]
459
+ count = count + board .points [idx ][player ]
461
460
if player == 'W' and count == 0 :
462
461
return 1
463
462
if player == 'B' and count == 0 :
464
463
return - 1
465
464
return 0
466
465
467
466
468
- class Board :
467
+ class BackgammonBoard :
469
468
"""The board consists of 24 points. Each player('W' and 'B') initially
470
469
has 15 checkers on board. Player 'W' moves from point 23 to point 0
471
470
and player 'B' moves from point 0 to 23. Points 0-7 are
@@ -474,19 +473,20 @@ class Board:
474
473
def __init__ (self ):
475
474
"""Initial state of the game"""
476
475
# 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
482
482
self .allow_bear_off = {'W' : False , 'B' : False }
483
483
484
484
def checkers_at_home (self , player ):
485
485
"""Returns the no. of checkers at home for a player."""
486
486
sum_range = range (0 , 7 ) if player == 'W' else range (17 , 24 )
487
487
count = 0
488
488
for idx in sum_range :
489
- count = count + self .points [idx ]. checkers [player ]
489
+ count = count + self .points [idx ][player ]
490
490
return count
491
491
492
492
def is_legal_move (self , start , steps , player ):
@@ -498,7 +498,7 @@ def is_legal_move(self, start, steps, player):
498
498
dest_range = range (0 , 24 )
499
499
move1_legal = move2_legal = False
500
500
if dest1 in dest_range :
501
- if self .points [dest1 ]. is_open_for ( player ):
501
+ if self .is_point_open ( player , self . points [dest1 ]):
502
502
self .move_checker (start [0 ], steps [0 ], player )
503
503
move1_legal = True
504
504
else :
@@ -508,7 +508,7 @@ def is_legal_move(self, start, steps, player):
508
508
if not move1_legal :
509
509
return False
510
510
if dest2 in dest_range :
511
- if self .points [dest2 ]. is_open_for ( player ):
511
+ if self .is_point_open ( player , self . points [dest2 ]):
512
512
move2_legal = True
513
513
else :
514
514
if self .allow_bear_off [player ]:
@@ -519,30 +519,15 @@ def move_checker(self, start, steps, player):
519
519
"""Moves a checker from starting point by a given number of steps"""
520
520
dest = start + steps
521
521
dest_range = range (0 , 24 )
522
- self .points [start ]. remove_checker ( player )
522
+ self .points [start ][ player ] -= 1
523
523
if dest in dest_range :
524
- self .points [dest ]. add_checker ( player )
524
+ self .points [dest ][ player ] += 1
525
525
if self .checkers_at_home (player ) == 15 :
526
526
self .allow_bear_off [player ] = True
527
527
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 ):
536
529
"""A point is open for a player if the no. of opponent's
537
530
checkers already present on it is 0 or 1. A player can
538
531
move a checker to a point only if it is open."""
539
532
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