SCRABBLE - Conceptual views w/Python

Anybody care to describe what this is?

[('D', 1), ('I', 3), ('O', 2), ('U', 1), ('V', 1), ('W', 1)]
1 Ted ['BLUE', 'TENNIS', 'EXIT', 'TANNER', 'FIG'] 48
2 Carol ['EARTH', 'EYES', 'MACHINE', 'TUG', 'GOOD'] 48
3 Bob ['ERASER', 'BELLY', 'OPAL', 'DEAD', 'JOK '] 48
4 Alice ['ZAP', 'COMA', 'NARROW', 'QUIT', 'FIV S'] 51
>>> 

Chime in so we may continue…

Briefly, the above is a dump of the four Player instances involved in the game, a Game instance. The words shown consist of 91 tiles drawn from the bag and the top row is the remaining tiles and their count.

>>> game.score_word('ZAPCOMANARROWQUITFIV S')
51
>>> game.score_word('ERASERBELLYOPALDEADJOK ')
48
>>> game.score_word('EARTHEYESMACHINETUGGOOD')
48
>>> game.score_word('BLUETENNISEXITTANNERFIG')
48
>>> len('ZAPCOMANARROWQUITFIV SERASERBELLYOPALDEADJOK EARTHEYESMACHINETUGGOODBLUETENNISEXITTANNERFIG')
91
>>> sum(game.bag.values())
9
>>> 
Player
class Player:
  count = 0
  def __init__(self, name='player'):
    Player.count += 1
    self.id = self.count
    self.name = f"{name}{self.id}" if name=='player' else name
    self.words = []
    self.score = 0

  def __str__(self):
    return f"{self.id} {self.name} {self.words} {self.score}"

  def add_to_words(self, word):
    self.words.append(word)

  def add_to_score(self, score):
    self.score += score
Game
class Game:
  tiles = {k: int(v) for k, v in zip(
    "ABCDEFGHIJKLMNOPRSTUVWXZ ",
    '1332142418513413111144840'
  )}
  tiles['Q'] = 10
  tiles['Y'] = 10
  bag = {k: int(v) for k, v in zip(
    "ABCDFGHIJKLMNOPQRSTUVWXYZ ",
    '92242329114268216464221212'
  )}
  bag['E'] = 12

  def bag_has_letters(self, word):
    return ''.join([x for x in word if int(self.bag.get(x, 0)) > 0]) == word

  def remove_tiles(self, word):
    for k in word:
      self.bag[k] -= 1
      if self.bag[k] < 1:
        self.bag.pop(k)

  def avail(self):
    return sorted(game.bag.items(), key=lambda x: x[0])

  def __init__(self):
    self.game = []

  def add_players(self, *players):
    self.game.extend(players)
    if len(self.game) > 4:
      self.game = self.game[:4]

  def print(self):
    for player in self.game:
      print (player)

  def play_word(self, player, word):
    while not self.bag_has_letters(word):
      print ("Word not in bag")
      word = input(f"{player.name} enter another word: ")
    player.add_to_words(word)
    player.add_to_score(self.score_word(word))
    print (player)
    self.remove_tiles(word)
    print (self.avail())

  def score_word(self, word):
    return sum([self.tiles.get(x, 0) for x in word])
Test Run
game = Game()
ted = Player('Ted')
carol = Player('Carol')
bob = Player('Bob')
alice = Player('Alice')
game.add_players(ted, carol, bob, alice)
game.print()
game.play_word(ted, "BLUE")
game.play_word(carol, "EARTH")
game.play_word(bob, "ERASER")
game.play_word(alice, "ZAP")
game.play_word(ted, "TENNIS")
game.play_word(carol, "EYES")
game.play_word(bob, "BELLY")
game.play_word(alice, "COMA")
game.play_word(ted, "EXIT")
game.play_word(carol, "MACHINE")
game.play_word(bob, "HUSKY") # OPAL
game.play_word(alice, "PERIOD") # NARROW
game.play_word(ted, "TAXI")  # TANNER
game.play_word(carol, "MEEK") # TUG
game.play_word(bob, "ROUND")  # DEAD
game.play_word(alice, "STOP")  # QUIT
game.play_word(ted, "FIG")
game.play_word(carol, "GOOD")
game.play_word(bob, "JOK ")
game.play_word(alice, "SU K")  # FIV S
game.print()

The words used are stolen from the Scrabble project, save the ones that could not be used owing to bag content limitations. When a word cannot be constructed from the tiles in the bag, the player is prompted for another word. We entered the alternate words shown as comments beside each command that was intercepted.

Obviously this is very limited in terms of actual play. The only real constraint at this point is the number of tiles in the bag and their distribution. Tile scores is moot. All we’ve done is use up the tiles in the bag in this run-through.

1 Like