title: python3 reversi game code
body: <p>I have a 2 files for the reversi game for python 3. My first file is called reversi.py. 
  It implements (a) the high level control of the game play (e.g., getting moves from the computer player and the human player, determining whether a player runs out of moves, determining the end of the game and declare the result of the game), (b) the rendering of the game through QuickDraw, as well as (c) taking the input from the human player.</p>
  
  <p>Heres the file:</p>
  
  <pre><code>from game import *
  from copy import deepcopy
  from time import sleep
  import sys
  from subprocess import PIPE,Popen
  from threading import Thread
  from queue import Queue,Empty
  
  
  
  def ParseEvent() :
      r=receive()
      if r==None:return None,None
      s=[x.rstrip().strip() for x in r.split(":")]
      return s[0],s[1]
  
  
  def highlight(move):
      send( 'color 255 0 0\n circle %d %d 11\n' % \
          (240+(move[0]+0.5)*40, 100+(move[1]+0.5)*40))
  
  
  def stone(x,y,turn):
      send('color %d %d %d\n' % \
          (255*(1-turn),255*(1-turn),255*(1-turn)))
      send('fillcircle %d %d %d\n' % \
          (240+(x+0.5)*40, 100+(y+0.5)*40, 17))
  
  
  def draw(board):
      send('color 20 20 20\n clear\n color 15 15 100\n')
      send( 'button button1 600 20 100 20 "Calculate W:L"')
      send('fillrect %d %d %d %d\n' % (240,100,320,320))
      send('color 0 70 0\n') 
      for i in range(1,8):
          send('line %d %d %d %d\n' %\
              (240+i*40,100, 240+i*40,420))
          send('line %d %d %d %d\n' %\
              (240, 100+i*40, 560, 100+i*40))
      for i in range(8):
          for j in range(8):
              if board[i][j] &gt;= 0:
                  stone(i, j, board[i][j])
  
  def makeBoard():
      board = []
      for i in range(8):
          board.append([])
          for j in range(8):
              board[i].append(-1)  
      board[3][3], board[4][4], board[3][4], board[4][3] = 0,0,1,1
      return board
  
  
  
  def _queueqd(ip,q):
      for line in iter(ip.readline,b''):
          q.put(line)
      ip.close()
  
  def send(*args):
      s=""
      for a in args:
          s+=str(a)
          if s[-1]!=" ":s+=" "
      if s!="":
          op.write((s[:-1]+"\n").encode('utf-8'))
      else:
          op.write("\n".encode('utf-8'))
  
  def receive():
      try:
          return qdq.get_nowait().decode('utf-8')[:-1]
      except Empty:
          return None
  def running():
      return qdp.poll()==None
  
  
  def simulate(numTimes=1000):
      w=0
      b=0
      for i in range(numTimes):
          goesFirst=i&amp;1
          gb=makeBoard()
          sg = Game(gb, goesFirst)
          count = 4
          while count &lt; 64: # max num of stones is 64
              sg.get_moves()
              if sg.moves == []: 
                  sg.turn = 1 - sg.turn
                  sg.get_moves()
                  if sg.moves!= []:
                      continue 
                  sg.turn = 1 - sg.turn
                  break 
              if sg.turn==0:
                  mv = sg.select_move()
              else:
                  mv= sg.moves[int(len(sg.moves)*random.random())]
              sg.play_move(mv)
              sg.turn=1-sg.turn
              count+=1
          num_white, num_black = sg.final_result()
          if num_white&gt;num_black:w+=1
          if num_black&gt;num_white:b+=1
      return w/b
  
  try:
      qdp = Popen("java -jar quickdraw.jar",shell=True,stdout=PIPE,stdin=PIPE)
      op=qdp.stdin
      qdq = Queue()
      qdt = Thread(target=_queueqd,args=(qdp.stdout,qdq))
      qdt.daemon=True
      qdt.start()
  except:
      print("quickdraw.jar must be in the same directory as this python script.")
      quit()
  
  send( "mouseclick True\n" )
  # initialize the board, get ready for the game 
  
  board =makeBoard()
  draw(board) 
  
  
  # game time, let's play...
  # human player is white and moves first
  
  g = Game(board, 0)
  count = 4
  while count &lt; 64: # max num of stones is 64
      g.get_moves()
      if g.moves == []: 
          g.turn = 1 - g.turn
          g.get_moves()
          if  g.moves!= []:
              continue 
          g.turn = 1 - g.turn
          break 
      if g.turn == 0:
          while running():
              event, val = ParseEvent()
              if event == "MouseClicked":
                  val=[ int(x) for x in val.split(",")]
                  move = [(val[0]-240)//40, (val[1]-100)//40]
                  if move in g.moves: break
              elif event=="ButtonClicked":
                  send("colour 20 20 20\nfillrect 600 50 200 50\ncolour 255 255 255")
                  send('text "Calculating..." 600 80')
                  r=simulate()
                  send("colour 20 20 20\nfillrect 600 50 200 50\ncolour 255 255 255")
                  send("text ",'"W:L=',r,'"'," 600 80")
      else:
          move = g.select_move()
      stone(move[0], move[1], g.turn)
      highlight(move)
      sleep(1)
      board = deepcopy(g.board)
      g.play_move(move)
      g.turn=1-g.turn
      for i in range(8):
          for j in range(8):
              if board[i][j]!= g.board[i][j]:
                  stone(i,j,1-g.turn)
      sleep(1)
      stone(move[0], move[1], 1-g.turn) # redraw to de-highlight
      count += 1
  
  
  # game over, let's announce the result:
  
  num_white, num_black = g.final_result()
  send('color 255 255 255\n')
  if num_black &gt; num_white:
      send('text "black wins!" 370 470\n')
  elif num_black &lt; num_white:
      send('text "white wins!" 370 470\n')
  else:
      send('text "tie!" 390 470\n')
  send('text "black:" 325 500\n')
  send('text "%d" 375 500\n' % num_black)
  send('text "white:" 425 500\n')
  send('text "%d" 475 500\n' % num_white)
  
  while running():
      pass
  </code></pre>
  
  <p>And this file is done. My second file is called Game.py. The first file imports this one for the moves the player can make.</p>
  
  <pre><code>import random
  
  class Game:
      delta = [[0,-1],[1,-1],[1,0],[1,1],[0,1],\
                  [-1,1],[-1,0],[-1,-1]]
  
      def __init__(self, board, turn):
          self.board = board
          self.turn = turn
          self.moves = self.get_moves()
  
      def check_move(self, move, d):
          pass #which I have to figure out!
  
      def get_moves(self):
          pass ##################
  
      def select_move(self):
          pass ##################
  
      def play_move(self, move): 
          m,n=move[0],move[1]
          for d in range(8):
              i, j = m, n
              if self.check_move(move,d):
                  i, j = i+self.delta[d][0], j+self.delta[d][1]
                  while self.board[i][j] == 1-self.turn:
                      self.board[i][j] = self.turn
                      i, j = i+self.delta[d][0], j+self.delta[d][1]
          self.board[m][n]=self.turn
  
      def final_result(self): 
          black, white = 0, 0   # color 0 is white
          for i in range(8):
              for j in range(8):
                  if self.board[i][j] == 0: white += 1
                  elif self.board[i][j] == 1: black += 1
          return white,black
  </code></pre>
  
  <p>I am supposed to fill in the three missing definitions. The check move(self, move, d) method checks whether a given move is validated along a certain direction d, assuming the given turn of play. It returns True or False accordingly. In other words, if starting at the grid specified by move, a number of opponent stones along the direction d can be captured, then a True should be returned. This method may be convenient to use in other methods such as get moves() and play move().The get moves(self) method finds all the valid moves for the current turn, and returns them in a list. For example, if there are two moves at [2,4] and [3,6], then the return value should be [[2,4], [3,6]]. The select move(self) method picks a move from self.move and returns it. Apparently the easiest way is to return a random move. SO basically I know what each of the three functions should do and why they are needed for the game, but I don't know exactly how to code them... any help or guidance would be appreciated!!</p>
  
  <p>so basically I have this is a base for "check_move" function:</p>
  
  <pre><code>def check_move(self,move,d):
      check neighboring tile:
          if empty:
              False #can't move
          if enemy present:
              while there are enemy pieces:
                  True #can move
  </code></pre>
  
  <p>is that the right direction?</p>
  
  <p>ALso for the get_moves I have this reasoning:</p>
  
  <pre><code>def get_moves(self): # grid[ij]
      for i in range 
      for j in range
          check for possible move directions:
              check move again:
                  if yes then append[ij] to a list of valid moves
          return list of valid moves
  </code></pre>