forked from almostimplemented/checkers
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathrobocheckers_link.py
130 lines (102 loc) · 3.71 KB
/
robocheckers_link.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
"""
This module is used for communication between almostimplemented game
engine and RoboCheckers node
"""
import rospy
from std_msgs.msg import String
NONE = 0b00
MOVE = 0b01
OPTS = 0b10
class RosComm(object):
"""
Class initializing ROS Node with one publisher and one subscriber
for communication with game_intergace node
"""
def __init__(self):
# Node initialization
rospy.init_node('game_logic')
self.ai_move = rospy.Publisher('/robocheckers/ai_move', String, queue_size=10)
rospy.Subscriber('/robocheckers/human_turn', String, self.receive_human_turn)
# Prepare human_turn tuple attribute
self.human_turn_tuples = None
self.human_move_list = None
# Prepare player_order attribute, 0 -> Human go first, 1 -> AI go first
self.player_order = None
def send_ai_move(self, move, options, format_data):
"""
Method for sending data to game_interface node
tuple move:
list of tuples options:
int format:
"""
if format_data & MOVE:
move = self.tuple_move_to_list(move)
if format_data & OPTS:
options_tuples = []
for option in options:
options_tuples.append(self.tuple_move_to_list(option))
options = options_tuples
msg = '|'.join(str(e) for e in [move, options])
self.ai_move.publish(msg)
def receive_human_turn(self, data):
"""
Method for receiving data from game_interface node
"""
self.human_turn_tuples = eval(data.data)
def get_human_move_list(self):
"""
Method for recalculating move data from 2-coords to 1-coord
"""
while not self.human_turn_tuples:
continue
rospy.sleep(0.001)
# Calculate the square number from coordinations
human_turn = []
for pos in self.human_turn_tuples:
tmp = (pos[1]-1)*4 + (pos[0]+1-(pos[1]%2))/2
human_turn.append(tmp)
# If player_order is 1, rotate the chessboard
if self.player_order:
human_turn[0] = 33 - human_turn[0]
human_turn[1] = 33 - human_turn[1]
# Change individual positions through the move to list of moves
self.human_move_list = []
for i in range(len(human_turn)-1):
self.human_move_list.append((human_turn[i], human_turn[i+1]))
self.human_turn_tuples = None
return self.human_move_list
def tuple_move_to_list(self, ai_move):
"""
Method for recalculating move data from tuple of ints to 2 list of tuples
"""
ai_move_list = []
for pos in ai_move:
y = int((pos-1)/4+1)
x = ((pos-1)%4+1)*2-1+y%2
# If player_order is 1, rotate the chessboard
if self.player_order:
x = 9-x
y = 9-y
ai_move_list.append((x, y))
return ai_move_list
def get_starting_player(self):
"""
Method to determine which player go first
"""
if self.player_order != None:
return None
while True:
while not self.human_turn_tuples:
continue
rospy.sleep(0.001)
if (0, 1) in self.human_turn_tuples:
self.player_order = 1
break
elif (0, 0) in self.human_turn_tuples:
self.player_order = 0
break
else:
print "ERROR: Invalid starting message! Expecting '[(0, 0)]' or '[(0, 1)]'!"
self.human_turn_tuples = None
self.human_turn_tuples = None
return self.player_order