Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
UCC
progcomp2013
Commits
f7cca7e9
Commit
f7cca7e9
authored
Apr 05, 2013
by
Sam Moore
Browse files
Changes to Networking code
Don't work
parent
7a6c3dd9
Changes
4
Show whitespace changes
Inline
Side-by-side
qchess/qchess.py
View file @
f7cca7e9
...
...
@@ -1131,42 +1131,98 @@ import select
network_timeout_start
=
-
1.0
# Timeout in seconds to wait for the start of a message
network_timeout_delay
=
1.0
# Maximum time between two characters being received
class
Network
():
def
__init__
(
self
,
colour
,
address
=
None
):
class
Network
(
Player
):
def
__init__
(
self
,
colour
,
address
=
(
None
,
4562
),
baseplayer
=
None
):
if
baseplayer
!=
None
:
name
=
baseplayer
.
name
+
" --> @network"
else
:
name
=
"<-- @network"
Player
.
__init__
(
self
,
name
,
colour
)
debug
(
"Colour is "
+
str
(
self
.
colour
))
self
.
socket
=
socket
.
socket
()
self
.
socket
.
setsockopt
(
socket
.
SOL_SOCKET
,
socket
.
SO_REUSEADDR
,
1
)
self
.
baseplayer
=
baseplayer
#self.socket.setblocking(0)
self
.
server
=
(
address
==
None
)
self
.
address
=
address
self
.
server
=
(
address
[
0
]
==
None
)
if
colour
==
"white"
:
self
.
port
=
4562
else
:
self
.
port
=
4563
if
self
.
colour
==
"black"
:
self
.
address
=
(
self
.
address
[
0
],
self
.
address
[
1
]
+
1
)
self
.
src
=
None
debug
(
str
(
self
)
+
":"
+
str
(
self
.
address
))
# print str(self) + " listens on port " + str(self.port)
self
.
board
=
None
if
address
==
None
:
def
connect
(
self
):
if
self
.
address
[
0
]
==
None
:
self
.
host
=
"0.0.0.0"
#socket.gethostname() # Breaks things???
self
.
socket
.
bind
((
self
.
host
,
self
.
port
))
self
.
socket
.
bind
((
self
.
host
,
self
.
address
[
1
]
))
self
.
socket
.
listen
(
5
)
self
.
src
,
self
.
address
=
self
.
socket
.
accept
()
self
.
src
,
self
.
actual_address
=
self
.
socket
.
accept
()
self
.
src
.
send
(
"ok
\n
"
)
if
self
.
get_response
()
==
"QUIT"
:
s
=
self
.
get_response
()
if
s
==
"QUIT"
:
self
.
src
.
close
()
return
elif
s
!=
"ok"
:
self
.
src
.
close
()
self
.
__init__
(
colour
,
(
self
.
address
[
0
],
int
(
s
)),
baseplayer
)
return
else
:
self
.
host
=
address
self
.
socket
.
connect
((
address
,
self
.
port
))
self
.
socket
.
connect
(
self
.
address
)
self
.
src
=
self
.
socket
self
.
src
.
send
(
"ok
\n
"
)
if
self
.
get_response
()
==
"QUIT"
:
s
=
self
.
get_response
()
if
s
==
"QUIT"
:
self
.
src
.
close
()
return
elif
s
!=
"ok"
:
self
.
src
.
close
()
self
.
address
=
(
address
,
self
.
port
)
self
.
__init__
(
colour
,
(
self
.
address
[
0
],
int
(
s
)),
baseplayer
)
return
def
select
(
self
):
if
self
.
baseplayer
!=
None
:
s
=
self
.
baseplayer
.
select
()
self
.
send_message
(
str
(
s
[
0
])
+
" "
+
str
(
s
[
1
]))
return
s
return
map
(
int
,
self
.
get_response
().
split
(
" "
))
def
get_move
(
self
):
if
self
.
baseplayer
!=
None
:
s
=
self
.
baseplayer
.
get_move
()
self
.
send_message
(
str
(
s
[
0
])
+
" "
+
str
(
s
[
1
]))
return
s
return
map
(
int
,
self
.
get_response
().
split
(
" "
))
def
update
(
self
,
result
):
if
self
.
baseplayer
!=
None
:
result
=
self
.
baseplayer
.
update
(
result
)
self
.
send_message
(
result
)
return
result
if
self
.
server
:
self
.
send_message
(
result
)
else
:
s
=
self
.
get_response
()
if
self
.
board
!=
None
:
self
.
board
.
update
(
s
)
def
__str__
(
self
):
return
"Network<"
+
str
(
self
.
colour
)
+
","
+
str
(
self
.
baseplayer
)
+
">:"
+
str
(
self
.
address
)
def
get_response
(
self
):
debug
(
str
(
self
)
+
" get_response called..."
)
# Timeout the start of the message (first character)
if
network_timeout_start
>
0.0
:
ready
=
select
.
select
([
self
.
src
],
[],
[],
network_timeout_start
)[
0
]
...
...
@@ -1189,6 +1245,7 @@ class Network():
else
:
raise
Exception
(
"UNRESPONSIVE"
)
debug
(
str
(
self
)
+
" get_response returns "
+
s
.
strip
(
"
\r\n
"
))
return
s
.
strip
(
"
\r\n
"
)
def
send_message
(
self
,
s
):
...
...
@@ -1202,6 +1259,8 @@ class Network():
else
:
raise
Exception
(
"UNRESPONSIVE"
)
debug
(
str
(
self
)
+
" send_message sent "
+
s
)
def
check_quit
(
self
,
s
):
s
=
s
.
split
(
" "
)
if
s
[
0
]
==
"QUIT"
:
...
...
@@ -1210,151 +1269,17 @@ class Network():
game
.
stop
()
return
True
def
quit
(
self
,
result
):
if
self
.
baseplayer
!=
None
:
self
.
send_message
(
"QUIT"
)
class
NetworkSender
(
Player
,
Network
):
def
__init__
(
self
,
base_player
,
address
=
None
):
self
.
base_player
=
base_player
Player
.
__init__
(
self
,
base_player
.
name
,
base_player
.
colour
)
self
.
address
=
address
def
connect
(
self
):
nAttempts
=
3
for
i
in
range
(
nAttempts
):
try
:
Network
.
__init__
(
self
,
self
.
colour
,
self
.
address
)
debug
(
str
(
self
)
+
" connected to "
+
str
(
self
.
address
))
return
except
Exception
,
e
:
debug
(
str
(
self
)
+
" attempt "
+
str
(
i
)
+
": "
+
str
(
e
.
message
))
raise
Exception
(
"NETWORK - Can't connect to "
+
str
(
self
.
address
))
def
select
(
self
):
[
x
,
y
]
=
self
.
base_player
.
select
()
choice
=
self
.
board
.
grid
[
x
][
y
]
s
=
str
(
x
)
+
" "
+
str
(
y
)
#debug(str(self) + " sends: " + str(s))
self
.
send_message
(
s
)
return
[
x
,
y
]
def
get_move
(
self
):
[
x
,
y
]
=
self
.
base_player
.
get_move
()
s
=
str
(
x
)
+
" "
+
str
(
y
)
#debug(str(self) + " sends: " + str(s))
self
.
send_message
(
s
)
return
[
x
,
y
]
def
update
(
self
,
s
):
self
.
base_player
.
update
(
s
)
if
self
.
server
==
True
:
#debug(str(self) + " sends: " + str(s))
self
.
send_message
(
s
)
return
s
s
=
s
.
split
(
" "
)
[
x
,
y
]
=
map
(
int
,
s
[
0
:
2
])
selected
=
self
.
board
.
grid
[
x
][
y
]
if
selected
!=
None
and
selected
.
colour
==
self
.
colour
and
len
(
s
)
>
2
and
not
"->"
in
s
:
s
=
" "
.
join
(
s
[
0
:
3
])
for
i
in
range
(
2
):
if
selected
.
types
[
i
][
0
]
!=
'?'
:
s
+=
" "
+
str
(
selected
.
types
[
i
])
else
:
s
+=
" unknown"
#debug(str(self) +" sending: " + str(s))
self
.
send_message
(
s
)
def
quit
(
self
,
final_result
):
self
.
base_player
.
quit
(
final_result
)
#self.src.send("QUIT " + str(final_result) + "\n")
self
.
src
.
close
()
def
__str__
(
self
):
s
=
"NetworkSender:"
if
self
.
server
:
s
+=
"server"
else
:
s
+=
"client"
s
+=
":"
+
str
(
self
.
address
)
return
s
class
NetworkReceiver
(
Player
,
Network
):
def
__init__
(
self
,
colour
,
address
=
None
):
s
=
"@network"
if
address
!=
None
:
s
+=
":"
+
str
(
address
)
Player
.
__init__
(
self
,
s
,
colour
)
self
.
address
=
address
self
.
board
=
None
def
connect
(
self
):
nAttempts
=
3
for
i
in
range
(
nAttempts
):
try
:
Network
.
__init__
(
self
,
self
.
colour
,
self
.
address
)
debug
(
str
(
self
)
+
" connected to "
+
str
(
self
.
address
))
return
except
Exception
,
e
:
debug
(
str
(
self
)
+
" attempt "
+
str
(
i
)
+
": "
+
str
(
e
.
message
))
raise
Exception
(
"NETWORK - Can't connect to "
+
str
(
self
.
address
))
def
select
(
self
):
s
=
self
.
get_response
()
#debug(str(self) +".select reads: " + str(s))
[
x
,
y
]
=
map
(
int
,
s
.
split
(
" "
))
if
x
==
-
1
and
y
==
-
1
:
#print str(self) + ".select quits the game"
with
game
.
lock
:
game
.
final_state
=
"network terminated "
+
self
.
colour
game
.
stop
()
return
[
x
,
y
]
def
get_move
(
self
):
s
=
self
.
get_response
()
#debug(str(self) +".get_move reads: " + str(s))
[
x
,
y
]
=
map
(
int
,
s
.
split
(
" "
))
if
x
==
-
1
and
y
==
-
1
:
#print str(self) + ".get_move quits the game"
with
game
.
lock
:
game
.
final_
state
=
"network terminated "
+
self
.
colour
game
.
final_
result
=
result
game
.
stop
()
return
[
x
,
y
]
def
update
(
self
,
result
):
if
self
.
server
==
True
:
return
result
s
=
self
.
get_response
()
#debug(str(self) + ".update reads: " + str(s))
if
not
"->"
in
s
.
split
(
" "
):
self
.
board
.
update
(
s
,
sanity
=
False
)
return
s
def
quit
(
self
,
final_result
):
self
.
src
.
close
()
def
__str__
(
self
):
s
=
"NetworkReceiver:"
if
self
.
server
:
s
+=
"server"
else
:
s
+=
"client"
s
+=
":"
+
str
(
self
.
address
)
return
s
# --- network.py --- #
import
threading
...
...
@@ -1583,8 +1508,8 @@ class GameThread(StoppableThread):
for
p
in
self
.
players
:
with
self
.
lock
:
if
isinstance
(
p
,
Network
Sender
)
:
self
.
state
[
"turn"
]
=
p
.
base
_
player
# "turn" contains the player who's turn it is
if
isinstance
(
p
,
Network
)
and
p
.
baseplayer
!=
None
:
self
.
state
[
"turn"
]
=
p
.
baseplayer
# "turn" contains the player who's turn it is
else
:
self
.
state
[
"turn"
]
=
p
#try:
...
...
@@ -1593,16 +1518,14 @@ class GameThread(StoppableThread):
if
self
.
stopped
():
break
if
not
(
isinstance
(
p
,
Network
)
and
p
.
server
==
False
)
:
if
isinstance
(
p
,
Network
)
==
False
or
p
.
server
==
True
:
result
=
self
.
board
.
select
(
x
,
y
,
colour
=
p
.
colour
)
else
:
#debug(str(self) + " don't update local board"
)
result
=
""
result
=
p
.
get_response
(
)
self
.
board
.
update
(
result
)
result
=
p
.
update
(
result
)
for
p2
in
self
.
players
:
if
p2
!=
p
:
result
=
p2
.
update
(
result
)
# Inform players of what happened
p2
.
update
(
result
)
# Inform players of what happened
log
(
result
)
...
...
@@ -2408,10 +2331,10 @@ def make_player(name, colour):
return
HumanPlayer
(
name
,
colour
)
s
=
name
[
1
:].
split
(
":"
)
if
s
[
0
]
==
"network"
:
address
=
None
address
=
(
None
,
4562
)
if
len
(
s
)
>
1
:
address
=
s
[
1
]
return
Network
Receiver
(
colour
,
address
)
address
=
(
s
[
1
]
,
4562
)
return
Network
(
colour
,
address
,
baseplayer
=
None
)
if
s
[
0
]
==
"internal"
:
import
inspect
...
...
@@ -2601,27 +2524,24 @@ def main(argv):
return
45
# Wrap Network
Sender
players around original players if necessary
# Wrap Network
s
players around original players if necessary
for
i
in
range
(
len
(
players
)):
if
isinstance
(
players
[
i
],
NetworkReceiver
):
players
[
i
].
board
=
board
# Network players need direct access to the board
if
isinstance
(
players
[
i
],
Network
)
and
players
[
i
].
baseplayer
==
None
:
for
j
in
range
(
len
(
players
)):
if
j
==
i
:
continue
if
isinstance
(
players
[
j
],
NetworkSender
)
or
isinstance
(
players
[
j
],
NetworkReceiver
):
if
i
==
j
:
continue
players
[
j
]
=
NetworkSender
(
players
[
j
],
players
[
i
].
address
)
players
[
j
].
board
=
board
# Connect the networked players
for
p
in
players
:
if
isinstance
(
p
,
NetworkSender
)
or
isinstance
(
p
,
NetworkReceiver
):
if
graphics
!=
None
:
graphics
.
board
.
display_grid
(
graphics
.
window
,
graphics
.
grid_sz
)
graphics
.
message
(
"Connecting to "
+
p
.
colour
+
" player..."
)
port
=
players
[
i
].
address
[
1
]
if
players
[
j
].
colour
==
"black"
and
players
[
i
].
colour
==
"white"
:
pass
elif
players
[
j
].
colour
==
"white"
and
players
[
i
].
colour
==
"black"
:
port
-=
1
players
[
j
]
=
Network
(
players
[
j
].
colour
,
(
players
[
i
].
address
[
0
],
port
),
baseplayer
=
players
[
j
])
# Handle race condition by having clients wait longer than servers to connect
if
p
.
address
!=
None
:
for
p
in
players
:
if
isinstance
(
p
,
Network
):
if
p
.
address
[
0
]
!=
None
:
time
.
sleep
(
0.2
)
p
.
connect
()
...
...
@@ -2691,4 +2611,4 @@ if __name__ == "__main__":
sys
.
exit
(
102
)
# --- main.py --- #
# EOF - created from make on
Tue
Apr
2
1
5:05:07
WST 2013
# EOF - created from make on
Fri
Apr
5
1
4:17:50
WST 2013
qchess/src/game.py
View file @
f7cca7e9
...
...
@@ -24,8 +24,8 @@ class GameThread(StoppableThread):
for
p
in
self
.
players
:
with
self
.
lock
:
if
isinstance
(
p
,
Network
Sender
)
:
self
.
state
[
"turn"
]
=
p
.
base
_
player
# "turn" contains the player who's turn it is
if
isinstance
(
p
,
Network
)
and
p
.
baseplayer
!=
None
:
self
.
state
[
"turn"
]
=
p
.
baseplayer
# "turn" contains the player who's turn it is
else
:
self
.
state
[
"turn"
]
=
p
#try:
...
...
@@ -34,16 +34,14 @@ class GameThread(StoppableThread):
if
self
.
stopped
():
break
if
not
(
isinstance
(
p
,
Network
)
and
p
.
server
==
False
)
:
if
isinstance
(
p
,
Network
)
==
False
or
p
.
server
==
True
:
result
=
self
.
board
.
select
(
x
,
y
,
colour
=
p
.
colour
)
else
:
#debug(str(self) + " don't update local board"
)
result
=
""
result
=
p
.
get_response
(
)
self
.
board
.
update
(
result
)
result
=
p
.
update
(
result
)
for
p2
in
self
.
players
:
if
p2
!=
p
:
result
=
p2
.
update
(
result
)
# Inform players of what happened
p2
.
update
(
result
)
# Inform players of what happened
log
(
result
)
...
...
qchess/src/main.py
View file @
f7cca7e9
...
...
@@ -25,10 +25,10 @@ def make_player(name, colour):
return
HumanPlayer
(
name
,
colour
)
s
=
name
[
1
:].
split
(
":"
)
if
s
[
0
]
==
"network"
:
address
=
None
address
=
(
None
,
4562
)
if
len
(
s
)
>
1
:
address
=
s
[
1
]
return
Network
Receiver
(
colour
,
address
)
address
=
(
s
[
1
]
,
4562
)
return
Network
(
colour
,
address
,
baseplayer
=
None
)
if
s
[
0
]
==
"internal"
:
import
inspect
...
...
@@ -218,27 +218,24 @@ def main(argv):
return
45
# Wrap Network
Sender
players around original players if necessary
# Wrap Network
s
players around original players if necessary
for
i
in
range
(
len
(
players
)):
if
isinstance
(
players
[
i
],
NetworkReceiver
):
players
[
i
].
board
=
board
# Network players need direct access to the board
if
isinstance
(
players
[
i
],
Network
)
and
players
[
i
].
baseplayer
==
None
:
for
j
in
range
(
len
(
players
)):
if
j
==
i
:
if
i
==
j
:
continue
if
isinstance
(
players
[
j
],
NetworkSender
)
or
isinstance
(
players
[
j
],
NetworkReceiver
):
continue
players
[
j
]
=
NetworkSender
(
players
[
j
],
players
[
i
].
address
)
players
[
j
].
board
=
board
# Connect the networked players
for
p
in
players
:
if
isinstance
(
p
,
NetworkSender
)
or
isinstance
(
p
,
NetworkReceiver
):
if
graphics
!=
None
:
graphics
.
board
.
display_grid
(
graphics
.
window
,
graphics
.
grid_sz
)
graphics
.
message
(
"Connecting to "
+
p
.
colour
+
" player..."
)
port
=
players
[
i
].
address
[
1
]
if
players
[
j
].
colour
==
"black"
and
players
[
i
].
colour
==
"white"
:
pass
elif
players
[
j
].
colour
==
"white"
and
players
[
i
].
colour
==
"black"
:
port
-=
1
players
[
j
]
=
Network
(
players
[
j
].
colour
,
(
players
[
i
].
address
[
0
],
port
),
baseplayer
=
players
[
j
])
# Handle race condition by having clients wait longer than servers to connect
if
p
.
address
!=
None
:
for
p
in
players
:
if
isinstance
(
p
,
Network
):
if
p
.
address
[
0
]
!=
None
:
time
.
sleep
(
0.2
)
p
.
connect
()
...
...
qchess/src/network.py
View file @
f7cca7e9
...
...
@@ -4,42 +4,98 @@ import select
network_timeout_start
=
-
1.0
# Timeout in seconds to wait for the start of a message
network_timeout_delay
=
1.0
# Maximum time between two characters being received
class
Network
():
def
__init__
(
self
,
colour
,
address
=
None
):
class
Network
(
Player
):
def
__init__
(
self
,
colour
,
address
=
(
None
,
4562
),
baseplayer
=
None
):
if
baseplayer
!=
None
:
name
=
baseplayer
.
name
+
" --> @network"
else
:
name
=
"<-- @network"
Player
.
__init__
(
self
,
name
,
colour
)
debug
(
"Colour is "
+
str
(
self
.
colour
))
self
.
socket
=
socket
.
socket
()
self
.
socket
.
setsockopt
(
socket
.
SOL_SOCKET
,
socket
.
SO_REUSEADDR
,
1
)
self
.
baseplayer
=
baseplayer
#self.socket.setblocking(0)
self
.
server
=
(
address
==
None
)
self
.
address
=
address
self
.
server
=
(
address
[
0
]
==
None
)
if
colour
==
"
white
"
:
self
.
port
=
4562
else
:
self
.
port
=
4563
if
self
.
colour
==
"
black
"
:
self
.
address
=
(
self
.
address
[
0
],
self
.
address
[
1
]
+
1
)
debug
(
str
(
self
)
+
":"
+
str
(
self
.
address
))
self
.
src
=
None
self
.
board
=
None
# print str(self) + " listens on port " + str(self.port)
if
address
==
None
:
def
connect
(
self
):
if
self
.
address
[
0
]
==
None
:
self
.
host
=
"0.0.0.0"
#socket.gethostname() # Breaks things???
self
.
socket
.
bind
((
self
.
host
,
self
.
port
))
self
.
socket
.
bind
((
self
.
host
,
self
.
address
[
1
]
))
self
.
socket
.
listen
(
5
)
self
.
src
,
self
.
address
=
self
.
socket
.
accept
()
self
.
src
,
self
.
actual_address
=
self
.
socket
.
accept
()
self
.
src
.
send
(
"ok
\n
"
)
if
self
.
get_response
()
==
"QUIT"
:
s
=
self
.
get_response
()
if
s
==
"QUIT"
:
self
.
src
.
close
()
return
elif
s
!=
"ok"
:
self
.
src
.
close
()
self
.
__init__
(
colour
,
(
self
.
address
[
0
],
int
(
s
)),
baseplayer
)
return
else
:
self
.
host
=
address
self
.
socket
.
connect
((
address
,
self
.
port
))
self
.
socket
.
connect
(
self
.
address
)
self
.
src
=
self
.
socket
self
.
src
.
send
(
"ok
\n
"
)
if
self
.
get_response
()
==
"QUIT"
:
s
=
self
.
get_response
()
if
s
==
"QUIT"
:
self
.
src
.
close
()
self
.
address
=
(
address
,
self
.
port
)
return
elif
s
!=
"ok"
:
self
.
src
.
close
()
self
.
__init__
(
colour
,
(
self
.
address
[
0
],
int
(
s
)),
baseplayer
)
return
def
select
(
self
):
if
self
.
baseplayer
!=
None
:
s
=
self
.
baseplayer
.
select
()
self
.
send_message
(
str
(
s
[
0
])
+
" "
+
str
(
s
[
1
]))
return
s
return
map
(
int
,
self
.
get_response
().
split
(
" "
))
def
get_move
(
self
):
if
self
.
baseplayer
!=
None
:
s
=
self
.
baseplayer
.
get_move
()
self
.
send_message
(
str
(
s
[
0
])
+
" "
+
str
(
s
[
1
]))
return
s
return
map
(
int
,
self
.
get_response
().
split
(
" "
))
def
update
(
self
,
result
):
if
self
.
baseplayer
!=
None
:
result
=
self
.
baseplayer
.
update
(
result
)
self
.
send_message
(
result
)
return
result
if
self
.
server
:
self
.
send_message
(
result
)
else
:
s
=
self
.
get_response
()
if
self
.
board
!=
None
:
self
.
board
.
update
(
s
)
def
__str__
(
self
):
return
"Network<"
+
str
(
self
.
colour
)
+
","
+
str
(
self
.
baseplayer
)
+
">:"
+
str
(
self
.
address
)
def
get_response
(
self
):
debug
(
str
(
self
)
+
" get_response called..."
)
# Timeout the start of the message (first character)
if
network_timeout_start
>
0.0
:
ready
=
select
.
select
([
self
.
src
],
[],
[],
network_timeout_start
)[
0
]
...
...
@@ -62,6 +118,7 @@ class Network():
else
:
raise
Exception
(
"UNRESPONSIVE"
)
debug
(
str
(
self
)
+
" get_response returns "
+
s
.
strip
(
"
\r\n
"
))
return
s
.
strip
(
"
\r\n
"
)
def
send_message
(
self
,
s
):
...
...
@@ -75,6 +132,8 @@ class Network():
else
:
raise
Exception
(
"UNRESPONSIVE"
)
debug
(
str
(
self
)
+
" send_message sent "
+
s
)
def
check_quit
(
self
,
s
):
s
=
s
.
split
(
" "
)
if
s
[
0
]
==
"QUIT"
:
...
...
@@ -83,149 +142,15 @@ class Network():
game
.
stop
()
return
True
def
quit
(
self
,
result
):
if
self
.
baseplayer
!=
None
: