diff --git a/CMakeLists.txt b/CMakeLists.txt
index c34b0070f919fe2751f4c8f3b59bbfad33087b5c..b0b539b82f761f1a73c941751a885edd7a721dd2 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,5 +1,5 @@
 cmake_minimum_required(VERSION 2.8.3)
-project(board_status)
+project(board_state)
 
 ## Compile as C++11, supported in ROS Kinetic and newer
 # add_compile_options(-std=c++11)
@@ -21,7 +21,7 @@ find_package(catkin REQUIRED COMPONENTS
 ## Uncomment this if the package has a setup.py. This macro ensures
 ## modules and global scripts declared therein get installed
 ## See http://ros.org/doc/api/catkin/html/user_guide/setup_dot_py.html
-# catkin_python_setup()
+catkin_python_setup()
 
 ################################################
 ## Declare ROS messages, services and actions ##
@@ -50,8 +50,8 @@ find_package(catkin REQUIRED COMPONENTS
 ## Generate messages in the 'msg' folder
 add_message_files(
   FILES
-  StrList.msg
-#   Message2.msg
+  TokenMsg.msg
+  BoardMsg.msg
 )
 
 ## Generate services in the 'srv' folder
diff --git a/launch/board_state.launch b/launch/board_state.launch
new file mode 100644
index 0000000000000000000000000000000000000000..0acf3fa399146af023a36f68fe6b2c5fa9bc7b9c
--- /dev/null
+++ b/launch/board_state.launch
@@ -0,0 +1,24 @@
+<launch>
+  <node pkg="board_state" type="main.py" name="board_state" output="screen"/>
+
+  <!-- Initial tokens locations -->
+  <rosparam param="initial_board">
+    {'1': '0', "2": '0', "3": '0', "4": '0', "5": '0',
+                   "6": '0', "7": '0', "8": '0', "9": '0', "10": '0',
+                   "11": '1', "12": '2', "13": '3', "14": '4', "15": '5',
+                   "16": '6', "17": '7', "18": '8', "19": '9', "20": '10'}
+  </rosparam>
+
+  
+
+ <rosparam param="tokens_number">
+    [ '111', '158',  '183','192', '253','328', '376', '394', '449','463', '475', '486','517', '744',  '819']
+  </rosparam>
+
+  <rosparam param="rfid_id">
+   3581181951 3306978559 894864895 2247134207 1439793151 3315042303 1972340735 2768466943 2509992703 2777051135 4117136895 3852242175 88436991 2504166399 356806911
+</rosparam>
+
+
+
+</launch>
diff --git a/msg/StrList.msg b/msg/BoardMsg.msg
similarity index 100%
rename from msg/StrList.msg
rename to msg/BoardMsg.msg
diff --git a/msg/TokenMsg.msg b/msg/TokenMsg.msg
new file mode 100644
index 0000000000000000000000000000000000000000..2daae82e1925c9e0db94d0c4428d0152622c4f8c
--- /dev/null
+++ b/msg/TokenMsg.msg
@@ -0,0 +1,4 @@
+string[] detected_token
+bool picked
+bool placed
+bool moved_back
diff --git a/package.xml b/package.xml
index a7288bbfb9cc223c70af54a205b00a6532d0ecaf..d5735f180c6f7009d3cff6b25f2ec0ed8c43c3b4 100644
--- a/package.xml
+++ b/package.xml
@@ -1,8 +1,8 @@
 <?xml version="1.0"?>
 <package format="2">
-  <name>board_status</name>
+  <name>board_state</name>
   <version>0.0.0</version>
-  <description>The board_status package</description>
+  <description>The board_state package</description>
 
   <!-- One maintainer tag required, multiple allowed, one person per tag -->
   <!-- Example:  -->
diff --git a/setup.py b/setup.py
new file mode 100644
index 0000000000000000000000000000000000000000..95d8db3d6344a52cb91dc8f8ef3d703cb974b063
--- /dev/null
+++ b/setup.py
@@ -0,0 +1,6 @@
+from distutils.core import setup
+from catkin_pkg.python_setup import generate_distutils_setup
+
+d = generate_distutils_setup(packages=['board_state'], package_dir={'':'src'})
+
+setup(**d)
diff --git a/sounds/beep.mp3 b/sounds/beep.mp3
new file mode 100644
index 0000000000000000000000000000000000000000..51e0670aeaa0c0cc200a66abe99ce6241125dac6
Binary files /dev/null and b/sounds/beep.mp3 differ
diff --git a/sounds/pair.ogg b/sounds/pair.ogg
new file mode 100644
index 0000000000000000000000000000000000000000..4a592345fe829e49ce97137424b1ae7eb8f755cb
Binary files /dev/null and b/sounds/pair.ogg differ
diff --git a/src/board_state/__init__.py b/src/board_state/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/src/board_state/main.py b/src/board_state/main.py
new file mode 100755
index 0000000000000000000000000000000000000000..f616afb73743b91e9d08ad249071841675f2a938
--- /dev/null
+++ b/src/board_state/main.py
@@ -0,0 +1,318 @@
+#!/usr/bin/python
+import os
+#This is necessary to import code that is not rosbased in the main.py
+path = os.path.abspath(__file__)
+dir_path = os.path.dirname(path)
+parent_dir_of_file = os.path.dirname(dir_path)
+parent_parent_dir_of_file = os.path.dirname(parent_dir_of_file)
+
+
+#ros import
+import time
+import rospy
+from std_msgs.msg import String, Int8
+import pygame
+
+
+from iri_rfid_board_scanner.msg import BoardIds
+from board_state.msg import TokenMsg
+from board_state.msg import BoardMsg
+
+class BoardGame():
+  def __init__(self):
+    rospy.init_node('big_hero', anonymous=True)
+    # subscriber for getting info from the board
+    rospy.Subscriber("/rfid_board_scanner/board_ids", BoardIds, self.get_electro_board_callback)
+
+    self.electro_board = list()
+    self.electro_board_with_tokens = dict()
+    self.current_board = dict()
+    self.initial_board = dict()
+    self.placed_token = (0,0,0)
+    self.picked_token = (0,0)
+
+    #getting the ids from the rfids sensors
+    self.ids = list(map(int, rospy.get_param('/rfid_id').split()))
+    self.ids = [ int(self.ids[i]) for i in range(len(self.ids))]
+
+    #get the numbers for playing the game
+    self.tokens = rospy.get_param('tokens_number')
+    #coupling ids with numbers
+    self.electro_board_from_ids_to_tokens = self.convert_electro_board_ids_to_tokens(self.ids, self.tokens)
+
+  def play_sound(self, file_path, sleep):
+    '''
+    play a sound using pygame
+    '''
+    pygame.mixer.init()
+    # pygame.mixer.music.load(parent_dir_of_file+'/sounds/wrong_move_trim.mp3')
+    pygame.mixer.music.load(parent_parent_dir_of_file + file_path)
+    pygame.mixer.music.play(0)
+    time.sleep(sleep)
+
+  def get_tokens_id(self):
+    '''
+    get the tokens id from the board
+    '''
+    return self.tokens
+
+  def get_initial_board(self):
+    '''
+    get initial board status
+    '''
+    return self.initial_board.copy()
+
+  #get value from the topic
+  def get_electro_board_ids(self):
+    '''
+    get the ids from the board, these ids need to be converted to the id on the top of the token
+    '''
+    return self.electro_board
+
+  #topic subscriber
+  def get_electro_board_callback(self, msg):
+    '''callback from the topic subscriber'''
+    self.electro_board = (msg.id)
+
+  def get_electro_board(self):
+    '''get the board with the correct ids on the top'''
+    return self.get_tokens_by_ids(self.electro_board_from_ids_to_tokens, self.electro_board)
+
+  def convert_electro_board_ids_to_tokens(self, ids, tokens):
+    '''
+    :param ids:
+    :param tokens:
+    :return: this method creates a dic where the ids are the keys and the values are the tokens
+    '''
+    from_ids_to_tokens = dict()
+    for i in range(len(ids)):
+      from_ids_to_tokens[ids[i]] = tokens[i]
+    return from_ids_to_tokens
+
+  def get_tokens_by_ids(self, from_ids_to_tokens_dict, msg):
+    '''
+    :param electro_board:
+    :param msg:
+    :return: given a dictionary where key is the id and value is the token change the msg according (0 empty !0 a token id)
+    '''
+    for i in range(len(msg)):
+        if msg[i] == 0:
+          # i+1 because the id start
+          self.electro_board_with_tokens[i+1] = '0'
+        else:
+          self.electro_board_with_tokens[i+1] = from_ids_to_tokens_dict.get(msg[i])
+    return self.electro_board_with_tokens
+
+  def get_token_location_from_board_state(self, previous_board, token):
+    '''
+    :param: token
+    :return: the location of the token given as input
+    '''
+    for key, val in previous_board.items():
+      if val == token:
+        return key
+
+  def detect_grasped_token(self, previous_board, current_board):
+    '''
+	this function detects if a token has been picked
+	Args:
+	  previous_board: the status of the board at time t-1
+	  current_board: the status of the board at time t
+	'''
+
+    picked_token = None
+    for k in current_board.keys():
+      if current_board.get(k) == '0' and previous_board.get(k) != current_board.get(k):
+        # if the location now is empty check where it was before
+        token_id = previous_board.get(k)
+        location = k
+        picked_token = (str(token_id), str(location))
+    return picked_token
+
+  def detect_placed_token(self, picked_token, current_board):
+      '''
+  	this function detects when token has been placed on the board
+  	Args:
+  	  picked_token: the token the user has picked
+  	  current_board: the status of the board at time t
+  	'''
+      token_id, loc_from = picked_token
+      move_it_back = False
+      placed_token = ()
+      for key, val in current_board.items():
+        if token_id == val and str(key) != loc_from:
+          loc_to = key
+          print("placed in a different location")
+          placed_token = (str(token_id), str(loc_from), str(loc_to))
+        elif token_id == val and str(key) == loc_from:
+          loc_to = key
+          print("placed in the same location")
+          placed_token = (str(token_id), str(loc_from), str(loc_to))
+          move_it_back = True
+      return placed_token, move_it_back
+
+  def detect_move(self, previous_board, current_board):
+    '''
+    	this function detects if a token has moved from loc_from to loc_to
+    	Args:
+    	  previous_board: the status of the board at time t-1
+    	  current_board: the status of the board at time t
+    	'''
+
+    move = ()
+    new_location = 0
+    for x1 in previous_board.keys():
+        z = current_board.get(x1) == previous_board.get(x1)
+        if not z:
+            #print('location', x1)
+            if (current_board.get(x1))!='0':
+              token = (current_board.get(x1))
+            #check where the token is in the new configuration
+              prev_location = self.get_token_location_from_board_state(previous_board, token)
+              for key, value in current_board.items():
+                if token == value and prev_location !=key:
+                  new_location = key
+              move = (token, prev_location, new_location)
+    return move
+
+  def get_current_board(self):
+    '''get the current board status'''
+    self.current_board = self.get_electro_board()
+    return self.current_board.copy()
+
+  def update_board(self, token_id, location):
+    '''
+    update the current board given a token and a location
+    Args
+      token_id: the number
+      location: its location
+    Return:
+      a board with the token token_id in location location
+    '''
+    if type(token_id)!=str:
+      token_id = str(token_id)
+
+
+    for loc, token in self.current_board.items():
+      if token == (token_id):
+        self.current_board[loc] = '0'
+
+    for key in self.current_board.keys():
+      if location == key:
+        self.current_board[key] = token_id
+
+
+
+def wait_for_subscribers(publisher):
+    wait_rate = rospy.Rate(20)
+    while not publisher.get_num_connections():
+        wait_rate.sleep()
+
+
+def main():
+  board_game = BoardGame()
+  ###############################################################
+  rospy.init_node('big_hero', anonymous=True)
+  pub_move = rospy.Publisher('detected_move', TokenMsg, queue_size=10)
+  pub_board_status = rospy.Publisher('board_status', BoardMsg, queue_size=10)
+  rate = rospy.Rate(10)  # 10hz
+  event_counter = 0
+  #this is necessary in order to give the time to the board to start publishing
+  rospy.sleep(2)
+
+  #initialise the publisher and the board
+  wait_for_subscribers(pub_move)
+  msg_move = TokenMsg()
+  msg_move.detected_token = []
+  msg_move.picked = False
+  msg_move.placed = False
+  msg_move.moved_back = False
+  pub_move.publish(msg_move)
+
+  wait_for_subscribers(pub_board_status)
+
+  initial_board = board_game.get_current_board()
+  current_board = initial_board
+  msg_board = BoardMsg()
+  msg_board.data = current_board.values()
+  pub_board_status.publish(msg_board)
+
+  token_picked = False
+  while not rospy.is_shutdown():
+    detected_board = board_game.get_current_board()
+    msg_board.data = detected_board.values()
+    pub_board_status.publish(msg_board)
+
+
+    #check if a token has been picked
+    picked_token = board_game.detect_grasped_token(current_board, detected_board)
+
+    #if a token has been picked
+    if (picked_token)!=None:
+      print("current ", current_board)
+      print("detected ", detected_board)
+      print("grasped token:", picked_token)
+
+      #prepare the message and publish it
+      msg_move.detected_token = picked_token
+      msg_move.picked = True
+      #detected_board.values()
+      board_game.play_sound("/sounds/pull-out.ogg", 0.2)
+      pub_move.publish(msg_move)
+      event_counter += 1
+      rate.sleep()
+      current_board = board_game.get_current_board()
+      msg_board.data = current_board.values()
+      pub_board_status.publish(msg_board)
+      board_game.picked_token = picked_token
+      #print("token {}, from {}, to {}".format(detected_action[1], detected_action[2], detected_action[3]))
+      print("***********************************")
+      print("Picked token " + str(msg_move.detected_token))
+      print("Picked "+ str(msg_move.picked))
+      print("Placed " + str(msg_move.placed))
+      print("Moved back " + str(msg_move.moved_back))
+      print("***********************************")
+      token_picked = True
+
+    #check when a picked token is going to be placed by the user
+    elif (token_picked):
+      placed_token, moved_back = board_game.detect_placed_token(board_game.picked_token, detected_board)
+      if len(placed_token)>0:
+        board_game.play_sound("/sounds/pull-out.ogg", 0.2)
+        msg_move.detected_token = placed_token
+        msg_move.picked = False
+        msg_move.placed = True
+        msg_move.moved_back = moved_back
+        pub_move.publish(msg_move)
+        event_counter += 1
+        rate.sleep()
+        current_board = board_game.get_current_board()
+        msg_board.data = current_board.values()
+        pub_board_status.publish(msg_board)
+        board_game.placed_token = placed_token
+        token_picked = False
+        print("***********************************")
+        print("Picked token " + str(msg_move.detected_token))
+        print("Picked " + str(msg_move.picked))
+        print("Placed " + str(msg_move.placed))
+        print("Moved back " + str(msg_move.moved_back))
+        print("***********************************")
+    else:
+      msg_move.detected_token = []
+      msg_move.picked = False
+      msg_move.placed = False
+      msg_move.moved_back = False
+
+
+if __name__ == '__main__':
+    try:
+        main()
+    except rospy.ROSInterruptException:
+        pass
+
+
+
+
+
+
+