# L-39 MCS 275 Mon 21 Apr 2008 : classboard.py

# A board of pebbles in a tic tac toe game is
# represented by a 3-by-3 matrix.
# Its string representation uses X and O for
# the pebbles 1 and 2 respectively.
# The number of adjacent pebbles on a board
# determines the value of a board.

from numpy import *

class Board():
   """
   Exports a tic tac toe board.
   """
   def __init__(self):
      """
      Returns an empty board.
      """
      self.m = zeros((3,3),int)

   def __str__(self):
      """
      X is 1, O is 2,
      the rest is blank
      """
      s = ''
      for i in range(0,3):
         if i > 0: s = s + '\n'
         for j in range(0,3):
            if self.m[i,j] == 1:
               s = s + 'X'
            else:
               if self.m[i,j] == 2:
                  s = s + 'O'
               else:
                  s = s + ' '
      return s

   def __repr__(self):
      """
      defines the representation of a board
      """
      return self.__str__()

   def parse(self,s):
      """
      Converts a string into a board.
      """
      ind = 0
      for i in range(0,3):
         for j in range(0,3):
            if s[ind] == '\n': ind = ind + 1
            self.m[i,j] = 0
            if s[ind] == 'X': self.m[i,j] = 1
            if s[ind] == 'O': self.m[i,j] = 2
            ind = ind + 1

   def copyBoard(self,b):
      """
      Copies the data in m to the board.
      """
      for i in range(0,3):
         for j in range(0,3):
            self.m[i,j] = b[i,j]

   def Value2(self,T):
      """
      Returns 1 if the two tuples in T are
      not adjacent, returns 2 otherwise.
      T[0] and [1] are in lexicographical order.
      """
      a = T[0]; b = T[1]
      if a[0] == b[0]:  # same row
         if abs(b[1] - a[1]) < 2:
            return 2
         else:
            return 1
      else:
         if a[1] == b[1]: # same column
            if abs(b[0] - a[0]) < 2:
               return 2
            else:
               return 1
         else:
            if (abs(b[0] - a[0]) == 1) and \
               (abs(b[1] - a[1]) == 1):
               return 2
            else:
               return 1

   def Value3(self,T):
      """
      Returns 3 if three adjacent tuples,
      otherwise returns what the maximum
      of Value2 applied to all pairs in T.
      """
      a = T[0]; b = T[1]; c = T[2]
      if (a[0] == b[0] == c[0]): return 3
      if (a[1] == b[1] == c[1]): return 3
      if (a[0] == b[0] - 1 == c[0] - 2):
         if (a[1] == b[1] - 1 == c[1] - 2):
            return 3
         if (a[1] == b[1] + 1 == c[1] + 2):
            return 3
      v12 = self.Value2([a,b])
      v13 = self.Value2([a,c])
      v23 = self.Value2([b,c])
      return max([v12,v13,v23])

   def Value(self,k):
      """
      The value of a board equals how
      many k's are next to each other.
      """
      T = []
      for i in range(0,3):
         for j in range(0,3):
            if self.m[i,j] == k:
               T.append((i,j))
      if len(T) == 0: return 0
      if len(T) == 1: return 1
      if len(T) == 2: return self.Value2(T)
      if len(T) == 3: return self.Value3(T)
